From 0457957c991dde4bbdeefb73bc9fb01827298bd9 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Thu, 10 Nov 2016 23:16:14 +0000 Subject: 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/33103 Reviewed-by: Joe Tsai --- src/net/http/clientserver_test.go | 3 --- src/net/http/h2_bundle.go | 16 +++++++++++----- src/net/http/server.go | 4 +++- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/net/http/clientserver_test.go b/src/net/http/clientserver_test.go index 0d231b87b0..286f816609 100644 --- a/src/net/http/clientserver_test.go +++ b/src/net/http/clientserver_test.go @@ -1189,9 +1189,6 @@ func testInterruptWithPanic(t *testing.T, h2 bool, panicValue interface{}) { if gotLog == "" { return } - if h2 { - t.Skip("TODO: make http2.Server respect ErrAbortHandler") - } t.Fatalf("want no log output; got: %s", gotLog) } if gotLog == "" { diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go index f606098796..20178dadf1 100644 --- a/src/net/http/h2_bundle.go +++ b/src/net/http/h2_bundle.go @@ -2184,6 +2184,10 @@ func http2configureServer18(h1 *Server, h2 *http2Server) error { return nil } +func http2shouldLogPanic(panicValue interface{}) bool { + return panicValue != nil && panicValue != ErrAbortHandler +} + var http2DebugGoroutines = os.Getenv("DEBUG_HTTP2_GOROUTINES") == "1" type http2goroutineLock uint64 @@ -4534,15 +4538,17 @@ func (sc *http2serverConn) runHandler(rw *http2responseWriter, req *Request, han rw.rws.stream.cancelCtx() if didPanic { e := recover() - // Same as net/http: - const size = 64 << 10 - buf := make([]byte, size) - buf = buf[:runtime.Stack(buf, false)] sc.writeFrameFromHandler(http2FrameWriteRequest{ write: http2handlerPanicRST{rw.rws.stream.id}, 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 } rw.handlerDone() diff --git a/src/net/http/server.go b/src/net/http/server.go index 2bc71c7dd5..257d82f8ac 100644 --- a/src/net/http/server.go +++ b/src/net/http/server.go @@ -75,7 +75,9 @@ var ( // If ServeHTTP panics, the server (the caller of ServeHTTP) assumes // 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, -// 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 { ServeHTTP(ResponseWriter, *Request) } -- cgit v1.2.3-54-g00ecf