Repository navigation
fix: never send HTTP/3 requests past the proxy, make HTTP/3 opt-in in the Rust crate - #595
Draft
metalwarrior665 wants to merge 1 commit into
Draft
metalwarrior665 wants to merge 1 commit into
metalwarrior665 wants to merge 1 commit into
Conversation
… the Rust crate reqwest sends HTTP/3 requests through its own QUIC connector, which ignores proxies. With `with_http3()` and a proxy, the first request to a host went through the proxy, and once the host's `Alt-Svc` header advertised h3, later requests went out over QUIC from the machine's own IP address. HTTP/3 is now disabled (with a warning) when a proxy is set, either with `with_proxy` or in `HTTPS_PROXY` / `ALL_PROXY`. reqwest's `http3` feature also makes every client set up a QUIC endpoint (a UDP socket, a driver task and a receive buffer of at least 2 MB), even when HTTP/3 is never used. HTTP/3 support is now behind the `http3` feature of the `impit` crate, so clients without it skip that setup, and the crate builds without `--cfg reqwest_unstable`. The Node and Python bindings enable the feature, so their `http3` option works as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0148RYR4BTGyCYHENSRZjC3S
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
HTTP/3 bypassed the proxy
reqwest sends HTTP/3 requests through its own QUIC connector (
h3_client/connect.rs), which resolves the host and connects directly. Only the TCP connector knows about proxies; that's true of both the crates.io release and the patched revision impit uses. So withwith_http3()and a proxy:Alt-Svcor its HTTPS DNS record, impit caches the host as HTTP/3-capable.Reproduced on
master. I usedwith_http3()with a local logging CONNECT proxy and fetchedhttps://www.google.com/:CONNECT www.google.com:443each.http3_prior_knowledgenever reached the proxy. strace shows the QUIC packets going straight from the process to142.251.153.119:443.H3Enginealso went straight to8.8.8.8/8.8.4.4.HTTP/3 is opt-in and off by default, so the default path is fine. The problem is only with
http3: trueplus a proxy.Now, when a proxy is set, HTTP/3 is disabled with a warning. A proxy counts as set when it's given with
with_proxy, or inHTTPS_PROXY/ALL_PROXY, the variables reqwest reads for HTTPS. A request withhttp3_prior_knowledgethen fails withHttp3Disabled. I picked this over failing at build time so existinghttp3: true+ proxy setups keep working, just over HTTP/2. It's easy to flip if you'd rather error.Unused QUIC setup on every client
reqwest's
http3feature also makes every client usinguse_preconfigured_tlsbuild an HTTP/3 connector, even when HTTP/3 is never used. That means a quinn endpoint per client: a UDP socket, a driver task, and a zeroed receive buffer of at least 2 MB.In a CPU profile of a Rust Instagram scraper that builds one impit client per proxy session, this endpoint setup took ~6% of all CPU, for a protocol it never uses.
HTTP/3 support is now behind a new
http3feature of theimpitcrate:hickory-*andtokioaren't needed.--cfg reqwest_unstable.impit-nodeandimpit-pythonenable the feature, so theirhttp3option behaves as before.with_http3()now needsfeatures = ["http3"]. I removed it from the README and doc examples. TheImpitBuilderdoc example combined it with a proxy, which is exactly the leaking setup.CI now also runs
cargo test -p impit --features http3, and the docs are built with the feature on.🤖 Generated with Claude Code
https://claude.ai/code/session_0148RYR4BTGyCYHENSRZjC3S