aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2014-05-16 15:39:59 -0700
committerBrad Fitzpatrick <bradfitz@golang.org>2014-05-16 15:39:59 -0700
commit4c8de36e2bb01af620cc2b32d2dba806e9f07f9b (patch)
tree25cb753aa2bc85c93254d653d0bd41e38e7d70ea
parentb04146e492ff88793ef834b85aea75044111a222 (diff)
downloadgo-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.go15
-rw-r--r--src/pkg/net/http/server.go12
-rw-r--r--src/pkg/net/http/transfer.go16
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"}