Checkpoint
This commit is contained in:
@@ -2,77 +2,58 @@ package proxy
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"git.maze.io/maze/styx/internal/log"
|
||||
)
|
||||
|
||||
func NewResponse(code int, body io.Reader, request *http.Request) *http.Response {
|
||||
if body == nil {
|
||||
body = new(bytes.Buffer)
|
||||
}
|
||||
|
||||
rc, ok := body.(io.ReadCloser)
|
||||
if !ok {
|
||||
rc = io.NopCloser(body)
|
||||
}
|
||||
|
||||
response := &http.Response{
|
||||
Status: strconv.Itoa(code) + " " + http.StatusText(code),
|
||||
StatusCode: code,
|
||||
Proto: "HTTP/1.1",
|
||||
ProtoMajor: 1,
|
||||
ProtoMinor: 1,
|
||||
Header: make(http.Header),
|
||||
Body: rc,
|
||||
Request: request,
|
||||
}
|
||||
|
||||
if request != nil {
|
||||
response.Close = request.Close
|
||||
response.Proto = request.Proto
|
||||
response.ProtoMajor = request.ProtoMajor
|
||||
response.ProtoMinor = request.ProtoMinor
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
type withLen interface {
|
||||
Len() int
|
||||
}
|
||||
|
||||
type withSize interface {
|
||||
type sizer interface {
|
||||
Size() int64
|
||||
}
|
||||
|
||||
func NewJSONResponse(code int, body io.Reader, request *http.Request) *http.Response {
|
||||
response := NewResponse(code, body, request)
|
||||
response.Header.Set(HeaderContentType, "application/json")
|
||||
if s, ok := body.(withLen); ok {
|
||||
response.Header.Set(HeaderContentLength, strconv.Itoa(s.Len()))
|
||||
} else if s, ok := body.(withSize); ok {
|
||||
response.Header.Set(HeaderContentLength, strconv.FormatInt(s.Size(), 10))
|
||||
} else {
|
||||
log.Trace().Str("type", fmt.Sprintf("%T", body)).Msg("can't detemine body size")
|
||||
// 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,
|
||||
}
|
||||
response.Close = true
|
||||
return response
|
||||
|
||||
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 ErrorResponse(request *http.Request, err error) *http.Response {
|
||||
response := NewResponse(http.StatusBadGateway, nil, request)
|
||||
func NewErrorResponse(err error, req *http.Request) *http.Response {
|
||||
switch {
|
||||
case os.IsNotExist(err):
|
||||
response.StatusCode = http.StatusNotFound
|
||||
case os.IsPermission(err):
|
||||
response.StatusCode = http.StatusForbidden
|
||||
case os.IsTimeout(err):
|
||||
return NewResponse(http.StatusGatewayTimeout, nil, req)
|
||||
default:
|
||||
return NewResponse(http.StatusBadGateway, nil, req)
|
||||
}
|
||||
response.Status = http.StatusText(response.StatusCode)
|
||||
response.Close = true
|
||||
return response
|
||||
}
|
||||
|
Reference in New Issue
Block a user