- proxy/proxy.go: decrement connection count on dangerous path rejection
(line 724) to prevent connection count leak
- handler/sendfile_linux.go: return *os.File from getSocketFile and let
linuxSendfile close it, fixing EBADF from deferred close in getSocketFd
- proxy/websocket.go: return bufio.Reader from readWebSocketUpgradeResponse
and wrap targetConn with bufferedConn to consume pre-buffered frame data,
preventing first-frame loss
- server/pool.go: use non-blocking send after starting new worker to avoid
deadlock when queue is full
- stream/stream.go: check stopCh on non-timeout UDP read errors to prevent
infinite loop and shutdown deadlock
- middleware/ratelimit: replace select-based close guard with sync.Once in
StopCleanup to prevent double-close panic
- Fix handleConnection to use addr parameter for direct upstream map
lookup instead of always selecting the first upstream
- Add Server.Stop() for graceful shutdown with listener closing, UDP
server cleanup, health checker termination, and goroutine joining
- Add shutdownStream() to App and call it in SIGTERM/SIGQUIT/SIGUSR2
signal handlers to prevent goroutine and port leaks on shutdown
- Server.connCount and Target.conns now use atomic.AddInt64/LoadInt64
instead of non-atomic ++ and --, fixing data races under concurrency
- UDP sessions now store a reference to their target and decrement
target.conns in close(), preventing monotonically increasing counts
that would break least_conn load balancing over time
- Add nolint comments for sync.Pool.Get() type assertions (pool always returns valid pointers)
- Extract TLS version strings to constants in sslutil/tlsconfig.go
- Extract expires directive strings to constants in handler/static.go
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Apply modern Go patterns across the codebase:
- Replace `interface{}` with `any` (Go 1.18+)
- Use `for range n` instead of `for i := 0; i < n; i++` (Go 1.22+)
- Replace `sort.Slice` with `slices.Sort` from slices package
- Simplify sync.WaitGroup patterns with errgroup where appropriate
- Add Makefile targets for modernize analyzer
Total: 84 files updated, net reduction of 79 lines
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Conflict: sendfile.go (!linux build tag) was incorrectly modified to
include linuxSendfile and getSocketFd functions which already exist
in sendfile_linux.go.
Resolution: Keep HEAD version (simple fallback returning ENOTSUP) as
Linux implementation is properly separated in sendfile_linux.go.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>