]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.17] net/http: do not send Transfer-Encoding: identity in responses
authorDamien Neil <dneil@google.com>
Wed, 27 Oct 2021 21:03:24 +0000 (14:03 -0700)
committerMichael Knyszek <mknyszek@google.com>
Wed, 1 Dec 2021 22:10:49 +0000 (22:10 +0000)
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 #49568.

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/+/368087
Reviewed-by: Michael Knyszek <mknyszek@google.com>
src/net/http/clientserver_test.go
src/net/http/server.go

index 5e227181acb05cf9e5034682c8dc0375e619f49f..125d63566bc789b696e07b36e66d3a1c8b9df4b6 100644 (file)
@@ -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)
+       }
+}
index 5b113cff970dc19148c5ba4fe96020b54bfd0d5a..4fc8fedfcdad2e4bc4c6504ab02a4932926a91fb 100644 (file)
@@ -1404,11 +1404,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
@@ -1419,6 +1419,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.