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 <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
diff --git a/http2/server.go b/http2/server.go
index 02830d3..778ef63 100644
--- a/http2/server.go
+++ b/http2/server.go
@@ -1661,6 +1661,7 @@
}
}
st.closeErr = err
+ st.cancelCtx()
st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc
sc.writeSched.CloseStream(st.id)
}
diff --git a/http2/server_test.go b/http2/server_test.go
index f5aec44..0db1a40 100644
--- a/http2/server_test.go
+++ b/http2/server_test.go
@@ -4900,3 +4900,39 @@
c2.Close()
<-donec
}
+
+// Issue 67036: A stream error should result in the handler's request context being canceled.
+func TestServerRequestCancelOnError(t *testing.T) {
+ recvc := make(chan struct{}) // handler has started
+ donec := make(chan struct{}) // handler has finished
+ st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
+ close(recvc)
+ <-r.Context().Done()
+ close(donec)
+ })
+ defer st.Close()
+
+ st.writePreface()
+ st.writeInitialSettings()
+ st.writeSettingsAck()
+
+ // Client sends request headers, handler starts.
+ st.writeHeaders(HeadersFrameParam{
+ StreamID: 1,
+ BlockFragment: st.encodeHeader(),
+ EndStream: true,
+ EndHeaders: true,
+ })
+ <-recvc
+
+ // Client sends an invalid second set of request headers.
+ // The stream is reset.
+ // The handler's context is canceled, and the handler exits.
+ st.writeHeaders(HeadersFrameParam{
+ StreamID: 1,
+ BlockFragment: st.encodeHeader(),
+ EndStream: true,
+ EndHeaders: true,
+ })
+ <-donec
+}