diff --git a/src/shrpx_downstream.cc b/src/shrpx_downstream.cc index b2dec66c..f02a0dc5 100644 --- a/src/shrpx_downstream.cc +++ b/src/shrpx_downstream.cc @@ -64,6 +64,7 @@ Downstream::Downstream(Upstream *upstream, int stream_id, int priority) request_connection_close_(false), request_expect_100_continue_(false), request_header_key_prev_(false), + request_http2_expect_body_(false), chunked_response_(false), response_connection_close_(false), response_header_key_prev_(false), @@ -393,6 +394,11 @@ bool Downstream::get_chunked_request() const return chunked_request_; } +void Downstream::set_chunked_request(bool f) +{ + chunked_request_ = f; +} + bool Downstream::get_request_connection_close() const { return request_connection_close_; @@ -403,6 +409,16 @@ void Downstream::set_request_connection_close(bool f) request_connection_close_ = f; } +bool Downstream::get_request_http2_expect_body() const +{ + return request_http2_expect_body_; +} + +void Downstream::set_request_http2_expect_body(bool f) +{ + request_http2_expect_body_ = f; +} + bool Downstream::get_expect_100_continue() const { return request_expect_100_continue_; diff --git a/src/shrpx_downstream.h b/src/shrpx_downstream.h index e68706ef..01e04552 100644 --- a/src/shrpx_downstream.h +++ b/src/shrpx_downstream.h @@ -137,8 +137,11 @@ public: int get_request_minor() const; int push_request_headers(); bool get_chunked_request() const; + void set_chunked_request(bool f); bool get_request_connection_close() const; void set_request_connection_close(bool f); + bool get_request_http2_expect_body() const; + void set_request_http2_expect_body(bool f); bool get_expect_100_continue() const; int push_upload_data_chunk(const uint8_t *data, size_t datalen); int end_upload_data(); @@ -274,6 +277,7 @@ private: bool request_connection_close_; bool request_expect_100_continue_; bool request_header_key_prev_; + bool request_http2_expect_body_; bool chunked_response_; bool response_connection_close_; diff --git a/src/shrpx_http2_downstream_connection.cc b/src/shrpx_http2_downstream_connection.cc index 3e7f2cd8..cf9316e3 100644 --- a/src/shrpx_http2_downstream_connection.cc +++ b/src/shrpx_http2_downstream_connection.cc @@ -347,11 +347,6 @@ int Http2DownstreamConnection::push_request_headers() http2::copy_norm_headers_to_nva(nva, downstream_->get_request_headers()); - bool content_length = false; - if(downstream_->get_norm_request_header("content-length") != end_headers) { - content_length = true; - } - bool chunked_encoding = false; auto transfer_encoding = downstream_->get_norm_request_header("transfer-encoding"); @@ -414,7 +409,7 @@ int Http2DownstreamConnection::push_request_headers() } if(downstream_->get_request_method() == "CONNECT" || - chunked_encoding || content_length) { + chunked_encoding || downstream_->get_request_http2_expect_body()) { // Request-body is expected. nghttp2_data_provider data_prd; data_prd.source.ptr = this; diff --git a/src/shrpx_http2_upstream.cc b/src/shrpx_http2_upstream.cc index e2c01a49..cd46c308 100644 --- a/src/shrpx_http2_upstream.cc +++ b/src/shrpx_http2_upstream.cc @@ -340,26 +340,17 @@ int on_request_headers(Http2Upstream *upstream, return 0; } } - if(!is_connect && - (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) { - auto content_length = http2::get_header(nva, "content-length"); - if(!content_length || http2::value_lws(content_length)) { - - // TODO We still need content-length here? - - if(upstream->error_reply(downstream, 400) != 0) { - upstream->rst_stream(downstream, NGHTTP2_PROTOCOL_ERROR); - } - - return 0; - } - } downstream->set_request_method(http2::value_to_str(method)); downstream->set_request_http2_scheme(http2::value_to_str(scheme)); downstream->set_request_http2_authority(http2::value_to_str(authority)); downstream->set_request_path(http2::value_to_str(path)); + + if(!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) { + downstream->set_request_http2_expect_body(true); + } + downstream->inspect_http2_request(); auto dconn = upstream->get_client_handler()->get_downstream_connection(); diff --git a/src/shrpx_http_downstream_connection.cc b/src/shrpx_http_downstream_connection.cc index 576e4f3d..9494f5a2 100644 --- a/src/shrpx_http_downstream_connection.cc +++ b/src/shrpx_http_downstream_connection.cc @@ -164,6 +164,13 @@ int HttpDownstreamConnection::push_request_headers() hdrs += "\r\n"; } + if(downstream_->get_request_http2_expect_body() && + downstream_->get_norm_request_header("content-length") == end_headers) { + + downstream_->set_chunked_request(true); + hdrs += "Transfer-Encoding: chunked\r\n"; + } + if(downstream_->get_request_connection_close()) { hdrs += "Connection: close\r\n"; } diff --git a/src/shrpx_spdy_upstream.cc b/src/shrpx_spdy_upstream.cc index 00760069..f5485231 100644 --- a/src/shrpx_spdy_upstream.cc +++ b/src/shrpx_spdy_upstream.cc @@ -204,6 +204,10 @@ void on_ctrl_recv_callback downstream->set_request_path(path); } + if(!(frame->syn_stream.hd.flags & SPDYLAY_CTRL_FLAG_FIN)) { + downstream->set_request_http2_expect_body(true); + } + downstream->inspect_http2_request(); if(LOG_ENABLED(INFO)) {