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 { 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") } response.Close = true return response } func ErrorResponse(request *http.Request, err error) *http.Response { response := NewResponse(http.StatusBadGateway, nil, request) switch { case os.IsNotExist(err): response.StatusCode = http.StatusNotFound case os.IsPermission(err): response.StatusCode = http.StatusForbidden } response.Status = http.StatusText(response.StatusCode) response.Close = true return response }