hyperium / hyperium/h2

Outbound HTTP/2 frames can emit conflicting :authority and host headers

Open
#876 0 comments 2 reactions 0 assignees View on GitHub

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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.