Checkpoint

This commit is contained in:
2025-09-30 08:08:22 +02:00
parent a76650da35
commit 4a60059ff2
24 changed files with 1034 additions and 2959 deletions

View File

@@ -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
}