61 lines
1.3 KiB
Go
61 lines
1.3 KiB
Go
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 ct, ok := res.getContentType(); ok {
|
|
hdrs.Add("Content-Type", ct)
|
|
}
|
|
|
|
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) {
|
|
status := http.StatusInternalServerError
|
|
|
|
if e, ok := GetError(err); ok {
|
|
if status, ok = e.GetStatus(); !ok {
|
|
status = http.StatusInternalServerError
|
|
}
|
|
}
|
|
|
|
http.Error(w, err.Error(), status)
|
|
}
|