Skip to content
Snippets Groups Projects
Unverified Commit 1223a736 authored by Bill Mill's avatar Bill Mill Committed by GitHub
Browse files

feat: add method property to responses (#123)

```console
# before: httpbingo lacks the "method" field but httpbin.org has it
$ curl -s https://httpbingo.org/anything | jq .method                                                                                                        9:31PM
null
$ curl -s https://httpbin.org/anything | jq .method
"GET"

# after: httpbingo has the method field!
$ curl -s http://0.0.0.0:8080/anything | jq .method
"GET"
```

This was mentioned in #6, but then not listed in #91

- I took the highly technical testing approach of adding a test for
`Method` anywhere in `handlers_test.go` that mentioned `Args`; do you
desire more tests? fewer tests?
- Anywhere else I should add this field that I didn't already?

For what it's worth, I discovered this when working on upgrading the
testing for our [httpsnippet
library](https://github.com/readmeio/httpsnippet); I wanted to use
`go-httpbin` but our tests expect the method field to be present in the
responses
parent 7e81a936
No related branches found
No related tags found
No related merge requests found
...@@ -47,6 +47,7 @@ func (h *HTTPBin) Get(w http.ResponseWriter, r *http.Request) { ...@@ -47,6 +47,7 @@ func (h *HTTPBin) Get(w http.ResponseWriter, r *http.Request) {
writeJSON(http.StatusOK, w, &noBodyResponse{ writeJSON(http.StatusOK, w, &noBodyResponse{
Args: r.URL.Query(), Args: r.URL.Query(),
Headers: getRequestHeaders(r), Headers: getRequestHeaders(r),
Method: r.Method,
Origin: getClientIP(r), Origin: getClientIP(r),
URL: getURL(r).String(), URL: getURL(r).String(),
}) })
...@@ -71,6 +72,7 @@ func (h *HTTPBin) RequestWithBody(w http.ResponseWriter, r *http.Request) { ...@@ -71,6 +72,7 @@ func (h *HTTPBin) RequestWithBody(w http.ResponseWriter, r *http.Request) {
resp := &bodyResponse{ resp := &bodyResponse{
Args: r.URL.Query(), Args: r.URL.Query(),
Headers: getRequestHeaders(r), Headers: getRequestHeaders(r),
Method: r.Method,
Origin: getClientIP(r), Origin: getClientIP(r),
URL: getURL(r).String(), URL: getURL(r).String(),
} }
...@@ -93,6 +95,7 @@ func (h *HTTPBin) Gzip(w http.ResponseWriter, r *http.Request) { ...@@ -93,6 +95,7 @@ func (h *HTTPBin) Gzip(w http.ResponseWriter, r *http.Request) {
mustMarshalJSON(gzw, &noBodyResponse{ mustMarshalJSON(gzw, &noBodyResponse{
Args: r.URL.Query(), Args: r.URL.Query(),
Headers: getRequestHeaders(r), Headers: getRequestHeaders(r),
Method: r.Method,
Origin: getClientIP(r), Origin: getClientIP(r),
Gzipped: true, Gzipped: true,
}) })
...@@ -115,6 +118,7 @@ func (h *HTTPBin) Deflate(w http.ResponseWriter, r *http.Request) { ...@@ -115,6 +118,7 @@ func (h *HTTPBin) Deflate(w http.ResponseWriter, r *http.Request) {
mustMarshalJSON(zw, &noBodyResponse{ mustMarshalJSON(zw, &noBodyResponse{
Args: r.URL.Query(), Args: r.URL.Query(),
Headers: getRequestHeaders(r), Headers: getRequestHeaders(r),
Method: r.Method,
Origin: getClientIP(r), Origin: getClientIP(r),
Deflated: true, Deflated: true,
}) })
...@@ -749,6 +753,7 @@ func (h *HTTPBin) ETag(w http.ResponseWriter, r *http.Request) { ...@@ -749,6 +753,7 @@ func (h *HTTPBin) ETag(w http.ResponseWriter, r *http.Request) {
mustMarshalJSON(&buf, noBodyResponse{ mustMarshalJSON(&buf, noBodyResponse{
Args: r.URL.Query(), Args: r.URL.Query(),
Headers: getRequestHeaders(r), Headers: getRequestHeaders(r),
Method: r.Method,
Origin: getClientIP(r), Origin: getClientIP(r),
URL: getURL(r).String(), URL: getURL(r).String(),
}) })
......
...@@ -150,6 +150,9 @@ func TestGet(t *testing.T) { ...@@ -150,6 +150,9 @@ func TestGet(t *testing.T) {
if resp.Args.Encode() != "" { if resp.Args.Encode() != "" {
t.Fatalf("expected empty args, got %s", resp.Args.Encode()) t.Fatalf("expected empty args, got %s", resp.Args.Encode())
} }
if resp.Method != "GET" {
t.Fatalf("expected method to be GET, got %s", resp.Method)
}
if resp.Origin != "" { if resp.Origin != "" {
t.Fatalf("expected empty origin, got %#v", resp.Origin) t.Fatalf("expected empty origin, got %#v", resp.Origin)
} }
...@@ -179,6 +182,9 @@ func TestGet(t *testing.T) { ...@@ -179,6 +182,9 @@ func TestGet(t *testing.T) {
if resp.Args.Encode() != params.Encode() { if resp.Args.Encode() != params.Encode() {
t.Fatalf("args mismatch: %s != %s", resp.Args.Encode(), params.Encode()) t.Fatalf("args mismatch: %s != %s", resp.Args.Encode(), params.Encode())
} }
if resp.Method != "GET" {
t.Fatalf("expected method to be GET, got %s", resp.Method)
}
}) })
t.Run("only_allows_gets", func(t *testing.T) { t.Run("only_allows_gets", func(t *testing.T) {
...@@ -601,6 +607,9 @@ func testRequestWithBodyBinaryBody(t *testing.T, verb string, path string) { ...@@ -601,6 +607,9 @@ func testRequestWithBodyBinaryBody(t *testing.T, verb string, path string) {
if len(resp.Args) > 0 { if len(resp.Args) > 0 {
t.Fatalf("expected no query params, got %#v", resp.Args) t.Fatalf("expected no query params, got %#v", resp.Args)
} }
if resp.Method != verb {
t.Fatalf("expected method to be %s, got %s", verb, resp.Method)
}
if len(resp.Form) > 0 { if len(resp.Form) > 0 {
t.Fatalf("expected no form data, got %#v", resp.Form) t.Fatalf("expected no form data, got %#v", resp.Form)
} }
...@@ -645,6 +654,9 @@ func testRequestWithBodyEmptyBody(t *testing.T, verb string, path string) { ...@@ -645,6 +654,9 @@ func testRequestWithBodyEmptyBody(t *testing.T, verb string, path string) {
if len(resp.Args) > 0 { if len(resp.Args) > 0 {
t.Fatalf("expected no query params, got %#v", resp.Args) t.Fatalf("expected no query params, got %#v", resp.Args)
} }
if resp.Method != verb {
t.Fatalf("expected method to be %s, got %s", verb, resp.Method)
}
if len(resp.Form) > 0 { if len(resp.Form) > 0 {
t.Fatalf("expected no form data, got %#v", resp.Form) t.Fatalf("expected no form data, got %#v", resp.Form)
} }
...@@ -675,6 +687,9 @@ func testRequestWithBodyFormEncodedBody(t *testing.T, verb, path string) { ...@@ -675,6 +687,9 @@ func testRequestWithBodyFormEncodedBody(t *testing.T, verb, path string) {
if len(resp.Args) > 0 { if len(resp.Args) > 0 {
t.Fatalf("expected no query params, got %#v", resp.Args) t.Fatalf("expected no query params, got %#v", resp.Args)
} }
if resp.Method != verb {
t.Fatalf("expected method to be %s, got %s", verb, resp.Method)
}
if len(resp.Form) != len(params) { if len(resp.Form) != len(params) {
t.Fatalf("expected %d form values, got %d", len(params), len(resp.Form)) t.Fatalf("expected %d form values, got %d", len(params), len(resp.Form))
} }
...@@ -731,6 +746,9 @@ func testRequestWithBodyFormEncodedBodyNoContentType(t *testing.T, verb, path st ...@@ -731,6 +746,9 @@ func testRequestWithBodyFormEncodedBodyNoContentType(t *testing.T, verb, path st
if len(resp.Args) > 0 { if len(resp.Args) > 0 {
t.Fatalf("expected no query params, got %#v", resp.Args) t.Fatalf("expected no query params, got %#v", resp.Args)
} }
if resp.Method != verb {
t.Fatalf("expected method to be %s, got %s", verb, resp.Method)
}
if len(resp.Form) != 0 { if len(resp.Form) != 0 {
t.Fatalf("expected no form values, got %d", len(resp.Form)) t.Fatalf("expected no form values, got %d", len(resp.Form))
} }
...@@ -781,6 +799,9 @@ func testRequestWithBodyMultiPartBody(t *testing.T, verb, path string) { ...@@ -781,6 +799,9 @@ func testRequestWithBodyMultiPartBody(t *testing.T, verb, path string) {
if len(resp.Args) > 0 { if len(resp.Args) > 0 {
t.Fatalf("expected no query params, got %#v", resp.Args) t.Fatalf("expected no query params, got %#v", resp.Args)
} }
if resp.Method != verb {
t.Fatalf("expected method to be %s, got %s", verb, resp.Method)
}
if len(resp.Form) != len(params) { if len(resp.Form) != len(params) {
t.Fatalf("expected %d form values, got %d", len(params), len(resp.Form)) t.Fatalf("expected %d form values, got %d", len(params), len(resp.Form))
} }
...@@ -846,6 +867,9 @@ func testRequestWithBodyJSON(t *testing.T, verb, path string) { ...@@ -846,6 +867,9 @@ func testRequestWithBodyJSON(t *testing.T, verb, path string) {
if len(resp.Args) > 0 { if len(resp.Args) > 0 {
t.Fatalf("expected no query params, got %#v", resp.Args) t.Fatalf("expected no query params, got %#v", resp.Args)
} }
if resp.Method != verb {
t.Fatalf("expected method to be %s, got %s", verb, resp.Method)
}
if len(resp.Form) != 0 { if len(resp.Form) != 0 {
t.Fatalf("expected no form values, got %d", len(resp.Form)) t.Fatalf("expected no form values, got %d", len(resp.Form))
} }
...@@ -905,6 +929,10 @@ func testRequestWithBodyQueryParams(t *testing.T, verb, path string) { ...@@ -905,6 +929,10 @@ func testRequestWithBodyQueryParams(t *testing.T, verb, path string) {
t.Fatalf("expected args = %#v in response, got %#v", params.Encode(), resp.Args.Encode()) t.Fatalf("expected args = %#v in response, got %#v", params.Encode(), resp.Args.Encode())
} }
if resp.Method != "POST" {
t.Fatalf("expected method to be POST, got %s", resp.Method)
}
if len(resp.Form) > 0 { if len(resp.Form) > 0 {
t.Fatalf("expected form data, got %#v", resp.Form) t.Fatalf("expected form data, got %#v", resp.Form)
} }
...@@ -942,6 +970,10 @@ func testRequestWithBodyQueryParamsAndBody(t *testing.T, verb, path string) { ...@@ -942,6 +970,10 @@ func testRequestWithBodyQueryParamsAndBody(t *testing.T, verb, path string) {
t.Fatalf("expected args = %#v in response, got %#v", args.Encode(), resp.Args.Encode()) t.Fatalf("expected args = %#v in response, got %#v", args.Encode(), resp.Args.Encode())
} }
if resp.Method != "POST" {
t.Fatalf("expected method to be POST, got %s", resp.Method)
}
if len(resp.Form) != len(form) { if len(resp.Form) != len(form) {
t.Fatalf("expected %d form values, got %d", len(form), len(resp.Form)) t.Fatalf("expected %d form values, got %d", len(form), len(resp.Form))
} }
......
...@@ -27,6 +27,7 @@ type userAgentResponse struct { ...@@ -27,6 +27,7 @@ type userAgentResponse struct {
type noBodyResponse struct { type noBodyResponse struct {
Args url.Values `json:"args"` Args url.Values `json:"args"`
Headers http.Header `json:"headers"` Headers http.Header `json:"headers"`
Method string `json:"method"`
Origin string `json:"origin"` Origin string `json:"origin"`
URL string `json:"url"` URL string `json:"url"`
...@@ -39,6 +40,7 @@ type noBodyResponse struct { ...@@ -39,6 +40,7 @@ type noBodyResponse struct {
type bodyResponse struct { type bodyResponse struct {
Args url.Values `json:"args"` Args url.Values `json:"args"`
Headers http.Header `json:"headers"` Headers http.Header `json:"headers"`
Method string `json:"method"`
Origin string `json:"origin"` Origin string `json:"origin"`
URL string `json:"url"` URL string `json:"url"`
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment