From 889850c04c8fff891cfa4f795362d31ae4028b5c Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sun, 8 Dec 2024 01:01:10 -0500 Subject: [PATCH] Move all http stuff into the http package --- http/handler.go | 4 +-- http/http.go | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 http/http.go diff --git a/http/handler.go b/http/handler.go index 8293b35..28a6308 100644 --- a/http/handler.go +++ b/http/handler.go @@ -107,7 +107,7 @@ func (this *Handler) serveDocument ( } // set up HTTP response recorder - recorder := step.HTTPResponseRecorder { } + recorder := HTTPResponseRecorder { } resetRecorder := func () { recorder.Reset() recorder.Head = res.Header().Clone() @@ -122,7 +122,7 @@ func (this *Handler) serveDocument ( } // execute document - data := step.HTTPData { } + data := HTTPData { } data.Res.Header = recorder.Header() data.Res.WriteHeader = recorder.WriteHeader data.Res.Reset = resetRecorder diff --git a/http/http.go b/http/http.go new file mode 100644 index 0000000..a3fd9c8 --- /dev/null +++ b/http/http.go @@ -0,0 +1,66 @@ +package http + +import "io" +import "bytes" +import "net/http" + +// HTTPData represents information about an ongoing HTTP request that is made +// available to templates as they are being executed. +type HTTPData struct { + // Res is like an http.ResponseWriter. + Res struct { + Header http.Header + WriteHeader func (statusCode int) + Reset func () + } + // Req is the HTTP request. + Req *http.Request +} + +var _ http.ResponseWriter = new(HTTPResponseRecorder) + +// HTTPResponseRecorder is an http.ResponseWriter that can buffer a response to +// be played back later. +type HTTPResponseRecorder struct { + Status int + Head http.Header + buffer bytes.Buffer +} + +func (this *HTTPResponseRecorder) Header () http.Header { + if this.Head == nil { + this.Head = make(http.Header) + } + return this.Head +} + +func (this *HTTPResponseRecorder) Write (buffer []byte) (int, error) { + return this.buffer.Write(buffer) +} + +func (this *HTTPResponseRecorder) WriteHeader (statusCode int) { + this.Status = statusCode +} +// Play replays the response to the given http.ResponseWriter. This resets the +// recorder. +func (this *HTTPResponseRecorder) Play (res http.ResponseWriter) error { + defer this.Reset() + status := this.Status + if status == 0 { + status = http.StatusOK + } + header := res.Header() + for name, value := range this.Head { + header[name] = value + } + res.WriteHeader(status) + _, err := io.Copy(res, &this.buffer) + return err +} + +// Reset resets this response recorder so it can be used again. +func (this *HTTPResponseRecorder) Reset () { + this.buffer.Reset() + this.Head = nil + this.Status = http.StatusOK +}