Summary #
Enforces bounded HTTP header/body read limits on http.Server and per-write flush deadlines on SSE streams so slow request bodies and silently stalled TCP clients cannot pin connections or wedge the serialized import queue.
Changes #
- HTTP request header & body limits (
internal/server/server.go,internal/server/import.go,cmd/goosefoot/main.go):- Set
ReadTimeout(DefaultReadTimeout = 15s),ReadHeaderTimeout: min(5s, ReadTimeout), andMaxHeaderBytes(DefaultMaxHeaderBytes = 16 KiB) onhttp.Server. - Consume
request.BodytoEOFviaio.ReadAll+json.UnmarshalinparseImportRequestwhileReadTimeoutis armed, ensuring trailing unread body bytes cannot block post-handler request drain before clearing the connection read deadline (rc.SetReadDeadline(time.Time{})) for long-lived SSE streaming.
- Set
- Per-write SSE flush deadlines & stalled-reader detachment (
internal/server/sse.go):- Arm
rc.SetWriteDeadline(time.Now().Add(writeTimeout))(DefaultSSEWriteTimeout = 10s) before initial header flush and everysendRawwrite/flush. - Mark the stream
detachedundersseStream.muon write/flush failure (or request context cancellation) and stop the heartbeat goroutine, treating silently stalled TCP sockets identically to clean client disconnects so queued/active imports complete in the background and releases.queueand admission slots.
- Arm
- Tests (
internal/server/server_test.go):- Behavioral
ListenAndServetests covering unauthenticated slow-body401socket closure, authenticated stalled-body400rejection,431oversized headers, SSE streams outlivingReadTimeout, and stalled TCP receive buffers detaching mid-import without wedging subsequent imports or post-import hooks.
- Behavioral