http: Change how HTTPResponseRecorder works

This commit is contained in:
Sasha Koshka 2024-12-20 20:27:30 -05:00
parent 478d990b8b
commit 2d5dbc50b3
2 changed files with 28 additions and 10 deletions

View File

@ -236,6 +236,7 @@ func (this *Handler) serveDocument (
// set up HTTP response recorder // set up HTTP response recorder
recorder := HTTPResponseRecorder { } recorder := HTTPResponseRecorder { }
defer recorder.Reset()
resetRecorder := func () { resetRecorder := func () {
recorder.Reset() recorder.Reset()
recorder.Head = res.Header().Clone() recorder.Head = res.Header().Clone()
@ -272,6 +273,7 @@ func (this *Handler) serveDocument (
} }
var httpRedirect Redirect var httpRedirect Redirect
if errors.As(err, &httpRedirect) { if errors.As(err, &httpRedirect) {
recorder.WriteHeaderValues(res)
http.Redirect(res, req, httpRedirect.Location, httpRedirect.Status) http.Redirect(res, req, httpRedirect.Location, httpRedirect.Status)
return return
} }
@ -283,9 +285,11 @@ func (this *Handler) serveDocument (
} }
// play back recorded response // play back recorded response
err = recorder.Play(res) recorder.WriteHeaderStatus(res)
_, err = recorder.WriteBody(res)
if err != nil { if err != nil {
this.logErr(name, err) this.logErr(name, err)
return
} }
} }

View File

@ -108,21 +108,35 @@ func (this *HTTPResponseRecorder) Write (buffer []byte) (int, error) {
func (this *HTTPResponseRecorder) WriteHeader (statusCode int) { func (this *HTTPResponseRecorder) WriteHeader (statusCode int) {
this.Status = statusCode this.Status = statusCode
} }
// Play replays the response to the given http.ResponseWriter. This resets the // Play replays the response in its entirety to res.
// recorder.
func (this *HTTPResponseRecorder) Play (res http.ResponseWriter) error { func (this *HTTPResponseRecorder) Play (res http.ResponseWriter) error {
defer this.Reset() this.WriteHeaderValues(res)
status := this.Status this.WriteHeaderStatus(res)
if status == 0 { _, err := this.WriteBody(res)
status = http.StatusOK return err
} }
// WriteHeaderValues adds all header values in the recorder to res, replacing
// them if they exist already.
func (this *HTTPResponseRecorder) WriteHeaderValues (res http.ResponseWriter) {
header := res.Header() header := res.Header()
for name, value := range this.Head { for name, value := range this.Head {
header[name] = value header[name] = value
} }
}
// WriteHeaderStatus calls res.WriteHeader with the status code in the recorder.
func (this *HTTPResponseRecorder) WriteHeaderStatus (res http.ResponseWriter) {
status := this.Status
if status == 0 {
status = http.StatusOK
}
res.WriteHeader(status) res.WriteHeader(status)
_, err := io.Copy(res, &this.buffer) }
return err
// WriteBody writes the body data within the recorder to res.
func (this *HTTPResponseRecorder) WriteBody (res http.ResponseWriter) (int64, error) {
return io.Copy(res, &this.buffer)
} }
// Reset resets this response recorder so it can be used again. // Reset resets this response recorder so it can be used again.