fix: canonicalize Host header into :authority for outbound HTTP/2#877
fix: canonicalize Host header into :authority for outbound HTTP/2#877magurotuna wants to merge 2 commits intohyperium:masterfrom
Conversation
When sending HTTP/2 requests or push promises, promote the first valid Host header value to :authority and strip all Host headers from regular fields. This prevents emitting conflicting :authority and Host on the wire, aligning with RFC 9113 and the behavior of other HTTP/2 client implementations such as curl, Go's std, and Python's httpx. Fixes hyperium#876
5508e4e to
bd48b82
Compare
@seanmonstar i wasn't around for that earlier consideration, but i pinged Oliver to take a look at this. i suspect he'll be better positioned to remember the details here 🙂 thank you for checking in with us! |
|
hi @seanmonstar, thank you for your patience. looking at what this function does... /// Canonicalize `Host` header into `:authority` pseudo-header for HTTP/2.
///
/// - If a `Host` header is present, attempt to parse its first value as a URI authority.
/// - On success, override `:authority` with the parsed value.
/// - Always remove all `Host` headers from the regular header map.
i believe the relevant portions of RFC 9113 are found in section 8.3.1. the strict rules i see for clients are:
so host headers are fine for clients to emit, so long as they do not differ from the ":authority" pseudo-header. removing them unconditionally would, i think, be going a step too far. for intermediaries, the rules i see are:
i think it's reasonable for h2 to enforce RFC 9113 compliance, and avoiding mismatched :authority and Host values seems like a wise decision, particularly because these MUST NOT differ. i don't think that we should always remove all ideally, it'd be nice to leave a way for intermediaries to retain the host header field, per https://www.rfc-editor.org/rfc/rfc9113.html#section-8.3.1-2.3.6. that's likely important for intermediaries like us (linkerd) that transport HTTP/1 traffic over an HTTP/2 intermediary layer. |
353f6ca to
570641f
Compare
570641f to
b7a0bcb
Compare
|
Thanks for the thorough review and the RFC analysis, @cratelyn! I've addressed your feedback:
|
When sending HTTP/2 requests or push promises, promote the first valid Host header value to :authority and retain it on the wire. Duplicate Host values are collapsed to a single entry matching :authority, and unparseable Host values are stripped. This prevents emitting conflicting :authority and Host while keeping the Host header available for intermediaries that may need it (RFC 9113 §8.3.1).
The "Host wins" semantics align with the behavior of other HTTP/2 client implementations such as curl, Go's std, and Python's httpx.
Fixes #876