Files
simplexcalc/internal/middleware/responsewriter.go
T
clawbot f8ce8cef83 Seed from go-template-repo, renamed to simplexcalc
The template's files at a77fd30, without its history or LICENSE, after
script/rename simplexcalc.

Model: opus-5-5
2026-09-26 21:38:57 +00:00

64 lines
1.7 KiB
Go

package middleware
import (
"net/http"
)
// responseRecorder remembers the status code and byte count for the
// logger and the metrics middleware. net/http gives no way to read
// them back off an http.ResponseWriter, so the only way to know what
// was answered is to be the thing that answered it.
type responseRecorder struct {
http.ResponseWriter
status int
written int64
wrote bool
}
func newResponseRecorder(w http.ResponseWriter) *responseRecorder {
// A handler that writes a body without calling WriteHeader has
// sent 200; recording that up front means Status() is right for
// the common case without waiting for a call that never comes.
return &responseRecorder{ResponseWriter: w, status: http.StatusOK}
}
func (r *responseRecorder) WriteHeader(status int) {
if r.wrote {
return
}
r.status = status
r.wrote = true
r.ResponseWriter.WriteHeader(status)
}
func (r *responseRecorder) Write(b []byte) (int, error) {
r.wrote = true
n, err := r.ResponseWriter.Write(b)
r.written += int64(n)
//nolint:wrapcheck // pass-through writer: wrapping would obscure the underlying error.
return n, err
}
// Status returns the status code that was sent.
func (r *responseRecorder) Status() int {
return r.status
}
// Written reports whether anything has been sent yet. The panic
// recoverer needs this: it can only substitute a 500 for a response
// that has not started.
func (r *responseRecorder) Written() bool {
return r.wrote
}
// Unwrap lets http.ResponseController reach the underlying writer, so
// wrapping does not cost the handler flushing or deadline control.
func (r *responseRecorder) Unwrap() http.ResponseWriter {
return r.ResponseWriter
}