Skip to content

feat(grpc): Add resolver wrapper to handle HTTP CONNECT proxy configuration#2679

Open
arjan-bal wants to merge 20 commits into
grpc:masterfrom
arjan-bal:http-proxy-resolver
Open

feat(grpc): Add resolver wrapper to handle HTTP CONNECT proxy configuration#2679
arjan-bal wants to merge 20 commits into
grpc:masterfrom
arjan-bal:http-proxy-resolver

Conversation

@arjan-bal

@arjan-bal arjan-bal commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

This PR implements a resolver wrapper that determines proxy routing by checking the HTTPS_PROXY and NO_PROXY environment variables. By default, hyper-util matches cURL's behavior by falling back to ALL_PROXY when HTTPS_PROXY is unset. However, because Go's FromEnvironment and gRPC C++ ignore ALL_PROXY, gRPC Rust manually configures the Matcher to bypass it, ensuring cross-language consistency.

Resolution Flow
When HttpsProxyResolver::Builder builds a resolver for a target URI, it uses hyper_util::client::proxy::Matcher to evaluate the environment variables:

  1. Direct Connection: If no proxy is required, it delegates resolution entirely to the wrapped child builder, bypassing the proxy resolver.
  2. Proxied Connection: If a proxy is required, it creates an HttpsProxyResolver, which uses the child DNS resolver to resolve the proxy server's hostname instead of the target.
  3. Attribute Injection: The HttpsProxyResolver intercepts resolution updates from the child resolver. It attaches the necessary proxy configuration (the original target authority and basic auth credentials) as attributes to each resolved proxy address.

In follow-up PRs, the subchannel will read these address attributes to wrap the channel credentials and carry out the HTTP CONNECT handshake prior to the standard credential handshake.

Internal design doc: go/grpc-rust-http-connect

@arjan-bal

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the gRPC client to support arbitrary byte-based addresses (via ByteStr) instead of requiring valid UTF-8 strings, enabling support for non-UTF-8 unix socket paths. It also introduces an HTTP CONNECT proxy resolver that intercepts DNS resolution and applies proxy configurations based on environment variables. The review feedback suggests bypassing proxy resolution entirely for non-DNS schemes (like unix or inmemory), safely handling empty NO_PROXY environment variables, and updating tests to verify that unix paths correctly bypass the proxy.

Comment thread grpc/src/client/name_resolution/proxy_resolver.rs
Comment thread grpc/src/client/name_resolution/proxy_resolver.rs
Comment thread grpc/src/client/name_resolution/proxy_resolver.rs
options: ResolverOptions,
matcher: Option<&Matcher>,
) -> Result<Box<dyn Resolver>, (String, ResolverOptions)> {
// Skip proxy lookup for known non-TCP schemes.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd expect to skip it for anything that isn't dns. I think there had been a little discussion around that, but I don't know where it ended.

The host will be passed to the proxy and the proxy then has to do the resolution, but we've discarded the scheme. It seems we are assuming dns formatting of the target string as well. We shouldn't be parsing the target string without knowledge of the specific scheme in use. Things would be better if we delegated to the name resolver to parse the target string into an authority.

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.

3 participants