From 4807e71b7dc1ba5ce8846e2492d46096b6f0b580 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Thu, 18 Aug 2016 22:31:53 +0900 Subject: [PATCH] nghttpx: Fix bug that api and healthmon params do not work with http2 proxy --- src/shrpx_http2_upstream.cc | 9 ++++++--- src/shrpx_https_upstream.cc | 13 +++++++------ src/shrpx_spdy_upstream.cc | 6 +++++- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/shrpx_http2_upstream.cc b/src/shrpx_http2_upstream.cc index 0772b8dc..83af04fa 100644 --- a/src/shrpx_http2_upstream.cc +++ b/src/shrpx_http2_upstream.cc @@ -306,8 +306,11 @@ int Http2Upstream::on_request_headers(Downstream *downstream, return 0; } - // For HTTP/2 proxy, we request :authority. - if (method_token != HTTP_CONNECT && get_config()->http2_proxy && !authority) { + auto faddr = handler_->get_upstream_addr(); + + // For HTTP/2 proxy, we require :authority. + if (method_token != HTTP_CONNECT && get_config()->http2_proxy && + !faddr->alt_mode && !authority) { rst_stream(downstream, NGHTTP2_PROTOCOL_ERROR); return 0; } @@ -331,7 +334,7 @@ int Http2Upstream::on_request_headers(Downstream *downstream, if (method_token == HTTP_OPTIONS && path->value == StringRef::from_lit("*")) { // Server-wide OPTIONS request. Path is empty. - } else if (get_config()->http2_proxy) { + } else if (get_config()->http2_proxy && !faddr->alt_mode) { req.path = path->value; } else { req.path = http2::rewrite_clean_path(downstream->get_block_allocator(), diff --git a/src/shrpx_https_upstream.cc b/src/shrpx_https_upstream.cc index 50b5b16a..2bfaaf13 100644 --- a/src/shrpx_https_upstream.cc +++ b/src/shrpx_https_upstream.cc @@ -202,7 +202,7 @@ int htp_hdr_valcb(http_parser *htp, const char *data, size_t len) { namespace { void rewrite_request_host_path_from_uri(BlockAllocator &balloc, Request &req, const StringRef &uri, - http_parser_url &u) { + http_parser_url &u, bool http2_proxy) { assert(u.field_set & (1 << UF_HOST)); // As per https://tools.ietf.org/html/rfc7230#section-5.4, we @@ -271,7 +271,7 @@ void rewrite_request_host_path_from_uri(BlockAllocator &balloc, Request &req, } } - if (get_config()->http2_proxy) { + if (http2_proxy) { req.path = path; } else { req.path = http2::rewrite_clean_path(balloc, path); @@ -338,6 +338,7 @@ int htp_hdrs_completecb(http_parser *htp) { downstream->inspect_http1_request(); + auto faddr = handler->get_upstream_addr(); auto &balloc = downstream->get_block_allocator(); if (method != HTTP_CONNECT) { @@ -349,7 +350,7 @@ int htp_hdrs_completecb(http_parser *htp) { } // checking UF_HOST could be redundant, but just in case ... if (!(u.field_set & (1 << UF_SCHEMA)) || !(u.field_set & (1 << UF_HOST))) { - if (get_config()->http2_proxy) { + if (get_config()->http2_proxy && !faddr->alt_mode) { // Request URI should be absolute-form for client proxy mode return -1; } @@ -372,7 +373,9 @@ int htp_hdrs_completecb(http_parser *htp) { req.scheme = StringRef::from_lit("http"); } } else { - rewrite_request_host_path_from_uri(balloc, req, req.path, u); + rewrite_request_host_path_from_uri(balloc, req, req.path, u, + get_config()->http2_proxy && + !faddr->alt_mode); } } @@ -411,8 +414,6 @@ int htp_hdrs_completecb(http_parser *htp) { return -1; } - auto faddr = handler->get_upstream_addr(); - if (faddr->alt_mode) { // Normally, we forward expect: 100-continue to backend server, // and let them decide whether responds with 100 Continue or not. diff --git a/src/shrpx_spdy_upstream.cc b/src/shrpx_spdy_upstream.cc index ef68bb20..0bd86c4b 100644 --- a/src/shrpx_spdy_upstream.cc +++ b/src/shrpx_spdy_upstream.cc @@ -267,7 +267,11 @@ void on_ctrl_recv_callback(spdylay_session *session, spdylay_frame_type type, } else { req.scheme = scheme->value; req.authority = host->value; - if (get_config()->http2_proxy) { + + auto handler = upstream->get_client_handler(); + auto faddr = handler->get_upstream_addr(); + + if (get_config()->http2_proxy && !faddr->alt_mode) { req.path = path->value; } else if (method_token == HTTP_OPTIONS && path->value == StringRef::from_lit("*")) {