net/http: dial should not be canceled if an idle connection is reused #66442
Labels
NeedsInvestigation
Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Go version
go1.22.1 linux/amd64
Output of
go env
in your module/workspace:What did you do?
When the HTTP transport processes a new request it first tries to get an idle connection (if keep alive is not disabled). If there are no idle connection it will dial a new connection. If an idle connection becomes ready while dialing the new connection, the idle connection will be reused and the new connection will be put to idle queue (if there is space). If the request's context is canceled, both the request's and the new connection's context will be canceled.
This causes problems when canceling a context after the response has already been read and closed but the new connection dial has not yet completed (e.g. TLS handshake not yet done). In this case the new connection will be closed. This may cause a lot of new connections to be created and closed (
MaxConnsPerHost
is ignored). If this repeats a lot, too many TCP connections are stuck inCLOSE_WAIT
state and new connections cannot be created.This only affects HTTP/1 (HTTP and HTTPS).
Example:
Example code:
What did you see happen?
With higher concurrency even setting
transport.MaxConnsPerHost
does not help. The setting fixes request errors but still creates too many TCP connections.What did you expect to see?
$ go run .
The text was updated successfully, but these errors were encountered: