http2: fix two cases of Server behavior not matching HTTP/1
* don't send automatic Content-Length from Server on HEAD requests if
response size is 0 (it's possible the handler didn't write because
they looked at the method)
* don't send Content-Type if handler explicitly set it to nothing.
Matches the behavior of HTTP/1.
Updates golang/go#13532
Updates golang/go#13495
Change-Id: If6e0898095cf88cb14efb6bbe82c88dbc2077e6b
Reviewed-on: https://go-review.googlesource.com/17590
Reviewed-by: Blake Mizerany <blake.mizerany@gmail.com>
diff --git a/http2/server.go b/http2/server.go
index 8ef9e24..992e546 100644
--- a/http2/server.go
+++ b/http2/server.go
@@ -1758,10 +1758,11 @@
clen = ""
}
}
- if clen == "" && rws.handlerDone && bodyAllowedForStatus(rws.status) {
+ if clen == "" && rws.handlerDone && bodyAllowedForStatus(rws.status) && (len(p) > 0 || !isHeadResp) {
clen = strconv.Itoa(len(p))
}
- if rws.snapHeader.Get("Content-Type") == "" && bodyAllowedForStatus(rws.status) {
+ _, hasContentType := rws.snapHeader["Content-Type"]
+ if !hasContentType && bodyAllowedForStatus(rws.status) {
ctype = http.DetectContentType(p)
}
var date string
diff --git a/http2/server_test.go b/http2/server_test.go
index 7e8eb7e..2c97faa 100644
--- a/http2/server_test.go
+++ b/http2/server_test.go
@@ -2637,3 +2637,52 @@
})
st.wantRSTStream(1, ErrCodeProtocol)
}
+
+func TestServerNoAutoContentLengthOnHead(t *testing.T) {
+ st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
+ // No response body. (or smaller than one frame)
+ })
+ defer st.Close()
+ st.greet()
+ st.writeHeaders(HeadersFrameParam{
+ StreamID: 1, // clients send odd numbers
+ BlockFragment: st.encodeHeader(":method", "HEAD"),
+ EndStream: true,
+ EndHeaders: true,
+ })
+ h := st.wantHeaders()
+ headers := decodeHeader(t, h.HeaderBlockFragment())
+ want := [][2]string{
+ {":status", "200"},
+ {"content-type", "text/plain; charset=utf-8"},
+ }
+ if !reflect.DeepEqual(headers, want) {
+ t.Errorf("Headers mismatch.\n got: %q\nwant: %q\n", headers, want)
+ }
+}
+
+// golang.org/issue/13495
+func TestServerNoDuplicateContentType(t *testing.T) {
+ st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
+ w.Header()["Content-Type"] = []string{""}
+ fmt.Fprintf(w, "<html><head></head><body>hi</body></html>")
+ })
+ defer st.Close()
+ st.greet()
+ st.writeHeaders(HeadersFrameParam{
+ StreamID: 1,
+ BlockFragment: st.encodeHeader(),
+ EndStream: true,
+ EndHeaders: true,
+ })
+ h := st.wantHeaders()
+ headers := decodeHeader(t, h.HeaderBlockFragment())
+ want := [][2]string{
+ {":status", "200"},
+ {"content-type", ""},
+ {"content-length", "41"},
+ }
+ if !reflect.DeepEqual(headers, want) {
+ t.Errorf("Headers mismatch.\n got: %q\nwant: %q\n", headers, want)
+ }
+}