nghttpx: Send non-final response to HTTP/1.1 or HTTP/2 client only

This commit is contained in:
Tatsuhiro Tsujikawa 2017-09-21 21:42:56 +09:00
parent 7d4d48a35e
commit 2576855ded
6 changed files with 40 additions and 0 deletions

View File

@ -115,6 +115,8 @@ int main(int argc, char *argv[]) {
shrpx::test_downstream_assemble_request_cookie) ||
!CU_add_test(pSuite, "downstream_rewrite_location_response_header",
shrpx::test_downstream_rewrite_location_response_header) ||
!CU_add_test(pSuite, "downstream_supports_non_final_response",
shrpx::test_downstream_supports_non_final_response) ||
!CU_add_test(pSuite, "config_parse_header",
shrpx::test_shrpx_config_parse_header) ||
!CU_add_test(pSuite, "config_parse_log_format",

View File

@ -743,6 +743,10 @@ bool Downstream::get_non_final_response() const {
return !upgraded_ && resp_.http_status / 100 == 1;
}
bool Downstream::supports_non_final_response() const {
return req_.http_major == 2 || (req_.http_major == 1 && req_.http_minor == 1);
}
bool Downstream::get_upgraded() const { return upgraded_; }
bool Downstream::get_http2_upgrade_request() const {

View File

@ -348,6 +348,9 @@ public:
// True if the response is non-final (1xx status code). Note that
// if connection was upgraded, 101 status code is treated as final.
bool get_non_final_response() const;
// True if protocol version used by client supports non final
// response. Only HTTP/1.1 and HTTP/2 clients support it.
bool supports_non_final_response() const;
void set_expect_final_response(bool f);
bool get_expect_final_response() const;

View File

@ -164,4 +164,29 @@ void test_downstream_rewrite_location_response_header(void) {
CU_ASSERT("https://localhost:8443/" == (*location).value);
}
void test_downstream_supports_non_final_response(void) {
Downstream d(nullptr, nullptr, 0);
auto &req = d.request();
req.http_major = 2;
req.http_minor = 0;
CU_ASSERT(d.supports_non_final_response());
req.http_major = 1;
req.http_minor = 1;
CU_ASSERT(d.supports_non_final_response());
req.http_major = 1;
req.http_minor = 0;
CU_ASSERT(!d.supports_non_final_response());
req.http_major = 0;
req.http_minor = 9;
CU_ASSERT(!d.supports_non_final_response());
}
} // namespace shrpx

View File

@ -36,6 +36,7 @@ void test_downstream_field_store_header(void);
void test_downstream_crumble_request_cookie(void);
void test_downstream_assemble_request_cookie(void);
void test_downstream_rewrite_location_response_header(void);
void test_downstream_supports_non_final_response(void);
} // namespace shrpx

View File

@ -1022,6 +1022,11 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
auto &resp = downstream->response();
auto &balloc = downstream->get_block_allocator();
if (!downstream->supports_non_final_response()) {
resp.fs.clear_headers();
return 0;
}
#ifdef HAVE_MRUBY
if (!downstream->get_non_final_response()) {
auto worker = handler_->get_worker();