From cc284e0861df9efc2e58dbc5b77f1c6b40645ad7 Mon Sep 17 00:00:00 2001 From: Alex Hultman Date: Mon, 10 Sep 2018 23:28:51 +0200 Subject: [PATCH] Get HTTP working, kind of --- design.dia | Bin 2424 -> 2454 bytes main.cpp | 6 +++-- src/new_design/HttpContext.h | 39 +++++++++++++++--------------- src/new_design/HttpContextData.h | 2 +- src/new_design/HttpResponse.h | 8 ++++-- src/new_design/HttpResponseData.h | 3 ++- uSockets | 2 +- 7 files changed, 33 insertions(+), 27 deletions(-) diff --git a/design.dia b/design.dia index dcfbb85ed0c16f324c9816435d091fd04f8582d5..9e05a8d67fc64709626158558a450a6cc48e83b5 100644 GIT binary patch literal 2454 zcmYM!c|6mP1IO{t9MRm$(MIIRk)z{lt~tup<(86Aq#P^0Q<*Ch+Fa4dqH-@+jh~wt z6Jfb>jZBWn(T2I(T)*${@%a6Iz5jeZ-haR368M4tjEj5eom=V;nB?=7`RjJwOI77c zktY{zlvBrgJ|n#SQ*SwP4Nb{mPpl%&wV%)fMN3vpNHap}?IyXB(&v9iL zlK{7Ef+o=zI`Ob$T^8|qfw5czdAJ=)oMQKur&jRwx{@}ZsG#8ahg{Xdzqxf?tAThc)UEzBR7Ii3QF0E0J90vy_lJXy?e#{I z4b1!HThGDAueyTP78%{)16#GkDU{fMIaf^U6Wphab(&G%J&K4c|h@N{qmC z?RF1AH(bS5QtnvxCylq}yEhoEdMh6})+WO%edte?h)AOT%$G4p(%0^J;ot`8T(0e3aopc?BRmGB%hRGN`SF!|&Tdne2?4y$x zb8bE;Nf#{Hs(hFHn%O(JPI||7cdzq1e!woXjV85pV78G$Ua?J2gW>aGbW6}?K~WNR z#6Ha`Tt6%RFXM5I?Xmg`g{MO?vf(h4Rz=Z$K03ZMw|Z(i{H1P!SWNU-7vp5j{DmPI ztOsFa%f3zj04KMpq}5MFW+8LmBU3YLVj4s6@ZO~1zLRUUh*0@Jzn&%^tn($@ng+Bv z{N*vc_(0cPzcV@~HygkCeJkc5zgrY}<2PbU*!K{#G_@<;+wbk}B(H7B*h(>POGLPs zJt%eE8&*vsM0R$FCC_87EIb)pTJ)Vo7?+W9$?l?(7M@1w+t$DF=U;i|^uC4&+$r7v z1o3<_Cjh#_?91gJBg($!f;H{T$3;NM z9%SrsgONiTqO+W~{z)boQqH=B<-u}^^2&ovkD^rpdms-m2mOIYp*)s=Eebxf`lvEm zA~0403v;G)21iVWQ=T2I_}5XesPnBT`S?@ch(33yK`{7{3orqKRRKr>22efLi>E-Gx0d^I}osrV<|?1g#7f6&3(}9qC zz7cXph-ijvy;sqS)TF7*RI^Lw>d_n{(=hZFuml?8uHy3%`Fi{hG%uYtb;WD(bP9*B zfDb=+=+uh&B4fr>fT(_b0PiSIK3>yxc4NtSZnHE`;9%NCAwWhr9Q2!u#XBWHkwR+& z9zYZD2PR-1fg9{+w%sbnBu{{^#pi;9)(hURDw!=2tMkEnMMk8~=D$l=jx}+G%?XS5 zh5NL)iU2!M4woq}8VpDP>VOmQUx?M^lGvvbxO?(gWqFEL6+&)q4d}yQ{^2V({9C2U zFQ3wQBx511x;8{|wS^(1$#c&}Eecj}H=|Ti5U4lQ=P3gG_2`IME`ua?_4??l{4cveBh_Bk(Lp)Yht>H9sm)z zFY~1dtIFCL+G;IyW@>lez99#l%a2%^M71V1lq=uGnL2*-EHX$Soz!RXl zvLcm!?zR9$60Hfi0yO{vG|E-Z`v+J;GW?=Gn1y=m*v}(NMwMqmwG_^)nGek*99|P> zH>GM~7IYFPUgCbq^U#;8XV00eCLUU-7W`zmX~_RIdJvH3V!0*);|V`1wc~&dMl<0$ z7HCU4w(s&$Y z#0s6-`~&;Y=}l?>>?wc6=1})0m)m7AK57MMa$KX&^Y8k z26ZPp<{~h{P2{^JQg=MiXeyMliDrQQ4|}!G7{xGRZAyN{Vnj^O0IwYT$@Cm4Yn|+H z&1#wFyZw48WwV2C<)0Rawx`p*&Wp>7cdicAKLi*c8utgj8v%l}8Owf%#!9;Cyft1d~9hk2;kX z*Rr}pT|3@yu|=lt+xoYRVOqqc*lX9|mJ=T;)gOpz#)7+kok&g>bK2LG8y)!TX^-+@ z;yiQHLEHurb;OmziP~g%?iIDiX*Sg#akVi_8=FtFZ$?SSEn@xra?uFI5`tggy4Y|B zW?2!sax2vE+;^n2~JQ?g&M|F@5NG*)kJ?-C}Dq8*!NvZ&X2 zEg;}~HUiQ-hnpw22`jf`^F)d#%1JkCwf7CORJI4>w1QQ;w#DeIjcGTw<$gvXg3Ve! NfZBW2W=;aYzX8y@-NgU^ literal 2424 zcmZwGdpHvc9|!O;rzuK8REbex#U|HE7zZ;9!z!1t!caym z&LY=z9Cw#6V#s?711oK7ME{d!Ikry7qA|Lu~y*U-Z^PzIMiVonnSC zVU-mVhc6!xdpi@wxcnR3r!v`Yy5=e~X`d$N{YwCH)u?6V>y}7fZT1ba6uA!h>u$Ho z0wWW_i-}{Fdo9+wCf4tbP-!IG#de0`@sHowM#pRRXiB$TRXC;`angoG-#BrHd6>s- z2}v|FxS)nPk5c=*CVkZgpCFGXpTs=s!0E1nX`5T4ll7d` zdNskyO|E%NnJ(Fa*&K944(;QAvXB8aKwAq@OT|qaW8|U>VV1{#F6-0bdc{${D!P5I zM{Dj;If~=CZw4H92;^--JoGsOS}v^`8=gNacK;#-7Lla7)rbmsWqf<_ZchMF4(Y|y zE=Hmk>#VIUQklVHLu*M9IBV?3DR6oW=TdTvy8&pG#&gDH_q}CC>G*)mvG&cp* zfKj-DP25gBBO?#J#Nn|#Adi#T0z;$Uc81bhFz5?Lq-p=g;U zkxz|)`M%8>D*N3 zlf60eP>?~POVaNw^rYRO`FOOaXT0Yo$j4Z2#1A{Q9T()-Ekl(b0t?G5NIM@@J*yrF zCi<-AN-qT%>=^(4B21XmKiK7)9b#l6e%4JRR&p3jh#9$`{ha3=&i2AxJuOb^(f7y- zsXJI)NJgb@D>>JGm`i8XBpZ1IPQL~@HGX#!s%OI!_FJogW~U##w{IU{k|U@CK8e{X z+V5|+kH?XoXKCo?z8RWbpzv})wgz7*YIja_cvXbo`#3jj7ew+!8`P@|7bp$;uCE3Z zemvP_2%dV;yE(9;OtcwU>CQdxS)%^tw$bPrIy>PyvdqI1e9z04B+e$*RDDW2v z;kq)#PueZ(kKxhB6a>=%U;zz5Z=p8fcyRy>a2fCeYJf0469(zW=&@F7h1_XE&-#u9 zo1#V;Cb5DIH2qM#VOExo`swrPTSS8!yN~^A^UsbxWEtQFI~ubD2dfus#`2T(HcQJ= zDimcZ8D&YL)ajDU0mexTrtuoYa#%I)R^j#$)uEIsd+}7Kx0PctcJ~fZJ_=sR?+7-$ z8KyQ;a8ij}6IY*)u8w_`$FI|I3ve%tCOOTWF`T$@0G^{oZsj0c^;CC^Rk-ak`z;sJlnxv?|Z_|`6zA8rroIIxQ z9J*{?{jHMUnkahrZRj4R_f)Mm-bZf<>}zT>vCvrRj}B8~A7hZu9ibU`W81iQ#C!eh zZ?25!yHBY>gFF*@9fsvTDG;dcK_OBmW#-kIOr)h>C#3H0Z=J{!C`M$JWgnr#cGwJwl9jJMUc6-knzIbZw@i-9AX-sWSxaWMQ1tan zq=UIy0%DtS%25iVVNK8 z!jIQmwq8w9oCNK?)P0Gcq$y76y?kK(g{BPA=>Vq0{Y08&t=z$N_Slxu@t5jJodxG$ z6_VXQ*Li$#j(C;r+BK3g>%<6rIO{QQ;j$Ig`VF_$vCp(W@V_niuUfDHg`L}iO{-Yn zmlPtx|NHRYBMJ0;C#}(AjO5_*S_xKLu){7vW@+V*B7xZQ;HO)U59tZt9Tyk?J_DK7 z93F5;^v4Ff8(oJyH!8@HE9^wt-jaRqco%OM5u?{UW!)SC3hG?WVFiLXwTutTUO$!Y zE16m8GXW)_%VKE|u%Skj_h#F2!T|6;utR4q=a8LjgH1mR7O(h=Nb0X`h3P#?FRk#H z&$&*wMJH{_B&2DBy|atDa8O*}|E=ZUIq~R%OF2+i zTebNc*`s*X&>~ag>Q-&pJFtxOWZgeAXFmSPLZ#Cu!qo5hY>1v;DRt|&D6DotPLJrs z&k1w_(?>BuGKuFWy)D^QC>zj#h#^HPGEUE|`THaWeNp^GKG^L#Lnbz>rxyPFnm)=( z>0FHbB+|ckpy4K~=7qcRYi43-a?4SyJhwQyCAIPx_CxE@H!)D!;SA^$irr diff --git a/main.cpp b/main.cpp index f3bf5da..b08eccf 100644 --- a/main.cpp +++ b/main.cpp @@ -57,9 +57,11 @@ int main(int argc, char **argv) { HttpContext *httpContext = HttpContext::create(loop.loop); // req, res? - httpContext->onGet("/", [](auto *res) { // maybe use the terminology of HttpRequest for both? + httpContext->onGet("/", [](auto *res, auto *req) { // maybe use the terminology of HttpRequest for both? - std::cout << "Why hello! How do we access the headers?" << std::endl; + std::cout << "URL: <" << req->getUrl() << ">" << std::endl; + std::cout << "Query: <" << req->getQuery() << ">" << std::endl; + std::cout << "User-Agent: <" << req->getHeader("user-agent") << ">" << std::endl; // read some data being passed res->read([](std::string_view chunk) { diff --git a/src/new_design/HttpContext.h b/src/new_design/HttpContext.h index caa4606..835820a 100644 --- a/src/new_design/HttpContext.h +++ b/src/new_design/HttpContext.h @@ -12,6 +12,7 @@ // we of course depend on our own data type #include "HttpContextData.h" +#include "HttpResponseData.h" // we should opaqeuly depend on HttpResponse namespace uWS { @@ -67,15 +68,15 @@ public: static_dispatch(us_ssl_socket_timeout, us_socket_timeout)(s, HTTP_IDLE_TIMEOUT_S); - /*new (static_dispatch(us_ssl_socket_ext, us_socket_ext)(s)) HTTP_SOCKET_DATA_TYPE; -*/ + new (static_dispatch(us_ssl_socket_ext, us_socket_ext)(s)) HttpResponseData; + return s; }); static_dispatch(us_ssl_socket_context_on_close, us_socket_context_on_close)(getSocketContext(), [](auto *s) { HttpContextData *httpContextData = getSocketContextData(s); - //((HTTP_SOCKET_DATA_TYPE *) static_dispatch(us_ssl_socket_ext, us_socket_ext)(s))->~HTTP_SOCKET_DATA_TYPE(); + ((HttpResponseData *) static_dispatch(us_ssl_socket_ext, us_socket_ext)(s))->~HttpResponseData(); return s; }); @@ -83,29 +84,25 @@ public: static_dispatch(us_ssl_socket_context_on_data, us_socket_context_on_data)(getSocketContext(), [](auto *s, char *data, int length) { HttpContextData *httpContextData = getSocketContextData(s); - // warning: should NOT reset timer on any data, ONLY reset data on full HTTP requests! - // warning: if we are in shutdown state, resetting the timer is a security issue! - static_dispatch(us_ssl_socket_timeout, us_socket_timeout)(s, HTTP_IDLE_TIMEOUT_S); + HttpResponseData *httpResponseData = (HttpResponseData *) static_dispatch(us_ssl_socket_ext, us_socket_ext)(s); + httpResponseData->consumePostPadded(data, length, s, [httpContextData](void *s, HttpRequest *httpRequest) { + // warning: if we are in shutdown state, resetting the timer is a security issue! + static_dispatch(us_ssl_socket_timeout, us_socket_timeout)((SOCKET_TYPE *) s, HTTP_IDLE_TIMEOUT_S); - // here we should totally parse and route this all on our own, no involving the HttpResponse at all! + // todo: route this according to our router - std::cout << "Got data!" << std::endl; + httpContextData->handler((uWS::HttpResponse *) s, httpRequest); - //Data *httpData = (Data *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) this); - - // we can reach the HttpResponseData which holds the parser, so let's just run the data through it from here (no onData) bullshit in the httpsocket! - - // todo: this is where the HttpSocket binds together HttpParser and HttpRouter into one - /*httpData->httpParser.consumePostPadded(data, length, this, [&onHttpRequest](void *user, HttpRequest *httpRequest) { - onHttpRequest((HttpSocket *) user, httpRequest); - }, [httpData](void *user, std::string_view data) { - if (httpData->inStream) { - httpData->inStream(data); + }, [httpResponseData](void *user, std::string_view data) { + if (httpResponseData->readHandler) { + httpResponseData->readHandler(data); } }, [](void *user) { std::cout << "INVALID HTTP!" << std::endl; - });*/ + + // close it down + }); return s; }); @@ -152,6 +149,8 @@ public: HttpContext *httpContext = (HttpContext *) us_create_socket_context(loop, sizeof(HttpContextData)); + new ((HttpContextData *) static_dispatch(us_ssl_socket_context_ext, us_socket_context_ext)((SOCKET_CONTEXT_TYPE *) httpContext)) HttpContextData(); + return httpContext->init(); } @@ -159,7 +158,7 @@ public: static_dispatch(us_ssl_socket_context_free, us_socket_context_free)(getSocketContext()); } - void onGet(std::string_view pattern, std::function *)> handler) { + void onGet(std::string_view pattern, std::function *, HttpRequest *)> handler) { HttpContextData *data = getSocketContextData(); // add things to the router diff --git a/src/new_design/HttpContextData.h b/src/new_design/HttpContextData.h index 4bbea49..8b05c22 100644 --- a/src/new_design/HttpContextData.h +++ b/src/new_design/HttpContextData.h @@ -27,7 +27,7 @@ public: HttpRouter httpRouter; // placeholder handler for response - std::function *)> handler; + std::function *, HttpRequest *)> handler; }; diff --git a/src/new_design/HttpResponse.h b/src/new_design/HttpResponse.h index 5977170..9cef5d3 100644 --- a/src/new_design/HttpResponse.h +++ b/src/new_design/HttpResponse.h @@ -2,18 +2,22 @@ #define HTTPRESPONSE_H #include "HttpResponseData.h" +#include "StaticDispatch.h" // we will most probably depend on the LoopData to do corking and such namespace uWS { template -struct HttpResponse { +struct HttpResponse : StaticDispatch { private: + using SOCKET_TYPE = typename StaticDispatch::SOCKET_TYPE; + using StaticDispatch::static_dispatch; + // helpers HttpResponseData *getHttpResponseData() { - + return (HttpResponseData *) static_dispatch(us_ssl_socket_ext, us_socket_ext)((SOCKET_TYPE *) this); } public: diff --git a/src/new_design/HttpResponseData.h b/src/new_design/HttpResponseData.h index 62075b6..f65baf5 100644 --- a/src/new_design/HttpResponseData.h +++ b/src/new_design/HttpResponseData.h @@ -3,10 +3,11 @@ // so what do we depend on? +#include "HttpParser.h" #include template -struct HttpResponseData { +struct HttpResponseData : HttpParser { std::function readHandler; diff --git a/uSockets b/uSockets index 7453ee4..2a19eab 160000 --- a/uSockets +++ b/uSockets @@ -1 +1 @@ -Subproject commit 7453ee4ec8eee404229e23021197c1d7c2a58369 +Subproject commit 2a19eab0ea4d9a48026d4d29c840bcf03c2138e7