http2: avoid race in server handler SetReadDeadine/SetWriteDeadline
Can't safely access responseWriter.rws from on the server's serve loop.
Change-Id: I477abe58cf9dd23813a0c5507aed2319696fdfaf
Reviewed-on: https://go-review.googlesource.com/c/net/+/589856
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Auto-Submit: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/http2/server.go b/http2/server.go
index d23640d..6c349f3 100644
--- a/http2/server.go
+++ b/http2/server.go
@@ -2821,9 +2821,9 @@
if deadline.IsZero() {
st.readDeadline = nil
} else if st.readDeadline == nil {
- st.readDeadline = sc.srv.afterFunc(deadline.Sub(w.rws.conn.srv.now()), st.onReadTimeout)
+ st.readDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onReadTimeout)
} else {
- st.readDeadline.Reset(deadline.Sub(w.rws.conn.srv.now()))
+ st.readDeadline.Reset(deadline.Sub(sc.srv.now()))
}
})
return nil
@@ -2847,9 +2847,9 @@
if deadline.IsZero() {
st.writeDeadline = nil
} else if st.writeDeadline == nil {
- st.writeDeadline = sc.srv.afterFunc(deadline.Sub(w.rws.conn.srv.now()), st.onWriteTimeout)
+ st.writeDeadline = sc.srv.afterFunc(deadline.Sub(sc.srv.now()), st.onWriteTimeout)
} else {
- st.writeDeadline.Reset(deadline.Sub(w.rws.conn.srv.now()))
+ st.writeDeadline.Reset(deadline.Sub(sc.srv.now()))
}
})
return nil
diff --git a/http2/server_test.go b/http2/server_test.go
index f877015..47c3c61 100644
--- a/http2/server_test.go
+++ b/http2/server_test.go
@@ -4661,3 +4661,16 @@
})
<-donec
}
+
+func TestServerSetReadWriteDeadlineRace(t *testing.T) {
+ ts := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
+ ctl := http.NewResponseController(w)
+ ctl.SetReadDeadline(time.Now().Add(3600 * time.Second))
+ ctl.SetWriteDeadline(time.Now().Add(3600 * time.Second))
+ })
+ resp, err := ts.Client().Get(ts.URL)
+ if err != nil {
+ t.Fatal(err)
+ }
+ resp.Body.Close()
+}