internal: record client disconnects as 499, not 200 or 502 (#1040)
A client that hangs up before a response is written was logged and recorded as a successful 200 with a 0-byte body: the cancellation branches return without touching the ResponseWriter, so the access log's seeded 200 was what got reported, and the metrics path filed it through the "empty body, recording minimal metrics" success arm. Aborted requests were invisible to status-code monitoring. Once the model was loaded, the same hangup surfaced as a 502, blaming a healthy upstream. Add swaputil.StatusClientClosedRequest (nginx's non-standard 499) as the sentinel. It is recorded only, never written to the connection: the client is already gone, and on a streamed response a late WriteHeader would just log "superfluous response.WriteHeader". - add StatusMarker/MarkClientClosed to swaputil; the response recorders implement it and forward outward so log and metrics agree - derive the sentinel in the access-log and metrics middleware, which covers every cancellation branch instead of each one separately - classify cancellation in the model and peer proxy ErrorHandlers so a client hangup no longer reports 502 - record cancelled requests with a client-disconnected ErrorMsg at debug level and without a capture, since an impatient caller is normal traffic rather than a server fault - tag health check polls so a booting upstream is not logged as a proxy error once per second A response that already started keeps the status the client actually received. fix: #1029
B
Benson Wong committed
4ec317589b21f58b64802c2b3371a179b9fdaa53
Parent: 23432e6
Committed by GitHub <noreply@github.com>
on 8/23/2026, 6:58:47 AM