From 0cd191b9e60118c9a77e63ad20025bcf4d1f195b Mon Sep 17 00:00:00 2001 From: Lu Qiuwen Date: Thu, 25 Oct 2018 16:47:19 +0800 Subject: [PATCH] =?UTF-8?q?Close=20#60=20=E4=BF=AE=E6=AD=A3POST=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=E6=97=A0Content-Length=E5=AD=97=E6=AE=B5=E6=97=B6?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E8=BD=AC=E5=8F=91=E8=AF=B7=E6=B1=82=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20*=20=E9=83=A8=E5=88=86HTTP=20POST=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=E4=B8=AD=E6=97=A0=E6=9C=89Content-Length=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=EF=BC=8C=E5=AF=BC=E8=87=B4=E6=97=A0=E6=B3=95=E7=A1=AE?= =?UTF-8?q?=E5=AE=9A=E8=AF=B7=E6=B1=82=E7=9A=84=E8=BE=B9=E7=95=8C=E3=80=82?= =?UTF-8?q?=20*=20=E7=8E=B0=E4=BF=AE=E6=AD=A3=E4=B8=BA=EF=BC=8C=E5=BD=93?= =?UTF-8?q?=E5=8F=91=E7=8E=B0Content-Length=E5=AD=97=E6=AE=B5=E7=BC=BA?= =?UTF-8?q?=E5=A4=B1=E6=97=B6=EF=BC=8CPassthrough=E6=95=B4=E4=B8=AATCP?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E3=80=82=20*=20TODO:=20=E8=A7=A3=E6=9E=90POS?= =?UTF-8?q?T=E7=BC=96=E7=A0=81=E6=88=96=E5=9B=9E=E5=BA=94411=E5=BA=94?= =?UTF-8?q?=E7=AD=94=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http/include/internal/http_half.h | 2 ++ plugin/protocol/http/src/http_entry.cpp | 11 ++++++++ plugin/protocol/http/src/http_half.cpp | 25 ++++++++++++++++--- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/plugin/protocol/http/include/internal/http_half.h b/plugin/protocol/http/include/internal/http_half.h index fe762b9..86c8414 100644 --- a/plugin/protocol/http/include/internal/http_half.h +++ b/plugin/protocol/http/include/internal/http_half.h @@ -95,6 +95,8 @@ struct http_half_private /* UPGRADE */ bool is_upgrade; + /* PASSTHROUGH */ + bool is_passthrough; }; struct http_half_private * hf_private_create(tfe_http_direction ht_dir, short major, short minor); diff --git a/plugin/protocol/http/src/http_entry.cpp b/plugin/protocol/http/src/http_entry.cpp index ccdcee4..8f42893 100644 --- a/plugin/protocol/http/src/http_entry.cpp +++ b/plugin/protocol/http/src/http_entry.cpp @@ -362,6 +362,11 @@ enum tfe_stream_action __http_connection_entry_on_request(const struct tfe_strea } /* Some kind of error happened, write log and detach the stream */ + if (ret == -1 && hf_private_req_in->is_passthrough) + { + goto __errout; + } + if (ret == -1) { TFE_STREAM_LOG_ERROR(stream, "Failed at parsing stream as HTTP: %u, %s, %s", @@ -475,6 +480,12 @@ enum tfe_stream_action __http_connection_entry_on_response(const struct tfe_stre return hf_private_resp_in->stream_action; } + /* Need to passthrough */ + if (ret == -1 && hf_private_resp_in->is_passthrough) + { + goto __errout; + } + /* Some kind of error happened, write log and detach the stream */ if (ret == -1) { diff --git a/plugin/protocol/http/src/http_half.cpp b/plugin/protocol/http/src/http_half.cpp index e2499af..a85374b 100644 --- a/plugin/protocol/http/src/http_half.cpp +++ b/plugin/protocol/http/src/http_half.cpp @@ -172,6 +172,8 @@ void __hf_public_req_fill_from_private(struct http_half_private * hf_private, st /* accept-encoding, host is located in header's K-V structure */ hf_req_spec->method = (enum tfe_http_std_method) parser->method; + hf_private->method_or_status = (enum tfe_http_std_method) parser->method; + const static struct http_field_name __host_field_name = {TFE_HTTP_HOST, NULL}; hf_req_spec->host = (char *) tfe_http_field_read(hf_public, &__host_field_name); @@ -320,6 +322,16 @@ static int __parser_callback_on_headers_complete(http_parser * parser) __hf_public_resp_fill_from_private(hf_private, parser); } + /* for POST, must contains 'content-length' */ + if (hf_direction == TFE_HTTP_REQUEST && hf_private->method_or_status == TFE_HTTP_METHOD_POST) + { + const static struct http_field_name __cont_encoding_field_name = {TFE_HTTP_CONT_LENGTH, NULL}; + char * __str_content_length = (char *) tfe_http_field_read(hf_public, &__cont_encoding_field_name); + + /* Does not contain a content-length, passthrough the whole TCP connection */ + if (unlikely(__str_content_length == NULL)) { hf_private->is_passthrough = true; return -1;} + } + tfe_http_event event = (hf_direction == TFE_HTTP_REQUEST) ? EV_HTTP_REQ_HDR : EV_HTTP_RESP_HDR; if (hf_private->event_cb) { @@ -334,8 +346,8 @@ static int __parser_callback_on_headers_complete(http_parser * parser) hf_private->stream_action = hf_private->user_stream_action; } - /* user's suspend tag is set, which indicate that the way to handle request/response - * cannot be determinate at now, need to defer */ + /* user's suspend tag is set, which indicate that the way to handle request/response + * cannot be determinate at now, need to defer */ else if (hs_private && hs_private->suspend_tag_user) { /* Pause parser, prevent to parse request/response body, @@ -1095,9 +1107,14 @@ void __write_access_log(struct http_session_private * hs_private) /* Upgrade Tag */ const char * __str_upgrade = response ? response->is_upgrade ? "UPGRADE" : "-" : "-"; + /* PASSTHROUGH */ + const char * __str_req_passthrough = request ? request->is_passthrough ? "PASS-THROUGH/REQ" : "-" : "-"; + const char * __str_resp_passthrough = response ? response->is_passthrough ? "PASS-THROUGH/REP" : "-" : "-"; + char * __access_log; - asprintf(&__access_log, "%d %s %s HTTP/%d.%d %s %s %s %s", hs_private->hs_public.session_id, __str_method, - __str_url, request->major, request->minor, __str_resp_code, __str_cont_type, __str_cont_encoding, __str_upgrade); + asprintf(&__access_log, "%d %s %s HTTP/%d.%d %s %s %s %s %s %s", hs_private->hs_public.session_id, __str_method, + __str_url, request->major, request->minor, __str_resp_code, __str_cont_type, __str_cont_encoding, + __str_upgrade, __str_req_passthrough, __str_resp_passthrough); const struct tfe_stream * stream = hs_private->hc_private->stream; tfe_stream_write_access_log(stream, RLOG_LV_INFO, "%s", __access_log);