Files
inventory-plus-plus/internal/server/response/write.go
T
2026-01-13 22:07:20 -07:00

69 lines
1.4 KiB
Go

package response
import (
"fmt"
"io"
"net/http"
"github.com/gin-gonic/gin"
)
func Write(c *gin.Context, res Response) {
w := c.Writer
// 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, c.Request, 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(c *gin.Context, err error) {
c.String(GetStatusFromError(err), err.Error())
}
func GetStatusFromError(err error) int {
status := http.StatusInternalServerError
if e, ok := GetError(err); ok {
if status, ok = e.GetStatus(); !ok {
status = http.StatusInternalServerError
}
}
return status
}