Skip to content

net/http: discrepancy between HeadContentLength of "" in http2 vs http1 #13532

Closed
@odeke-em

Description

@odeke-em

HeadContentLength of "" in http1 returns a length of -1 but in http2 it returns 0.
The test that found this issue is through CL https://go-review.googlesource.com/17526

diff --git a/src/net/http/client_test.go b/src/net/http/client_test.go
index e59ab2c..6e20877 100644
--- a/src/net/http/client_test.go
+++ b/src/net/http/client_test.go
@@ -765,14 +765,22 @@ func TestHTTPSClientDetectsHTTPServer(t *testing.T) {
 }

 // Verify Response.ContentLength is populated. https://golang.org/issue/4126
-func TestClientHeadContentLength(t *testing.T) {
+func TestClientHeadContentLength_h1(t *testing.T) {
+   testClientHeadContentLength(t, false)
+}
+
+func TestClientHeadContentLength_h2(t *testing.T) {
+   testClientHeadContentLength(t, true)
+}
+
+func testClientHeadContentLength(t *testing.T, h2 bool) {
    defer afterTest(t)
-   ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+   cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
        if v := r.FormValue("cl"); v != "" {
            w.Header().Set("Content-Length", v)
        }
    }))
-   defer ts.Close()
+   defer cst.close()
    tests := []struct {
        suffix string
        want   int64
@@ -782,8 +790,8 @@ func TestClientHeadContentLength(t *testing.T) {
        {"", -1},
    }
    for _, tt := range tests {
-       req, _ := NewRequest("HEAD", ts.URL+tt.suffix, nil)
-       res, err := DefaultClient.Do(req)
+       req, _ := NewRequest("HEAD", cst.ts.URL+tt.suffix, nil)
+       res, err := cst.c.Do(req)
        if err != nil {
            t.Fatal(err)
        }

where the test cases

        tests := []struct {
                suffix string
                want   int64
        }{
                {"/?cl=1234", 1234},
                {"/?cl=0", 0},
                {"", -1},
        }
        for _, tt := range tests {
                req, _ := NewRequest("HEAD", cst.ts.URL+tt.suffix, nil)
                res, err := cst.c.Do(req)
                if err != nil {
                        t.Fatal(err)
                }
                if res.ContentLength != tt.want {
                        t.Errorf("Content-Length = %d; want %d", res.ContentLength, tt.want)
                }
                bs, err := ioutil.ReadAll(res.Body)
                if err != nil {
                        t.Fatal(err)
                }
                if len(bs) != 0 {
                        t.Errorf("Unexpected content: %q", bs)
                }
        }

Gives result

$ go test -cover
--- FAIL: TestClientHeadContentLength_h2 (0.01s)
    client_test.go:799: Content-Length = 0; want -1

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions