diff options
| author | T <t@tjp.lol> | 2025-04-03 10:00:40 -0600 |
|---|---|---|
| committer | t <t@tjp.lol> | 2026-07-01 10:47:36 -0600 |
| commit | 748a806adc5a325e63ca6883b2aa9bf15da90513 (patch) | |
| tree | a60cf2e32370f9e2cf194e8b52bcb2af3ed6a120 /internal/server.go | |
| parent | 74bbf67ebbd1325ff699a052933ad94bc0401c58 (diff) | |
Reject oversized or malformed Gopher selectors as parse errors instead of panicking. Keep search requests bounded, and wrap shared server goroutines with panic logging so one bad connection cannot take down the process.
Diffstat (limited to 'internal/server.go')
| -rw-r--r-- | internal/server.go | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/internal/server.go b/internal/server.go index 46b95ef..3ae9be2 100644 --- a/internal/server.go +++ b/internal/server.go @@ -2,7 +2,9 @@ package internal import ( "context" + "fmt" "net" + "runtime/debug" "strings" "sync" @@ -84,6 +86,7 @@ func (s *Server) Serve() error { go func() { defer s.Wg.Done() defer func() { _ = conn.Close() }() + defer s.recoverPanic("connection", "remote", conn.RemoteAddr().String()) s.HandleConn(conn) }() } @@ -129,12 +132,25 @@ func (s *Server) propagateClose() { s.Wg.Add(1) go func() { defer s.Wg.Done() + defer s.recoverPanic("close propagation") <-s.Ctx.Done() _ = s.Listener.Close() }() } +func (s *Server) recoverPanic(goroutine string, keyvals ...any) { + if r := recover(); r != nil { + keyvals = append([]any{ + "msg", "panic in server goroutine", + "goroutine", goroutine, + "panic", fmt.Sprintf("%v", r), + "stack", string(debug.Stack()), + }, keyvals...) + _ = s.ErrorLog.Log(keyvals...) + } +} + // JoinDefaultPort appends ":<port>" iff the address does not already contain a port. func JoinDefaultPort(address string, port string) string { if len(address) > 0 && address[0] == '[' { |
