nghttpx: Remove requirement of content-length for HTTP2 upstream POST

This commit is contained in:
Tatsuhiro Tsujikawa 2014-07-03 19:59:10 +09:00
parent 9cddb05f54
commit 1ce00f455c
6 changed files with 37 additions and 20 deletions

View File

@ -64,6 +64,7 @@ Downstream::Downstream(Upstream *upstream, int stream_id, int priority)
request_connection_close_(false), request_connection_close_(false),
request_expect_100_continue_(false), request_expect_100_continue_(false),
request_header_key_prev_(false), request_header_key_prev_(false),
request_http2_expect_body_(false),
chunked_response_(false), chunked_response_(false),
response_connection_close_(false), response_connection_close_(false),
response_header_key_prev_(false), response_header_key_prev_(false),
@ -393,6 +394,11 @@ bool Downstream::get_chunked_request() const
return chunked_request_; return chunked_request_;
} }
void Downstream::set_chunked_request(bool f)
{
chunked_request_ = f;
}
bool Downstream::get_request_connection_close() const bool Downstream::get_request_connection_close() const
{ {
return request_connection_close_; return request_connection_close_;
@ -403,6 +409,16 @@ void Downstream::set_request_connection_close(bool f)
request_connection_close_ = 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 bool Downstream::get_expect_100_continue() const
{ {
return request_expect_100_continue_; return request_expect_100_continue_;

View File

@ -137,8 +137,11 @@ public:
int get_request_minor() const; int get_request_minor() const;
int push_request_headers(); int push_request_headers();
bool get_chunked_request() const; bool get_chunked_request() const;
void set_chunked_request(bool f);
bool get_request_connection_close() const; bool get_request_connection_close() const;
void set_request_connection_close(bool f); 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; bool get_expect_100_continue() const;
int push_upload_data_chunk(const uint8_t *data, size_t datalen); int push_upload_data_chunk(const uint8_t *data, size_t datalen);
int end_upload_data(); int end_upload_data();
@ -274,6 +277,7 @@ private:
bool request_connection_close_; bool request_connection_close_;
bool request_expect_100_continue_; bool request_expect_100_continue_;
bool request_header_key_prev_; bool request_header_key_prev_;
bool request_http2_expect_body_;
bool chunked_response_; bool chunked_response_;
bool response_connection_close_; bool response_connection_close_;

View File

@ -347,11 +347,6 @@ int Http2DownstreamConnection::push_request_headers()
http2::copy_norm_headers_to_nva(nva, downstream_->get_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; bool chunked_encoding = false;
auto transfer_encoding = auto transfer_encoding =
downstream_->get_norm_request_header("transfer-encoding"); downstream_->get_norm_request_header("transfer-encoding");
@ -414,7 +409,7 @@ int Http2DownstreamConnection::push_request_headers()
} }
if(downstream_->get_request_method() == "CONNECT" || if(downstream_->get_request_method() == "CONNECT" ||
chunked_encoding || content_length) { chunked_encoding || downstream_->get_request_http2_expect_body()) {
// Request-body is expected. // Request-body is expected.
nghttp2_data_provider data_prd; nghttp2_data_provider data_prd;
data_prd.source.ptr = this; data_prd.source.ptr = this;

View File

@ -340,26 +340,17 @@ int on_request_headers(Http2Upstream *upstream,
return 0; 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_method(http2::value_to_str(method));
downstream->set_request_http2_scheme(http2::value_to_str(scheme)); downstream->set_request_http2_scheme(http2::value_to_str(scheme));
downstream->set_request_http2_authority(http2::value_to_str(authority)); downstream->set_request_http2_authority(http2::value_to_str(authority));
downstream->set_request_path(http2::value_to_str(path)); 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(); downstream->inspect_http2_request();
auto dconn = upstream->get_client_handler()->get_downstream_connection(); auto dconn = upstream->get_client_handler()->get_downstream_connection();

View File

@ -164,6 +164,13 @@ int HttpDownstreamConnection::push_request_headers()
hdrs += "\r\n"; 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()) { if(downstream_->get_request_connection_close()) {
hdrs += "Connection: close\r\n"; hdrs += "Connection: close\r\n";
} }

View File

@ -204,6 +204,10 @@ void on_ctrl_recv_callback
downstream->set_request_path(path); 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(); downstream->inspect_http2_request();
if(LOG_ENABLED(INFO)) { if(LOG_ENABLED(INFO)) {