diff --git a/http3/server.go b/http3/server.go index b0204416781..c27d8286b2f 100644 --- a/http3/server.go +++ b/http3/server.go @@ -576,12 +576,15 @@ func (s *Server) handleRequest(conn quic.Connection, str quic.Stream, decoder *q func() { defer func() { if p := recover(); p != nil { + panicked = true + if p == http.ErrAbortHandler { + return + } // Copied from net/http/server.go const size = 64 << 10 buf := make([]byte, size) buf = buf[:runtime.Stack(buf, false)] s.logger.Errorf("http: panic serving: %v\n%s", p, buf) - panicked = true } }() handler.ServeHTTP(r, req) diff --git a/http3/server_test.go b/http3/server_test.go index 9008067e8a2..15c59cc611c 100644 --- a/http3/server_test.go +++ b/http3/server_test.go @@ -201,6 +201,23 @@ var _ = Describe("Server", func() { Expect(hfs).To(HaveKeyWithValue(":status", []string{"200"})) }) + It("handles a aborting handler", func() { + s.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + panic(http.ErrAbortHandler) + }) + + responseBuf := &bytes.Buffer{} + setRequest(encodeRequest(exampleGetRequest)) + str.EXPECT().Context().Return(reqContext) + str.EXPECT().Write(gomock.Any()).DoAndReturn(responseBuf.Write).AnyTimes() + str.EXPECT().CancelRead(gomock.Any()) + + serr := s.handleRequest(conn, str, qpackDecoder, nil) + Expect(serr.err).ToNot(HaveOccurred()) + hfs := decodeHeader(responseBuf) + Expect(hfs).To(HaveKeyWithValue(":status", []string{"500"})) + }) + It("handles a panicking handler", func() { s.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { panic("foobar")