aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/http
diff options
context:
space:
mode:
authorDave Grijalva <dgrijalva@ngmoco.com>2011-08-10 14:16:13 -0700
committerBrad Fitzpatrick <bradfitz@golang.org>2011-08-10 14:16:13 -0700
commit8f3c7497acd69d980d40f55ebf97ae2f9a7fd034 (patch)
treeaf6e82bcfe61cad5051b762df33d9100d9f78b89 /src/pkg/http
parentebb2f4af3506f788213cb7c741340226f601b4c5 (diff)
downloadgo-8f3c7497acd69d980d40f55ebf97ae2f9a7fd034.tar.xz
http: corrects undocumented side effects in http.DefaultTransport's RoundTrip method
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
Diffstat (limited to 'src/pkg/http')
-rw-r--r--src/pkg/http/transport.go3
-rw-r--r--src/pkg/http/transport_test.go62
2 files changed, 65 insertions, 0 deletions
diff --git a/src/pkg/http/transport.go b/src/pkg/http/transport.go
index 3c16c880d5..d03aadfd34 100644
--- a/src/pkg/http/transport.go
+++ b/src/pkg/http/transport.go
@@ -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")
diff --git a/src/pkg/http/transport_test.go b/src/pkg/http/transport_test.go
index 76e97640e3..20895da869 100644
--- a/src/pkg/http/transport_test.go
+++ b/src/pkg/http/transport_test.go
@@ -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