diff options
author | Brad Fitzpatrick <bradfitz@golang.org> | 2014-05-16 15:39:59 -0700 |
---|---|---|
committer | Brad Fitzpatrick <bradfitz@golang.org> | 2014-05-16 15:39:59 -0700 |
commit | 4c8de36e2bb01af620cc2b32d2dba806e9f07f9b (patch) | |
tree | 25cb753aa2bc85c93254d653d0bd41e38e7d70ea | |
parent | b04146e492ff88793ef834b85aea75044111a222 (diff) | |
download | go-4c8de36e2bb01af620cc2b32d2dba806e9f07f9b.tar.gz go-4c8de36e2bb01af620cc2b32d2dba806e9f07f9b.zip |
net/http: allow Content-Type on 204 responses
Accidental change from fixing Content-Length on 204s
in http://golang.org/issue/6685 earlier.
LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/92400047
-rw-r--r-- | src/pkg/net/http/serve_test.go | 15 | ||||
-rw-r--r-- | src/pkg/net/http/server.go | 12 | ||||
-rw-r--r-- | src/pkg/net/http/transfer.go | 16 |
3 files changed, 36 insertions, 7 deletions
diff --git a/src/pkg/net/http/serve_test.go b/src/pkg/net/http/serve_test.go index b3850a590d..9e4d226bfe 100644 --- a/src/pkg/net/http/serve_test.go +++ b/src/pkg/net/http/serve_test.go @@ -2154,6 +2154,21 @@ func TestCodesPreventingContentTypeAndBody(t *testing.T) { } } +func TestContentTypeOkayOn204(t *testing.T) { + ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) { + w.Header().Set("Content-Length", "123") // suppressed + w.Header().Set("Content-Type", "foo/bar") + w.WriteHeader(204) + })) + got := ht.rawResponse("GET / HTTP/1.1") + if !strings.Contains(got, "Content-Type: foo/bar") { + t.Errorf("Response = %q; want Content-Type: foo/bar", got) + } + if strings.Contains(got, "Content-Length: 123") { + t.Errorf("Response = %q; don't want a Content-Length", got) + } +} + // Issue 6995 // A server Handler can receive a Request, and then turn around and // give a copy of that Request.Body out to the Transport (e.g. any diff --git a/src/pkg/net/http/server.go b/src/pkg/net/http/server.go index 9c5f3ffaba..eae097eb8e 100644 --- a/src/pkg/net/http/server.go +++ b/src/pkg/net/http/server.go @@ -799,18 +799,16 @@ func (cw *chunkWriter) writeHeader(p []byte) { } code := w.status - if !bodyAllowedForStatus(code) { - // Must not have body. - // RFC 2616 section 10.3.5: "the response MUST NOT include other entity-headers" - for _, k := range []string{"Content-Type", "Content-Length", "Transfer-Encoding"} { - delHeader(k) - } - } else { + if bodyAllowedForStatus(code) { // If no content type, apply sniffing algorithm to body. _, haveType := header["Content-Type"] if !haveType { setHeader.contentType = DetectContentType(p) } + } else { + for _, k := range suppressedHeaders(code) { + delHeader(k) + } } if _, ok := header["Date"]; !ok { diff --git a/src/pkg/net/http/transfer.go b/src/pkg/net/http/transfer.go index 4c3050fed6..0f2b7854f5 100644 --- a/src/pkg/net/http/transfer.go +++ b/src/pkg/net/http/transfer.go @@ -268,6 +268,22 @@ func bodyAllowedForStatus(status int) bool { return true } +var ( + suppressedHeaders304 = []string{"Content-Type", "Content-Length", "Transfer-Encoding"} + suppressedHeadersNoBody = []string{"Content-Length", "Transfer-Encoding"} +) + +func suppressedHeaders(status int) []string { + switch { + case status == 304: + // RFC 2616 section 10.3.5: "the response MUST NOT include other entity-headers" + return suppressedHeaders304 + case !bodyAllowedForStatus(status): + return suppressedHeadersNoBody + } + return nil +} + // msg is *Request or *Response. func readTransfer(msg interface{}, r *bufio.Reader) (err error) { t := &transferReader{RequestMethod: "GET"} |