From a52914175bab9fd29770b02781de3aaea538a9fe Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Tue, 2 May 2017 15:49:22 -0700 Subject: [PATCH] Refactor http::header contents (API Change): fix #124 The http::header data members "method", "url", and "reason" are changed from data members, to pairs of get and set functions which forward the call to the Fields type used to instantiate the template. Previously, these data members were implemented using std::string. With this change, the implementation of the Fields type used to instantiate the template is now in control of the representation of those values. This permits custom memory allocation strategies including uniform use of the Allocator type already provided to beast::http::basic_fields. --- CHANGELOG.md | 8 +++ README.md | 4 +- doc/examples.qbk | 4 +- doc/http.qbk | 12 ++-- doc/images/message.png | Bin 30460 -> 40410 bytes examples/http_async_server.hpp | 8 +-- examples/http_crawl.cpp | 4 +- examples/http_example.cpp | 4 +- examples/http_sync_server.hpp | 8 +-- examples/ssl/http_ssl_example.cpp | 4 +- include/beast/http/basic_parser.hpp | 2 +- include/beast/http/detail/basic_parser.hpp | 2 +- include/beast/http/fields.hpp | 41 +++++++++++ include/beast/http/header_parser.hpp | 9 +-- include/beast/http/impl/basic_parser.ipp | 6 +- include/beast/http/impl/message.ipp | 5 +- include/beast/http/impl/write.ipp | 10 ++- include/beast/http/message.hpp | 76 +++++++++++++++++--- include/beast/http/message_parser.hpp | 11 ++- include/beast/websocket/impl/handshake.ipp | 52 +++++++------- include/beast/websocket/impl/rfc6455.ipp | 2 +- include/beast/websocket/impl/stream.ipp | 18 ++--- include/beast/websocket/stream.hpp | 72 +++++++++---------- test/http/message.cpp | 54 +++++++------- test/http/message_fuzz.hpp | 2 +- test/http/message_parser.cpp | 6 +- test/http/write.cpp | 78 ++++++++++----------- test/websocket/rfc6455.cpp | 6 +- test/websocket/stream.cpp | 24 +++---- 29 files changed, 319 insertions(+), 213 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3653254b..c3b0fd3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +1.0.0-b39 + +API Changes: + +* Refactor http::header contents + +-------------------------------------------------------------------------------- + 1.0.0-b38 * Refactor static_string diff --git a/README.md b/README.md index e9479e46..a2246fdb 100644 --- a/README.md +++ b/README.md @@ -240,8 +240,8 @@ int main() // Send HTTP request using beast beast::http::request req; - req.method = "GET"; - req.url = "/"; + req.method("GET"); + req.target("/"); req.version = 11; req.fields.replace("Host", host + ":" + boost::lexical_cast(sock.remote_endpoint().port())); diff --git a/doc/examples.qbk b/doc/examples.qbk index 708e33f0..5276e2b1 100644 --- a/doc/examples.qbk +++ b/doc/examples.qbk @@ -35,8 +35,8 @@ int main() // Send HTTP request using beast beast::http::request req; - req.method = "GET"; - req.url = "/"; + req.method("GET"); + req.target("/"); req.version = 11; req.fields.replace("Host", host + ":" + boost::lexical_cast(sock.remote_endpoint().port())); diff --git a/doc/http.qbk b/doc/http.qbk index 5d6bae74..b4459020 100644 --- a/doc/http.qbk +++ b/doc/http.qbk @@ -113,7 +113,7 @@ that type. This illustration shows the declarations and members of the __header__ and __message__ class templates, as well as the inheritance relationship: -[$images/message.png [width 650px] [height 390px]] +[$images/message.png [width 711px] [height 424px]] For notational convenience, these template type aliases are provided which supply typical choices for the [*`Fields`] type: @@ -137,8 +137,8 @@ object: ``` request req; req.version = 11; // HTTP/1.1 - req.method = "GET"; - req.url = "/index.htm" + req.method("GET"); + req.target("/index.htm"); req.fields.insert("Accept", "text/html"); req.fields.insert("Connection", "keep-alive"); req.fields.insert("User-Agent", "Beast"); @@ -148,7 +148,7 @@ object: response res; res.version = 11; // HTTP/1.1 res.status = 200; - res.reason = "OK"; + res.reason("OK"); res.fields.insert("Server", "Beast"); res.fields.insert("Content-Length", 4); res.body = "****"; @@ -295,8 +295,8 @@ operations performed). To send messages synchronously, use one of the { request req; req.version = 11; - req.method = "GET"; - req.url = "/index.html"; + req.method("GET"); + req.target("/index.html"); ... write(sock, req); // Throws exception on error ... diff --git a/doc/images/message.png b/doc/images/message.png index 9b88298a162c184f59dea151a5da913acd7019fe..3ea625090c9dd7c8538a4d46719a5727f9c767d9 100644 GIT binary patch delta 39928 zcmezKmhskZCdJMGKX+a(DJ}*E23}7OmmmfPrsE6@j4L?U7#J8EaktaqG=q?k%EMr@r5N zuDrPTc<4m8#eutDYCI@i@gpmbr8mP}amC>u3{SIawg^hI2wl23WATx^0}?GaUR}*w zbSW!mV#a5o&iTh0mMGgDFzJ=(nZK4pHg8JC>W_`Klitn#d^JDxZ0)sm!PW0?{hqV= z{Jr%5^~v>X0;{hlUtJX%T6}g^_PU+7tgNi&2sm*lwg?>B`QJTMp#{vDlB@`3ERo@c zFrG$$lsIu{9tW#+@~{+xFivd*YY+(PYXvh_O!VLK>F9RXGqX%zf3MfFF!aGXZ6@F-r_#xU-XoJ-m*_;JXtERNcBnT>gc|w z#kwsSW_F@WV^8L9Zn<*!uH&a5j*CK{HeH>X9O={|aQ4`|lb`DE3rqg9KIyI4^1`xG zb32z}ONQQug^RmC>{m02$rE+rxY+zD=x&M=$Hf?hC-#BqMuxZhrH=fBhO|2F-P)mj_Bf8U#LUO(>?9OhL$9sX*D@i~jbYa=%=Tls3% zr)j&x6kU>ylaADLm=`=ap!dlrrvJ>N@|9Z>54UZ)t^G9EGcHZ`^HKe}jW3@p6>vIL z=>7Tb`?~9Y&))yz8+zR4>y_ZVKR-U^{r>jWx3G80TOQFq(&l%SmRug~`Xi}%-EUgq0cyJ5wQ)R_tY7M4DLyZ!#R*EiZiWm4zd zkBB<3=KeSPGw&a^%bzRd`^LTY_O`ifFHb1OP+}=RW@N_O<0tm#$r3?-qBv`{O-#@f}kR#Z4D^Ds>MuFf#uUa{coD-@Er* zuYdl1xBI=Alwga=HQ|c4Td&{QzVGYWRp&$B$#A^2|Gn8>`_}xo&1}3y;;|(Y^QH(a zN_?VP-<1+IZSUuE)~u0bFPBa)o0wYvfxZ60y4~+~Eh=R*5IHh%ec+j4F` z+V`PVU*u`y(b@Ah2W))4<3r4opF7Xjo|{{I&hp)+(|Xz`-h7amZJuAoE?1FoGh4uE zirciuS~v3d|Ls~ck7Ln2riGc$4HYF`p|Nr0n z-zSyovU};}33^Y{`FOYg+3{|s9It(mB5}1}L+3yEJpX@ zZ0Qtz_S6HR%v!O{0*g$FRj>AIbJQ+W@{^VvU*>NC8~rn9k9Bx}tUjn#WO zpF8~c|JnZk=J1Z6`FYab)AdUG?S8G0Gf=GmB^aUYT-j-#lYh$l&y;M-V=?>_ri1hy zJ7F{>X3E7aI=>(C*GFu(`gbaP-y^%v_;TrB zZ28^L39G-~t6u*<)^DS4bCbWN#q^z756UKf2ghAB+nVDIuFV?45msmZo4>X0{gBqc z;iWrGc9C0)o?zzF>vzNc{PSk(zoT7YiY+g+D?6i`P8!+$yS(r6 z300kAFD*_+Zt5w0_9@}h7ytiX{Qq8JyE!wvP4l|O=E|5`1_2RoGQ6iff7mV`_Yq<< z-;~(RQqdI)^6P)!c5Qwm@T5d{mceoH8*DWj-df-P=@&SUPaJ=^=V6aQ)fojZB9`+r7!<)&gpZWbz-OZ zEaLBZ2<=!iAzq`|lKrWX{L`ZA3N0GG(eCcZ>y)Do%Qv$LEe%VEZxS+yEbZQ zf9V&fJ^$wB=EB)l+P{A0O(|15-M{F|?tAsqo~r4eJ*DO49Fw$WhsLs(9AZu#zZ$w< z&ao`cnlybAT7B1%By!4k%8_Mz#GE)L%GcDLeIL$ovF1dP4!Cw~fmM@T6Qf(Zn-6d+ zx-8y&T(0^{rKAL-9wbx^G-K^U%#~`G3NQ!n(Arq-cHjkOx^SCR`$C$o6m=}!u0(Ti0oVa zr|P}->%)1wEz55_ER?cZQ(c)@`NI44;pN|6?wPjtTi%=B^R@*=ctzXj?Ruef{o=)k z)2|l&c-a2iBNJCj$>{e3a{#C)TbJMYxUpbsQ9)mQ<<8BF#`{E0 ztf;^H?vA~UguZ3{yrLSJxqs@{ZogLqDy|pao2J`)`XhU@Qlr_Oo#*FH_+Mr5z5C)u z{r^h;{@+ZVD_t3L=f%?Rk@B&h4>X?pd-1`Je{ZVR+SPsAQ~Z9v{B*@V>6J4L5}Rfl zr~6&pRr~$!b^Xgu_0V$dWsv#m@bzW=w%=w*n`BIowk}&^{d7w3syeax^);V7zyJAs ze)nnp{WhEb)&KiEe|N96`L46G&39j1?7sW&_xtzfr~m%;cHf@ety9%oo-BpH6E4#p zbGdvv?Yr~F&fnt4{_nRn{^xJBkbknC=DS_i#XidoQuj*+KPvUNeR=2U^dtYnb-P*^9zn|sSqUt%fw_M!$klnKUdHwfK(@TGE`yr#2kRJE+&YIU&+izQ5Ti-o7mR(b1 zL3&T;>4t=~ll3j-nu`4gtUsMlzI)lm5~9>4!i4UGZ;TrPcqfHQ$fz_`{L; zs_C^;K|8PX(_Md`MO-NMJ9qG}QP{eUer5h|3lH+WkBs|vuljw{)aQvGfsvWi?aIssZ zqkpsa%xOB2kG2=a@35aU`L`-ONHmyZrPt0q!$^QCMK~7j?+1swkhV^-S;&<>J z`n=4t-sz)Z*}4z69u>cR6|p5F@c4y=&b5!euY00!y7~25mzA3$WF?-MZ{GXa{^?1r z@Dm>v7RoMLzhA1tRn321OyPdr=xsl0Bimeh8{*GjlCZ5RIo`r4T=e|ny?b$6=BZY; zJbfg$p*}DC*wJab!x!yzh+F9G_OeCe;`%+}MQh|X#Xz#mmaaWhqFwnN%H=OC{ra$d z?(6I8U;n8+#`4_G`qIwu_|kWG%e~4&b$4jLm}g~w?(nYHT8{bxzh@n7yq~6c^0w)> z7e&wAdi&OLDDM9iy8LPL`gb=sr~m%1bG%F7 zOLbzK3;+IIb>i2?nxCKUJdfX&Gqby8%k~2dr=9t2w`9ogViwnndEsaKHALK$$@T8k zJJL13clejR*ID|0ZoR;y=@7WK?~Ya#gRoQFg>~JR|99Lw>aAA(PMB}W3F{S)n!m5s zX16OU(fwDD`hES$b>ub*LeD7lP`rFTm z0sXfY>d(8HDVg+uhf}ft{-ZmVvASwg9W1UJt&)-mU^2f`;5@xiz49Q}r*qctMgHyo z`|b9-r_3#Ba znESNHd-P+3OxqZ_o-NLgzneZsQh&eI)?(SPiSl+qe=9j8UF3ND7Ish2|GURvM)GOy zjjk=l_4a~acH3#)>p!T@@pyi2$Nys6GT%Aw{o#NWUZ{ujg@k{xQbay^;Pm&i#F8 z$N0VXx4NUgioPlswoZ9GOL2uw7@M0`ebsl1w&lG!&$8#d(`b3(`1{!H7weM06l_hX z|Ekb0oqoLX)71IXXL>gLn0WYc;K?7ofzKwpmvY5gSWmOBvrT0 zPn`dgvu#Q1zTSOm{C{q3@VQ}mLizoP^jDLO3T%!WR{dhve%#ixC*k=yi+pY6@2zfX zUqqis9r|tf=fw)cxqj!R}4R{(I%O_iocO(@xg-a_RrsE@8Ke3k|u?i|5&|al0w-Y~nfl_a76! z&iE&PufIMhb&F9*wSAQo+q0b8+jJ|h+`jLA z`Nhgfs@u-p|GG_Q`kpC!rtA?}tEB(5I7am;%lxyauEg%ro^mPmgqHAgjq-V3w?D_Z zmw)n*pFK5v>92R4uU~L}D15z+m5DLVuOs}H9<0=^U%H~_j+Ru*-|zZzPeHAyPeB}k z^(mHl0uq9Meg=o|JAv9EEib%NpgnFS$7$fPh$n3ar`&EjIHl;W=wIH*K3BmbKfY09b`(J3fTj;LPh>xGRN0a6F`}c3; zwq~9AR&piKJ+xM*&|a5QvGV4uGcyk#kvzftyrb=C(VZQ8jFuRG6`!#5s!x7yPq)_D zCok{pEdH9{Y58uyK*QXdoxg-0wFULb+b{e*k$o3i{l>Zo@x;y1`j<3wW34_MV6IL0 zoq2g#Xf22_6SZqDNq&(FPIocE@)a8ssR zq@VxSNgwU!w3*c3>5uHuvoP0dkF>S8zj*bd`{&oZ)^WD#w=sD8tW$m7i#A^AXZybI zeZO>#uKaH4{5==*l|TM|eBjHen6GP+rTjlVsF=OV_)POU#czrKb#9#d$gw1Q-OgnO zcUL*?Tf!@C_M=9_d+9p2QwM))@Yx2hp7bl}WPOmvZw;x)qE{<8_G#BoXgk<-XxoOW zi2UE>^Nj7xwBkx^KmOaBxH3&_#f4qoyT0AZ<}OW*-MD0p)%M?6-{)HW-*KwxR;?=k zwD)^H`#q~&%2T#~P4|U&y%Y9K*^{GFDf#^VOSX^qs^|Xq42!8#em$W$<*x^CaFcTV z;#VIk6|zsNhsyr5$#Irj{xsKrQ&IiXQ+h^ICBNo$y);NoEIn(Rc=CUgNa?5Nk~dF= zv`aoW*qNKU@ws~5>nplSPj^gD&jG^`}=I~xwq^02yuts`04iN z_N0y3;Wqbef9mW|75cLL=-U+Z+vb{m*zq_fq%Q4sVPI{*{Bvs~ zE`C0*St<}!?itbbaDp>m;bQmxZ=F_E#x)y+-t3!Kb}RGWy)*Oe@7Ml)9e=*I?$wQV z+TZ7XHsHvZgYJZN6>uIy)Z&xGldbSgC~Z(4l1q;u@`r0Or9PJ<$H zxml%B99xZeuGKRib5nKzn&-t#VX^!@WpG2_}eaTojGCOa+`SZxQfJ(cg2z_zW%HKQuO=n#pzrA zpEt5edvW0s>uiHWC-*Ox#QtsHUcddf&9>az(_(Jx?dSh_AUc2V)9ttaf7o+zdiC^8 z>moNVE0{C&a>Cs^JB$C;O*#0@^hDowg%jI2HYHb2alN=pBbxtqQ&QQ<^L_mO(y>|Y z0kXDCrGnSOEf4+94A3vT&%1j2p2`B9*Oh69s^y<0e%HCPeAe%)uN2lV+GT0%rGBBz zy*^X_NrY|6PEfDnO4I@8x_>-Kw{ zcaVCezvuj&{W?1(w+nagdNQ#z-q$Z$F6`XSMCQ;{Wbl0q0w;>L3YInlk!FD9p7wMx7#T0|LX7Sr`%U+g1+BK z?q8I9-uC;P_)n^TZY1}M?whbZ?{3r=)9$SYx9$IMh}-q{{Mv7k`%PA>#XqWvl|EB0 zAFUpzR}!9DdOkYR-%@p*N6iksT`v|jJ$?Lc_xo>QQu~%EFATb|e%bG`+~@C~i0m}* zJ}q1RLG=BkUj=&gEBfS^U%TFF3e5cX!;iZ%rzm=N+1l*}k$-1D)#{(WQMUYupu0%q zW@k0OIWJCku(Fy@SQ)%r?5_Ab#dQkPuZ07K@Hix`uZD%?0+O| z-1_4%|7ZF73ywS5kM7NnXi<0lt}n#OIzLTX`jF~u_2$@D%Y1F$*PoV&%6)4WH)S#7 z0=w(3hwOvAvir1>zEAy~_-6b4x|P4IPRwuq{q4u&{@?T3KcBN+Z=h>-p6jWsechhu zjY+NVYd0LR+SZ-3MCSQ}&B}|X8&&yD*DcNa>0B6of5nT+*uNpKuO6*_fAsI-MDwH{ zpO|9XN|Zk_$rYb5j0swR#rro!qVT^Xu8{-|OV+&!lg?(tT9iIDX?p@v>W09UpjWy*B!M zvd>*9VNsBm+42t41=EaXoiEho zkuW%*-*5ZvMqYHr#+JakKN@F$#l)zyS9#xFIz8^yU&Fw5o-`wO7 z-okUz`(*v;W7DShEOuDlUt)S)R`B%37%5GyN#Q%>>ny_hI@jkEZN0QqDL5eLBfr_r zAl+xhF}h`Tb|qPR)sHRnon0e2VfE@9mP#+jXa6P!bp6!$_0qpSN~7HW`yww(F;Cz2tcG_r=x|5BS}z>#bh?tzWUtaDk%YfA{I-xjAWD z+)rKqQ*p&KcIuSpt-j}EYki(quJN&td8yPW!#UYDsqxcH=IUj7KYlHdZg*s8S-)_0 zyWp1d_W$?1=eut^F|MX?aY3TumUVTn=WSfTlxljwvxVan9sgB_P<^z ze}A=l{jR^?@7sUxj$P$l|MJ=F{BKPxJ~tL!i7S)5yXfPtJ)1-pGfY4JPa^KpJE8P> zlF@b>TJDqt&#`CzUH7p&DV*0}wST-uvq{f2R*8GpL4&b#>wdl5DJ5P!bH~45um5f} zaM0jg{K9hjQ~&FV=b3*hAKCdnO>=S(xMGR;wCN9f*`Aa&igW$bOx2dv8@4su%(bgw zHc*(`&DkCAg$h&vlRoClM+E>`Vy6#o<&f?s9Emlk?;=y}S zqw^_>U3$zDKDS&lna=r+@jTo2#JjsnSN^KHbo#~QNnFO}a=-mqgwN?N-BBg7R!M#P zeVOBjZ7Qb}SG&r8`>yxyS82`DtDW^uCTjP}pM3c9vpzBA&ex9C)YIJO)<#_}ouB_V z)aKQ!wt_40rcK{UbOLv6{b^&4>Q=@woBTvJy?&#Z$n;5%XZCrj(8o_lE;cR0!lCQ4*!0?|316h^P|r!YC^c*+*S)BE9>jmen(b;9%9Opmm z%j0t{3~5L{*{m1!F1osU_x|^aCB~0`CH}lD+A~$6B8|`XOTc=O%QHL;r-AanPG#gj z=G&IfHXZP2ka00{dvw74Rp*yocNB_pzS%Act5=xsJonwT=*OQIXc|?Qzj4d=lg3y3K?=RVvv%Lp zbENzgVG5L*@|+-?j(?qOPo6$lIz6svwps3{unF#Rl`f)6V1*rZT{_1tZ|p2yF8(Ed z&&Rg;t7AFft~s<|((-v#r(!FgPJQ?5_4@Eu4#oNw@ciP&8^z~s@BaDuIaCnR;hIpS zQ}*V@L-z!3#g++sM4UV<^D4LH-+%Y*Zh3rY3&@S2dByHdVf9^4Pfy>i8N6% z)D;|>$JcT*`(9fU`Iyhxf!!nQ8EVt<0qwdE`1&*FSw(P~t9XIxVy%xQS zM^Qz;^~ur+MR%lRihGK?#g3kis`zyB#w4X*k2e?ke96%X%87uedEqRwc9CDp-TEeu zU(I}4_x#Qa$RB8z_xn)uyzFgJUwPg9+OF@>n~v;k<(|9yh0@i`@&(#_-G?8BR2(=i zU;k!X?rpKV^PBJF?S31!h40YUx!=F3>M!`-nRm_mWbeJ&?{{lCR)49BtlT4FBg0YC zcebw0>O1%8+^36qWU^CzG+)8_b4;_t+-(;u zJG>>;`{Os)?nhsXpQpV~zr8ugNuVw}8 zbZM|&{kA~0i!}=C7yT|zo8s4TX@kbwR+-i9$Q}H!!0r7LEOKuK)$N~YJU2VPJnvxB zkN>MeKNj8D@#6-k@T32KwoTc#s^e6Tto1e5ri-?JJ{)#^4I1)$c5d!#UC{{dV?C0O z`|N&Y>)+)Z_ z581`B8C;(GB9w=|0qpI@f z#IyPjj&o~H9((Qjy|ZQ0b}kpDEeT&A{NI*)yGuu6jrj(>9ane_v|AkOrm=f(UQpli zGbQo4ceGPP`&88q zRlTR}00n5xeNZl$9^riJ)~y?!`!Ydh7fd+6A@Oj{55+(CJ~f<|PDtgn z{C=m{_;kX)%IbGJm*;Jmut#K4{q#xG7qOWr_;1nSNNV{F>Y@4B|1G)i>LEVcu;N3) z{*=3Qzu$&`t^`f2nAiQO`2KnR|2yS|mvVm`WS8HOd3o7WEoIQ8jqB^n|62vXGc8|u zHp!UJZRnbAX}`pkb(!DXSKIRLzS7(IMCg5R`6)!u;@B5u8n!$G_AK4+~^eG55_{pVt z{Oq}n$B&)%Fxx4eUvjZq`uHc2t&IilC)P)AKX-PX?e5cNI;zI$=f2!6Qqy>;SEKoS zO02)l$Cmd}d!Eh8Ui7sQu|J(Zic|Jd{M z+3a0E5w_Lxzt_|YeYxYQ*c-c+|HA6aS|=B4hwt)eIP%f9-|E!Pye|oz9Y?#xtL?WJ z@)Y`S%(-cF-`67P2#3DLMmvK;Rx-9{Hy)odV`+oU`(3Z~-rsNg`gqmqb)O1N>o+H* zP2VJ1NzUgn~>oq@}ni?tybwJmpEvkzrM1OvC`<6uQ-`iirHwgR{ zU1JzgmQirY@w@Be<~6g7)6Yd-JYT+ei*aO~$kO}ZAu^Fk(-(z4S*ml~X^Q|eJKvXS zGMrW5QtzflRI7ll%RIsRPW2p$D*DlqkNf0)_7si8XVgL>tc7;(O(;}M7h4-X43)#?u$R(^BXC}aVfS; zc`UY6J?*jLGL=Hv^?SeFYTF-o$}=nNjMW_uujkkI|0|7`bK*Zc+kCx%{FFvj{e3?c zS^s*mc<-Z}&F-e!_MLGPUk0n_|FUkmv=t7^u)^^qMCvmH6Km0#!NRq51k;}3J3A~z*|8mMA>?QijrWk3HZ$*|?*eT3wSZc**9A683b&RlR&_*MTQYG>W*?53l) zw?@_)#cF+j`{lB~{+0T$+Q8*y?+<5&Uw&@!<3TewvMN&zuz^jxA~jXT)cjt)PK8QGb)I%jOy1Z;JLh zS2=Cn(otbu$u}eV(atB8$={Ny*XI1bwe_4K^T!^^g&!CEuoV31`0VeW=l1>g{)gAz zKA2Oc#{af9+Iy+{oRUkPt&b0VW3b#-{M_&RMR)m~i~Ford4xsEy(}|0qkLDcb(2kf z&T*e*QI?l)`_?T#t=`h^aANH&C6287f&ANYZXV*aR%+dm{OQTbf9BrJ|06Z;9RHM& zpRa!_{o*3my4_D_$IZ8^JJiDI`upr$>+KoyFD`Z$Kb5ura^=*dgH5b;|2PeKiL?AuabbiC4OsZs2? zEtArnW^9V6o$2Hr7q%>*(zJEP<4xy+y)2i>y)l2z@tM!w?M>WFp}AA9PwNRY|0D2V z`_^e@T6aL4_+)fKxn zPiw5!*uLf;U}>f7LL=}j&<0)O;CM$<4JTzgTuOIx1%+W z2lbs+{V8*uGwoL6%HZX{-sSHqDOfXl|;c*g6(rVsj$7|n8%i}xT&i_4ik<9YB zWwX{V&U#q!YLeCRJ;y+E*A;pztY7_^Q+)2@>w@bI^~dGw@94js7u>(})uc^fN^e%J zX>*| zc>&ie4N>ee5A3hXddcSh+qCdg827R}YvcCb(mwJ1PI3SI$9tllouB`Hs;yAdxgTGa z+rOQzafsvEi`N(Q}L^s*}C7SG~S|^mez@0-jjgnC~yA%=Ho{P1; zyR-RQ>AUFbNA{g@Dydx`!v3|X|Fdhi*iL3Xivy>Vr^Eyod~OOlbE9wd`hB-fZ#BPH zu~>XwC-dJa=eH!E$UEg3;oZ7XB&biiUO+^j&B1U1*J<4@S+64HeH#+LbWFdboLqDu z!HDHDXg!r^%DU1R-os~CE-wjZkN>?a!)Qm(=NY13?^VBl8>m|J;laVW&a38&yLY-j z+-abt`P0T2G&8X5s7in6?Q@}73MnVu(lcy0-re_N*(G6Wbx-b75O1T0owd<6o&4&0 z?XXGt^W~pb&rj(PsO8;j;BWhNO1|<0bB*~Ldnz3@m!(g%d2v(o`fN~h>&dM&x1JK| zBbF2H3aj~iaO1tD1X^4vv2f}P{Q?%3mGA!Vu@wexaVN66Wmn4h%+zW?npR%Q{i>!8z;qI=?y&E|UJI z{)@%n*RH6JNsJLGJIp@S{&?8_cUN-1?KS<%upMUSP9HzDa{0VjH$^QoFRAR0U&_Dk zxLoxbjUcZ$y?G+~@AvMGaQt`u?Z={=8tps$LdinwL{?8b>h(3zlD)aO=V|ZmWAW!Y z>)-E8|Msu`f0&w*?861OZrxh7EwA%mb7!+!f6NVm1uV037OvfJ?||*M8;eix)8GH6 zXnN_hZQ|QHBY)p)-{-pbL{shwr+Xhu^5vdyEMt;vcbdm~Tv^`3$;0xU@&=*LLZ6Ht zUu!tca7gv;)c#Ay&Ax3sws)RR+@2j5a?NUgm8`#Ut*KS|a8^zIvzh5(r8=cep^T1R z(`Q_j+|Ri+&57U7?&p(5PZir`E-jYljp-~D#mCSDn?65Tw# z_@7ZZC;xssbK`E}o6d8*9dh;O-`|VaBU}Gaxy{nNsNzjm;rmB_o-5SMep-8QXQ7ijNb9tXxIB|dPsG#Trx)0yT%BWCEHM+j+|GNKPTlp}oA%86v?)04X!E;E8#{IT z3N`AZJ}?{(*3k8;xI2$;-sH#q>1!IL{=a(fdZ%tiv>5X;@2?!6-tC>m!I@&d@#ipDYmY83Pp#h>aq8h$gG`~^S!_?gLM!9Q8|GGK7g?BC z7Z%?wyv@^4N&nN2*l-}W>g7^Xcdtw}i5BPS z+PvxYGg+2gosz6rbvdE+A-l7a@fkJkSK9if&hs>wPMh6LWs8lAkPOr_IUP~l(Avr` z^V*hS&9Tb0ul};uZ2Nfsda-uPi6*(gozWbc#}_G;*iZhn!=>Yx+Me>Y74n~tT@`cM zB3EM){ieP`afwWKjLZs#MWFTb8IB@rL9_s9Na*b8FPeoMYvZ5HnBV+&nSbEiucAk8 zyzMQh;n|@rs@E5IW6tys9$S4LT@p6&{u970eD(5Im%5gTN?|+Fo@M3e+{?Z9p}V&8 z(Wh@Vk)I}&PiNeF+f;t%lw?Jh&&>wvJ_?IVIA0#CSFj1JUr~POneCSg&j0FGOcY&I z`Q+)E$jx_-^-BN!U%;fV_%y=Afcst1yTg5dHurVjJG$m@ZR%3f4Gl3xCspf&ri;hd zT;yM~#>~pqvb)6e%QchRw!9M~a-u%XYpF`#aK69pi*oswi|*!cLO!1L^FPyYV()Xw z7k+QvS6$S3A8K45;1_2!WBSY_&dFF@BfE>(=tTr(Dnfo#%V5w>zdZo=YV1 z&^1AqdG9uN3akIh44BE9b*x9y^^{QJg&7R2e)fOA9O6iSlwy=TzuvcVSJqXn`RWE= zOJ=Y){n+>WUGZ%5{BMR!4o4goyJBa<{;>5@m#$dP^ZE7nV(Tiu^{Vopa{94JXXyMd^OyH8sGF_! zdrtAWmqsr;W3@MH3!S+ywPw%v`qDc)3SAZNyouW=m$U5Xnrxo_oxk7huH9?sFjbNx z@|NYMzKvGfa__WTzuR%R{Yv!4B-dw#)8fNww;K7VG=A+XZ<9QC=ojbw^95dy3g&;9 zXY9!T{`vyP=9(2=_s$kf>ReN9_PXMo{rmW;BGq@g8}yGa`K;ACRq=03%lU|T-%q`& z?=J5uH=1IY_EV>n=Y7(>=Y3V%IcH8Nw|T$NM@L4Pi@qb^1zni}Q&(i6|FHhR% z$S1w#m$A6OD`&IgMeRBjeP_vp_xk7kclBwX^iEJ(TK#V4@$G_JYiuHS|MmIO@$cY* z7tT2qHibbq*6ByTx^v$A`0ev{$9JCZ(+SJES%1CWJ#e>N_i4S~6OI?3x7z;CQvB-l z;(C)CJN0|I)m@BaAI~hE`%`k8|F6h1zu$bTe&fAGG?>Nlt##Gxquo|k-#X6yxHRq2 z*JQWyk~8zA|JT*k?%~h8_2k_BHSKS2Kl-ZDmmDqiZDa0pe~okgBEp(wHVm@P?R;M~ zh32(_wnuRNu0K21`ucnG%1-$h2QqXw|>^Fs1(=Y@SHwZMQk_>FFJn+x6Gi z#n%1amV2A)b#DBrQ||@(I8V!cx)z-;dhVcUp-$zJ(-WpT9m?MLDa!KNn#kZ4%h!Bb z+Q0qCzNhQ1);&MC&Uj7ygZ*>ciz6)G#$?_&K9ARWn#;c!_2VCA|EWK5{M_-s=XSBL zc^va}-cg(D9ecXIrP_THUSy)Dq)cYQ;hm+k6@cHio5eLgm+ zI^(_Ccb%H`xwXG4s@*o7bF_SWlVkqtlDMT2JByayumAh&tLtm;z2Qse39r_#-v730 z;oiM_KfEcF>)ZbMqji4d+Iu_0qTA}9u2IoHoIckmHFtY?>z=p!KF_b77#`QQ$#zfv zmD0G%nbTyy?F(mq`|-oVLg}1b+tWw8cjYbLyX}5=^X-Xwr#;_HkI8cE-|)xR-XQjH zN&lKD*WA7KvY+)Sf3kGSV=Io|+wXVDy9Kv6r{0hY2+q1+xBABn!^Pg(w=>_UZn8NM zeX72&^68A!Yx&t8mk!-#DG!TV$Z$UB&`EwqIkSQ?KB?{!=Hx?jaufgQT<)D@8Y2_E zPSDR>AoG%!N7!SJMTXnlEbs1^dir?Z^I0pnvn$@*x^zA3R8id18|P%T?&$cQ)Ge*w z^oc{-C3wn>`*oYQ{7yf`{`CAV_NC{9wd^CGW`{n#QU6Zy`~FFr!d4k>|1I*&S@!nk zXwCT_9$()!lPPCLQ^xsOnky?sc_yYSNlxZxi7mDDqFhd+2+TT|9CSqXJh)7 zE0tN5|39BNy`^d9zlg4oYTWl`BPqnO^S$aqq*}t-imV zx$!pho$~d?={_&s#6|Ac`ULmCv7^OMZB$b)WV$y`p!!OS9kK*tj^r?Apb*=l?FLzP78G-}=pl zNk7wm>IJoz+zgBE|0{WiX-E2xYN3ydt?TXPcZ=)m9m!qZx4Ja8bIM|;={E1{U;J{A z?6?2-Ln;1h)&q+_QP0oMe?MQoIQ-E~@7+>Un=~J-%~4xk;n&zX=L~PxC%b$pOt@_UfFqmdWA}uuJ*li$|m2oxcKF~zVjZmU?)9pkFBbn ztnh+K$ES2ZUJ+vd^4JZ>cgjT`>tYRq`d%NA{P_Fz-^ReQ_wf>(Gglt{{bp$lnskAB-=9A+9;y4LIH^_b`pNqN>mxTGv**6N-2eM~ z7Ox`RE3582v90^@q5k3BQ}Xd;5xYuOhDQYQbe06^f_hI6BVE%z?s>QG_q$fjCqHK- z-%gz#`)s<+dYkRGrhBX8Dm(3szP9RUsj3GS{Y-E$eD?Uom0TW2xFC+yeDiP z*SW+zH#a2MGD{gq*)_9GX)Mm{*1EQAYxebNTO20Yi{0M;YxVw5i??j-yOprZtuZ@d zUrpu2(muCMw~T~lbvA}aEYDbyzw2fFvQ?*>lEShC__z$NnSV-i5Ht)5JhXP+5e^|$Oz9Dj2;J;O^)#r|1)7^e2sN%l! z>5Mo~$7RxcyUI`disdG!*4TV|vOC^0?vrBQCI9miry7SW;(hmi>-D(T!h2(C&e;EW zP~ZHoUam5-ca5gHKJRPOO~2=g->R-E4h*s1>i_cX4RxRX?Ty7(=Wr?CGGE_&xjet8 zdWGbZa@VP{fqT-wn0zq2s_{M|Ug>n9?99T@H);nDTmLfBv$;OF!C@4s`O7K_Sp3g?o#w1xH9gI_v2ve$#p z3#2TcEB0MG>FTn?Bd0>TrMs_ca}}A!USXT2{YvQRtyc#`O7jJ~P93#%xOu=y^xyd) zt_^H{vrIHU$Ly%jE3mn)o#YhGHAUz(?}?y*GfR)!nY?24(mgNcrT)DyU2OZ(s0H5} zpU>fEm^V4g$zYL6kh#Y7Z+*f1f3|&}@oVwCH+zrII{n%A=WA8{z&$(M7WL1_Zr$sz zmaI|y!mIGj#^Yj|_bQ*H#+^EOTA+C2s&9wCp7y-`_v*^I@AzE$f84BZd-V4HPCK)d zi)okZ7Ms+oJzsgEd(TR}OA9;QuPe4sxp&_qdb;nuWy(Ld=txa4U!8aEp~aQk9apyB zf3-{3R%`12hbyjlo%4LGUe{({uH|W2vs8%~vevYjrQf}Qb!T)7vpDt3GQss9@LqD?U$g7jDE}V)y zTc5C}==phV{kMCj@ju;MRD9R0z(Uu%oRv3GwQ}ZHzx1iQ=j>S{;;W)>)}ZHeO|IB8 zu{xLe!}fgbzA!<)ZJQY@%oOsko?7?we2%`n<>8x)KBOa0Q~mdezpf?C^O zesF(j^lYWHcjDoYm3*gSldpX&ySqCmzVTtbl!3^ZqJ^I~iB#_Hi;aw*Az2!=Qg73{ z@Cx0R|HX{Xu`d4YeRb+-%c6auQyy>V({^2xQ2k?1Sk*SKy}MsNw|ZS+9Uc~WxH?nN zL(6u3Or@8ln4&J{i59s~7q%=#$Z( z7bic*O*?!mJLuZeh}rY6F59eUvZSyk%x;>y>fY0+E_-nO^ohTBs1(TZ?5W>4@#oTn`B~|# zZ+Kt4TiPvT&RsL{^j+p%(+mHfC|*AyG_dZ>st<_$YSW%hnyz=5wew`wi+|}4C12-Ruw=2s)4(eq7rRWnq%h-I^UbFL>m*Fr zYIp=wn}4r6IQ6Wye)PxMJ&(Gy|0KM1Gte_(3hHZpvD{?wgw1WMroM{vD*Sxt%84ca zKAiE2dw1>9`z3bIx&pUwK{k!U7E35T-EseLf&!a}KzaS zzW&?epOY7*(*Zbb&2x|_PpBqmm{u1Ink!?_6z!9H%dEzxEW8SQ+Z;d*Yt(s0V1mC*EB{2AN zY~Fsi{{P=Puk>w#Y^!Fv^YqKeX)AM^xOti|T=iS59mSmXaQBBp+q11 zE}K2AY{R9H+jq0f7nMyg$+)19@A&TZgrZF{*FU;0IX!o_-=DB)iQ+c<-`ZcUx%K}8 z_o-d=8}vQ}P2!LJvW-7@-KM)izg}zG%*(6kOV4`rWxD=tUH;#5zk8oMHKFZgcdl(^ z>(eJQbavDgJ96CRyRrX{;nW!EL!0W`en$Llxt^7pDxJDOC$coG6EtAkuIjCQjO~=c zg_&3Q^wUV7?VY%i|1n5r=??pos4rxxE5?{8t9QM{q{ zP3PR_1~ZO*VfVcH|McmP`QDjt?wy|MvSjDy>Z9jFf8FGsZ(cnwvhDm#+w+O1n!Z1- z-)&xI_j{3z+WLvlPdMJ15YTq%T;y$+N97iO_iT-Q(wy_WJnZ-3s%^!5-*~Hof6C5N zemg16NV=Kjc=T_|Kh)$rEz6s-G_tht#37ss60sB{D1wPPhN@gkCq9o zkYRoO@wj~XWHsMUukY7<_T6vuWPvO;6^V!w_!{2YW#|K)P=ii&Naz{}7aryc^+m{H>k=f2%@&E7l zyUzT!Ar*lYlD-KEGtY8A=RKeMRX9$2f8_C?dQS6`?kC8?98^3=Us18(AUU3_xGnK=ZYn4R-Hf6zv1>zw?DUoq+U%4@wM%` zrXZyFPm;&}-i7S6I8poRWg7D>)#~QGj}p9HNOO5FAN46D*r_t`5?R&G$4HOJwgt6P!G^Jg|&Qct7@*ZHRPOPQYXKXGX1 zjdnAO7PFQ;o7PO$m~-vkg}BM=AFo@d-qnsdxeJf+>O=-l?BcumySRT;MbHHCA{ z^hCn^w1cNj@~&;qHTeH_aclAq-<@xhS>tNIUiEPftgha@f0@pkf6w+Fn|1Na#ji8@ zt}YW=Yht@X+j#p<-}$FQrkkx*yF8^n?di;^{j%p{zLoV%)wbz-`_N?8x>G-|&3rfA zNNUPNn@!8!m#9A519V< z3HqAy^O@#!-^i%9UzSw6wDZVERox2M)-QSY>x|FpC4RwKzi*f<$+@kpaq7>`kN>x3 zpPF9ZUc1a!Z$JOnkX3T7+5YlpKcCtxW9MvBY!hxaRqwp!|HGOE-g}w5#YOFpw>_O$ z=dWeEdu@;Rvc210UYMBq?e>!zi@zIAJ})w|$jSE!+hmvhD#QAC6DzluUv-Yr?N1xN z9l6!c6UZd-JP}>Q9&I94}3JbfmMcQ+1kN z`#Xy{#-Y(igo>`}AR`&Y6+dfFwf4KLlRm!HK;OcRet55aj zg&ZoHduE5tw$Iyk`MVyKH?`Wv*M6t0y|`Vq|5#kLc>eD{CqD{x%ig_VU$f-f>m_{E zo8??TH)TAIJa#KP&$0OVk-9hYz2v5Uef{YF!t8%N-(E!Ck9y-3!gpHPrhfejo=ta_ zg)EcZc>mhtwl!uudt>+x?#k9HduAjM6+Q88MDa!*xymOK@5L&VtlUuCBVo8`!#TEj z_TO$KyFNeEKfUZyiciK*({Fc*&!5S*dDtQxv*bXfw$3}Q9i~g}8hvWIdgIo<4f{Sh z)y}e>x3!i{tWalHS#Qkyd)4n_L;poAtv`6@=e&wXocm?$>uTQF>}bDo9kj@!K7Re~ zcUJr7HNGl)8__v4OLnz^Si!CAclLYFKCOzq9MHZ+cCYQ)?Nc6G9qd(cV!ZpQHl=pO3tsJ7o_hVH`uvy)w>2&;Ok`&5S@|$9BmK;bhq1rA?0d>S zH&33~H2a(2cg~c3Ki5lDzuD;iu)JJJeafWm8YMg&hg}=$KQDGzw5HsAQb@kT&t1%? zmhH5dWz>Ig<*l+Q)tTSt9;ubLE?aZ|7(0KL(YpoD=M?wd_pA2(-5V6!wQtT=|BG6$ zILv2VoHsqLYUTH{Mz6CL``pgZzjlAilpxKOG8R^ONVH{F%e?r^DsEs#dO$ zed75qZQ?U~eRHl-(}cP8X5DTYN2(Xc)&IIYKWxh@D~vQp904tHp*o))_PL*A_$KYyo7hrGXguxjrHmb8=ABHmNZ7)S-zPn#-S zdEleU6m1?)e)~Tg`cn)N4mAAOmwPK@!cv#-jGsHtauLiwtY*!@rWgKQdK|rK@3Bk%x7!3?cPRILc)LaO zapW)l-&1$Zw{f4--M{GGmAOk~u5-#+#g)|0`B47u&dYo~bNkxj$`e1LY(cAS;*Ve5 z<$HzeP{Z`D_G#|B7@8u`O(A6bHd(B=jHF}3%a+j}tvOD$L{rdk+50=cS zdCK(kY0OnF)^+>`+ZXi)yf|Bx%D^G-wseZ4h})^)w+%MIDgj~zz`BocWZ>FrNPsqhZ5}A z{s{Uu6gfmyZgZR;A^hrVP4}}$cRD{BcdtIeAGH3+7wx&btEyyDoBmGI?fkwtTv>ld z;)lZH3j3ySJF?&PZI871x$W^Ks~=xV$dzrr4qD}xuVPTI%;u$+C$LOG@%IGglFgg{ zd#cZUa{V$de_CUTr<~gNgLTFKvK%B`BDWW}8z}tYS57>>!1wEsv@e(>7yAOZe zn7`NlM`n12@rJD148Nl`RBbie617w~+$$#FLh%{jW_}5W#AUME9baBKTXdHY!+=+*Z#XT)pYDIV?Y7bO&ri>5P!Egz~i^%9_)Ep98-8yly$qk_GaG?A^ZV0h6VxlTW(IdDdM+oWl(kQb>F>F zUsgxOD7?(vwjwBuU!qb+Y5LaF*Yal1uc%sNl+B(w-B9JLW>=V@xATP42RMSK_n2%w zAy)r%l16Xum8EjIOLP}kOLm@lakn6(xc>N}qLf|_@wKvRojR%-_n6-7mdPutbosec z?8$1^e;U(2xs|PQ-?_4WQCvtCyRMMiQV*rBFvThnx2KO5B{UwH>DaN}R_9>N*XJ1y zuAD!1J=eaU#=x|O=Sah{Xs-J^-9FmC&)sk>S#Z++`i%mM);ru&DxbLj#KWqn+G?gX z`^{!@<$hneeBP_O%%FMy_gX;R?c1yj%g1x;{k^@`L=IgZxICUIjRoxMHDrvPM=qN7G0b)WamU&M9N~>jF z%oB*38e`V!=-pGoy8FHCAr4sw^YEp5x^7P%C0`Z)7gzS~UZ3F2;L_XDPg6qvtb4(l zCHnteSOt4_rQeITd!lC~CaLpxZ@l&DA^S>ewL*rNk8M1XLG>!%ee}Yj{loSvPW@ys zbJ>iSi_|AR-NC6Cru%T?w&xPo2kPGFSFv+PC!bt)Pe=8L1 zujJ-WnOyDSe9B?knwOrgpZ7LzwNaN5-nYB*(}SBYSC?-OOn4yvo0Dv*GKlv7HGOxpI7qyO!}ht9PHD!ZrwWd?)1v%oJIc4L8o=R zO}vhDzv;Wmb=vHs#!R237hkR|dNkktP41&iq5i2qmTpoq7mE~gQU3eq`mZ?xwZ|X5 z3#%%3RrlHDC=<2FX3C~3*Q{=5ys-Cnk)N&N0-lSWZ|_=qA!or2r5BuG@%678+-Fy9 zwLZ0x_dy0*)#f=@n1#<8^jg1kxBoS9SBf;pY}VD6*faC()fZ{Ea3wb_D|+Akt}~)3dn;_;@g@7e`E&lu9_CwC!nfZ_)U+SYW%iP=nz3oRjivnMMO~K? zW^SlB+%R88Ohx2oz{=FSZM@Po<~IB5Ju~AUdnM#5KJlBD)HAgw(|l&#l~4S;D-IVe zO1NDgV{$3A{>eo5u2Y%U5B=MwSKIrv@A#$M2V#c`bJQd6f+jO#ldH_M)?Hl|x79|s z^}D)`dxfn`_EVnMr_wq$ecoudCS2+}xJ&D(v@LCA`jT1MBDUTuBVN6HzVp^|75(}> zvu%va_#RDJo>=|koPhei{ijcZx?UgVw^RrHx~rSo>z>#8TcLQ>!6yRWCs+M{>0f^< zb^aEa(?tu7W-gCoR(!gnU&8p>&bQHXZ-0pS(R4icXI*8{@}!!tCC~Lb|E-S_*1!30 z`^lWcJo|2MQ1$bfJd5>|LGa3d{mzdwYxl30t6wR{yx%Ix;}UDUE=S@T-R1M^s-At@ z{eIu=^TzutJ|^A&QPh{*Z@X>7+=l07Z=Wq}my7yQe?qan(ciw3w(P1Gu0~Poa1?c_W|`wrpPE6_9@krtNY9d z2r`^!SG#Mv{u|JA#_QEm_v_VmImFF4_;6Zu-piuw^z(3F+E?zw1B0ywrdGlTqSwvrGHFRQ>axy(ZIXbAnX*q{Pd)ZoQd_ zvil>Cm&|!+wQPgWWIMCD`72jiYUFlq0tUk9R27@jqI98#|+Tfb8w-=)dxyr*2<$L{!&%4e776ddCGclW7H zgj%8Op(4#q)fXDR-+$-1RZuss`mO1HpYIH`B`MoF!NrMj=9AX@%Lq` z+n);G%y5XC`{U4#ik~mEp4aU)4ok`3y|`lj{XNtF?w@r};iz$5jNPvni_d&5d29Sh zx}14g{l6u*KQ3&S%leVIG&}IY@qYRDvBqI*qn?(%yYo`oYu(PM7h2}7Hx%}S?2ujh zbkFB=pTC~`=~epmQJ$mu#*8!b&b|wHX{mYq_xt_vKOD5ae{4B)Y(`7FeBF)Ru@ipG zxWXQ4R>RXS|8Yb9xeMO%bw3uy-;!w638?z1a4huk#^Z9I>)+RxvpaWRbDs9ts1h__Zdd%|#cDS6Nxi-Em%E$&?Z^KI7S6r))N8~0SI2z|JO9pbt;}iQYZ9@) zb?<=G<6dd=X`(M8ssvx9#pbGTPceAj5lZ<&UWQy;%!}&-0)CulSR|=uZI5k&PSBqc%uJXRUrS`=Q1)F>KZ|Cpd`=tH!mdwjs zk6l265PI+J-fv^O-KCRaxlTEKj->W+jlHXb9`8zv5sjYgF8A`z7wx&x_5T9){JVAY z=jZ(uL38Xc8qTXXJLf+o?ZN`bx&{d^k=TO0ti6WJ{t^~NFPBa)%bc^Z$!C_yNnSad z8?_$}vd1YpJNlVRnCQH8EcnVb(B?P!szv*zRQnako+{Rt zOkfj_t5{fXUzv9KyiJ}6Xb;7Ey$g>I7i(~*nw`+E>Z?#cd$yHd;@(x8jrV;I9+T=x zoquprWPoJ#y zHErjIElhuwO+3r|d+MwnhNC^76LMAe<*iV-oS<-KIy3i4jppg8r7Mej z7uALQzL#pNzWrWR_Os$iS6k;#Wk1itC2}z(;82BMhd^_WLB+O?lBB&(&*#_Iom^q^ zx3#FKe%+Ke9H|V)gWA=Ozqoj^XtKsscD)RjMGqH?s?M(N{(2)tyeQ##pX|SVkBwZf za4mYbwcb&uj*d7Y`WN@`oxL;FHQ=BwiMQKyc79x?diw$*(NXaj@6%c>v_B{;GFKF zz=dZjPoJ$<&{lN$-^`yJ+0zPI8n^vGl@|9Z0jG|CeNH<$!P6EK6;2m2J84L{eF?jr zI=4?^f;vB&dhV?)E0;RoG%#ScPf&Zv;KX3~$nuN()`%HbuT8$1@3GWI;>Wim!u~%x zL}z(8m`JO&UwS`5z{!MrlZ?4S%QDWxtWTd#4UhYnSf8m=5;)H$;Ev9<&M}uTG{lDo6I5_lo%AJ9|@PM;epmkpy2mqnW$HITUB{M)tjSnZ|n2 zBU-3aIa;$XMJ(}1Ly)m$=Q@GIQ!1t(QPgAozC`TM!FUZWA3sHxdNxa!McZ5ZZJeH- z43Fhdd>T=5P^W&&Ql`bi%;neD#s0IuJMpPn@rIQ-oN4jd+pR07y#BN#`@YWfzk9Pq zTBq(f{PfiUwHX?%ckSOrukB)}Oz{m!cW%neb#+(#g++0cbvS8jkisi zy|r~^d*ey&4M9n*$HK)}b=TJmnPpwkSpQ>@$Jtq?r}^h`CMHO6eg5_Jb#3I0{?A|C zcj)alOY_?NUqvKT=U17(mv3tK{!gEtp1wQFH2Y7TkAz|IGoSy0lf=``KDG;ZUh~H0 z_nXbGw*#9%D^@-~lZm*!rpL)dYeySs-{UF{#g-|_fpUL79CEpyBo{CtAnJU*{r{T# zsePtxo{|T4UDE#e<+A_pr&m@6*P5&C+wgK_LT*$0?7UqkwJ*Q99>4p=PQBgR4mPuk z|BL<`*3>T~@({EK@lTh()k~HAHD9lW7vB#rel1~Hw8Z|qZ26tQE$2Z)B-6LwDe4a2 zRk-w|mhx+@+62x({R(x^sk8StA2O-GllkWH=D=m5;-D3$wJolC8&c|yP2F&?Ch@y{ z*yAh%ZOz#4OC{{<_H3V&#Cz1Jv)k1)>_XTfJFgYmyVbAmGPzM}`(%Q%*SqFRJy#`E zrB46fka(DD;nS83HnaSDYd{A%^GZz!PtV#qDdG#)pTNt_hd-6A2Q47fKh68?uvERL zWd4qaZ106nC^(52?fN8Iyj^1T@o(S0=_%ei#k+=kqoX%y)b8eAiNEzPmrnl`aps45 z@xG{}MD9TS0?|XR9>HI@z&T+y%jR!MxqQ3-f8ND#AhBKc*>tm;t*ud9hUWYtiMwob z3vP7l?^`i@0@HM1HW@*tKK>~m<~{j4q5c3D52&*CUh@TXMA|dkhjxp3^yBv2_-|g$ zeVFZ==C(B%EHgNs^qSw(SZ(upP1?>F4n-Hxii^n&n_RD3<%#O=|Fh}4?XuOA*xDRp zD*rTn{I5JupZP$+VBnv>zNrBnY4oSe;GYLk47C!SA)by=^QqS|@UZLYuB=gIuCttXh|Ux>$5I8L*; zxcq@y<7@%>OpX0ZpNQr;MohabSPU|Dqrf8f15Lfz$DdA*Uw2BNmThAAw>!oD_VX0q z{+b-t_fq%d=Rz&e@vE%@q0L9-w@WDgnzZM!ut}dINBzYWpv{=zHP=DVO_&;Pd7_pH z4V-~Y9k(1rn0(v7)xbsjiBB!q&9>?*?&@F$om9r5xI|{V4v&oD8L^KUoKfd}QoyDx z`meaXODn-mT|<<8MrIx7a@RdK!@5PmIxfmjc)G)DQ<{bGjH@|6K0JJPtX?`l#1&l6 zcv!x>e?#Q3eEpw|TF&6Z)lU^>A2wM5+QI}rcyo$o@UEQnWy|~e_}cvn|EEm& zNzh7dk-g3A{9&nJeIAy1v2vA91ovMN*$Z~kU*VmhAqU&#>t0OLkB=+*&CGA};MT2M zMzMM=^`J49mMM?xj{f`o{{3{R3F_bjX`k+RTKVti^S?#6x8=^feY{utc^jYXsxBdr zaT!5RisvxjQJEphujVu3!Q!x#kB_?bcdd=yt`!A2^L@(Wf85L;($36ySU)|eCvpGZ zZ^hZy)_lC|3pqSq^Z4IMdx9MoTTBn0R}a?VlB_%*e5xBLOd*OCah)))#NHJqXjuI% zC$tH2qCiXb>lZIF?sn&A|4!L*!`7>L(U$y8PyVZa&FHW)H1_)L^78sBu8Ga}T{FX{ z-0Qv+eR9(O{jYN)^(r;JKD?~g@a?)36WaPh|I?tr)rc7 z2kO@eEd9NxqXZHAlJqHduV1CJik$UyU$A7-zx+v7uO1YG ztljbby!*>8jlYvuIe$^FT={Opjzx9zb?Vg}>-B#%)c0Jv9VjKb^y(_UiOvsZUs(VB z_>?D04fZ{F^7 zD8(!_qcw0={jya8P9_$?i%X_Yz8dl6I)6y*Q_hR*`f=M*GyZGjc3!%m@pqZvY28Xi zm-#2#-5&BU+G6T;c=4BIDJ?JhL1%V6c5wcjF-0#lltWQ!ioSZ$E8oyo&@So~>^x^? zuPYDcxVXTId0l+{>Q&$?3BES%SomLTss1Xh76IO4;==VmzZgR`sBgF8JtOR7B6nH% zrwZsOXP4N>myZtWwXX!JW%~5ugT~r`P|%GB9aYX1ORN`tF%4}MSmgMl+ePp1@>Nb> z%0*83cI>P8sMVhJYf85|v*a@=jWx5Mv`$c>CYcqt_nSPwo-;D;wF@n&Fet zFvF|bGP_{0z`H zSY){M@6EtlDw2v(j38rTGCJyBid^&MxLB@GzwLQo57hfCxBqj8HVZ83clf6hU<$9OZil;XU zoIS`LSY_+=I8@ZBBQC8*Dc@|h7B~u&i=(G3TP4*Zu=mUsjlcP!&7io=D3L2Ij98i+ z0#eQNvuHy1^7Z12R41O_C{X+H(badsKYBG}<(BGycLfJq#?K4Fcf^5u(tUde}L)6ULX8ueDyZlRXI zqLn+W1!uHGUeYL1bn$PBu{=C=##G~=w$)c}z4w~pl$<<8ZP$(YI|CmwCwNT}`&O{; z^CTNzMY+Jl`d24jRd1C$`%7s%m*TAM`#UW5ToMHZ6n}F}{<$8*Y& zu#|vTixU>hZ9nFkC+hU&X!rHKd6y3_`qI+tTM`leB<=(T^t z)XnMV{mS3#_gwS!+_v!mQ`L0sZ7qDhB97PkJ^vlHSADIn_W$xawusQ@?6==>iJVkC z`K{HnvcP!8q@4S+)@)Bcx!E@0+;Wxr-^KG(J!kT47Fxdc&aoR$ZbU`SwTl0>=i#^O zlRxjBH?e){(GzRFM{Z90nf(0B%*#vp7UgDtDSPTXEm?6Eztp<=Lax_pEiWu5sOz_P z6)s}f-)HUmC}`qSzC^Cn=t=+5JO8Mwcg@kva29%+msE6TibLSG-0Ld0r?GLBs9Kz_ z>~yNXH*L=OHCLajcD;x@xovM#_N+%%cO{mwT;Hsw>Fw@zYu23gi(RB9X>5u7IqUYZ zSqXPvH#*IJZuQYRPr3E0oaV7sE01lhr3yuLnp}#r`fpEeOYU6d#Bq_iX0ID-R_3A= ziK532S=%pl;rA4A4dxSP>(W~CH`9HGU-pYb4`eD&m(|aEZ8hU8YuAg{C$}y2JeBM_ z_mS1wE0HDF?RP4N9=r2ZPV-P}mHFzz2=W#Gk;L(%QI4%sBXXJ zVZ`Q|S*7LK3x4c!ku>GbomSl#S?KJ&_G8>Rqa|xkNe5SMV@*A{$i^_>%x8_ecQ?vR zUu^4{7Q4>vWPRM^h*oZpHHmxkO;#5r#EO9y)Ls8$CwL=1IFv(i*U27@yAw}L&C2wj zlC5(rSg6%(t;oLV8cUw<^xMuTJwfbSU9ab-O}UeqpPJ0QKf&Rk?3AEu?mLpcw|q;P zf6~*aKJ~Ww+BeHj+p9X?+~(NE?VY3jv~AMTE3^H-a!kKpTff9MsLkEQD?e=S@7G=1 z#9uYs50qNs9(!t|z+c%zy9CQJ?Lp;}+c*CwC-$1k^&fJ*Za3{xxv;DLX{J+EF$bTi zdTr8N@vQ8kpvJ-MnCA*R`*>7~6Bl{h-d6DY&jXuj`5A${*ZGTLlX>GGcdb1*xq9O} zakbQX^T1E$YFwXQ?WzANr@1Hgm2KdRTG$x{y44i_Hokd!q6*)LIR%^-}U}D?Axuz_|i7TQf$%Ah1w-qQ|wl* z5^xIPENZ@StbCPL3x{1mDyPsQ{w01dr^Ii%u?>fC96_e z1m=ROlh4i(+t;seu|@kG zf2giG9uKN}ij0&eO79O35FbrnZoUO`1rDGtBZb3kdt|9tKfBev5AdW{(wmaUEe_N=2>3Nrz$|pG#yCy!};p&lgLNfZO;!DZKj%3Rv2lY3bCj~|6 zoORp(jX%~#A%E7qGDR2GWvZVZDTlTS1ogR=3e35a#^_`@XSr5p#tWsnPeAoRpwyGY zPdoPrfX-~veRgK1@sYISo|j@*zCCj!*;sn&Y;HSSX2FDowdNM!z!v=R&rap198X{MIb3&ned} zA5Wf|@3G3JHG8IQwb{%0i>?SydwG4)7E7<^uV0EgO=0-CL31LwQ@Qr&n#j#@{&zIJ z&VI~0HTx{{e|ztgqjegWvYAr(>yH+I$^{ok8IhdbYB#rCc{*Qv-e-fOPcJ;VVY=>e zRBha%n0HfiZfoyQoBiGHPww&Mcb%P%Ru^^Vew*lEc}6rfV?zFk2}|;BHT_!I5*r-7 zL}a__*UQ206#iR#)h}Eg&k@Mk!a zrUl9p6U-O2zkAugxMX$rVUxAjmGxRUEcCqo>rNDQ>JU0nbm!2SS*F}ijkdhY;}waY zuCX|6;n|`<1MR$wmAq4r*&vF9s(Nd9neaTcZ}ncc=`|e{rwbc4$Bzm=|heEI48NegpsD;#cB-PW2{uOU6zC_MRQ zt$sjPd&-rAvz|n8$;(VEx^u62`?ueLR+e7%OP0rQOf;~V$bBEwaCjOqh3)BCwkLaM zYcxgXv8_4YUJVmo!{#l@6KbQ z(aqI|`oHg0xv#3XKlJC`C-qjE>vuM``1riaEHzSCzuft#;JnO<+VB08S~7GewAa5E z+2`BQl_4}iY&qZLh8g@HMXuNWzgOqZ@5eMLEn>>N&P$DfzrN2q74pfc!^-50tv%<7 z`tpw|j`NH6$}DvFZxm#yYGZ*y|RnF1E@`JzI##0{O+~xP94`Ctv>nt|Hf5L9a?q) zU#F_O$nUB6x><(#+T!PnOD4Qdi!cYd(ala^UvBi2zEax@*`T%{XJlXNi~ko4*7aX< zUB#ss)z&@f`@iX{K&P~EEABefFlYTrsg?}Me@d0_K}AQafaIU#DgV~jgF+>W@!seE z9`~w2!&8bbod2#Jy{4k*^1tnSP2(!Zj$0QRY(VAl>h}#c&5TyJ7n>MGhV_D)wfgcB z72WGUHm;k^T%fA#vRdi%MuD}=yidO`Hi->YblKnPS^w@W_tA)s|MT~5X56-F*QY;q zrgvXTx#lD-IoNa8AVEi@KJb_qgL0H($3;)(E~`l$Pdk{IY?mBa!r2$x@zPP!Yt4<` z9uX_CghvvJ4n}n*{K1Ti8(bAxmSiklc-ZBI`vsR4m&rfU{-59Z`d;mM>+k!j^}p}^ z{jqNUs@Uh%^=tN?w|u>3^S67xpBqnw%Q^7o?YR}v*Xqlq@cL5w)3`IAnHJQqo6o;D z#-=7ZRPFCdmU)5~coHnxUPQiV{n^DI?=HgNdpvjM@7WJ;GX(T8F5r>-p16%)w}WXx z=7qm&BtQOR3}jd!!|YJ`=Sq8j%@3nR3>i}U=ImU*U4e^XN-~4S{P({Mm<<_BcwcoK zUn0*C+Q3)Iuyx1BsH}Gv6AtgHz1UvvRlm36Ijcjgojlv`561HUPPN~^YV_Vld4c4C zBAyGz7Y+PR*Zz=pVZ89+%(*+~_dAO)g#K`Ns?EQE%{a==XQ^uL~rYL2fqwu%bKt zOmcmMdBd^8ZTZzA5U-Tpcy*Zb_=Y@&-i~*-aFsa4 zyFko5&in4y`pX;gs%s>kB*`BOsfc5^Qh)UG!}GNk4-N-}r!Nlq0C6}tyZ!fvcQc9 zX3xXJdk>mDmSZllcW(NcpZ3lh9Pd&e`R#1li+BQz-|V|w`{R2DGs9B}hOG1T9~13Q z89Mj|r0=Oeb*CL1vZV*u^}gB5b!af`n#-v7&G;V!Bt`w*aQmpR0E5H#PZiJpF*oG3 zEWEQ|qtu%8e}8_?SKzE?V8|#D(~00Mc7JB_|8Fagscm>F@nZoq1H%g5`5zyq zq}|myzJqU(4D%G$_^S*I7j(Xy)2W|*@uZ!b%2sx5nFTV;3=CJ;e#)F)TK~x3*h=!f z#gt?Q28IT??kSJ#9Sz+qK{rBzLV$sR0Ytq>+_Uxi&dpJun!jCDK6U$hSb470=4H=M zJKdhTsr-GMFWcj=^>Mz=s|~Zvudcf8mh$V%%fJ=Stt?k_)?K-68{fI6G*-f^GEYNx zF1N;Uh5%PKo|3%V^DJueW$QovxLs*kSyL+XDMM^ujqcZ|^QE8ei!1fpR)0%jc35dJ zMcPDl(>$N~Li-i;cJ26m+5U0QtEJi3b}aQb$*cWywc*aM<>xK;?$F!!BPsmll~oH( zGrqjIn0I1=;=7CP@?XD}x;dY^s*~w&6FB?W$C<^C1A438dZkp#Se0ayRbN`-S^w_S zY5ns1KaQD8ZF}dva~<@Yba=V}YL6bt9~ zi2iZPtSPP8_i6r=<)@0y?)YQjH{Ex(*-mBmzLf3l{POo69xZ=!!*F}`_q^@3zstVQ zzW+xpsAJM|Ps93IMyXxag^yfJYG2!azccx}(zG1Vo`blGhpg9^`^%f>-LWV?YkIxJ zBmHQX=sWKCA5GF`IWww%KAnCSw2$+g?e{x5cKN$?!##gZoqeYLT(A}B1jQvQKznj4 zyKXIXZojj7{k~V*a&A7-+xsQx`tI`gIdi5R+gJO0(?{vVUG-OYEuZ(_@s8X7J^kTk zd-{GJ)%MPRon>raeRb#ma*KQaE=kBASCzee{atL~@10MAo}ZSwA6=$@WACS9WzS!m zo^!6SpMGjr>BsyzpwsW}mfx=pl&<{ous!&-i_!kaeb!bQ=gazT1w{S!IaPmqTkgBJ z+wZT-+S~Gd_SKWD;uhb3)(bAZ{_^#D%kQV-t;&ChpX>el{gvwBqECG1Z@zk3_wDAn zzq>zwetl$~q;=VmT<7z>|Na)AzgXlEReIj$^O;HSf2Qn>t^fNq?@$Y;Xstu;jSUBT z#eLS(a!hm`PpmzTbG`G{^aE3x2wa}X33jm1Z)xMI{!(2+SNxKsaczXDwb|t zY*V_o>FCV1lY3&O>BZi%%e}RwZ2g^8iYcGvH`NzBJhURG`1!fsrgOaKFPC;5zF>K) z{KJETZ|u6`pKGdI4zk;Fe!s%vEh1aq#(%h2xLa*Wgv_a8qxgS^Rp0OE)091Y$%Ff< z%9`q{%WtiG^?hdO((9|gMgHDWCbUiVzRKqBGvCS2UH|n%-NmiD{9bBn%-dok;#4Yp zZQ=%yg1L+T)?Z`Wvab5rE0?c{rKz8`Rb}Vq_HNtC6DZTQJL<*0Ezc)EN%`b4d9STA z*W2q`%ly^n$0qKLluDetf^Ti?i#cBJUT>*ZeLK&8H~-|X%d9qkb^7Gj?ff=)_i+U-J#tS~D3O_xZ zAL4Pi{a0J*&e~;HTCeBbpH*F`G4I2}{O1|Br+5T&d589WJ$H6b`Dc-ag81}POEjg+ zdY6h$(_JYtJ1Iy1?~~)rr)2l(==M6Z7wf10HsE-=Gb8c%rahOUY@b@Je6eJ&#$>Ow zjgNymRJk>6j_oRay{LGLNlA=;z3Xnb<8O~@NX}}CT~(CRl|REjc-q^iv!?YsopRmy zX`bG-Wmna#76#kf^PbN*CJ%Q@b6?*9w3r#mBR#eWN|Z!5Y} zKQl>MYnf;2&MOv^zDNBK40)q$`jo{gi)F6oA6Uy&B~#Qd@cUlTyCa=<{;iEJ zdi^S9N&J-j{crD7ALstRkN0nb`dz8xiR;+sF5JKM+v%Hiy6*cg^H2M?`^WL@IntK5 zc9v#;{{FgrhE`}hdqrkeRF+HecjZy%!rv^qQ8F2JhwJR?)lAs zRj*+<$cau2-v0#5z7-AG6b_+Gm}} z#y@p4pRd}Gc6L^VraAkYpc<#aIW{T)TF3!9mIJg`MZl&U<~j#`*Y{ z68lxMei@&i-J)^pwTm?F=(y|1S4**aZ&-43Poc~71xojL0ERb~EHfxGcp z<-c6l-~WGlnr`=>bm#9&FQ-25>(Rb(c6qq^vu&a~1GYT1|9|f7>pKmO=jv^@o!A+_ zUw-%8UWuvixs<<)+cNKa^8NfQ;pfkdMXSVA+!tzGZLfQNZU;kA|HkT*uTH*NVEks@ z_Fvnou6|a$nRl#D_Vu$fGljQK-r#ptP2@{X<1JUsZ3(EBoS3|0;u7ty7&9b&fal+s*jeTk~vY zy3+pR=d2V?&Nn>y{8MSei=!HT^Ul0|{aal2`qT3_=I;4&$vf}mrKJ-mX&w#wci@vK zkLCM4pYN>Qeot!cYtP z7r(o+^I~^>*^?6!Co&aktu5L$BjxV&)BkHuXm7b(YG3uVWy*Xe%F&nLZctEkO?KktzIJNrsoxwlE1?aTkvNBmFxH1$vatljCy zlt1$9J+m|aY*F5V@D=~BKb~5DrEOu%y~^ivo4yCF6bVlHdM770w{&`J+05Cd+0&#g z3KmrV`PkPwwP}r2xa5_6SK_h?&pU}8sPW5i+s^enboR5b#Qmz=fBCMgKXIY<(6!5V zv@X>-PJb1)aEH_WJ5K8qj@}Wd@A~x?@OmGyub9Q;II6sy0_cc{xlaWdcL8i zegDz3R~O0Lzml~hbje>m-umkH+s{r3982Es&;3`-_g^1>{bRAB)duyh-pA{+UUEh?@j)$l_%OOx@*V`BD?wl3+detZW$$u;5?fzmD<=5)l%kplnUuI!4sin?)n(?|7ZVPXGPRnr& zyY=7Nc+tg^{GZPU=a>B5SCbrlZc}z@P}L@tmsPjd|8QD8Yt4jTzL~a%zIF$MdHnvX zAy=iK*Zkze+@Bx!tzOqRJ$Tu%)BnG{{juX*@T^S%rw=We$bIB{*wIXFop`bLo0IQ0 zo?3i=*0t(8YZ_YX>NC&Ju{5?WYF$(Fs7*SrW14Z=nG?qrS6pA;FMWJ!_%YU~Jr#u| zy-zf_13TO-1vcr_{=R*`Z_Pf%#csVt|DL{jxA*(KoLyepXLeuW*1cD>S|erSwNkPE zH6fnfQ(r|N+<)ctw3S<*|Noe9=ii#zsa6YpZ|_gjnY#YS^%Grdw&{ec);qs_*_$i- z-|L2L&i7?^SO2dI$gx~|WRWiS;uO`Jr}nyjUGV$xtCW+IR3j^^j;iiD7L#$Mk59%z z;P1ZcUw>%}{;M)q^PeZ9o9ej5Vv^053(kRaGp0-~n%LbOvB_fJ`L%xcZiL%V zS*=3Z>`SGS{y+2mS>G!%{iv?q9)r(1^_(^xDXM(BCpRgaPJPy6y!-vU>l}uUqVN9- z`zGgM$8P1UCselomDOKg19L6s<8LZ8ySL~Z$>NwS$|Cdu@LB`y|-h?}&SQ{{4i9lz|GjI-Q_wbx#iUAxHm^v2Rv zT+KQT3rmkL?cqwCD{^*I*0mJ|En?2EZ@dsvmYxxM=~Mc_HJ*ueQ^Q{$5N3P*Avx@< z!QU-%Khmc1Ie$9uu<-BF$hDVmhwoe*+Vb|2Tl2=>XW!K?G-#3icIH>in!i(TrA;#8 zU0WTsy=tpK)TFC+YxLIUYA%Uxw$)Y&mIt8CN8I6{w92B`p2b9b5D4s*d5D!-tx)k*?Q}VM?LJ0 zf8t(K(!?IweCCo?cfck2i+$R>r4>`YMoz1I&5%+#A$4U$y3Xb@QLFQP;`Og1QZgk^ z7M(t&`MPw*{vyuX;i{$CVez|x6d)Wx0`8qIM>zamFIh%zGmev z-dw#)CgeZ2n9hX-XWsuTFxh-%|Ka|NXX~@pWCt)_ICH8nTu|%yh0Pc9zbz?>@y~d| zU8+*`@8|QCYxMqUOrG6x_Q$ew3tR2ZJ;_`AtK#q1>yl>|us0XQ>^GPq?ZBF$w&M13 zMfQS=K9N(u^u5=6vR}trtwdMde_l_`1XCd|3zZnD^82;rPm24Jcp8d$E|_Gzxu<{e zK2uCyeb42prE+U;p6#gHI^D`H-}JaGTf?iv8KR(`FKBE4L~9&pU|6}LIM&p>J&D5qa&Bx`cv!`hq5gtpMBl>WMoAeq$>F*alh)Myd3^c` z`xU-Y745CYkshTHU};d^bKBmAg?=-*p3kqh z>y>7BDxu(Z`E1s%$KGtmgKe_!Uf8nY{^>pYOV0&nP99_b@z{QX+lhw3gS)@_$}g>^o1Z`w{2z zCce)rA5S{@@Nj#usOImj>$V)S;yt}`$JDlzWuLoF`WS7iaI(~FDGl_yEwCv>>%^s% zhVv&^UNF^KeQHwJ`bjgtY1d7SHVXW=MsJc)Slr~V+LjS>GiFZNxo-Qn)Z82AHd<|d zxgfRh>NcnF9lLa5b{J?Ib8o5-i;g@zq3x6GHr~mhJG*u*ofzh}x_wLazBw;vG6wW9 zzG^W4^ZQ-4@LcQPInSTjKDZ<9ZvFlB_u}K<-}g@qEc|k};%?Kz$c15g{f{Ge9nn5^ z{pjz0nUlKVdguMaZFVa{4 zVse)m(TJvyA6%-S4;WPO8r@DSmdQv#D-#-S^%1&jxQ=a^Z#f zI<}?PKQ;5)od{mB@88$;yJfA*Tuz-o(kUD}->!C1VQla7dDVJV8(+_uvLbSG+Rk2S z^Jja{m=<5{*54=5%e>m=^_kCllQlc?x|g(i5ND?RzYM zGx>O5@1^-BnL#4wyF|4=i5Q=JJ*W6w;p=N_yPquo{5IKP|I^amzhdDwlj1w3@Ww9Q z#l`OKjxXz5N&~ZQ8=MKMd_K3_?e_Y8zp}o~cok5%VolccN$t0mD5l2dI;RHw z(c1o`P^H*-rHxj4gx*urHSx1q13coKZZCBDdp5uBvhD9Tn{S%wbiZkrubbiP+_mwE z!j)@V*A{$vadDOX;*^V~Gb1NRx5sF#@pFli-nJ>~_J(g!eM0Nabm}d+PaeGHoOWhL z;D>qF_pY@HzPm`pIrxywtrj;fxw8|(OZNS8<-UEp`se2Omno~N=NcDB{o1&<`q5)& z_O09Htt8$D*WA*d7bz<5e{A{RM^8@P`FeCi$(vn8AG+FDF5SCzYgX+2U8UJ&u|KA# zZ&|nWVSL%!W;Whax3^VXy0JOkzofqA;h|R5=e{4$&$Tw+{WkvFO`D^iEG2Wba|=H_ zILMc&6T8dg*7K=nH$7SO$BT_?>ZvQ*M+4{Gdh9m+?DD74$9Yfs{+^O26~-<$|CPsW zt@urA#M&S6pU!*P_KEZJs>j>(r%eBrJ^z)n zdkf!L>utMLS30RUe)gj~@%}4x^djf2Jsf8_xlZQP4xM_xnYX?^y~-l;ZFTjL4#9VC zx8FY}clpZ}C$Zh)aTSW$yfy_79KOj!{!Upq>8t0opvay>p1NOlhfmXq{CtL~_VZcu z=V#xko_=!K-+pd-ZO#9`b9TmwSscw(v9_MMG;mt#=5I4a{ioe1N)s~nzVlMRZ>vmM zm~ni_)01_T^7eH$QT6Zc>@=ReZcVlQpNIU)k~a!B?~42zQ}^@f&5G*p@8(Y5r*j}K zvE=*x`g->34JzDXIwwwj-gZ0h^tI!+wr0=u-MsE;ulc=*GWE^Tc{^3J=lW$!xAk@` zusQ8|;7>~V`+KswsiJdd0Gjp^Y`UfW78vUdrUJu`)PjL)`uJZs-~_hn=|ElZ28@(<@0>& z7C-O2wO}59k+|nP_6r>gWSlR5{3-a4^};jJIr2ZmPj23redNT&bGdi!d`?N^T2pfB~>q0dizbxeGHZSBRaPWoAzn}4P1i#G%? z8a-*dAo=TS-rSBU{+i2v)kf#@NE)g5_f2~L;o;%MrGM{DGtzW@2x>Cdo%TNIacOn< z`bC*1Le+enU(Z^#OJvC&@5CvOG$pn2r}peqc)C2|HpkQpKR-V&*I2$&x8-Zrr=Y!B z^OfFiudmyAV(y9=d#0po7G)g|dLj}P9i45od*Q8PKR!O*eEaFPkC!v0-O}fN4O*XUn#KY6co^}LdI`OmNV@l|D>`c!_9RlL5WVrA=zre*g&mftCKf5NY& z>K^8`d5!1BOWgjB*IYC`H}z=wX*PQ)hnP(2+Mp9_b==LxqwLit@!fGZmPTFRN<3WH zndLt>=Wv#%UhAiyHDaQ>U_J4<4$j{(iSyd(*e5e=4tUZccaq zIq{PwtK03Tr7MYcO0)Toy#gX#mwxX&Y4b(a|8>gB zU&fWa(&l>a=WQ>O{x^5R*WH)Cae-PsM^`A{Nw$k&864!@9Sm1>sS1@lQb~+ zZ?iLI#pXF~?LWHfKJF`;nyz`T>;Lg=E3N07pI5nN2HJSF##m38Z(eRye)B_&)wJdE zYm4I=zv{1xyDD29nLO`R>MFj(plMe)y{DaddwYBORP$aTh1dNelEF8Y%(>Ye-*w{O z-`{tyhR4h1zK&Wbp7vwY)I|$l*MFTfg=wk95(zKP3EFLI&c6Dor#dZa0{L!hc(N_b<%$446TH*IUr(>vr=JHa)MYi(@&x*(OC%Qa6f<-5IX+rp}C zW%bHS4RWLve@*>&#`wI8*YZzmP2POp^D1tgvYLMBmt7wYaVuA9+INfTcHL^wxpLAk zAY(-Y+X#Ub5M*{C4m!;mr9~XKq#|vhO};bxJn-^wNbES0eQ*_x;+a zp`R$V-S5?nz<}p1l^Rz(H$Ngj9-0pIAeEsS`{nF2e`ogX?x*xPkZIwN9rBmDIc&gQ*$mi>dtgr5za?WRJNt0Ju zSTMWlQ|p=juP?0l)~=Z}d9M7ayH=MXr6xt+c)4oQx#Veima?DL zlsVqpBF8zzwkby!Oba8^p(JJ!DxmBmWe_F3@?hFY}S(Z{aLr_ z^UNtJr4J7K3tkF{)-3NNSeQT($1fBIs@wR!w@N=J^Zh|HzY<8fgC*OGySukX zZ^;mBVyFjO*l@U=-(5KjWZwcA=lAn_Es=N-{{F zDY*G|##Fs0P273~%5FU`CVrY>S)5i@`}5ON)3e@-qwd!;GH9`$HgphIN)DU#@Y5Ad zP1%o|78?n@=Rf~(SMrv)4(IkqkE5Px&y{`bF;95eY#-$_&Fg|?66Ls$CO)6q75Q=r z$Em1a2blSHOjLH?bzHvQCNwhGB4mZa%;HNTAGZ8mUgNmse@K9W_4dssT(RX^t`@iI zbp(2rM(gxCEqNOGv3|+a^WVZJ^=YKkZnu%~UYT=Se%|D1&$raP)4g`VJLFlvXhy@* zB@44BU!NXy?c6Ok1`~m|Z{M;w9cDSd{Mq^W_v7BLiCTJQS-WlZt=s%^J=dq}o!!4~ ztLeShoV&hj;h#Rax$^y&^rqU{DcbghrRrI| zrlSij4qHshR7rhjf8o3wa?jn zHFGSpqCi03>i+ukZe2_3!_!5RxWDbYRvpHbwu0H?;Fj;}HJ2@$)AsSE^<9zB;2FM> z+saGpS1i%y3*L9Qe9t#cjq_ZmCSOne^l3q@Son^-_jOOBf3L0C6?a_p{!5MH#k$IY zQj0ftb%;m?8@!e3cIKMYm%U#zMQr)DQkxKk%Tu;`O-(+%+^ORc=jBkzB?j8H!E>&+ z#@mJl^!Z-gTrvHZzF}_uR{i;Y0ry1qA6;C^ojbE@YjS7?&?#3wZ0R;$ zhAGKYl9?7B*E(+5s#-jKslr`_kQ`sZt>0JXwpT@el3LqdHACd`2dUsBXYQ>fTTJGj zUvt$e?|t>@=1ZGPHR~@W#yNAB8_i$(ifx(8%&pg_LMQiU|D?4Q2@Xp#>bjE6nO=L+KLH+G#9-d*;#YZ`Ot1g4nkw_7h39d6^j7-V-Y z?q=chdDVGWUzOh3QFu-}?cK`d^SZW$uZa-M?Uypus_tvcl77>=YEN70DzRtrIyblc z;0kUd9DjxURoMD*7GbOn}s_6aRjYYew zw#Gd;cXodKpBm}VRrUYx*sY)Ka;iY$-M-ylY;3+vC=QQNWK}FX5KuF9LrLcG8j*{^ z!4sJlPn4Qh|L>>A%cw0G6K`+JjsEuI;o){`jj*5qC#QPWl{15Tlu%g=s%e0;MsxJC7_?LMVL3Gy6Q zlfJ#VIkD*Xm&^XURlTP@nQGcQ|No!oE5FV=^L$U`XRULSQ*z{e#rD6ldeY2qr(u2X z)dCgF>pE;;y>5iobmeu!8OMJ1z z>6V7Tv|~3mCMzHP_-uCmIl1b;U#~B&O+MDsDYE*q`MFKP}|v{5@ks&5HUp#%X6fbXWfii->%`>-D-#x7ip>7=BC> z_+a_YY7O(882hKIGUh&Vdcr@)Y?t#5Nx!PM*_&4<`DNaARAvk{1<2gSa+uzL* zTVMKZbMDdU&!XqV@Sk3gy)|zxuXpKjpU;-t-Y$8+`ls^lBOT127_V+C-BKhuKYIEj z{cO7xtycBR=lZqpNs(G8pZ#LB)U)$e%}Yz2yidDJv~yc6ZcW|VS9eR_KJv9jc%Od$ zraYZ_Oa5;uT@)>0HBa5@N$b~5CIwCW?uvnTx)$H5*>%K2T+R5i;kIpw$8&AZwEt9S z&po~Lhe&kfLSG7Ip9Vbn3^BKU2fko{B6#s=NKk@%0w*)n|8Z zzgLuZbCX4#b2SK``3?aPi>Z(UwSRF za^LD%El$_mBLAdJ{M_Z6Qoq#1d&RWfpt|I_Bw+22}I`802V$+|74PAsUYYQ3=c!y)c{@2YoC)ed)?78kkFzvbK$N2`-H z8hq>jxYeDl{q?1D%>(yZWzOYu!fu+>ZHZxc(y#0NX7BfV(viVar~S+jf7Gd7Kkr18 z_g<$LW_focPR3sUuKl1Q?u6^nQwuCo9`dcdermeT-cJurPp{Sa<+)ST`6K^%i|5&~ zKY5o=3aj!uoU(8~Z&vg}OMd%51uE{b>lb{9ul;&8XOG+Zp2zhYXNpg)-+8s9b-p=6 ziLLI{Pvy)nrm@|=q;&eD`={^OY)=>$oXh@Hf1Ov&wfjPR&R70P@AEcImJ4aCTkh>R z`H;@jP0P<6Q2*W(Fwt-E70HiJnhX*TwRl`KX|=Lh=9d>_HaoG+wpQjusM^{!im!4i z?^QnEd3LsW@nuKHFLKcv5)QKL|22=_-S{+r?GK5&Yqlj=vaOi8NM2vv_tgps=dXsY zzAJ*`{6p(|j+$nkdn>B2KT4YO(M5Op+^m_csegCx|Gj(B^HWB(<(7Ms7#HljcfMw> zL$c?=<(1&$A-^70(JP zzea>L6df#z*$=W@aPG^DppJ`=SGE7C3hY_!ov!RpJ)-kymO+;o1ibA|f8 zV>(v@yvaRw(x_n{`!%^Hrl?x-E69Qkp+cPIo_w2|9Rvi|LeyE^UYVjEuX;0z+fUE z|GVH)`}f+6(>h!K8t#hBJy^uk+cr;P{*MpU@^+sdhJ2X7$iPsaAyPNLvb}anEPIhrsqTu69tZ2aSo;%C3Z zMLk740fO~sYy$qx`1!~!#*mGn!7X%xucsSm+2x8KjzV>Xprp7!#+md oG6ba!2Jpg71~f|K@qcau1|Q?gPwxje*@D8>)78&qol`;+03JpGYybcN delta 29900 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 OFnGH9xvX res; res.status = 404; - res.reason = "Not Found"; + res.reason("Not Found"); res.version = req_.version; res.fields.insert("Server", "http_async_server"); res.fields.insert("Content-Type", "text/html"); @@ -248,7 +248,7 @@ private: { resp_type res; res.status = 200; - res.reason = "OK"; + res.reason("OK"); res.version = req_.version; res.fields.insert("Server", "http_async_server"); res.fields.insert("Content-Type", mime_type(path)); @@ -262,7 +262,7 @@ private: { response res; res.status = 500; - res.reason = "Internal Error"; + res.reason("Internal Error"); res.version = req_.version; res.fields.insert("Server", "http_async_server"); res.fields.insert("Content-Type", "text/html"); diff --git a/examples/http_crawl.cpp b/examples/http_crawl.cpp index a34f067d..6f4a02d5 100644 --- a/examples/http_crawl.cpp +++ b/examples/http_crawl.cpp @@ -37,8 +37,8 @@ int main(int, char const*[]) connect(sock, it); auto ep = sock.remote_endpoint(); request req; - req.method = "GET"; - req.url = "/"; + req.method("GET"); + req.target("/"); req.version = 11; req.fields.insert("Host", host + std::string(":") + boost::lexical_cast(ep.port())); diff --git a/examples/http_example.cpp b/examples/http_example.cpp index d58524f5..1eccff54 100644 --- a/examples/http_example.cpp +++ b/examples/http_example.cpp @@ -23,8 +23,8 @@ int main() // Send HTTP request using beast beast::http::request req; - req.method = "GET"; - req.url = "/"; + req.method("GET"); + req.target("/"); req.version = 11; req.fields.replace("Host", host + ":" + boost::lexical_cast(sock.remote_endpoint().port())); diff --git a/examples/http_sync_server.hpp b/examples/http_sync_server.hpp index 37877568..26f1b997 100644 --- a/examples/http_sync_server.hpp +++ b/examples/http_sync_server.hpp @@ -158,7 +158,7 @@ private: http::read(sock, sb, req, ec); if(ec) break; - auto path = req.url; + auto path = req.target().to_string(); if(path == "/") path = "/index.html"; path = root_ + path; @@ -166,7 +166,7 @@ private: { response res; res.status = 404; - res.reason = "Not Found"; + res.reason("Not Found"); res.version = req.version; res.fields.insert("Server", "http_sync_server"); res.fields.insert("Content-Type", "text/html"); @@ -181,7 +181,7 @@ private: { resp_type res; res.status = 200; - res.reason = "OK"; + res.reason("OK"); res.version = req.version; res.fields.insert("Server", "http_sync_server"); res.fields.insert("Content-Type", mime_type(path)); @@ -195,7 +195,7 @@ private: { response res; res.status = 500; - res.reason = "Internal Error"; + res.reason("Internal Error"); res.version = req.version; res.fields.insert("Server", "http_sync_server"); res.fields.insert("Content-Type", "text/html"); diff --git a/examples/ssl/http_ssl_example.cpp b/examples/ssl/http_ssl_example.cpp index cb9391ec..86005604 100644 --- a/examples/ssl/http_ssl_example.cpp +++ b/examples/ssl/http_ssl_example.cpp @@ -35,8 +35,8 @@ int main() // Send HTTP request over SSL using Beast beast::http::request req; - req.method = "GET"; - req.url = "/"; + req.method("GET"); + req.target("/"); req.version = 11; req.fields.insert("Host", host + ":" + boost::lexical_cast(sock.remote_endpoint().port())); diff --git a/include/beast/http/basic_parser.hpp b/include/beast/http/basic_parser.hpp index df7a4d9f..e1b67ea6 100644 --- a/include/beast/http/basic_parser.hpp +++ b/include/beast/http/basic_parser.hpp @@ -94,7 +94,7 @@ enum class parse_state void on_request( boost::string_ref const& method, - boost::string_ref const& path, + boost::string_ref const& target, int version, error_code& ec); diff --git a/include/beast/http/detail/basic_parser.hpp b/include/beast/http/detail/basic_parser.hpp index 96e2c4f4..254694de 100644 --- a/include/beast/http/detail/basic_parser.hpp +++ b/include/beast/http/detail/basic_parser.hpp @@ -285,7 +285,7 @@ protected: static boost::string_ref - parse_path(char const*& it) + parse_target(char const*& it) { auto const first = it; while(is_pathchar(*it)) diff --git a/include/beast/http/fields.hpp b/include/beast/http/fields.hpp index 0c301199..4fc0a2d5 100644 --- a/include/beast/http/fields.hpp +++ b/include/beast/http/fields.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -297,6 +298,46 @@ public: replace(name, boost::lexical_cast(value)); } + +#if BEAST_DOXYGEN +private: +#endif + + boost::string_ref + method() const + { + return (*this)[":method"]; + } + + void + method(boost::string_ref const& s) + { + return this->replace(":method", s); + } + + boost::string_ref + target() const + { + return (*this)[":target"]; + } + + void + target(boost::string_ref const& s) + { + return this->replace(":target", s); + } + + boost::string_ref + reason() const + { + return (*this)[":reason"]; + } + + void + reason(boost::string_ref const& s) + { + return this->replace(":reason", s); + } }; /// A typical HTTP header fields container diff --git a/include/beast/http/header_parser.hpp b/include/beast/http/header_parser.hpp index 72cdaa01..3dc0c0d9 100644 --- a/include/beast/http/header_parser.hpp +++ b/include/beast/http/header_parser.hpp @@ -112,10 +112,8 @@ private: boost::string_ref const& path, int version, error_code&) { - h_.url = std::string{ - path.data(), path.size()}; - h_.method = std::string{ - method.data(), method.size()}; + h_.target(path); + h_.method(method); h_.version = version; } @@ -125,9 +123,8 @@ private: int version, error_code&) { h_.status = status; - h_.reason = std::string{ - reason.data(), reason.size()}; h_.version = version; + h_.reason(reason); } void diff --git a/include/beast/http/impl/basic_parser.ipp b/include/beast/http/impl/basic_parser.ipp index b7e5ba4b..533fed19 100644 --- a/include/beast/http/impl/basic_parser.ipp +++ b/include/beast/http/impl/basic_parser.ipp @@ -396,8 +396,8 @@ parse_startline(char const*& it, return; } - auto const path = parse_path(it); - if(path.empty()) + auto const target = parse_target(it); + if(target.empty()) { ec = error::bad_path; return; @@ -416,7 +416,7 @@ parse_startline(char const*& it, } impl().on_request( - method, path, version, ec); + method, target, version, ec); if(ec) return; } diff --git a/include/beast/http/impl/message.ipp b/include/beast/http/impl/message.ipp index b15b89d6..aa50cdbf 100644 --- a/include/beast/http/impl/message.ipp +++ b/include/beast/http/impl/message.ipp @@ -28,8 +28,6 @@ swap( { using std::swap; swap(m1.version, m2.version); - swap(m1.method, m2.method); - swap(m1.url, m2.url); swap(m1.fields, m2.fields); } @@ -42,7 +40,6 @@ swap( using std::swap; swap(a.version, b.version); swap(a.status, b.status); - swap(a.reason, b.reason); swap(a.fields, b.fields); } @@ -199,7 +196,7 @@ prepare(message& msg, { using beast::detail::ci_equal; if(*pi.content_length > 0 || - ci_equal(msg.method, "POST")) + ci_equal(msg.method(), "POST")) { msg.fields.insert( "Content-Length", *pi.content_length); diff --git a/include/beast/http/impl/write.ipp b/include/beast/http/impl/write.ipp index a6e64025..bb8f16e0 100644 --- a/include/beast/http/impl/write.ipp +++ b/include/beast/http/impl/write.ipp @@ -37,9 +37,9 @@ write_start_line(DynamicBuffer& dynabuf, header const& msg) { BOOST_ASSERT(msg.version == 10 || msg.version == 11); - write(dynabuf, msg.method); + write(dynabuf, msg.method()); write(dynabuf, " "); - write(dynabuf, msg.url); + write(dynabuf, msg.target()); switch(msg.version) { case 10: @@ -68,7 +68,7 @@ write_start_line(DynamicBuffer& dynabuf, } write(dynabuf, msg.status); write(dynabuf, " "); - write(dynabuf, msg.reason); + write(dynabuf, msg.reason()); write(dynabuf, "\r\n"); } @@ -82,6 +82,10 @@ write_fields(DynamicBuffer& dynabuf, FieldSequence const& fields) // "FieldSequence requirements not met"); for(auto const& field : fields) { + auto const name = field.name(); + BOOST_ASSERT(! name.empty()); + if(name[0] == ':') + continue; write(dynabuf, field.name()); write(dynabuf, ": "); write(dynabuf, field.value()); diff --git a/include/beast/http/message.hpp b/include/beast/http/message.hpp index ae47d633..5d4621fb 100644 --- a/include/beast/http/message.hpp +++ b/include/beast/http/message.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -65,17 +66,53 @@ struct header */ int version; - /** The Request Method + /** Return the Request Method - @note This field is present only if `isRequest == true`. + @note This function is only available if `isRequest == true`. */ - std::string method; + auto + method() const -> + decltype(std::declval().method()) const + { + return fields.method(); + } - /** The Request URI + /** Set the Request Method - @note This field is present only if `isRequest == true`. + @param value A value that represents the request method. + + @note This function is only available if `isRequest == true`. */ - std::string url; + template + void + method(Value&& value) + { + fields.method(std::forward(value)); + } + + /** Return the Request Target + + @note This function is only available if `isRequest == true`. + */ + auto + target() const -> + decltype(std::declval().target()) const + { + return fields.target(); + } + + /** Set the Request Target + + @param value A value that represents the request method. + + @note This function is only available if `isRequest == true`. + */ + template + void + target(Value&& value) + { + fields.target(std::forward(value)); + } /// The HTTP field values. fields_type fields; @@ -197,17 +234,36 @@ struct header /** The Response Status-Code. - @note This field is present only if `isRequest == false`. + @note This member is only available if `isRequest == false`. */ int status; - /** The Response Reason-Phrase. + /** Return the Reason-Phrase. The Reason-Phrase is obsolete as of rfc7230. - @note This field is present only if `isRequest == false`. + @note This function is only available if `isRequest == false`. */ - std::string reason; + auto + reason() const -> + decltype(std::declval().method()) const + { + return fields.reason(); + } + + /** Set the Reason-Phrase + + @param value A value that represents the reason phrase. + + @note This function is only available if `isRequest == false`. + */ + template + void + reason(Value&& value) + { + fields.reason(std::forward(value)); + } + }; /** A container for a complete HTTP message. diff --git a/include/beast/http/message_parser.hpp b/include/beast/http/message_parser.hpp index a6112481..1b6dcc78 100644 --- a/include/beast/http/message_parser.hpp +++ b/include/beast/http/message_parser.hpp @@ -158,13 +158,11 @@ private: void on_request( boost::string_ref const& method, - boost::string_ref const& path, + boost::string_ref const& target, int version, error_code&) { - m_.url = std::string{ - path.data(), path.size()}; - m_.method = std::string{ - method.data(), method.size()}; + m_.target(target); + m_.method(method); m_.version = version; } @@ -174,9 +172,8 @@ private: int version, error_code&) { m_.status = status; - m_.reason = std::string{ - reason.data(), reason.size()}; m_.version = version; + m_.reason(reason); } void diff --git a/include/beast/websocket/impl/handshake.ipp b/include/beast/websocket/impl/handshake.ipp index c4c5e142..337f128f 100644 --- a/include/beast/websocket/impl/handshake.ipp +++ b/include/beast/websocket/impl/handshake.ipp @@ -43,14 +43,14 @@ class stream::handshake_op data(Handler& handler, stream& ws_, response_type* res_p_, boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, Decorator const& decorator) : cont(beast_asio_helpers:: is_continuation(handler)) , ws(ws_) , res_p(res_p_) , req(ws.build_request(key, - host, resource, decorator)) + host, target, decorator)) { ws.reset(); } @@ -164,7 +164,7 @@ typename async_completion::result_type stream:: async_handshake(boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, HandshakeHandler&& handler) { static_assert(is_AsyncStream::value, @@ -173,7 +173,7 @@ async_handshake(boost::string_ref const& host, void(error_code)> completion{handler}; handshake_op{ completion.handler, *this, nullptr, - host, resource, &default_decorate_req}; + host, target, &default_decorate_req}; return completion.result.get(); } @@ -184,7 +184,7 @@ typename async_completion:: async_handshake(response_type& res, boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, HandshakeHandler&& handler) { static_assert(is_AsyncStream::value, @@ -193,7 +193,7 @@ async_handshake(response_type& res, void(error_code)> completion{handler}; handshake_op{ completion.handler, *this, &res, - host, resource, &default_decorate_req}; + host, target, &default_decorate_req}; return completion.result.get(); } @@ -203,7 +203,7 @@ typename async_completion::result_type stream:: async_handshake_ex(boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, RequestDecorator const& decorator, HandshakeHandler&& handler) { @@ -216,7 +216,7 @@ async_handshake_ex(boost::string_ref const& host, void(error_code)> completion{handler}; handshake_op{ completion.handler, *this, nullptr, - host, resource, decorator}; + host, target, decorator}; return completion.result.get(); } @@ -227,7 +227,7 @@ typename async_completion:: async_handshake_ex(response_type& res, boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, RequestDecorator const& decorator, HandshakeHandler&& handler) { @@ -240,7 +240,7 @@ async_handshake_ex(response_type& res, void(error_code)> completion{handler}; handshake_op{ completion.handler, *this, &res, - host, resource, decorator}; + host, target, decorator}; return completion.result.get(); } @@ -248,13 +248,13 @@ template void stream:: handshake(boost::string_ref const& host, - boost::string_ref const& resource) + boost::string_ref const& target) { static_assert(is_SyncStream::value, "SyncStream requirements not met"); error_code ec; handshake( - host, resource, ec); + host, target, ec); if(ec) throw system_error{ec}; } @@ -264,12 +264,12 @@ void stream:: handshake(response_type& res, boost::string_ref const& host, - boost::string_ref const& resource) + boost::string_ref const& target) { static_assert(is_SyncStream::value, "SyncStream requirements not met"); error_code ec; - handshake(res, host, resource, ec); + handshake(res, host, target, ec); if(ec) throw system_error{ec}; } @@ -279,7 +279,7 @@ template void stream:: handshake_ex(boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, RequestDecorator const& decorator) { static_assert(is_SyncStream::value, @@ -288,7 +288,7 @@ handshake_ex(boost::string_ref const& host, RequestDecorator>::value, "RequestDecorator requirements not met"); error_code ec; - handshake_ex(host, resource, decorator, ec); + handshake_ex(host, target, decorator, ec); if(ec) throw system_error{ec}; } @@ -299,7 +299,7 @@ void stream:: handshake_ex(response_type& res, boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, RequestDecorator const& decorator) { static_assert(is_SyncStream::value, @@ -308,7 +308,7 @@ handshake_ex(response_type& res, RequestDecorator>::value, "RequestDecorator requirements not met"); error_code ec; - handshake_ex(res, host, resource, decorator, ec); + handshake_ex(res, host, target, decorator, ec); if(ec) throw system_error{ec}; } @@ -317,12 +317,12 @@ template void stream:: handshake(boost::string_ref const& host, - boost::string_ref const& resource, error_code& ec) + boost::string_ref const& target, error_code& ec) { static_assert(is_SyncStream::value, "SyncStream requirements not met"); do_handshake(nullptr, - host, resource, &default_decorate_req, ec); + host, target, &default_decorate_req, ec); } template @@ -330,13 +330,13 @@ void stream:: handshake(response_type& res, boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, error_code& ec) { static_assert(is_SyncStream::value, "SyncStream requirements not met"); do_handshake(&res, - host, resource, &default_decorate_req, ec); + host, target, &default_decorate_req, ec); } template @@ -344,7 +344,7 @@ template void stream:: handshake_ex(boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, RequestDecorator const& decorator, error_code& ec) { @@ -354,7 +354,7 @@ handshake_ex(boost::string_ref const& host, RequestDecorator>::value, "RequestDecorator requirements not met"); do_handshake(nullptr, - host, resource, decorator, ec); + host, target, decorator, ec); } template @@ -363,7 +363,7 @@ void stream:: handshake_ex(response_type& res, boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, RequestDecorator const& decorator, error_code& ec) { @@ -373,7 +373,7 @@ handshake_ex(response_type& res, RequestDecorator>::value, "RequestDecorator requirements not met"); do_handshake(&res, - host, resource, decorator, ec); + host, target, decorator, ec); } //------------------------------------------------------------------------------ diff --git a/include/beast/websocket/impl/rfc6455.ipp b/include/beast/websocket/impl/rfc6455.ipp index 684112bb..e04bd11c 100644 --- a/include/beast/websocket/impl/rfc6455.ipp +++ b/include/beast/websocket/impl/rfc6455.ipp @@ -19,7 +19,7 @@ is_upgrade(http::header const& req) { if(req.version < 11) return false; - if(req.method != "GET") + if(req.method() != "GET") return false; if(! http::is_upgrade(req)) return false; diff --git a/include/beast/websocket/impl/stream.ipp b/include/beast/websocket/impl/stream.ipp index 135248e8..3fc0bf6f 100644 --- a/include/beast/websocket/impl/stream.ipp +++ b/include/beast/websocket/impl/stream.ipp @@ -128,7 +128,7 @@ void stream:: do_handshake(response_type* res_p, boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, RequestDecorator const& decorator, error_code& ec) { @@ -137,7 +137,7 @@ do_handshake(response_type* res_p, detail::sec_ws_key_type key; { auto const req = build_request( - key, host, resource, decorator); + key, host, target, decorator); pmd_read(pmd_config_, req.fields); http::write(stream_, req, ec); } @@ -157,13 +157,13 @@ request_type stream:: build_request(detail::sec_ws_key_type& key, boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, Decorator const& decorator) { request_type req; - req.url = { resource.data(), resource.size() }; + req.target(target); req.version = 11; - req.method = "GET"; + req.method("GET"); req.fields.insert("Host", host); req.fields.insert("Upgrade", "websocket"); req.fields.insert("Connection", "upgrade"); @@ -215,7 +215,7 @@ build_response(request_type const& req, { response_type res; res.status = 400; - res.reason = http::reason_string(res.status); + res.reason(http::reason_string(res.status)); res.version = req.version; res.body = text; prepare(res); @@ -224,7 +224,7 @@ build_response(request_type const& req, }; if(req.version < 11) return err("HTTP version 1.1 required"); - if(req.method != "GET") + if(req.method() != "GET") return err("Wrong method"); if(! is_upgrade(req)) return err("Expected Upgrade request"); @@ -246,7 +246,7 @@ build_response(request_type const& req, { response_type res; res.status = 426; - res.reason = http::reason_string(res.status); + res.reason(http::reason_string(res.status)); res.version = req.version; res.fields.insert("Sec-WebSocket-Version", "13"); prepare(res); @@ -264,7 +264,7 @@ build_response(request_type const& req, res.fields, unused, offer, pmd_opts_); } res.status = 101; - res.reason = http::reason_string(res.status); + res.reason(http::reason_string(res.status)); res.version = req.version; res.fields.insert("Upgrade", "websocket"); res.fields.insert("Connection", "upgrade"); diff --git a/include/beast/websocket/stream.hpp b/include/beast/websocket/stream.hpp index 74b2e184..28d38b4a 100644 --- a/include/beast/websocket/stream.hpp +++ b/include/beast/websocket/stream.hpp @@ -1445,7 +1445,7 @@ public: @param host The name of the remote host, required by the HTTP protocol. - @param resource The requesting URI, which may not be empty, + @param target The Request Target, which may not be empty, required by the HTTP protocol. @throws system_error Thrown on failure. @@ -1466,7 +1466,7 @@ public: */ void handshake(boost::string_ref const& host, - boost::string_ref const& resource); + boost::string_ref const& target); /** Send an HTTP WebSocket Upgrade request and receive the response. @@ -1492,7 +1492,7 @@ public: @param host The name of the remote host, required by the HTTP protocol. - @param resource The requesting URI, which may not be empty, + @param target The Request Target, which may not be empty, required by the HTTP protocol. @throws system_error Thrown on failure. @@ -1515,7 +1515,7 @@ public: void handshake(response_type& res, boost::string_ref const& host, - boost::string_ref const& resource); + boost::string_ref const& target); /** Send an HTTP WebSocket Upgrade request and receive the response. @@ -1538,7 +1538,7 @@ public: @param host The name of the remote host, required by the HTTP protocol. - @param resource The requesting URI, which may not be empty, + @param target The Request Target, which may not be empty, required by the HTTP protocol. @param decorator A function object which will be called to modify @@ -1573,7 +1573,7 @@ public: template void handshake_ex(boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, RequestDecorator const& decorator); /** Send an HTTP WebSocket Upgrade request and receive the response. @@ -1600,7 +1600,7 @@ public: @param host The name of the remote host, required by the HTTP protocol. - @param resource The requesting URI, which may not be empty, + @param target The Request Target, which may not be empty, required by the HTTP protocol. @param decorator A function object which will be called to modify @@ -1637,7 +1637,7 @@ public: void handshake_ex(response_type& res, boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, RequestDecorator const& decorator); /** Send an HTTP WebSocket Upgrade request and receive the response. @@ -1661,7 +1661,7 @@ public: @param host The name of the remote host, required by the HTTP protocol. - @param resource The requesting URI, which may not be empty, + @param target The Request Target, which may not be empty, required by the HTTP protocol. @param ec Set to indicate what error occurred, if any. @@ -1671,7 +1671,7 @@ public: websocket::stream ws{io_service}; ... error_code ec; - ws.handshake(host, resource, ec); + ws.handshake(host, target, ec); if(ec) { // An error occurred. @@ -1680,7 +1680,7 @@ public: */ void handshake(boost::string_ref const& host, - boost::string_ref const& resource, error_code& ec); + boost::string_ref const& target, error_code& ec); /** Send an HTTP WebSocket Upgrade request and receive the response. @@ -1703,7 +1703,7 @@ public: @param host The name of the remote host, required by the HTTP protocol. - @param resource The requesting URI, which may not be empty, + @param target The Request Target, which may not be empty, required by the HTTP protocol. @param ec Set to indicate what error occurred, if any. @@ -1717,7 +1717,7 @@ public: ... error_code ec; response_type res; - ws.handshake(res, host, resource, ec); + ws.handshake(res, host, target, ec); if(ec) { // An error occurred. @@ -1727,7 +1727,7 @@ public: void handshake(response_type& res, boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, error_code& ec); /** Send an HTTP WebSocket Upgrade request and receive the response. @@ -1751,7 +1751,7 @@ public: @param host The name of the remote host, required by the HTTP protocol. - @param resource The requesting URI, which may not be empty, + @param target The Request Target, which may not be empty, required by the HTTP protocol. @param decorator A function object which will be called to modify @@ -1785,7 +1785,7 @@ public: template void handshake_ex(boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, RequestDecorator const& decorator, error_code& ec); @@ -1813,7 +1813,7 @@ public: @param host The name of the remote host, required by the HTTP protocol. - @param resource The requesting URI, which may not be empty, + @param target The Request Target, which may not be empty, required by the HTTP protocol. @param decorator A function object which will be called to modify @@ -1849,7 +1849,7 @@ public: void handshake_ex(response_type& res, boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, RequestDecorator const& decorator, error_code& ec); @@ -1879,9 +1879,9 @@ public: @param host The name of the remote host, required by the HTTP protocol. Copies may be made as needed. - @param resource The requesting URI, which may not be empty, - required by the HTTP protocol. Copies may be made as - needed. + @param target The Request Target, which may not be empty, + required by the HTTP protocol. Copies of this parameter may + be made as needed. @param handler The handler to be called when the request completes. Copies will be made of the handler as required. The equivalent @@ -1902,7 +1902,7 @@ public: void(error_code)>::result_type #endif async_handshake(boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, HandshakeHandler&& handler); /** Start an asynchronous operation to send an upgrade request and receive the response. @@ -1935,9 +1935,9 @@ public: @param host The name of the remote host, required by the HTTP protocol. Copies may be made as needed. - @param resource The requesting URI, which may not be empty, - required by the HTTP protocol. Copies may be made as - needed. + @param target The Request Target, which may not be empty, + required by the HTTP protocol. Copies of this parameter may + be made as needed. @param handler The handler to be called when the request completes. Copies will be made of the handler as required. The equivalent @@ -1959,7 +1959,7 @@ public: #endif async_handshake(response_type& res, boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, HandshakeHandler&& handler); /** Start an asynchronous operation to send an upgrade request and receive the response. @@ -1988,9 +1988,9 @@ public: @param host The name of the remote host, required by the HTTP protocol. Copies may be made as needed. - @param resource The requesting URI, which may not be empty, - required by the HTTP protocol. Copies may be made as - needed. + @param target The Request Target, which may not be empty, + required by the HTTP protocol. Copies of this parameter may + be made as needed. @param decorator A function object which will be called to modify the HTTP request object generated by the implementation. This @@ -2020,7 +2020,7 @@ public: void(error_code)>::result_type #endif async_handshake_ex(boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, RequestDecorator const& decorator, HandshakeHandler&& handler); @@ -2054,9 +2054,9 @@ public: @param host The name of the remote host, required by the HTTP protocol. Copies may be made as needed. - @param resource The requesting URI, which may not be empty, - required by the HTTP protocol. Copies may be made as - needed. + @param target The Request Target, which may not be empty, + required by the HTTP protocol. Copies of this parameter may + be made as needed. @param decorator A function object which will be called to modify the HTTP request object generated by the implementation. This @@ -2087,7 +2087,7 @@ public: #endif async_handshake_ex(response_type& res, boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, RequestDecorator const& decorator, HandshakeHandler&& handler); @@ -2969,7 +2969,7 @@ private: void do_handshake(response_type* res_p, boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, RequestDecorator const& decorator, error_code& ec); @@ -2977,7 +2977,7 @@ private: request_type build_request(detail::sec_ws_key_type& key, boost::string_ref const& host, - boost::string_ref const& resource, + boost::string_ref const& target, Decorator const& decorator); template diff --git a/test/http/message.cpp b/test/http/message.cpp index 54f49f1b..99513368 100644 --- a/test/http/message.cpp +++ b/test/http/message.cpp @@ -70,7 +70,8 @@ public: }; }; - void testMessage() + void + testMessage() { static_assert(std::is_constructible< message>::value, ""); @@ -130,42 +131,43 @@ public: // swap message m1; message m2; - m1.url = "u"; + m1.target("u"); m1.body = "1"; m1.fields.insert("h", "v"); - m2.method = "G"; + m2.method("G"); m2.body = "2"; swap(m1, m2); - BEAST_EXPECT(m1.method == "G"); - BEAST_EXPECT(m2.method.empty()); - BEAST_EXPECT(m1.url.empty()); - BEAST_EXPECT(m2.url == "u"); + BEAST_EXPECT(m1.method() == "G"); + BEAST_EXPECT(m2.method().empty()); + BEAST_EXPECT(m1.target().empty()); + BEAST_EXPECT(m2.target() == "u"); BEAST_EXPECT(m1.body == "2"); BEAST_EXPECT(m2.body == "1"); BEAST_EXPECT(! m1.fields.exists("h")); BEAST_EXPECT(m2.fields.exists("h")); } - struct MoveHeaders + struct MoveFields : fields { bool moved_to = false; bool moved_from = false; - MoveHeaders() = default; + MoveFields() = default; - MoveHeaders(MoveHeaders&& other) + MoveFields(MoveFields&& other) : moved_to(true) { other.moved_from = true; } - MoveHeaders& operator=(MoveHeaders&& other) + MoveFields& operator=(MoveFields&& other) { return *this; } }; - void testHeaders() + void + testHeaders() { { using req_type = request_header; @@ -182,22 +184,23 @@ public: } { - MoveHeaders h; - header r{std::move(h)}; + MoveFields h; + header r{std::move(h)}; BEAST_EXPECT(h.moved_from); BEAST_EXPECT(r.fields.moved_to); - request m{std::move(r)}; + request m{std::move(r)}; BEAST_EXPECT(r.fields.moved_from); BEAST_EXPECT(m.fields.moved_to); } } - void testFreeFunctions() + void + testFreeFunctions() { { request m; - m.method = "GET"; - m.url = "/"; + m.method("GET"); + m.target("/"); m.version = 11; m.fields.insert("Upgrade", "test"); BEAST_EXPECT(! is_upgrade(m)); @@ -211,7 +214,8 @@ public: } } - void testPrepare() + void + testPrepare() { request m; m.version = 10; @@ -253,7 +257,8 @@ public: BEAST_EXPECT(! is_keep_alive(m)); } - void testSwap() + void + testSwap() { message m1; message m2; @@ -262,14 +267,14 @@ public: m1.body = "1"; m1.fields.insert("h", "v"); m2.status = 404; - m2.reason = "OK"; + m2.reason("OK"); m2.body = "2"; m2.version = 11; swap(m1, m2); BEAST_EXPECT(m1.status == 404); BEAST_EXPECT(m2.status == 200); - BEAST_EXPECT(m1.reason == "OK"); - BEAST_EXPECT(m2.reason.empty()); + BEAST_EXPECT(m1.reason() == "OK"); + BEAST_EXPECT(m2.reason().empty()); BEAST_EXPECT(m1.version == 11); BEAST_EXPECT(m2.version == 10); BEAST_EXPECT(m1.body == "2"); @@ -291,7 +296,8 @@ public: }(); } - void run() override + void + run() override { testMessage(); testHeaders(); diff --git a/test/http/message_fuzz.hpp b/test/http/message_fuzz.hpp index 9317add0..991baaab 100644 --- a/test/http/message_fuzz.hpp +++ b/test/http/message_fuzz.hpp @@ -131,7 +131,7 @@ public: "msrp", "msrps", "mtqp", "mumble", "mupdate", "mvn", "news", "nfs", "ni", "nih", "nntp", "notes", "oid", "opaquelocktoken", "pack", "palm", "paparazzi", "pkcs11", "platform", "pop", "pres", "prospero", "proxy", "psyc", "query", - "redis", "rediss", "reload", "res", "resource", "rmi", "rsync", "rtmfp", + "redis", "rediss", "reload", "res", "target", "rmi", "rsync", "rtmfp", "rtmp", "rtsp", "rtsps", "rtspu", "secondlife", "service", "session", "sftp", "sgn", "shttp", "sieve", "sip", "sips", "skype", "smb", "sms", "smtp", "snews", "snmp", "soap.beep", "soap.beeps", "soldat", "spotify", "ssh", diff --git a/test/http/message_parser.cpp b/test/http/message_parser.cpp index de3842d9..41bbbd2c 100644 --- a/test/http/message_parser.cpp +++ b/test/http/message_parser.cpp @@ -130,8 +130,8 @@ public: auto const& m = p.get(); BEAST_EXPECTS(! ec, ec.message()); BEAST_EXPECT(p.is_complete()); - BEAST_EXPECT(m.method == "GET"); - BEAST_EXPECT(m.url == "/"); + BEAST_EXPECT(m.method() == "GET"); + BEAST_EXPECT(m.target() == "/"); BEAST_EXPECT(m.version == 11); BEAST_EXPECT(m.fields["User-Agent"] == "test"); BEAST_EXPECT(m.body == "*"); @@ -182,7 +182,7 @@ public: BEAST_EXPECTS(! ec, ec.message()); BEAST_EXPECT(p.is_complete()); BEAST_EXPECT(m.status == 200); - BEAST_EXPECT(m.reason == "OK"); + BEAST_EXPECT(m.reason() == "OK"); BEAST_EXPECT(m.version == 11); BEAST_EXPECT(m.fields["Server"] == "test"); BEAST_EXPECT(m.body == "*"); diff --git a/test/http/write.cpp b/test/http/write.cpp index 76b2220f..51bfc2f0 100644 --- a/test/http/write.cpp +++ b/test/http/write.cpp @@ -146,8 +146,8 @@ public: { header m; m.version = 11; - m.method = "GET"; - m.url = "/"; + m.method("GET"); + m.target("/"); m.fields.insert("User-Agent", "test"); error_code ec; test::string_ostream ss{ios_}; @@ -162,7 +162,7 @@ public: header m; m.version = 10; m.status = 200; - m.reason = "OK"; + m.reason("OK"); m.fields.insert("Server", "test"); m.fields.insert("Content-Length", "5"); error_code ec; @@ -184,7 +184,7 @@ public: message m; m.version = 10; m.status = 200; - m.reason = "OK"; + m.reason("OK"); m.fields.insert("Server", "test"); m.fields.insert("Content-Length", "5"); m.body = "*****"; @@ -203,7 +203,7 @@ public: message m; m.version = 11; m.status = 200; - m.reason = "OK"; + m.reason("OK"); m.fields.insert("Server", "test"); m.fields.insert("Transfer-Encoding", "chunked"); m.body = "*****"; @@ -236,8 +236,8 @@ public: message m( std::piecewise_construct, std::forward_as_tuple(fc, ios_)); - m.method = "GET"; - m.url = "/"; + m.method("GET"); + m.target("/"); m.version = 10; m.fields.insert("User-Agent", "test"); m.fields.insert("Content-Length", "5"); @@ -269,8 +269,8 @@ public: message m( std::piecewise_construct, std::forward_as_tuple(fc, ios_)); - m.method = "GET"; - m.url = "/"; + m.method("GET"); + m.target("/"); m.version = 10; m.fields.insert("User-Agent", "test"); m.fields.insert("Transfer-Encoding", "chunked"); @@ -304,8 +304,8 @@ public: message m( std::piecewise_construct, std::forward_as_tuple(fc, ios_)); - m.method = "GET"; - m.url = "/"; + m.method("GET"); + m.target("/"); m.version = 10; m.fields.insert("User-Agent", "test"); m.fields.insert("Transfer-Encoding", "chunked"); @@ -339,8 +339,8 @@ public: message m( std::piecewise_construct, std::forward_as_tuple(fc, ios_)); - m.method = "GET"; - m.url = "/"; + m.method("GET"); + m.target("/"); m.version = 10; m.fields.insert("User-Agent", "test"); m.fields.insert("Content-Length", "5"); @@ -369,8 +369,8 @@ public: message m( std::piecewise_construct, std::forward_as_tuple(fc, ios_)); - m.method = "GET"; - m.url = "/"; + m.method("GET"); + m.target("/"); m.version = 10; m.fields.insert("User-Agent", "test"); m.fields.insert("Content-Length", "5"); @@ -398,8 +398,8 @@ public: // auto content-length HTTP/1.0 { message m; - m.method = "GET"; - m.url = "/"; + m.method("GET"); + m.target("/"); m.version = 10; m.fields.insert("User-Agent", "test"); m.body = "*"; @@ -415,8 +415,8 @@ public: // keep-alive HTTP/1.0 { message m; - m.method = "GET"; - m.url = "/"; + m.method("GET"); + m.target("/"); m.version = 10; m.fields.insert("User-Agent", "test"); m.body = "*"; @@ -433,8 +433,8 @@ public: // upgrade HTTP/1.0 { message m; - m.method = "GET"; - m.url = "/"; + m.method("GET"); + m.target("/"); m.version = 10; m.fields.insert("User-Agent", "test"); m.body = "*"; @@ -451,8 +451,8 @@ public: // no content-length HTTP/1.0 { message m; - m.method = "GET"; - m.url = "/"; + m.method("GET"); + m.target("/"); m.version = 10; m.fields.insert("User-Agent", "test"); m.body = "*"; @@ -471,8 +471,8 @@ public: // auto content-length HTTP/1.1 { message m; - m.method = "GET"; - m.url = "/"; + m.method("GET"); + m.target("/"); m.version = 11; m.fields.insert("User-Agent", "test"); m.body = "*"; @@ -488,8 +488,8 @@ public: // close HTTP/1.1 { message m; - m.method = "GET"; - m.url = "/"; + m.method("GET"); + m.target("/"); m.version = 11; m.fields.insert("User-Agent", "test"); m.body = "*"; @@ -510,8 +510,8 @@ public: // upgrade HTTP/1.1 { message m; - m.method = "GET"; - m.url = "/"; + m.method("GET"); + m.target("/"); m.version = 11; m.fields.insert("User-Agent", "test"); prepare(m, connection::upgrade); @@ -525,8 +525,8 @@ public: // no content-length HTTP/1.1 { message m; - m.method = "GET"; - m.url = "/"; + m.method("GET"); + m.target("/"); m.version = 11; m.fields.insert("User-Agent", "test"); m.body = "*"; @@ -550,8 +550,8 @@ public: { // Conversion to std::string via operator<< message m; - m.method = "GET"; - m.url = "/"; + m.method("GET"); + m.target("/"); m.version = 11; m.fields.insert("User-Agent", "test"); m.body = "*"; @@ -590,8 +590,8 @@ public: void testOstream() { message m; - m.method = "GET"; - m.url = "/"; + m.method("GET"); + m.target("/"); m.version = 11; m.fields.insert("User-Agent", "test"); m.body = "*"; @@ -631,9 +631,9 @@ public: test::string_ostream os{ios}; BEAST_EXPECT(handler::count() == 0); message m; - m.method = "GET"; + m.method("GET"); m.version = 11; - m.url = "/"; + m.target("/"); m.fields.insert("Content-Length", 5); m.body = "*****"; async_write(os, m, handler{}); @@ -653,9 +653,9 @@ public: test::string_ostream is{ios}; BEAST_EXPECT(handler::count() == 0); message m; - m.method = "GET"; + m.method("GET"); m.version = 11; - m.url = "/"; + m.target("/"); m.fields.insert("Content-Length", 5); m.body = "*****"; async_write(is, m, handler{}); diff --git a/test/websocket/rfc6455.cpp b/test/websocket/rfc6455.cpp index 080b5f43..534a9cf9 100644 --- a/test/websocket/rfc6455.cpp +++ b/test/websocket/rfc6455.cpp @@ -24,10 +24,10 @@ public: req.version = 10; BEAST_EXPECT(! is_upgrade(req)); req.version = 11; - req.method = "POST"; - req.url = "/"; + req.method("POST"); + req.target("/"); BEAST_EXPECT(! is_upgrade(req)); - req.method = "GET"; + req.method("GET"); req.fields.insert("Connection", "upgrade"); BEAST_EXPECT(! is_upgrade(req)); req.fields.insert("Upgrade", "websocket"); diff --git a/test/websocket/stream.cpp b/test/websocket/stream.cpp index 3da3d28d..2d3e42ee 100644 --- a/test/websocket/stream.cpp +++ b/test/websocket/stream.cpp @@ -691,8 +691,8 @@ public: // request in message { request_type req; - req.method = "GET"; - req.url = "/"; + req.method("GET"); + req.target("/"); req.version = 11; req.fields.insert("Host", "localhost"); req.fields.insert("Upgrade", "websocket"); @@ -705,8 +705,8 @@ public: } { request_type req; - req.method = "GET"; - req.url = "/"; + req.method("GET"); + req.target("/"); req.version = 11; req.fields.insert("Host", "localhost"); req.fields.insert("Upgrade", "websocket"); @@ -723,8 +723,8 @@ public: // request in message, close frame in buffers { request_type req; - req.method = "GET"; - req.url = "/"; + req.method("GET"); + req.target("/"); req.version = 11; req.fields.insert("Host", "localhost"); req.fields.insert("Upgrade", "websocket"); @@ -750,8 +750,8 @@ public: } { request_type req; - req.method = "GET"; - req.url = "/"; + req.method("GET"); + req.target("/"); req.version = 11; req.fields.insert("Host", "localhost"); req.fields.insert("Upgrade", "websocket"); @@ -781,8 +781,8 @@ public: // request in message, close frame in stream { request_type req; - req.method = "GET"; - req.url = "/"; + req.method("GET"); + req.target("/"); req.version = 11; req.fields.insert("Host", "localhost"); req.fields.insert("Upgrade", "websocket"); @@ -809,8 +809,8 @@ public: // request in message, close frame in stream and buffers { request_type req; - req.method = "GET"; - req.url = "/"; + req.method("GET"); + req.target("/"); req.version = 11; req.fields.insert("Host", "localhost"); req.fields.insert("Upgrade", "websocket");