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
+}