Skip to content

Use the request target as the CONNECT :authority in Mint.HTTP2#497

Open
ericmj wants to merge 2 commits into
mainfrom
http2-connect-target
Open

Use the request target as the CONNECT :authority in Mint.HTTP2#497
ericmj wants to merge 2 commits into
mainfrom
http2-connect-target

Conversation

@ericmj

@ericmj ericmj commented Jul 21, 2026

Copy link
Copy Markdown
Member

Mint.HTTP2 hardcoded the :authority pseudo-header of CONNECT requests to the connection's own authority and ignored the path argument, so a CONNECT could only target the server itself. Per RFC 9113 section 8.5 the request target of a CONNECT is the host and port of the tunnel destination, which request/5 now takes from its path argument, mirroring HTTP/1 (HTTP1.request(conn, "CONNECT", "host:443", ...)). This makes Mint.HTTP2 usable as a tunnel client, so pooling libraries can multiplex CONNECT tunnels over one HTTP/2 proxy connection (the part that can't live in Mint itself, since it means sharing a connection across conns).

Extended CONNECT (RFC 8441) is unchanged: when the headers contain a :protocol pseudo-header, :authority stays the connection authority and the caller passes :scheme and :path explicitly. Verified against mint_web_socket's h2 upgrade path, which always sends :protocol and relies on this.

The new tests pin the tunnel stream lifecycle: bytes flow both directions on the open stream, a content-length on the 2xx response doesn't end the tunnel (no h2 analog of #493), a server END_STREAM closes the whole tunnel (Mint doesn't do RFC 9113's TCP-style half-close in that direction, now documented), and a client :eof half-closes while receiving keeps working. Docs: a CONNECT section in Mint.HTTP2.request/5, a note in Mint.HTTP.request/5, and a "Proxying over HTTP/2" subsection explaining the relay pattern (address dials the relay, :hostname keeps the real identity, building on #496).

Mint.HTTP2 hardcoded the :authority pseudo-header of CONNECT requests to
the connection's own authority and ignored the path argument, so a
CONNECT could only target the server itself. Per RFC 9113 section 8.5
the request target of a CONNECT is the host and port of the tunnel
destination, which request/5 now takes from its path argument, mirroring
HTTP/1 (HTTP1.request(conn, "CONNECT", "host:443", ...)).

Extended CONNECT (RFC 8441) is unchanged: when the headers contain a
:protocol pseudo-header, :authority stays the connection authority and
the caller passes :scheme and :path explicitly, which is how
mint_web_socket drives WebSocket over HTTP/2.

The new tests also pin the tunnel stream lifecycle: bytes flow in both
directions on the open stream, a content-length header on the 2xx
response doesn't end the tunnel, a server END_STREAM closes the whole
tunnel, and a client :eof half-closes it while receiving keeps working.
The docs describe CONNECT tunnels in Mint.HTTP2.request/5 and how to
build HTTP/2 proxying on top of them in the Proxying section.
@coveralls

coveralls commented Jul 21, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 0

Coverage increased (+0.02%) to 87.95%

Details

  • Coverage increased (+0.02%) from the base build.
  • Patch coverage: 3 of 3 lines across 1 file are fully covered (100%).
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 1668
Covered Lines: 1467
Line Coverage: 87.95%
Coverage Strength: 496.68 hits per line

💛 - Coveralls

The relay pattern in the Proxying section claimed the request Host header
targets the real host; the default Host header and :authority contain the
connection port, which is the relay's port, so the docs now say so and
give the workarounds. Also qualify that the path argument doesn't apply
to extended CONNECT requests, and note that servers gate extended CONNECT
behind the :enable_connect_protocol setting, which Mint doesn't enforce.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants