Skip to content

http-client: add safe route-aware request pool#31917

Open
bolinfest wants to merge 1 commit into
pr31916from
pr31917
Open

http-client: add safe route-aware request pool#31917
bolinfest wants to merge 1 commit into
pr31916from
pr31917

Conversation

@bolinfest

@bolinfest bolinfest commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Why

PAC and OS proxy decisions are URL-specific. An API that resolves a route and then exposes a reusable transport client lets callers accidentally send a different URL through that client. The shared abstraction should instead couple request creation, route selection, and the URL that is ultimately sent.

What changed

  • Add RouteAwareClientPool, whose public API creates requests rather than exposing pooled clients.
  • Resolve the exact request URL at send time and reuse a bounded set of transports keyed by the concrete route.
  • Disable reqwest's automatic redirects so this layer performs one exact-URL request; http-client: add route-aware redirect handling #31918 adds route-aware redirect handling on top.
  • Provide named standard, ChatGPT-cookie, and no-request-diagnostics constructors.
  • Expose the pool's effective proxy policy so higher-level test seams can verify the client actually in use.
  • Export response/error aliases needed by migrating crates without giving them a direct reqwest dependency.

Review guide

  1. http-client/src/route_aware_client_pool.rs contains the request API, route-keyed cache, and one-shot send path.
  2. http-client/src/default_client.rs contains the internal execute path and response/error aliases.
  3. http-client: add route-aware redirect handling #31918 adds redirects and the end-to-end exact-route/privacy coverage separately.

Validation

  • Unit coverage for exact URL forwarding, route reuse, bounded eviction, and timeout classification.

Stack created with Sapling. Best reviewed with ReviewStack.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2fd8c58fab

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

let method = request.method().clone();
let headers = request.headers().clone();
let version = request.version();
let timeout = request.timeout().copied();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Preserve the caller's timeout across redirects

When a request with .timeout(...) follows redirects, copying the same timeout into every redirected Request gives each hop a fresh full budget; for example, a 5s timeout can run for roughly 55s over the allowed 10 redirects before failing. Since this pool replaces reqwest's built-in redirect handling, it should track a single deadline for the whole send() and pass only the remaining time (or stop redirecting once it expires).

Useful? React with 👍 / 👎.

Comment on lines +88 to +89
let cross_origin = previous.host_str() != next.host_str()
|| previous.port_or_known_default() != next.port_or_known_default();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Treat scheme changes as cross-origin redirects

For redirects that change only the scheme while keeping an explicit same port, such as https://host:443 to http://host:443, this check evaluates as same-origin and preserves Authorization/Cookie headers onto the redirected request. Origins include the scheme, so include previous.scheme() != next.scheme() in this decision before carrying sensitive headers forward.

Useful? React with 👍 / 👎.

Comment on lines +132 to +135
let request = url
.into_url()
.map(|url| reqwest::Request::new(method, url))
.map_err(RouteAwareRequestError::Request);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Preserve URL userinfo as Basic auth

When callers pass credentials in the request URL, e.g. https://user:pass@example.com, this builder creates a raw reqwest::Request and never performs reqwest's usual userinfo extraction, so the request is sent without the expected Authorization: Basic ... header and can fail authentication for endpoints that rely on that supported URL form. Strip the userinfo and populate Basic auth when constructing the request.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant