diff --git a/src/net/http/clientserver_test.go b/src/net/http/clientserver_test.go index a7e0bac282..29afe48833 100644 --- a/src/net/http/clientserver_test.go +++ b/src/net/http/clientserver_test.go @@ -121,15 +121,17 @@ func testChunkedResponseHeaders(t *testing.T, h2 bool) { } } +type reqFunc func(c *Client, url string) (*Response, error) + // h12Compare is a test that compares HTTP/1 and HTTP/2 behavior // against each other. type h12Compare struct { - Handler func(ResponseWriter, *Request) // required - ReqFunc func(c *Client, url string) (*Response, error) // optional - CheckResponse func(proto string, res *Response) // optional + Handler func(ResponseWriter, *Request) // required + ReqFunc reqFunc // optional + CheckResponse func(proto string, res *Response) // optional } -func (tt h12Compare) reqFunc() func(c *Client, url string) (*Response, error) { +func (tt h12Compare) reqFunc() reqFunc { if tt.ReqFunc == nil { return (*Client).Get } @@ -213,6 +215,36 @@ func (tt h12Compare) normalizeRes(t *testing.T, res *Response, wantProto string) } } +// Issue 13532 +func TestH12_HeadContentLengthNoBody(t *testing.T) { + h12Compare{ + ReqFunc: (*Client).Head, + Handler: func(w ResponseWriter, r *Request) { + }, + }.run(t) +} + +func TestH12_HeadContentLengthSmallBody(t *testing.T) { + h12Compare{ + ReqFunc: (*Client).Head, + Handler: func(w ResponseWriter, r *Request) { + io.WriteString(w, "small") + }, + }.run(t) +} + +func TestH12_HeadContentLengthLargeBody(t *testing.T) { + h12Compare{ + ReqFunc: (*Client).Head, + Handler: func(w ResponseWriter, r *Request) { + chunk := strings.Repeat("x", 512<<10) + for i := 0; i < 10; i++ { + io.WriteString(w, chunk) + } + }, + }.run(t) +} + func TestH12_200NoBody(t *testing.T) { h12Compare{Handler: func(w ResponseWriter, r *Request) {}}.run(t) } @@ -371,3 +403,12 @@ func test304Responses(t *testing.T, h2 bool) { t.Errorf("got unexpected body %q", string(body)) } } + +func TestH12_ServerEmptyContentLength(t *testing.T) { + h12Compare{ + Handler: func(w ResponseWriter, r *Request) { + w.Header()["Content-Type"] = []string{""} + io.WriteString(w, "hi") + }, + }.run(t) +} diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go index 52cde23910..81eae3ccbf 100644 --- a/src/net/http/h2_bundle.go +++ b/src/net/http/h2_bundle.go @@ -3562,10 +3562,11 @@ func (rws *http2responseWriterState) writeChunk(p []byte) (n int, err error) { clen = "" } } - if clen == "" && rws.handlerDone && http2bodyAllowedForStatus(rws.status) { + if clen == "" && rws.handlerDone && http2bodyAllowedForStatus(rws.status) && (len(p) > 0 || !isHeadResp) { clen = strconv.Itoa(len(p)) } - if rws.snapHeader.Get("Content-Type") == "" && http2bodyAllowedForStatus(rws.status) { + _, hasContentType := rws.snapHeader["Content-Type"] + if !hasContentType && http2bodyAllowedForStatus(rws.status) { ctype = DetectContentType(p) } var date string