From 4be4d875f30182e1e1fc291aec93e0e254c775e4 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Mon, 4 May 2015 23:24:33 +0900 Subject: [PATCH] nghttpx: Log absolute URI for HTTP/2 or client proxy request --- src/shrpx_client_handler.cc | 54 ++++++++++++++++++++++++++++++++++--- src/shrpx_https_upstream.cc | 9 +++++-- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/shrpx_client_handler.cc b/src/shrpx_client_handler.cc index 063c8388..1d66e2e3 100644 --- a/src/shrpx_client_handler.cc +++ b/src/shrpx_client_handler.cc @@ -690,15 +690,63 @@ void ClientHandler::start_immediate_shutdown() { ev_timer_start(conn_.loop, &reneg_shutdown_timer_); } +namespace { +// Construct absolute request URI from |downstream|, mainly to log +// request URI for proxy request (HTTP/2 proxy or client proxy). This +// is mostly same routine found in +// HttpDownstreamConnection::push_request_headers(), but vastly +// simplified since we only care about absolute URI. +std::string construct_absolute_request_uri(Downstream *downstream) { + const char *authority = nullptr, *host = nullptr; + if (!downstream->get_request_http2_authority().empty()) { + authority = downstream->get_request_http2_authority().c_str(); + } + auto h = downstream->get_request_header(http2::HD_HOST); + if (h) { + host = h->value.c_str(); + } + if (!authority && !host) { + return downstream->get_request_path(); + } + std::string uri; + if (downstream->get_request_http2_scheme().empty()) { + // this comes from HTTP/1 upstream without scheme. Just use http. + uri += "http://"; + } else { + uri += downstream->get_request_http2_scheme(); + uri += "://"; + } + if (authority) { + uri += authority; + } else { + uri += host; + } + + // Server-wide OPTIONS takes following form in proxy request: + // + // OPTIONS http://example.org HTTP/1.1 + // + // Notice that no slash after authority. See + // http://tools.ietf.org/html/rfc7230#section-5.3.4 + if (downstream->get_request_path() != "*") { + uri += downstream->get_request_path(); + } + return uri; +} +} // namespace + void ClientHandler::write_accesslog(Downstream *downstream) { upstream_accesslog( get_config()->accesslog_format, LogSpec{ downstream, ipaddr_.c_str(), downstream->get_request_method().c_str(), - downstream->get_request_path().empty() - ? downstream->get_request_http2_authority().c_str() - : downstream->get_request_path().c_str(), + (downstream->get_request_method() != "CONNECT" && + (get_config()->http2_proxy || get_config()->client_proxy)) + ? construct_absolute_request_uri(downstream).c_str() + : downstream->get_request_path().empty() + ? downstream->get_request_http2_authority().c_str() + : downstream->get_request_path().c_str(), alpn_.c_str(), diff --git a/src/shrpx_https_upstream.cc b/src/shrpx_https_upstream.cc index e620a5da..f634bf4e 100644 --- a/src/shrpx_https_upstream.cc +++ b/src/shrpx_https_upstream.cc @@ -218,7 +218,12 @@ void rewrite_request_host_path_from_uri(Downstream *downstream, const char *uri, path += '?'; path.append(uri + fdata.off, fdata.len); } - downstream->set_request_path(path); + downstream->set_request_path(std::move(path)); + if (get_config()->http2_proxy || get_config()->client_proxy) { + std::string scheme; + http2::copy_url_component(scheme, &u, UF_SCHEMA, uri); + downstream->set_request_http2_scheme(std::move(scheme)); + } } } // namespace @@ -275,7 +280,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()->client_proxy) { + if (get_config()->http2_proxy || get_config()->client_proxy) { // Request URI should be absolute-form for client proxy mode return -1; }