diff options
| author | Adnan Maolood <[email protected]> | 2021-02-15 00:36:08 -0500 |
|---|---|---|
| committer | Adnan Maolood <[email protected]> | 2021-02-15 00:36:33 -0500 |
| commit | 2c7f8273e9e45e498d7214e660a5553acc3c1a75 (patch) | |
| tree | 7f81278e7ab370ec10fd03de219c39baf56e337e /server.go | |
| parent | request: Don't read more than 1026 bytes (diff) | |
| download | go-gemini-2c7f8273e9e45e498d7214e660a5553acc3c1a75.tar.xz go-gemini-2c7f8273e9e45e498d7214e660a5553acc3c1a75.zip | |
server: Recover from ServeGemini panics
Diffstat (limited to 'server.go')
| -rw-r--r-- | server.go | 15 |
1 files changed, 13 insertions, 2 deletions
@@ -6,6 +6,7 @@ import ( "errors" "log" "net" + "runtime" "strings" "sync" "sync/atomic" @@ -348,6 +349,15 @@ func (srv *Server) deleteConn(conn *net.Conn) { func (srv *Server) respond(conn net.Conn) { defer conn.Close() + defer func() { + if err := recover(); err != nil && err != ErrAbortHandler { + const size = 64 << 10 + buf := make([]byte, size) + buf = buf[:runtime.Stack(buf, false)] + srv.logf("gemini: panic serving %v: %v\n%s", conn.RemoteAddr(), err, buf) + } + }() + srv.trackConn(&conn) defer srv.deleteConn(&conn) @@ -359,11 +369,11 @@ func (srv *Server) respond(conn net.Conn) { } w := NewResponseWriter(conn) - defer w.Flush() req, err := ReadRequest(conn) if err != nil { w.Status(StatusBadRequest) + w.Flush() return } @@ -379,10 +389,12 @@ func (srv *Server) respond(conn net.Conn) { resp := srv.responder(req) if resp == nil { w.Status(StatusNotFound) + w.Flush() return } resp.ServeGemini(w, req) + w.Flush() } func (srv *Server) responder(r *Request) Handler { @@ -418,7 +430,6 @@ func (srv *Server) logf(format string, args ...interface{}) { // // Handlers should not modify the provided Request. // -// TODO: // If ServeGemini panics, the server (the caller of ServeGemini) 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 closes the |