go: x/net/http2: Client POST request fails against golang http/2 server if client request.Body isn't completely consumed.
1. What version of Go are you using (go version)? go version go1.6 darwin/amd64
2. What operating system and processor architecture are you using (go env)? OS X El Capitan 10.11.1
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/nimi/go"
GORACE=""
GOROOT="/usr/local/Cellar/go/1.6/libexec"
GOTOOLDIR="/usr/local/Cellar/go/1.6/libexec/pkg/tool/darwin_amd64"
GO15VENDOREXPERIMENT="1"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fno-common"
CXX="clang++"
CGO_ENABLED="1"
3. What did you do?
Initiate a POST request with a large body. Ignore the request (and/or also Close the request body). The golang http/2 server will not send the response body back to the client. In cases where the request Body is closed, Chrome and other browsers get an error in the connection (net::ERR_SPDY_PROTOCOL_ERROR)
See https://gist.github.com/nemothekid/c20921999d1cce1b3c982d035d6b09b5
This program will server a javascript application that will try to issue a POST request with some data to the server. When run, the POST request will fail.
4. What did you expect to see?
POST request should succeed, the browser should be able to retrieve the server’s message body.
5. What did you see instead?
The POST request fails, and the body is never sent by the server. The works fine in HTTP/1.1 (Tested with GODEBUG=http2server=0). I discovered this issue while trying to debug mholt/caddy#782, where an upstream proxy server was rejecting the body. Also this issue would occur on servers that decide to refuse a payload above a specific size and need to respond with a sensible error message.
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 1
- Comments: 33 (9 by maintainers)
Commits related to this issue
- http2: let handlers close Request.Body without killing streams Also, fix a Transport goroutine leak if the transport is still trying to write its body after the stream has completed. Updates golang/... — committed to golang/net by bradfitz 8 years ago
- net/http: update bundled http2 Updates x/net/http2 to git rev 4d07e8a49 for CL 23287: http2: let handlers close Request.Body without killing streams https://golang.org/cl/23287 Fixes #15425 ... — committed to mk0x9/go by bradfitz 8 years ago
I was able to craft a script that mimics Chrome’s behavior - https://gist.github.com/nemothekid/753ca2db95faaa6fd0395fe857b36c21
EDIT: The script is racy 😕 sometimes it reliably fails, sometimes it succeeds 😕 (or it might just succeed the first time, and fail every other time).
Now its just fixing the http2 code in Go.
I’ve sent a fix for review: https://golang.org/cl/23287