Commit 0457957c authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

net/http: update bundled http2 for ErrAbortHandler support, document it more

Updates http2 to x/net/http2 git rev 0e2717d for:

   http2: conditionally log stacks from panics in Server Handlers like net/http
   https://golang.org/cl/33102

Fixes #17790

Change-Id: Idd3f0c65540398d41b412a33f1d80de3f7f31409
Reviewed-on: https://go-review.googlesource.com/33103Reviewed-by: 's avatarJoe Tsai <thebrokentoaster@gmail.com>
parent a501fef3
...@@ -1189,9 +1189,6 @@ func testInterruptWithPanic(t *testing.T, h2 bool, panicValue interface{}) { ...@@ -1189,9 +1189,6 @@ func testInterruptWithPanic(t *testing.T, h2 bool, panicValue interface{}) {
if gotLog == "" { if gotLog == "" {
return return
} }
if h2 {
t.Skip("TODO: make http2.Server respect ErrAbortHandler")
}
t.Fatalf("want no log output; got: %s", gotLog) t.Fatalf("want no log output; got: %s", gotLog)
} }
if gotLog == "" { if gotLog == "" {
......
...@@ -2184,6 +2184,10 @@ func http2configureServer18(h1 *Server, h2 *http2Server) error { ...@@ -2184,6 +2184,10 @@ func http2configureServer18(h1 *Server, h2 *http2Server) error {
return nil return nil
} }
func http2shouldLogPanic(panicValue interface{}) bool {
return panicValue != nil && panicValue != ErrAbortHandler
}
var http2DebugGoroutines = os.Getenv("DEBUG_HTTP2_GOROUTINES") == "1" var http2DebugGoroutines = os.Getenv("DEBUG_HTTP2_GOROUTINES") == "1"
type http2goroutineLock uint64 type http2goroutineLock uint64
...@@ -4534,15 +4538,17 @@ func (sc *http2serverConn) runHandler(rw *http2responseWriter, req *Request, han ...@@ -4534,15 +4538,17 @@ func (sc *http2serverConn) runHandler(rw *http2responseWriter, req *Request, han
rw.rws.stream.cancelCtx() rw.rws.stream.cancelCtx()
if didPanic { if didPanic {
e := recover() e := recover()
// Same as net/http:
const size = 64 << 10
buf := make([]byte, size)
buf = buf[:runtime.Stack(buf, false)]
sc.writeFrameFromHandler(http2FrameWriteRequest{ sc.writeFrameFromHandler(http2FrameWriteRequest{
write: http2handlerPanicRST{rw.rws.stream.id}, write: http2handlerPanicRST{rw.rws.stream.id},
stream: rw.rws.stream, stream: rw.rws.stream,
}) })
sc.logf("http2: panic serving %v: %v\n%s", sc.conn.RemoteAddr(), e, buf)
if http2shouldLogPanic(e) {
const size = 64 << 10
buf := make([]byte, size)
buf = buf[:runtime.Stack(buf, false)]
sc.logf("http2: panic serving %v: %v\n%s", sc.conn.RemoteAddr(), e, buf)
}
return return
} }
rw.handlerDone() rw.handlerDone()
......
...@@ -75,7 +75,9 @@ var ( ...@@ -75,7 +75,9 @@ var (
// If ServeHTTP panics, the server (the caller of ServeHTTP) assumes // If ServeHTTP panics, the server (the caller of ServeHTTP) assumes
// that the effect of the panic was isolated to the active request. // that the effect of the panic was isolated to the active request.
// It recovers the panic, logs a stack trace to the server error log, // It recovers the panic, logs a stack trace to the server error log,
// and hangs up the connection. // and hangs up the connection. To abort a handler so the client sees
// an interrupted response but the server doesn't log an error, panic
// with the value ErrAbortHandler.
type Handler interface { type Handler interface {
ServeHTTP(ResponseWriter, *Request) ServeHTTP(ResponseWriter, *Request)
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment