Skip to content

Open a new connection for a redirect after sending Connection: close - #2645

Merged
yhirose merged 1 commit into
yhirose:masterfrom
wleeaf:redirect-new-connection-after-close
Oct 25, 2026
Merged

yhirose merged 1 commit into
yhirose:masterfrom
wleeaf:redirect-new-connection-after-close

Conversation

@wleeaf

@wleeaf wleeaf commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

With keep-alive off (the default), the client sends Connection: close. In handle_request, the connection is only closed before following a redirect (or retrying with auth) if the response itself says Connection: close, if socket_should_be_closed_when_request_is_done_ is set, or if the response is HTTP/1.0. The request's own close_connection isn't checked until send_ finishes, which is after the redirect has already been sent.

RFC 9112 section 9.6 says a server that receives close closes the connection after its response, and only SHOULD repeat the option in the response. A client that sent close MUST NOT send further requests on that connection. When a server doesn't repeat it, cpp-httplib writes the redirected request to the connection that is closing. Whether that works depends on timing, so following redirects from such servers fails intermittently with Failed to read connection. Against a server built on Python's http.server, 14 of 39 redirect cases failed in one run and 3 in the next.

close_connection is now part of that check, so the client disconnects before the redirect or auth retry and opens a new connection.

The new RedirectTest.NewConnectionAfterConnectionClose uses a raw socket server. It answers the first request with a 302 that doesn't repeat Connection: close, then reads again from the same connection. Without the change, the client sends the redirected request on that connection and the test fails on reused. With it, the client closes that connection and connects again. test (OpenSSL build, with g++) passes all offline tests (1046), and git clang-format reports nothing for the change.

Without keep-alive, the client sends "Connection: close", but before
following a redirect it disconnected only when the response repeated
the option. RFC 9112 (section 9.6) lets a server close the connection
without repeating it, and a client that sent "close" must not send
another request on that connection. The redirected request was written
to the closing connection and failed with "Failed to read connection"
whenever the server closed it first. The client now disconnects before
a redirect or an auth retry whenever the request asked for the close.
@yhirose
yhirose merged commit 5ceef83 into yhirose:master Oct 25, 2026
26 of 28 checks passed
@yhirose

yhirose commented Oct 25, 2026

Copy link
Copy Markdown
Owner

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