feat(proxy): add Proxy::resolve_local to tunnel CONNECT to a locally-resolved IP#1185
Open
eav93 wants to merge 1 commit into
Open
feat(proxy): add Proxy::resolve_local to tunnel CONNECT to a locally-resolved IP#1185eav93 wants to merge 1 commit into
eav93 wants to merge 1 commit into
Conversation
Contributor
There was a problem hiding this comment.
Code Review
This pull request introduces a resolve_local option for proxies, allowing the client to resolve the destination host locally and send the HTTP CONNECT request to the resolved IP address instead of the hostname. This is implemented by making the DNS resolver always available in ConnectorBuilder and ConnectorService, and adding a resolve_connect_dst helper. Feedback on the changes suggests a more idiomatic way to format the resolved IP and port using SocketAddr's built-in formatting rather than manually matching on the IP address type.
Comment on lines
+388
to
+391
| let authority = match addr.ip() { | ||
| IpAddr::V4(ip) => format!("{ip}:{port}"), | ||
| IpAddr::V6(ip) => format!("[{ip}]:{port}"), | ||
| }; |
Contributor
There was a problem hiding this comment.
…resolved IP By default an HTTP CONNECT tunnel is opened to the destination hostname, leaving DNS resolution to the proxy. With Proxy::resolve_local(true) the destination is resolved by the client's own resolver (honoring resolve overrides) and CONNECT is sent to the resolved IP instead, while TLS SNI and the tunneled request keep using the original hostname. This mirrors the socks5:// (local DNS) vs socks5h:// (remote DNS) distinction for HTTP(S) proxies, and helps when the proxy's own DNS is unreliable or the hostname in the CONNECT line is filtered upstream.
eav93
added a commit
to eav93/wreq-php
that referenced
this pull request
May 28, 2026
…d IP New client option `proxy_resolve_local` (bool). With an HTTP(S) `proxy`, the destination host is resolved by the client and CONNECT is sent to the resolved IP instead of the hostname; TLS SNI and Host keep the original hostname. Helps when the proxy's own DNS is unreliable or the hostname in the CONNECT line is filtered upstream. Backed by a patched wreq (Proxy::resolve_local) via [patch.crates-io], pending upstream PR 0x676e67/wreq#1185.
Owner
|
I would like to know if this functionality has been implemented in other HTTP client libraries. |
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.
Summary
Adds an opt-in
Proxy::resolve_local(bool)for HTTP(S) proxies.By default, an HTTPS request through an HTTP proxy opens the tunnel with the
destination hostname (
CONNECT example.com:443), leaving DNS resolution tothe proxy. When
resolve_local(true)is set, the destination host is resolvedby the client's own resolver (honoring
ClientBuilder::resolve/resolve_to_addrsoverrides) and theCONNECTrequest is sent to the resolvedIP instead (
CONNECT 93.184.216.34:443). The IP is used for both theCONNECTrequest-target and that request'sHostheader; the original port ispreserved.
The TLS SNI and the tunneled HTTP request keep using the original hostname, so
certificate validation and virtual hosting are unaffected.
Motivation
This mirrors the existing
socks5://(local DNS) vssocks5h://(remote DNS)distinction, but for HTTP(S) proxies, which currently have no equivalent. It is
useful when the proxy's own DNS is unreliable or when the hostname in the
CONNECTline is filtered upstream — resolving locally and tunneling to the IPsidesteps both, while the connection pool still keys on the original hostname.
Behavior / scope
Unix-socket proxies, or on plain HTTP requests.
[::1]) are passed through unchanged.SocketAddr(a custom resolver may return a synthetic/zero port).Tests
tests/proxy.rscovers: hostname → resolved IP in CONNECT; opt-out leaves thehostname even with a
resolveoverride present; explicit non-default port ispreserved; IPv6 literal passthrough.
cargo fmt,cargo check(with andwithout
socks), clippy and the proxy suite all pass.Implementation note
The
resolverfield on the connector was previously gated behind thesocksfeature; it is now always present, since the HTTP tunnel path also needs it.