diff options
author | Damien Neil <dneil@google.com> | 2021-10-27 14:03:24 -0700 |
---|---|---|
committer | Michael Knyszek <mknyszek@google.com> | 2021-12-01 22:10:53 +0000 |
commit | 266ee22f9c35774caa118225e52e97c4eb06f961 (patch) | |
tree | 3c122b08516be1119797e7773c73d5ebb39c01f5 | |
parent | 5a93142cec6c4da528e12939398a615869361d5a (diff) | |
download | go-266ee22f9c35774caa118225e52e97c4eb06f961.tar.gz go-266ee22f9c35774caa118225e52e97c4eb06f961.zip |
[release-branch.go1.16] net/http: do not send Transfer-Encoding: identity in responses
Server handlers may set a "Transfer-Encoding: identity" header on
responses to disable chunking, but this header should not be sent
on the wire.
For #49194.
Fixes #49567.
Change-Id: I46a9e3b8ff9d93edd7d1c34d264fc309fa322ad5
Reviewed-on: https://go-review.googlesource.com/c/go/+/359176
Trust: Damien Neil <dneil@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
(cherry picked from commit b69b2f63d65609b400b4a40ae01e4a48638f050f)
Reviewed-on: https://go-review.googlesource.com/c/go/+/368086
Reviewed-by: Michael Knyszek <mknyszek@google.com>
-rw-r--r-- | src/net/http/clientserver_test.go | 34 | ||||
-rw-r--r-- | src/net/http/server.go | 7 |
2 files changed, 38 insertions, 3 deletions
diff --git a/src/net/http/clientserver_test.go b/src/net/http/clientserver_test.go index 5e227181ac..125d63566b 100644 --- a/src/net/http/clientserver_test.go +++ b/src/net/http/clientserver_test.go @@ -1582,3 +1582,37 @@ func TestH12_WebSocketUpgrade(t *testing.T) { }, }.run(t) } + +func TestIdentityTransferEncoding_h1(t *testing.T) { testIdentityTransferEncoding(t, h1Mode) } +func TestIdentityTransferEncoding_h2(t *testing.T) { testIdentityTransferEncoding(t, h2Mode) } + +func testIdentityTransferEncoding(t *testing.T, h2 bool) { + setParallel(t) + defer afterTest(t) + + const body = "body" + cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) { + gotBody, _ := io.ReadAll(r.Body) + if got, want := string(gotBody), body; got != want { + t.Errorf("got request body = %q; want %q", got, want) + } + w.Header().Set("Transfer-Encoding", "identity") + w.WriteHeader(StatusOK) + w.(Flusher).Flush() + io.WriteString(w, body) + })) + defer cst.close() + req, _ := NewRequest("GET", cst.ts.URL, strings.NewReader(body)) + res, err := cst.c.Do(req) + if err != nil { + t.Fatal(err) + } + defer res.Body.Close() + gotBody, err := io.ReadAll(res.Body) + if err != nil { + t.Fatal(err) + } + if got, want := string(gotBody), body; got != want { + t.Errorf("got response body = %q; want %q", got, want) + } +} diff --git a/src/net/http/server.go b/src/net/http/server.go index 198102ffd2..f9e518416d 100644 --- a/src/net/http/server.go +++ b/src/net/http/server.go @@ -1407,11 +1407,11 @@ func (cw *chunkWriter) writeHeader(p []byte) { hasCL = false } - if w.req.Method == "HEAD" || !bodyAllowedForStatus(code) { - // do nothing - } else if code == StatusNoContent { + if w.req.Method == "HEAD" || !bodyAllowedForStatus(code) || code == StatusNoContent { + // Response has no body. delHeader("Transfer-Encoding") } else if hasCL { + // Content-Length has been provided, so no chunking is to be done. delHeader("Transfer-Encoding") } else if w.req.ProtoAtLeast(1, 1) { // HTTP/1.1 or greater: Transfer-Encoding has been set to identity, and no @@ -1422,6 +1422,7 @@ func (cw *chunkWriter) writeHeader(p []byte) { if hasTE && te == "identity" { cw.chunking = false w.closeAfterReply = true + delHeader("Transfer-Encoding") } else { // HTTP/1.1 or greater: use chunked transfer encoding // to avoid closing the connection at EOF. |