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

Most upvoted comments

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