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)
+	}
+}