Record cancellation from what the reverse proxy observed, not the request context

Implemented-By: OpenCode session (model recorded in docs/implementer-log.md)
This commit is contained in:
2026-09-25 11:32:18 -07:00
parent 317293cfb3
commit f3dfdbfa50
3 changed files with 91 additions and 1 deletions
+7 -1
View File
@@ -54,7 +54,7 @@ func (p *Handler) forward(w http.ResponseWriter, r *http.Request, route, host, l
total := time.Since(started)
req := forwardRow(route, fp, model, host, started, waited, rev, rec.status, total.Milliseconds())
if r.Context().Err() != nil {
if rev.cancelled {
req.Status = 499
req.Err = "client cancelled"
}
@@ -126,6 +126,9 @@ type forwardState struct {
ttfb time.Time
streamed bool
tee *tee
// cancelled is set when the reverse proxy's ErrorHandler observed the client leaving before a
// response byte was written; it is the one signal that turns a delivered row into a 499.
cancelled bool
}
// statusRecorder records the status written and forwards Flush so the reverse proxy can stream.
@@ -215,6 +218,9 @@ func newReverseProxy(h Health, host, leaseState, ctxHeader string, target *url.U
},
ErrorHandler: func(w http.ResponseWriter, req *http.Request, err error) {
if errors.Is(err, context.Canceled) {
// The client left before any byte was written; record it so the row is a 499,
// not the post-hoc context check that misread a pooled close as a cancel.
rev.cancelled = true
return
}
h.MarkDown(host, err.Error())