From ac6db4f3bc86c8dd92a8cb09e8a0cc3e037740bb Mon Sep 17 00:00:00 2001 From: Nate Meyer <672246+notnmeyer@users.noreply.github.com> Date: Mon, 23 Oct 2023 14:32:03 -0700 Subject: [PATCH 1/4] handle missing x-response-json handle missing x-response-json --- main.go | 38 ++++++++++++++++++++++++++++++++++---- main_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/main.go b/main.go index 50b1c11..f6e3acf 100644 --- a/main.go +++ b/main.go @@ -34,23 +34,53 @@ func main() { func handler(w http.ResponseWriter, r *http.Request) { var ( contentType = "application/json; charset=utf-8" - responseBody = r.Header["X-Response-Json"][0] + responseBody string responseCode int ) - responseCode, err := validateResponseCode(r.Header) + err := validateResponseBody(r.Header) + if err == nil { + responseBody = r.Header["X-Response-Json"][0] + } else { + responseBody = err.Error() + responseCode = http.StatusBadRequest + writeRequest(w, contentType, responseBody, responseCode) + return + } + + responseCode, err = validateResponseCode(r.Header) if err != nil { responseBody = err.Error() - } else if !isJSON(responseBody) { - responseBody = errorResponseFormatter("x-response-json must be valid JSON").Error() responseCode = http.StatusBadRequest + writeRequest(w, contentType, responseBody, responseCode) + return } + writeRequest(w, contentType, responseBody, responseCode) + + // w.Header().Set("Content-Type", contentType) + // w.WriteHeader(responseCode) + // w.Write([]byte(responseBody)) +} + +func writeRequest(w http.ResponseWriter, contentType string, responseBody string, responseCode int) { w.Header().Set("Content-Type", contentType) w.WriteHeader(responseCode) w.Write([]byte(responseBody)) } +func validateResponseBody(header map[string][]string) error { + if _, exists := header["X-Response-Json"]; !exists { + return errorResponseFormatter("x-response-json must be set on the request") + } + + if !isJSON(header["X-Response-Json"][0]) { + return errorResponseFormatter("x-response-json must be valid JSON") + } + + return nil +} + func validateResponseCode(header map[string][]string) (int, error) { if val, exists := header["X-Response-Code"]; exists { // verify its a number diff --git a/main_test.go b/main_test.go index a67510f..236422d 100644 --- a/main_test.go +++ b/main_test.go @@ -41,6 +41,32 @@ func TestHandlerValidRequest(t *testing.T) { } } +func TestHandlerWithoutXResponseJson(t *testing.T) { + expectedResponseBody := `{"error":"x-response-json must be set on the request"}` + expectedResponseCode := http.StatusBadRequest + + // set up the request + req, err := http.NewRequest("GET", "/test", nil) + if err != nil { + t.Fatal(err) + } + + // make the request + rr := httptest.NewRecorder() + h := http.HandlerFunc(handler) + h.ServeHTTP(rr, req) + + // status code + if status := rr.Code; status != expectedResponseCode { + t.Errorf("handler returned wrong status code: got '%d' want '%d'", status, expectedResponseCode) + } + + // response body + if rr.Body.String() != expectedResponseBody { + t.Errorf("handler returned unexpected body: got '%s' want '%s'", rr.Body.String(), expectedResponseBody) + } +} + func TestHandlerWithInvalidXResponseJson(t *testing.T) { invalidResponseBody := `{"foo":bar}` expectedResponseBody := `{"error":"x-response-json must be valid JSON"}` From 2862d3042b6c88ad738e7a50f3562fb8bfdb518c Mon Sep 17 00:00:00 2001 From: Nate Meyer <672246+notnmeyer@users.noreply.github.com> Date: Mon, 23 Oct 2023 14:49:14 -0700 Subject: [PATCH 2/4] simplify handler logic simplify handler logic --- main.go | 48 +++++++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/main.go b/main.go index f6e3acf..e169fe6 100644 --- a/main.go +++ b/main.go @@ -32,53 +32,43 @@ func main() { } func handler(w http.ResponseWriter, r *http.Request) { + responseBody, responseCode := buildResponse(r.Header) + + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(responseCode) + w.Write([]byte(responseBody)) +} + +func buildResponse(header map[string][]string) (string, int) { var ( - contentType = "application/json; charset=utf-8" responseBody string responseCode int ) - err := validateResponseBody(r.Header) - if err == nil { - responseBody = r.Header["X-Response-Json"][0] - } else { - responseBody = err.Error() - responseCode = http.StatusBadRequest - writeRequest(w, contentType, responseBody, responseCode) - return + responseBody, err := validateResponseBody(header) + if err != nil { + return err.Error(), http.StatusBadRequest + } - responseCode, err = validateResponseCode(r.Header) + responseCode, err = validateResponseCode(header) if err != nil { - responseBody = err.Error() - responseCode = http.StatusBadRequest - writeRequest(w, contentType, responseBody, responseCode) - return + return err.Error(), http.StatusBadRequest } - writeRequest(w, contentType, responseBody, responseCode) - - // w.Header().Set("Content-Type", contentType) - // w.WriteHeader(responseCode) - // w.Write([]byte(responseBody)) -} - -func writeRequest(w http.ResponseWriter, contentType string, responseBody string, responseCode int) { - w.Header().Set("Content-Type", contentType) - w.WriteHeader(responseCode) - w.Write([]byte(responseBody)) + return responseBody, responseCode } -func validateResponseBody(header map[string][]string) error { +func validateResponseBody(header map[string][]string) (string, error) { if _, exists := header["X-Response-Json"]; !exists { - return errorResponseFormatter("x-response-json must be set on the request") + return "", errorResponseFormatter("x-response-json must be set on the request") } if !isJSON(header["X-Response-Json"][0]) { - return errorResponseFormatter("x-response-json must be valid JSON") + return "", errorResponseFormatter("x-response-json must be valid JSON") } - return nil + return header["X-Response-Json"][0], nil } func validateResponseCode(header map[string][]string) (int, error) { From a191fb63c08b4a428fc3d6d55474b89d73191e2d Mon Sep 17 00:00:00 2001 From: Nate Meyer <672246+notnmeyer@users.noreply.github.com> Date: Mon, 23 Oct 2023 14:53:01 -0700 Subject: [PATCH 3/4] these dont need to be predeclared these dont need to be predeclared --- main.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/main.go b/main.go index e169fe6..1adf057 100644 --- a/main.go +++ b/main.go @@ -40,18 +40,13 @@ func handler(w http.ResponseWriter, r *http.Request) { } func buildResponse(header map[string][]string) (string, int) { - var ( - responseBody string - responseCode int - ) - responseBody, err := validateResponseBody(header) if err != nil { return err.Error(), http.StatusBadRequest } - responseCode, err = validateResponseCode(header) + responseCode, err := validateResponseCode(header) if err != nil { return err.Error(), http.StatusBadRequest } From c0e0e37292cfc04a040e304425303b2986d199b7 Mon Sep 17 00:00:00 2001 From: Nate Meyer <672246+notnmeyer@users.noreply.github.com> Date: Mon, 23 Oct 2023 14:53:09 -0700 Subject: [PATCH 4/4] rm obvious comments rm obvious comments --- main.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/main.go b/main.go index 1adf057..90ba69f 100644 --- a/main.go +++ b/main.go @@ -68,13 +68,11 @@ func validateResponseBody(header map[string][]string) (string, error) { func validateResponseCode(header map[string][]string) (int, error) { if val, exists := header["X-Response-Code"]; exists { - // verify its a number code, err := strconv.Atoi(val[0]) if err != nil { return http.StatusBadRequest, errorResponseFormatter("x-response-code must be a number") } - // verify it falls in the range of status codes if !(code >= 100 && code <= 599) { return http.StatusBadRequest, errorResponseFormatter("x-response-code must be between 100 and 599") } @@ -82,7 +80,6 @@ func validateResponseCode(header map[string][]string) (int, error) { return code, nil } - // if x-response-code was not supplied default to a 200 return http.StatusOK, nil }