Skip to content

fix(http): keep connection alive for single 407 auth retry#4227

Open
tianhuyang wants to merge 4 commits into
SagerNet:testingfrom
tianhuyang:fix/http-proxy-auth-retry
Open

fix(http): keep connection alive for single 407 auth retry#4227
tianhuyang wants to merge 4 commits into
SagerNet:testingfrom
tianhuyang:fix/http-proxy-auth-retry

Conversation

@tianhuyang

@tianhuyang tianhuyang commented Jun 21, 2026

Copy link
Copy Markdown

Bugs Fixed

  1. HTTP 407 challenge flow closed connection too early
  • Impact: clients using challenge auth (no initial Proxy-Authorization) could receive 407 but then lose the same TCP connection before sending a second authenticated request.
  • Fixed in:
    • protocol/http/inbound.go
    • protocol/mixed/inbound.go
  • Behavior now:
    • Retry only when error is exactly http: authentication failed, no Proxy-Authorization header.
    • Retry only once.
    • Keep connection open for a bounded wait window, then timeout.
    • Clear read deadline after the one retry attempt.
  1. Tests could hide a failure path (silent early return)
  • Impact: in two auth-retry tests, a write failure could return early and skip assertions.
  • Fixed in:
    • test/http_test.go
  • Behavior now:
    • write errors are asserted with require.NoError, so failures are explicit.

How To Reproduce (Before Fix)

  1. Challenge auth via proxy (expected to fail pre-fix due to connection closure):
curl --proxy https://<host>:443 --proxy-anyauth --proxy-user '<user>:<pass>' https://www.google.com -v
  1. Preemptive auth (often succeeds even when challenge path is broken):
curl --proxy https://<host>:443 --proxy-user '<user>:<pass>' https://www.google.com -v

How To Verify Fixed

  1. Run focused HTTP auth regression tests from test module:
cd test
go test -v -tags "$(cat ../release/DEFAULT_BUILD_TAGS_OTHERS)" -run 'TestHTTPProxyAuthRetryAfter407|TestHTTPProxyAuthRetryOnlyOnce|TestHTTPProxyAuthRetryTimeout' .
  1. Expected:
  • TestHTTPProxyAuthRetryAfter407: first CONNECT gets 407, second CONNECT on same socket with valid auth gets 200.
  • TestHTTPProxyAuthRetryOnlyOnce: second unauthenticated retry still 407, third authenticated attempt after retry budget is exhausted does not proceed on same connection.
  • TestHTTPProxyAuthRetryTimeout: authenticated attempt after timeout window fails as expected.

Notes

  • Preemptive-only success is not sufficient proof; challenge flow behavior is the regression target.

@nekohasekai nekohasekai force-pushed the testing branch 2 times, most recently from f7ca395 to f27d0e3 Compare June 21, 2026 04:16
@tianhuyang tianhuyang closed this Jun 22, 2026
@tianhuyang tianhuyang deleted the fix/http-proxy-auth-retry branch June 22, 2026 12:36
@tianhuyang tianhuyang restored the fix/http-proxy-auth-retry branch June 22, 2026 12:36
@tianhuyang tianhuyang reopened this Jun 22, 2026
@tianhuyang

Copy link
Copy Markdown
Author

@nekohasekai could you please review this PR when you have time? Thanks!

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.

2 participants