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