nghttpx: Don't emit :authority if request dones not contain authority info
RFC 7540 says that proxy should not emit :authority when translating HTTP/1 request in origin or asterisk form to HTTP/2. To keep this semantics in tact, we should also refrain from emitting :authority if it is missing (host header field is required in this case).
This commit is contained in:
parent
7be0217bc0
commit
f25fd09bbb
|
@ -127,7 +127,7 @@ struct Request {
|
|||
: fs(16), recv_body_length(0), unconsumed_body_length(0), method(-1),
|
||||
http_major(1), http_minor(1), upgrade_request(false),
|
||||
http2_upgrade_seen(false), connection_close(false),
|
||||
http2_expect_body(false) {}
|
||||
http2_expect_body(false), no_authority(false) {}
|
||||
|
||||
void consume(size_t len) {
|
||||
assert(unconsumed_body_length >= len);
|
||||
|
@ -165,6 +165,10 @@ struct Request {
|
|||
// true if this is HTTP/2, and request body is expected. Note that
|
||||
// we don't take into account HTTP method here.
|
||||
bool http2_expect_body;
|
||||
// true if request does not have any information about authority.
|
||||
// This happens when: For HTTP/2 request, :authority is missing.
|
||||
// For HTTP/1 request, origin or asterisk form is used.
|
||||
bool no_authority;
|
||||
};
|
||||
|
||||
struct Response {
|
||||
|
|
|
@ -287,7 +287,7 @@ int Http2DownstreamConnection::push_request_headers() {
|
|||
// 1. :method
|
||||
// 2. :scheme
|
||||
// 3. :path
|
||||
// 4. :authority
|
||||
// 4. :authority (or host)
|
||||
// 5. via (optional)
|
||||
// 6. x-forwarded-for (optional)
|
||||
// 7. x-forwarded-proto (optional)
|
||||
|
@ -300,8 +300,6 @@ int Http2DownstreamConnection::push_request_headers() {
|
|||
nva.push_back(
|
||||
http2::make_nv_lc_nocopy(":method", http2::to_method_string(req.method)));
|
||||
|
||||
nva.push_back(http2::make_nv_lc_nocopy(":authority", authority));
|
||||
|
||||
if (req.method != HTTP_CONNECT) {
|
||||
assert(!req.scheme.empty());
|
||||
|
||||
|
@ -312,6 +310,14 @@ int Http2DownstreamConnection::push_request_headers() {
|
|||
} else {
|
||||
nva.push_back(http2::make_nv_ls_nocopy(":path", req.path));
|
||||
}
|
||||
|
||||
if (!req.no_authority) {
|
||||
nva.push_back(http2::make_nv_lc_nocopy(":authority", authority));
|
||||
} else {
|
||||
nva.push_back(http2::make_nv_lc_nocopy("host", authority));
|
||||
}
|
||||
} else {
|
||||
nva.push_back(http2::make_nv_lc_nocopy(":authority", authority));
|
||||
}
|
||||
|
||||
http2::copy_headers_to_nva_nocopy(nva, req.fs.headers());
|
||||
|
|
|
@ -298,6 +298,7 @@ int Http2Upstream::on_request_headers(Downstream *downstream,
|
|||
|
||||
// nghttp2 library guarantees either :authority or host exist
|
||||
if (!authority) {
|
||||
req.no_authority = true;
|
||||
authority = req.fs.header(http2::HD_HOST);
|
||||
}
|
||||
|
||||
|
|
|
@ -308,6 +308,8 @@ int htp_hdrs_completecb(http_parser *htp) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
req.no_authority = true;
|
||||
|
||||
if (method == HTTP_OPTIONS && path == "*") {
|
||||
req.path = "";
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue