Skip to content

Commit 8aa6dbf

Browse files
committed
http2: cancel handler context on stream errors
When we reset a stream due to an error, cancel the handler context. Fixes golang/go#67036 Change-Id: I66941d9bffb35d8b4358ff8d85cc784c1846afa6 Reviewed-on: https://go-review.googlesource.com/c/net/+/585595 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Jonathan Amsterdam <[email protected]>
1 parent 2c14f51 commit 8aa6dbf

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

Diff for: http2/server.go

+1
Original file line numberDiff line numberDiff line change
@@ -1661,6 +1661,7 @@ func (sc *serverConn) closeStream(st *stream, err error) {
16611661
}
16621662
}
16631663
st.closeErr = err
1664+
st.cancelCtx()
16641665
st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc
16651666
sc.writeSched.CloseStream(st.id)
16661667
}

Diff for: http2/server_test.go

+36
Original file line numberDiff line numberDiff line change
@@ -4900,3 +4900,39 @@ func TestServerUpgradeRequestPrefaceFailure(t *testing.T) {
49004900
c2.Close()
49014901
<-donec
49024902
}
4903+
4904+
// Issue 67036: A stream error should result in the handler's request context being canceled.
4905+
func TestServerRequestCancelOnError(t *testing.T) {
4906+
recvc := make(chan struct{}) // handler has started
4907+
donec := make(chan struct{}) // handler has finished
4908+
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
4909+
close(recvc)
4910+
<-r.Context().Done()
4911+
close(donec)
4912+
})
4913+
defer st.Close()
4914+
4915+
st.writePreface()
4916+
st.writeInitialSettings()
4917+
st.writeSettingsAck()
4918+
4919+
// Client sends request headers, handler starts.
4920+
st.writeHeaders(HeadersFrameParam{
4921+
StreamID: 1,
4922+
BlockFragment: st.encodeHeader(),
4923+
EndStream: true,
4924+
EndHeaders: true,
4925+
})
4926+
<-recvc
4927+
4928+
// Client sends an invalid second set of request headers.
4929+
// The stream is reset.
4930+
// The handler's context is canceled, and the handler exits.
4931+
st.writeHeaders(HeadersFrameParam{
4932+
StreamID: 1,
4933+
BlockFragment: st.encodeHeader(),
4934+
EndStream: true,
4935+
EndHeaders: true,
4936+
})
4937+
<-donec
4938+
}

0 commit comments

Comments
 (0)