From d0f764cc76445cb69d4656561406a5e14a7cb5bd Mon Sep 17 00:00:00 2001
From: Will McCutchen <will@mccutch.org>
Date: Fri, 14 Oct 2016 23:13:07 -0700
Subject: [PATCH] Add /cookies endpoint

---
 httpbin/handlers.go      | 13 +++++++++++
 httpbin/handlers_test.go | 47 ++++++++++++++++++++++++++++++++++++++++
 httpbin/httpbin.go       |  4 ++++
 3 files changed, 64 insertions(+)

diff --git a/httpbin/handlers.go b/httpbin/handlers.go
index 2d856e6..5f8c8af 100644
--- a/httpbin/handlers.go
+++ b/httpbin/handlers.go
@@ -241,3 +241,16 @@ func (h *HTTPBin) RelativeRedirect(w http.ResponseWriter, r *http.Request) {
 func (h *HTTPBin) AbsoluteRedirect(w http.ResponseWriter, r *http.Request) {
 	doRedirect(w, r, false)
 }
+
+// Cookies responds with the cookies in the incoming request
+func (h *HTTPBin) Cookies(w http.ResponseWriter, r *http.Request) {
+	resp := cookiesResponse{}
+	for _, c := range r.Cookies() {
+		if _, found := resp[c.Name]; !found {
+			resp[c.Name] = []string{}
+		}
+		resp[c.Name] = append(resp[c.Name], c.Value)
+	}
+	body, _ := json.Marshal(resp)
+	writeJSON(w, body, http.StatusOK)
+}
diff --git a/httpbin/handlers_test.go b/httpbin/handlers_test.go
index 1793749..5cc3be9 100644
--- a/httpbin/handlers_test.go
+++ b/httpbin/handlers_test.go
@@ -808,3 +808,50 @@ func TestRedirects(t *testing.T) {
 		})
 	}
 }
+
+func TestCookies(t *testing.T) {
+	testCookies := func(t *testing.T, cookies cookiesResponse) {
+		r, _ := http.NewRequest("GET", "/cookies", nil)
+		for k, vs := range cookies {
+			for _, v := range vs {
+				r.AddCookie(&http.Cookie{
+					Name:  k,
+					Value: v,
+				})
+			}
+		}
+		w := httptest.NewRecorder()
+		handler.ServeHTTP(w, r)
+
+		assertStatusCode(t, w, http.StatusOK)
+		assertContentType(t, w, jsonContentType)
+
+		resp := cookiesResponse{}
+		err := json.Unmarshal(w.Body.Bytes(), &resp)
+		if err != nil {
+			t.Fatalf("failed to unmarshal body %s from JSON: %s", w.Body, err)
+		}
+
+		if !reflect.DeepEqual(cookies, resp) {
+			t.Fatalf("expected cookies %#v, got %#v", cookies, resp)
+		}
+	}
+
+	t.Run("no cookies", func(t *testing.T) {
+		testCookies(t, cookiesResponse{})
+	})
+
+	t.Run("single cookies", func(t *testing.T) {
+		testCookies(t, cookiesResponse{
+			"k1": {"v1"},
+			"k2": {"v2"},
+		})
+	})
+
+	t.Run("duplicate cookies", func(t *testing.T) {
+		testCookies(t, cookiesResponse{
+			"k1": {"v1"},
+			"k2": {"v2a", "v2b"},
+		})
+	})
+}
diff --git a/httpbin/httpbin.go b/httpbin/httpbin.go
index cd1a1aa..7080e25 100644
--- a/httpbin/httpbin.go
+++ b/httpbin/httpbin.go
@@ -39,6 +39,8 @@ type bodyResponse struct {
 	JSON  interface{}         `json:"json"`
 }
 
+type cookiesResponse map[string][]string
+
 // Options are used to configure HTTPBin
 type Options struct {
 	MaxMemory int64
@@ -73,6 +75,8 @@ func (h *HTTPBin) Handler() http.Handler {
 	mux.HandleFunc("/relative-redirect/", h.RelativeRedirect)
 	mux.HandleFunc("/absolute-redirect/", h.AbsoluteRedirect)
 
+	mux.HandleFunc("/cookies", h.Cookies)
+
 	// Make sure our ServeMux doesn't "helpfully" redirect these invalid
 	// endpoints by adding a trailing slash. See the ServeMux docs for more
 	// info: https://golang.org/pkg/net/http/#ServeMux
-- 
GitLab