Skip to content
Snippets Groups Projects
Unverified Commit bd122ea6 authored by Will McCutchen's avatar Will McCutchen Committed by GitHub
Browse files

Extract inline vars from the status handler (#93)

parent 7d0621ff
No related branches found
No related tags found
No related merge requests found
...@@ -14,14 +14,6 @@ import ( ...@@ -14,14 +14,6 @@ import (
"github.com/mccutchen/go-httpbin/v2/httpbin/digest" "github.com/mccutchen/go-httpbin/v2/httpbin/digest"
) )
var acceptedMediaTypes = []string{
"image/webp",
"image/svg+xml",
"image/jpeg",
"image/png",
"image/",
}
func notImplementedHandler(w http.ResponseWriter, r *http.Request) { func notImplementedHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, "Not implemented", http.StatusNotImplemented) http.Error(w, "Not implemented", http.StatusNotImplemented)
} }
...@@ -151,36 +143,29 @@ func (h *HTTPBin) Headers(w http.ResponseWriter, r *http.Request) { ...@@ -151,36 +143,29 @@ func (h *HTTPBin) Headers(w http.ResponseWriter, r *http.Request) {
writeJSON(w, body, http.StatusOK) writeJSON(w, body, http.StatusOK)
} }
// Status responds with the specified status code. TODO: support random choice
// from multiple, optionally weighted status codes.
func (h *HTTPBin) Status(w http.ResponseWriter, r *http.Request) {
parts := strings.Split(r.URL.Path, "/")
if len(parts) != 3 {
http.Error(w, "Not found", http.StatusNotFound)
return
}
code, err := strconv.Atoi(parts[2])
if err != nil {
http.Error(w, "Invalid status", http.StatusBadRequest)
return
}
type statusCase struct { type statusCase struct {
headers map[string]string headers map[string]string
body []byte body []byte
} }
redirectHeaders := &statusCase{ var (
statusRedirectHeaders = &statusCase{
headers: map[string]string{ headers: map[string]string{
"Location": "/redirect/1", "Location": "/redirect/1",
}, },
} }
notAcceptableBody, _ := jsonMarshalNoEscape(map[string]interface{}{ statusNotAcceptableBody = []byte(`{
"message": "Client did not request a supported media type", "message": "Client did not request a supported media type",
"accept": acceptedMediaTypes, "accept": [
}) "image/webp",
"image/svg+xml",
http300body := []byte(`<!doctype html> "image/jpeg",
"image/png",
"image/"
]
}
`)
statusHTTP300body = []byte(`<!doctype html>
<head> <head>
<title>Multiple Choices</title> <title>Multiple Choices</title>
</head> </head>
...@@ -192,7 +177,7 @@ func (h *HTTPBin) Status(w http.ResponseWriter, r *http.Request) { ...@@ -192,7 +177,7 @@ func (h *HTTPBin) Status(w http.ResponseWriter, r *http.Request) {
</body> </body>
</html>`) </html>`)
http308body := []byte(`<!doctype html> statusHTTP308Body = []byte(`<!doctype html>
<head> <head>
<title>Permanent Redirect</title> <title>Permanent Redirect</title>
</head> </head>
...@@ -200,20 +185,20 @@ func (h *HTTPBin) Status(w http.ResponseWriter, r *http.Request) { ...@@ -200,20 +185,20 @@ func (h *HTTPBin) Status(w http.ResponseWriter, r *http.Request) {
</body> </body>
</html>`) </html>`)
specialCases := map[int]*statusCase{ statusSpecialCases = map[int]*statusCase{
300: { 300: {
body: http300body, body: statusHTTP300body,
headers: map[string]string{ headers: map[string]string{
"Location": "/image/jpeg", "Location": "/image/jpeg",
}, },
}, },
301: redirectHeaders, 301: statusRedirectHeaders,
302: redirectHeaders, 302: statusRedirectHeaders,
303: redirectHeaders, 303: statusRedirectHeaders,
305: redirectHeaders, 305: statusRedirectHeaders,
307: redirectHeaders, 307: statusRedirectHeaders,
308: { 308: {
body: http308body, body: statusHTTP308Body,
headers: map[string]string{ headers: map[string]string{
"Location": "/image/jpeg", "Location": "/image/jpeg",
}, },
...@@ -230,7 +215,7 @@ func (h *HTTPBin) Status(w http.ResponseWriter, r *http.Request) { ...@@ -230,7 +215,7 @@ func (h *HTTPBin) Status(w http.ResponseWriter, r *http.Request) {
}, },
}, },
406: { 406: {
body: notAcceptableBody, body: statusNotAcceptableBody,
headers: map[string]string{ headers: map[string]string{
"Content-Type": jsonContentType, "Content-Type": jsonContentType,
}, },
...@@ -247,8 +232,23 @@ func (h *HTTPBin) Status(w http.ResponseWriter, r *http.Request) { ...@@ -247,8 +232,23 @@ func (h *HTTPBin) Status(w http.ResponseWriter, r *http.Request) {
}, },
}, },
} }
)
// Status responds with the specified status code. TODO: support random choice
// from multiple, optionally weighted status codes.
func (h *HTTPBin) Status(w http.ResponseWriter, r *http.Request) {
parts := strings.Split(r.URL.Path, "/")
if len(parts) != 3 {
http.Error(w, "Not found", http.StatusNotFound)
return
}
code, err := strconv.Atoi(parts[2])
if err != nil {
http.Error(w, "Invalid status", http.StatusBadRequest)
return
}
if specialCase, ok := specialCases[code]; ok { if specialCase, ok := statusSpecialCases[code]; ok {
for key, val := range specialCase.headers { for key, val := range specialCase.headers {
w.Header().Set(key, val) w.Header().Set(key, val)
} }
...@@ -256,9 +256,10 @@ func (h *HTTPBin) Status(w http.ResponseWriter, r *http.Request) { ...@@ -256,9 +256,10 @@ func (h *HTTPBin) Status(w http.ResponseWriter, r *http.Request) {
if specialCase.body != nil { if specialCase.body != nil {
w.Write(specialCase.body) w.Write(specialCase.body)
} }
} else { return
w.WriteHeader(code)
} }
w.WriteHeader(code)
} }
// Unstable - returns 500, sometimes // Unstable - returns 500, sometimes
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment