Outbound HTTP/2 frames can emit conflicting :authority and host headers
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 1.6k
- Forks
- 382
- Avg merge
- 20h 23m
- Merged PRs (30d)
- 9
Description
Problem
When a user-provided Host header is present on an outbound HTTP/2 request, h2 emits it as a regular header field alongside the :authority pseudo-header derived from the URI. If the two values differ, this produces contradictory authority metadata on the wire.
For example, sending a request with URI https://example.net/ and header Host: example.com results in a HEADERS frame containing both :authority: example.net and host: example.com.
Expected behavior
Per RFC 9113 §8.3.1, clients must not generate a request containing inconsistent value in Host and :authority. The simplest way to guarantee consistency is to never emit host as a regular header on the wire for HTTP/2.
Other HTTP/2 implementations do this. For instance, curl with an explicit Host header (curl -H 'host: foo.net' https://bar.com) promotes the user-supplied Host value to :authority and strips host from regular headers entirely (verified via Wireshark). Go's net/http and Python's httpx behave the same way.
Additional info
This issue is evident in Deno's fetch implementation, which is implemented with the hyper stack (including h2). We expect the following code to send a request with :authority = example.net (instead of example.com), but what's actually sent with Deno v2.6.9 is :authority = example.com and host = example.net, violating the HTTP/2 spec.
using client = Deno.createHttpClient({ allowHost: true });
const res = await fetch("https://example.com", {
client,
headers: {
host: "example.net",
},
});
console.log(res.status);
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the provided Deno fetch example and inspect h2's outbound HTTP/2 header encoding path. Add coverage for a user-provided Host value that differs from the URI authority, and verify the emitted HEADERS frame does not contain conflicting authority metadata.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- deno, rust
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 50/100