Skip to content
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

net/http: client fails when server closes connection before reading request body #51109

Open
djmitche opened this issue Feb 9, 2022 · 1 comment
Labels
NeedsInvestigation
Milestone

Comments

@djmitche
Copy link

@djmitche djmitche commented Feb 9, 2022

What version of Go are you using (go version)?

$ go version
go version go1.17.6 linux/amd64

Does this issue reproduce with the latest release?

Yes (go1.18beta2)

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/dustin/.cache/go-build"
GOENV="/home/dustin/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/dustin/.gvm/pkgsets/go1.15.14/global/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/dustin/.gvm/pkgsets/go1.15.14/global"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/dustin/.gvm/gos/go1.15.14"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/dustin/.gvm/gos/go1.15.14/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/dustin/tmp/server/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build635155538=/tmp/go-build -gno-record-gcc-switches"

What did you do?

https://go.dev/play/p/QW2sddZp7XY

tl;dr: when a server sends a response and closes the connection before reading the request body, net/http fails with an error. We've observed this behavior with haproxy, and it appears to be allowed by RFC 7230:

A server MUST read
the entire request message body or close the connection after sending
its response, since otherwise the remaining data on a persistent
connection would be misinterpreted as the next request. Likewise, a
client MUST read the entire response message body if it intends to
reuse the same connection for a subsequent request.

and

A client sending a message body SHOULD monitor the network connection
for an error response while it is transmitting the request. If the
client sees a response that indicates the server does not wish to
receive the message body and is closing the connection, the client
SHOULD immediately cease transmitting the body and close its side of
the connection.

What did you expect to see?

Successful HTTP response (307 Redirect)

The client should, on noting that it cannot write to the connection, check whether the data received on the connection constitutes a valid response, and if so return that response instead of an error.

What did you see instead?

2009/11/10 23:00:00 Post "http://127.0.0.1:8080": write tcp 127.0.0.1:22845->127.0.0.1:8080: write: connection reset by peer

Looking at a packet dump of this behavior, it appears that when the server closes the socket, the client continues sending data, which generates RST frames from the server, which translate into the given error. In fact, this all occurs before the server sends a FIN frame.

@cherrymui cherrymui added the NeedsInvestigation label Feb 11, 2022
@cherrymui cherrymui added this to the Backlog milestone Feb 11, 2022
@cherrymui
Copy link
Member

@cherrymui cherrymui commented Feb 11, 2022

cc @neild

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation
Projects
None yet
Development

No branches or pull requests

2 participants