-
Notifications
You must be signed in to change notification settings - Fork 18k
net/http: Request body is not closed by Transport.RoundTrip on some net.Conn errors #49621
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
There are workaround: |
cc @neild |
Not really because adding correct |
@neild This is in the 1.18 milestone; time to move to 1.19? Thanks. |
Yes please, looks like this shall be moved to Go1.19 as we haven't had any movement for almost 3 months. I shall move it to the next milestone. Thank you everyone for chiming. |
CC @neild Rolling forward to 1.20. |
When there is still a request in writech after writeLoop exits, the request body will not be closed and will not be retried. The request is not sent to the server, so it can be safely retried without regard to idempotence. Fixes golang#49621
Change https://go.dev/cl/458437 mentions this issue: |
Change https://go.dev/cl/461675 mentions this issue: |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
net.Listener
with error injectionshttp.Server
using such listenerKind of a minimal example to run described steps: https://play.golang.com/p/lku8lEgiPu6
Yeah, I know that reproducer feels big, but the most of it is to create error injections actually, but
main part (see main fn) is straightforward and simple.
What did you expect to see?
I expect that
net/http
eventually closesRequest.Body
as it is told in documentation for RoundTripper: https://pkg.go.dev/net/http#RoundTripperWhat did you see instead?
Specified example program hangs indefinitely while waiting for
Request.Body
to be closed.Investigation
errServerClosedIdle
error insidenet/http
, because we have met described hangs only after receiving that error fromClient.Do
.Post
request may be important becausenet/http
does not retryPost
(non-idepotent) request on such error.In case next assumption is true:
Once request execution got to
func (pc *persistConn) roundTrip(req *transportRequest)
call,Request.Body
closure is expected to be done byfunc (pc *persistConn) writeLoop()
.Then it seems like there is a possibility of not closing body in the
writeLoop
in casepc
is closed concurrently.Imagine:
So request was sent successfully into
pc.writech
(channel has buffer of size 1), but won't be ever read from it becausewriteLoop
exited.Related places in the code:
go/src/net/http/transport.go
Line 2383 in f659183
go/src/net/http/transport.go
Line 2595 in f659183
The text was updated successfully, but these errors were encountered: