Skip to content

Commit a870f35

Browse files
committed
http2: support Server.ReadTimeout
Return an error when reading from the request body in a server handler after Server.ReadTimeout expires. Tested by net/http CL 446255. For golang/go#49837 Change-Id: Idcc3d92209f944bd7fead832525fd563b50bcebc Reviewed-on: https://go-review.googlesource.com/c/net/+/446256 Reviewed-by: Brad Fitzpatrick <[email protected]> Reviewed-by: Bryan Mills <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Damien Neil <[email protected]>
1 parent d7f77dc commit a870f35

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

http2/server.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,7 @@ type stream struct {
622622
resetQueued bool // RST_STREAM queued for write; set by sc.resetStream
623623
gotTrailerHeader bool // HEADER frame for trailers was seen
624624
wroteHeaders bool // whether we wrote headers (not status 100)
625+
readDeadline *time.Timer // nil if unused
625626
writeDeadline *time.Timer // nil if unused
626627

627628
trailer http.Header // accumulated trailers
@@ -1579,6 +1580,9 @@ func (sc *serverConn) closeStream(st *stream, err error) {
15791580
panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state))
15801581
}
15811582
st.state = stateClosed
1583+
if st.readDeadline != nil {
1584+
st.readDeadline.Stop()
1585+
}
15821586
if st.writeDeadline != nil {
15831587
st.writeDeadline.Stop()
15841588
}
@@ -1842,6 +1846,14 @@ func (st *stream) copyTrailersToHandlerRequest() {
18421846
}
18431847
}
18441848

1849+
// onReadTimeout is run on its own goroutine (from time.AfterFunc)
1850+
// when the stream's ReadTimeout has fired.
1851+
func (st *stream) onReadTimeout() {
1852+
// Wrap the ErrDeadlineExceeded to avoid callers depending on us
1853+
// returning the bare error.
1854+
st.body.CloseWithError(fmt.Errorf("%w", os.ErrDeadlineExceeded))
1855+
}
1856+
18451857
// onWriteTimeout is run on its own goroutine (from time.AfterFunc)
18461858
// when the stream's WriteTimeout has fired.
18471859
func (st *stream) onWriteTimeout() {
@@ -1953,6 +1965,9 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
19531965
// (in Go 1.8), though. That's a more sane option anyway.
19541966
if sc.hs.ReadTimeout != 0 {
19551967
sc.conn.SetReadDeadline(time.Time{})
1968+
if st.body != nil {
1969+
st.readDeadline = time.AfterFunc(sc.hs.ReadTimeout, st.onReadTimeout)
1970+
}
19561971
}
19571972

19581973
go sc.runHandler(rw, req, handler)

0 commit comments

Comments
 (0)