]> Cypherpunks repositories - gostls13.git/commitdiff
http: corrects undocumented side effects in http.DefaultTransport's RoundTrip method
authorDave Grijalva <dgrijalva@ngmoco.com>
Wed, 10 Aug 2011 21:16:13 +0000 (14:16 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Wed, 10 Aug 2011 21:16:13 +0000 (14:16 -0700)
Fixes #2140.

The http.DefaultTransport's RoundTrip method leaves the http.Request object
in an altered state after performing the round trip.  This patch removes
the header from the Request before returning to the client.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/4857041

src/pkg/http/transport.go
src/pkg/http/transport_test.go

index 3c16c880d5a1e1a1452c5ad3ce76f9441d5971b6..d03aadfd34462c26a64f17bd6203d3ede18f42e1 100644 (file)
@@ -511,6 +511,9 @@ func (pc *persistConn) readLoop() {
                        if err != nil || resp.ContentLength == 0 {
                                return resp, err
                        }
+                       if rc.addedGzip {
+                               forReq.Header.Del("Accept-Encoding")
+                       }
                        if rc.addedGzip && resp.Header.Get("Content-Encoding") == "gzip" {
                                resp.Header.Del("Content-Encoding")
                                resp.Header.Del("Content-Length")
index 76e97640e357881f180e88834438951555196877..20895da8695e667a4253ba956d1b57a1f5ad768a 100644 (file)
@@ -387,6 +387,68 @@ func TestTransportNilURL(t *testing.T) {
        }
 }
 
+var roundTripTests = []struct {
+       accept       string
+       expectAccept string
+       compressed   bool
+}{
+       // Requests with no accept-encoding header use transparent compression
+       {"", "gzip", false},
+       // Requests with other accept-encoding should pass through unmodified
+       {"foo", "foo", false},
+       // Requests with accept-encoding == gzip should be passed through
+       {"gzip", "gzip", true}}
+
+// Test that the modification made to the Request by the RoundTripper is cleaned up
+func TestRoundTripGzip(t *testing.T) {
+       const responseBody = "test response body"
+       ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
+               accept := req.Header.Get("Accept-Encoding")
+               if expect := req.FormValue("expect_accept"); accept != expect {
+                       t.Errorf("Accept-Encoding = %q, want %q", accept, expect)
+               }
+               if accept == "gzip" {
+                       rw.Header().Set("Content-Encoding", "gzip")
+                       gz, _ := gzip.NewWriter(rw)
+                       gz.Write([]byte(responseBody))
+                       gz.Close()
+               } else {
+                       rw.Header().Set("Content-Encoding", accept)
+                       rw.Write([]byte(responseBody))
+               }
+       }))
+       defer ts.Close()
+
+       for i, test := range roundTripTests {
+               // Test basic request (no accept-encoding)
+               req, _ := NewRequest("GET", ts.URL+"?expect_accept="+test.expectAccept, nil)
+               req.Header.Set("Accept-Encoding", test.accept)
+               res, err := DefaultTransport.RoundTrip(req)
+               var body []byte
+               if test.compressed {
+                       gzip, _ := gzip.NewReader(res.Body)
+                       body, err = ioutil.ReadAll(gzip)
+                       res.Body.Close()
+               } else {
+                       body, err = ioutil.ReadAll(res.Body)
+               }
+               if err != nil {
+                       t.Errorf("%d. Error: %q", i, err)
+               } else {
+                       if g, e := string(body), responseBody; g != e {
+                               t.Errorf("%d. body = %q; want %q", i, g, e)
+                       }
+                       if g, e := req.Header.Get("Accept-Encoding"), test.accept; g != e {
+                               t.Errorf("%d. Accept-Encoding = %q; want %q", i, g, e)
+                       }
+                       if g, e := res.Header.Get("Content-Encoding"), test.accept; g != e {
+                               t.Errorf("%d. Content-Encoding = %q; want %q", i, g, e)
+                       }
+               }
+       }
+
+}
+
 func TestTransportGzip(t *testing.T) {
        const testString = "The test string aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
        const nRandBytes = 1024 * 1024