81 lines
2.0 KiB
Go
81 lines
2.0 KiB
Go
|
package handler
|
||
|
|
||
|
import (
|
||
|
"net/http"
|
||
|
"strconv"
|
||
|
)
|
||
|
|
||
|
// HTTPRequest contains basic details of an incoming HTTP request.
|
||
|
type HTTPRequest struct {
|
||
|
// Method is the HTTP method, e.g. POST or PATCH.
|
||
|
Method string
|
||
|
// URI is the full HTTP request URI, e.g. /files/fooo.
|
||
|
URI string
|
||
|
// RemoteAddr contains the network address that sent the request.
|
||
|
RemoteAddr string
|
||
|
// Header contains all HTTP headers as present in the HTTP request.
|
||
|
Header http.Header
|
||
|
}
|
||
|
|
||
|
type HTTPHeaders map[string]string
|
||
|
|
||
|
// HTTPResponse contains basic details of an outgoing HTTP response.
|
||
|
type HTTPResponse struct {
|
||
|
// StatusCode is status code, e.g. 200 or 400.
|
||
|
StatusCode int
|
||
|
// Body is the response body.
|
||
|
Body string
|
||
|
// Headers contains additional HTTP headers for the response.
|
||
|
// TODO: Uniform naming with HTTPRequest.Header
|
||
|
Headers HTTPHeaders
|
||
|
}
|
||
|
|
||
|
// writeTo writes the HTTP response into w, as specified by the fields in resp.
|
||
|
func (resp HTTPResponse) writeTo(w http.ResponseWriter) {
|
||
|
headers := w.Header()
|
||
|
for key, value := range resp.Headers {
|
||
|
headers.Set(key, value)
|
||
|
}
|
||
|
|
||
|
if len(resp.Body) > 0 {
|
||
|
headers.Set("Content-Length", strconv.Itoa(len(resp.Body)))
|
||
|
}
|
||
|
|
||
|
w.WriteHeader(resp.StatusCode)
|
||
|
|
||
|
if len(resp.Body) > 0 {
|
||
|
w.Write([]byte(resp.Body))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// MergeWith returns a copy of resp1, where non-default values from resp2 overwrite
|
||
|
// values from resp1.
|
||
|
func (resp1 HTTPResponse) MergeWith(resp2 HTTPResponse) HTTPResponse {
|
||
|
// Clone the response 1 and use it as a basis
|
||
|
newResp := resp1
|
||
|
|
||
|
// Take the status code and body from response 2 to
|
||
|
// overwrite values from response 1.
|
||
|
if resp2.StatusCode != 0 {
|
||
|
newResp.StatusCode = resp2.StatusCode
|
||
|
}
|
||
|
|
||
|
if len(resp2.Body) > 0 {
|
||
|
newResp.Body = resp2.Body
|
||
|
}
|
||
|
|
||
|
// For the headers, me must make a new map to avoid writing
|
||
|
// into the header map from response 1.
|
||
|
newResp.Headers = make(HTTPHeaders, len(resp1.Headers)+len(resp2.Headers))
|
||
|
|
||
|
for key, value := range resp1.Headers {
|
||
|
newResp.Headers[key] = value
|
||
|
}
|
||
|
|
||
|
for key, value := range resp2.Headers {
|
||
|
newResp.Headers[key] = value
|
||
|
}
|
||
|
|
||
|
return newResp
|
||
|
}
|