]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: allow Content-Type on 204 responses
authorBrad Fitzpatrick <bradfitz@golang.org>
Fri, 16 May 2014 22:39:59 +0000 (15:39 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Fri, 16 May 2014 22:39:59 +0000 (15:39 -0700)
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

src/pkg/net/http/serve_test.go
src/pkg/net/http/server.go
src/pkg/net/http/transfer.go

index b3850a590dcab79a2d219dc1f45bf606786b9a3e..9e4d226bfe0f7c89ec5779e4f000c2f46c22dc4b 100644 (file)
@@ -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
index 9c5f3ffaba7505d3ae50586a64158bf8e58ce7b7..eae097eb8e91c1e6046dc8ddac0ab35941795296 100644 (file)
@@ -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 {
index 4c3050fed6c814bf9157c3965154be01228fb5b4..0f2b7854f5511cc4e9c7d419b261e798be8e5b62 100644 (file)
@@ -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"}