Skip to content

Add H1 same-connection redirect follow-up#867

Closed
kursadaltan wants to merge 3 commits intocloudflare:mainfrom
kursadaltan:fix/h1-same-connection-redirect
Closed

Add H1 same-connection redirect follow-up#867
kursadaltan wants to merge 3 commits intocloudflare:mainfrom
kursadaltan:fix/h1-same-connection-redirect

Conversation

@kursadaltan
Copy link
Copy Markdown

Summary

Adds Session::h1_set_same_connection_followup so user code can follow an HTTP/1.1 upstream redirect (e.g. 3xx) on the same pooled upstream connection: the intermediate response body is consumed without writing it to the client, then a follow-up request is issued on that connection via an internal loop in proxy_to_h1_upstream. This avoids the pattern of returning Err from response_filter and relying on the outer process_request retry loop, which drops upstream keep-alive (client_reuse == false and no release_http_session on that path).

Related issue: #866

Motivation

Following redirects by erroring out of response_filter causes proxy_1to1 to fail try_join! and return client_reuse = false, so each retry opens a new upstream connection. At scale this hurts latency and connection reuse. RFC-aligned behavior for H/1 is to drain the redirect response on the same TCP connection when the next hop is the same origin, then send the next request on that connection.

What changed

Session: optional follow-up RequestHeader, flag to skip writing the current upstream response downstream, and h1_set_same_connection_followup (disables cache for the skipped hop when caching is enabled).
proxy_to_h1_upstream: loops while a follow-up is scheduled after a successful proxy_1to1 leg.
process_upstream_tasks: when skipping downstream for the current response, does not forward response tasks to the client while the upstream side still drains the body through the filter chain.
Docs: ProxyHttp::response_filter points to the new API.
CHANGELOG: Unreleased entry.
Unit test for the follow-up / skip behavior.
Usage (conceptual)

From response_filter, on an intermediate response you choose to follow on the same connection, build the next RequestHeader and call session.h1_set_same_connection_followup(request) and return Ok(()). Do not use this for untrusted cross-origin redirects without validating Location in application code.

Testing

cargo test -p pingora-proxy --lib

@johnhurt johnhurt added enhancement New feature or request bug Something isn't working labels Apr 24, 2026
@kursadaltan kursadaltan force-pushed the fix/h1-same-connection-redirect branch from dd72ae4 to 0d80c66 Compare April 24, 2026 19:58
Avoid noisy warnings when a synthetic 3xx is used for the redirect follow-up
hop (context prefix redirect_follow_hop:).

Made-with: Cursor
@kursadaltan kursadaltan force-pushed the fix/h1-same-connection-redirect branch from 0d80c66 to 7b06bda Compare April 24, 2026 20:01
Updated the reuse_hash method in BasicPeer to incorporate the SNI when TLS is used, ensuring distinct connection reuse for different hostnames on the same IP:port. This change maintains historical behavior when SNI is empty (non-TLS).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants