Revert "net/http: apply header timeout to server's unencrypted HTTP/2 check" This reverts commit 1952e618b834bda60fb9efff0fc0af46b38e110d. Reason for revert: The release is too close for the minors, to make rc2 consistent with minors we revert it until rc3. Change-Id: Id463ab4f078e75e4fac46d5651f3c9aa0ac774bc Reviewed-on: https://go-review.googlesource.com/c/go/+/795909 Reviewed-by: Neal Patel <nealpatel@google.com> Auto-Submit: Junyang Shao <shaojunyang@google.com> Reviewed-by: Damien Neil <dneil@google.com> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go index d8c78a3..08fbf35 100644 --- a/src/net/http/serve_test.go +++ b/src/net/http/serve_test.go
@@ -821,63 +821,6 @@ return nil } -func TestServerUnencryptedHTTP2HeaderTimeout(t *testing.T) { - for _, test := range []struct { - name string - f func(*fakeNetConn) - }{{ - name: "client sends nothing", - f: func(conn *fakeNetConn) { - }, - }, { - name: "client sends slowly", - f: func(conn *fakeNetConn) { - // Trickling out writes should not extend the deadline. - conn.Write([]byte("PRI")) - time.Sleep(100 * time.Millisecond) - conn.Write([]byte(" * ")) - time.Sleep(100 * time.Millisecond) - conn.Write([]byte("HTT")) - time.Sleep(100 * time.Millisecond) - }, - }, { - name: "header read expires", - f: func(conn *fakeNetConn) { - // Time spent waiting for the HTTP/2 preface should count against - // time spent waiting for HTTP/1 headers. - time.Sleep(100 * time.Millisecond) - conn.Write([]byte("GET / HTTP/1.1\r\nHost: example.tld\r\n")) - }, - }} { - t.Run(test.name, func(t *testing.T) { - synctest.Test(t, func(t *testing.T) { - listener := fakeNetListen() - defer listener.Close() - - srv := &Server{ - Protocols: new(Protocols), - ReadHeaderTimeout: 1 * time.Second, - } - srv.Protocols.SetHTTP1(true) - srv.Protocols.SetUnencryptedHTTP2(true) - go srv.Serve(listener) - - conn := listener.connect() - go test.f(conn) - - start := time.Now() - _, err := io.ReadAll(conn) - if err != nil { - t.Errorf("ReadAll from server: %v, want EOF", err) - } - if got, want := time.Since(start), srv.ReadHeaderTimeout; got != want { - t.Errorf("connection closed after %v, want %v", got, want) - } - }) - }) - } -} - func TestServerReadTimeout(t *testing.T) { run(t, testServerReadTimeout, http3SkippedMode) } func testServerReadTimeout(t *testing.T, mode testMode) { respBody := "response body"
diff --git a/src/net/http/server.go b/src/net/http/server.go index ae21427..d193dcd 100644 --- a/src/net/http/server.go +++ b/src/net/http/server.go
@@ -1039,11 +1039,18 @@ return nil, ErrHijacked } + var ( + wholeReqDeadline time.Time // or zero if none + hdrDeadline time.Time // or zero if none + ) t0 := time.Now() - var wholeReqDeadline time.Time // or zero if none + if d := c.server.readHeaderTimeout(); d > 0 { + hdrDeadline = t0.Add(d) + } if d := c.server.ReadTimeout; d > 0 { wholeReqDeadline = t0.Add(d) } + c.rwc.SetReadDeadline(hdrDeadline) if d := c.server.WriteTimeout; d > 0 { defer func() { c.rwc.SetWriteDeadline(time.Now().Add(d)) @@ -1099,7 +1106,10 @@ body.doEarlyClose = true } - c.rwc.SetReadDeadline(wholeReqDeadline) + // Adjust the read deadline if necessary. + if !hdrDeadline.Equal(wholeReqDeadline) { + c.rwc.SetReadDeadline(wholeReqDeadline) + } w = &response{ conn: c, @@ -2057,10 +2067,6 @@ c.bufr = newBufioReader(c.r) c.bufw = newBufioWriterSize(checkConnErrorWriter{c}, 4<<10) - if d := c.server.readHeaderTimeout(); d > 0 { - c.rwc.SetReadDeadline(time.Now().Add(d)) - } - protos := c.server.protocols() if c.tlsState == nil && protos.UnencryptedHTTP2() { if c.maybeServeUnencryptedHTTP2(ctx) { @@ -2193,11 +2199,7 @@ return } - if d := c.server.readHeaderTimeout(); d > 0 { - c.rwc.SetReadDeadline(time.Now().Add(d)) - } else { - c.rwc.SetReadDeadline(time.Time{}) - } + c.rwc.SetReadDeadline(time.Time{}) } }