diff --git a/src/shrpx_http2_downstream_connection.cc b/src/shrpx_http2_downstream_connection.cc index 6c894b50..549ecd13 100644 --- a/src/shrpx_http2_downstream_connection.cc +++ b/src/shrpx_http2_downstream_connection.cc @@ -321,7 +321,12 @@ int Http2DownstreamConnection::push_request_headers() http2::copy_url_component(path, &u, UF_PATH, url); http2::copy_url_component(query, &u, UF_QUERY, url); if(path.empty()) { - path = "/"; + if(!authority.empty() && + downstream_->get_request_method() == "OPTIONS") { + path = "*"; + } else { + path = "/"; + } } if(!query.empty()) { path += "?"; diff --git a/src/shrpx_http_downstream_connection.cc b/src/shrpx_http_downstream_connection.cc index 140c2336..592dabcf 100644 --- a/src/shrpx_http_downstream_connection.cc +++ b/src/shrpx_http_downstream_connection.cc @@ -135,15 +135,25 @@ int HttpDownstreamConnection::push_request_headers() hdrs += downstream_->get_request_path(); } } else if(get_config()->http2_proxy && - !downstream_->get_request_http2_scheme().empty() && - !downstream_->get_request_http2_authority().empty() && - downstream_->get_request_path().c_str()[0] == '/') { + !downstream_->get_request_http2_scheme().empty() && + !downstream_->get_request_http2_authority().empty() && + (downstream_->get_request_path().c_str()[0] == '/' || + downstream_->get_request_path() == "*")) { // Construct absolute-form request target because we are going to // send a request to a HTTP/1 proxy. hdrs += downstream_->get_request_http2_scheme(); hdrs += "://"; hdrs += downstream_->get_request_http2_authority(); - hdrs += downstream_->get_request_path(); + + // 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() != "*") { + hdrs += downstream_->get_request_path(); + } } else { // No proxy case. get_request_path() may be absolute-form but we // don't care.