http response tooling written
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func Write(w http.ResponseWriter, r *http.Request, res Response) {
|
||||
// w.Header() must be set before ResponseWriter.WriteHeader is called
|
||||
// or redirect is attempted
|
||||
hdrs := w.Header()
|
||||
for _, ck := range res.getCookies() {
|
||||
hdrs.Add("Set-Cookie", ck.String())
|
||||
}
|
||||
|
||||
if code, to, ok := res.getRedirect(); ok {
|
||||
http.Redirect(w, r, to, code.Int())
|
||||
return
|
||||
}
|
||||
|
||||
// the body is written after the status header, but it's read here
|
||||
// first, because if an error is incurred, an error status header will
|
||||
// need to be written.
|
||||
body, bodySet, err := res.getBody()
|
||||
if err != nil {
|
||||
http.Error(
|
||||
w,
|
||||
fmt.Sprintf("Failed to construct response body: %v", err.Error()),
|
||||
http.StatusInternalServerError,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if status, ok := res.getStatus(); ok {
|
||||
w.WriteHeader(status)
|
||||
}
|
||||
if bodySet {
|
||||
// will automatically set the status header,
|
||||
// if w.WriteHeader wasn't already called
|
||||
io.Copy(w, body)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func WriteError(w http.ResponseWriter, err error) {
|
||||
var status int
|
||||
|
||||
if e, ok := getError(err); ok {
|
||||
if status, ok = e.getStatus(); !ok {
|
||||
status = http.StatusInternalServerError
|
||||
}
|
||||
}
|
||||
|
||||
http.Error(w, err.Error(), status)
|
||||
}
|
||||
Reference in New Issue
Block a user