From b9f4b1f59a798cbcfe8cb800036d1db753b71154 Mon Sep 17 00:00:00 2001 From: Will McCutchen <will@mccutch.org> Date: Mon, 10 Oct 2016 21:22:15 -0700 Subject: [PATCH] Add /response-headers handler --- httpbin/handlers.go | 20 +++++++++++ httpbin/handlers_test.go | 71 ++++++++++++++++++++++++++++++++++++++++ httpbin/httpbin.go | 1 + 3 files changed, 92 insertions(+) diff --git a/httpbin/handlers.go b/httpbin/handlers.go index baccdfa..384abbe 100644 --- a/httpbin/handlers.go +++ b/httpbin/handlers.go @@ -176,3 +176,23 @@ func (h *HTTPBin) Status(w http.ResponseWriter, r *http.Request) { w.WriteHeader(code) } } + +// ResponseHeaders responds with a map of header values +func (h *HTTPBin) ResponseHeaders(w http.ResponseWriter, r *http.Request) { + args, err := url.ParseQuery(r.URL.RawQuery) + if err != nil { + http.Error(w, fmt.Sprintf("error parsing query params: %s", err), http.StatusBadRequest) + return + } + + for k, vs := range args { + for _, v := range vs { + w.Header().Add(http.CanonicalHeaderKey(k), v) + } + } + body, _ := json.Marshal(args) + if contentType := w.Header().Get("Content-Type"); contentType == "" { + w.Header().Set("Content-Type", "application/json; encoding=utf-8") + } + w.Write(body) +} diff --git a/httpbin/handlers_test.go b/httpbin/handlers_test.go index 11bc1ff..7545812 100644 --- a/httpbin/handlers_test.go +++ b/httpbin/handlers_test.go @@ -109,6 +109,30 @@ func TestGet__Basic(t *testing.T) { } } +func TestGet__WithParams(t *testing.T) { + params := url.Values{} + params.Set("foo", "foo") + params.Add("bar", "bar1") + params.Add("bar", "bar2") + + r, _ := http.NewRequest("GET", fmt.Sprintf("/get?%s", params.Encode()), nil) + w := httptest.NewRecorder() + handler.ServeHTTP(w, r) + + assertStatusCode(t, w, http.StatusOK) + assertContentType(t, w, "application/json; encoding=utf-8") + + var resp *bodyResponse + err := json.Unmarshal(w.Body.Bytes(), &resp) + if err != nil { + t.Fatalf("failed to unmarshal body %s from JSON: %s", w.Body, err) + } + + if resp.Args.Encode() != params.Encode() { + t.Fatalf("args mismatch: %s != %s", resp.Args.Encode(), params.Encode()) + } +} + func TestGet__OnlyAllowsGets(t *testing.T) { r, _ := http.NewRequest("POST", "/get", nil) w := httptest.NewRecorder() @@ -461,3 +485,50 @@ func TestStatus__Simple(t *testing.T) { } } } + +func TestResponseHeaders(t *testing.T) { + headers := map[string][]string{ + "Content-Type": {"test/test"}, + "Foo": {"foo"}, + "Bar": {"bar1, bar2"}, + } + + params := url.Values{} + for k, vs := range headers { + for _, v := range vs { + params.Add(k, v) + } + } + + r, _ := http.NewRequest("GET", fmt.Sprintf("/response-headers?%s", params.Encode()), nil) + w := httptest.NewRecorder() + handler.ServeHTTP(w, r) + + assertStatusCode(t, w, http.StatusOK) + + for k, expectedValues := range headers { + values, ok := w.HeaderMap[k] + if !ok { + t.Fatalf("expected header %s in response headers", k) + } + if !reflect.DeepEqual(values, expectedValues) { + t.Fatalf("expected key values %#v for header %s, got %#v", expectedValues, k, values) + } + } + + resp := &http.Header{} + err := json.Unmarshal(w.Body.Bytes(), resp) + if err != nil { + t.Fatalf("failed to unmarshal body %s from JSON: %s", w.Body, err) + } + + for k, expectedValues := range headers { + values, ok := (*resp)[k] + if !ok { + t.Fatalf("expected header %s in response body", k) + } + if !reflect.DeepEqual(values, expectedValues) { + t.Fatalf("expected key values %#v for header %s, got %#v", expectedValues, k, values) + } + } +} diff --git a/httpbin/httpbin.go b/httpbin/httpbin.go index 83a6d26..48e7214 100644 --- a/httpbin/httpbin.go +++ b/httpbin/httpbin.go @@ -65,6 +65,7 @@ func (h *HTTPBin) Handler() http.Handler { mux.HandleFunc("/user-agent", h.UserAgent) mux.HandleFunc("/headers", h.Headers) mux.HandleFunc("/status/", h.Status) + mux.HandleFunc("/response-headers", h.ResponseHeaders) return logger(cors(mux)) } -- GitLab