60 lines
1.1 KiB
Go
60 lines
1.1 KiB
Go
package proxy
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"strconv"
|
|
)
|
|
|
|
type sizer interface {
|
|
Size() int64
|
|
}
|
|
|
|
// NewResponse prepares a net [http.Response], based on the status code, optional body and
|
|
// optional [http.Request].
|
|
func NewResponse(code int, body io.ReadCloser, req *http.Request) *http.Response {
|
|
res := &http.Response{
|
|
StatusCode: code,
|
|
Header: make(http.Header),
|
|
Proto: "HTTP/1.1",
|
|
ProtoMajor: 1,
|
|
ProtoMinor: 1,
|
|
}
|
|
|
|
if text := http.StatusText(code); text != "" {
|
|
res.Status = strconv.Itoa(code) + " " + text
|
|
} else {
|
|
res.Status = strconv.Itoa(code)
|
|
}
|
|
|
|
if body == nil && code >= 400 {
|
|
body = io.NopCloser(bytes.NewBufferString(http.StatusText(code)))
|
|
}
|
|
|
|
res.Body = body
|
|
|
|
if s, ok := body.(sizer); ok {
|
|
res.ContentLength = s.Size()
|
|
}
|
|
|
|
if req != nil {
|
|
res.Close = req.Close
|
|
res.Proto = req.Proto
|
|
res.ProtoMajor = req.ProtoMajor
|
|
res.ProtoMinor = req.ProtoMinor
|
|
}
|
|
|
|
return res
|
|
}
|
|
|
|
func NewErrorResponse(err error, req *http.Request) *http.Response {
|
|
switch {
|
|
case os.IsTimeout(err):
|
|
return NewResponse(http.StatusGatewayTimeout, nil, req)
|
|
default:
|
|
return NewResponse(http.StatusBadGateway, nil, req)
|
|
}
|
|
}
|