]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: make Transport respect non lower case Content-Encoding
authorJan Berktold <jan@berktold.co>
Thu, 23 Feb 2017 14:53:27 +0000 (15:53 +0100)
committerBrad Fitzpatrick <bradfitz@golang.org>
Wed, 24 May 2017 01:20:11 +0000 (01:20 +0000)
The existing Transport implementation does not detect gzip encoding
when the Content-Encoding header is not lower-case. This is not
compliant with RFC2616 section 3.5 "All content-coding values are
case-insensitive." and caused issues in the wild.

Fixes #19248

Change-Id: I1b49992832dc3c8ef700058596a27dd9909640a3
Reviewed-on: https://go-review.googlesource.com/37431
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/net/http/transport.go
src/net/http/transport_test.go

index 425db360182280f7c8c81fbf25f127f89f7b9086..abb22d4f8dbace02889f3a34a0157521f4a04afb 100644 (file)
@@ -1626,7 +1626,7 @@ func (pc *persistConn) readLoop() {
                }
 
                resp.Body = body
-               if rc.addedGzip && resp.Header.Get("Content-Encoding") == "gzip" {
+               if rc.addedGzip && strings.EqualFold(resp.Header.Get("Content-Encoding"), "gzip") {
                        resp.Body = &gzipReader{body: body}
                        resp.Header.Del("Content-Encoding")
                        resp.Header.Del("Content-Length")
index 8e211aad27d3c2599162ede5692d545a16620c49..a5ed5c4693da7a183f121e6a663a3da0ac2fdd72 100644 (file)
@@ -2900,6 +2900,40 @@ func TestTransportResponseCancelRace(t *testing.T) {
        res.Body.Close()
 }
 
+// Test for issue 19248: Content-Encoding's value is case insensitive.
+func TestTransportContentEncodingCaseInsensitive(t *testing.T) {
+       setParallel(t)
+       defer afterTest(t)
+       for _, ce := range []string{"gzip", "GZIP"} {
+               ce := ce
+               t.Run(ce, func(t *testing.T) {
+                       const encodedString = "aaaa"
+                       ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+                               conn, _, _ := w.(Hijacker).Hijack()
+                               fmt.Fprintf(conn, "HTTP/1.1 200 OK\r\nContent-Encoding: %s\r\nContent-Length: 28\r\n\r\n", ce)
+                               conn.Write([]byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x4a\x4c\x4c\x4c\x04\x04\x00\x00\xff\xff\x45\xe5\x98\xad\x04\x00\x00\x00"))
+                               conn.Close()
+                       }))
+                       defer ts.Close()
+
+                       res, err := ts.Client().Get(ts.URL)
+                       if err != nil {
+                               t.Fatal(err)
+                       }
+
+                       body, err := ioutil.ReadAll(res.Body)
+                       res.Body.Close()
+                       if err != nil {
+                               t.Fatal(err)
+                       }
+
+                       if string(body) != encodedString {
+                               t.Fatalf("Expected body %q, got: %q\n", encodedString, string(body))
+                       }
+               })
+       }
+}
+
 func TestTransportDialCancelRace(t *testing.T) {
        defer afterTest(t)