Skip to content

Commit

Permalink
feat: add method property to responses (#123)
Browse files Browse the repository at this point in the history
```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
  • Loading branch information
llimllib authored Jun 18, 2023
1 parent 7e81a93 commit 1223a73
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 0 deletions.
5 changes: 5 additions & 0 deletions httpbin/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func (h *HTTPBin) Get(w http.ResponseWriter, r *http.Request) {
writeJSON(http.StatusOK, w, &noBodyResponse{
Args: r.URL.Query(),
Headers: getRequestHeaders(r),
Method: r.Method,
Origin: getClientIP(r),
URL: getURL(r).String(),
})
Expand All @@ -71,6 +72,7 @@ func (h *HTTPBin) RequestWithBody(w http.ResponseWriter, r *http.Request) {
resp := &bodyResponse{
Args: r.URL.Query(),
Headers: getRequestHeaders(r),
Method: r.Method,
Origin: getClientIP(r),
URL: getURL(r).String(),
}
Expand All @@ -93,6 +95,7 @@ func (h *HTTPBin) Gzip(w http.ResponseWriter, r *http.Request) {
mustMarshalJSON(gzw, &noBodyResponse{
Args: r.URL.Query(),
Headers: getRequestHeaders(r),
Method: r.Method,
Origin: getClientIP(r),
Gzipped: true,
})
Expand All @@ -115,6 +118,7 @@ func (h *HTTPBin) Deflate(w http.ResponseWriter, r *http.Request) {
mustMarshalJSON(zw, &noBodyResponse{
Args: r.URL.Query(),
Headers: getRequestHeaders(r),
Method: r.Method,
Origin: getClientIP(r),
Deflated: true,
})
Expand Down Expand Up @@ -749,6 +753,7 @@ func (h *HTTPBin) ETag(w http.ResponseWriter, r *http.Request) {
mustMarshalJSON(&buf, noBodyResponse{
Args: r.URL.Query(),
Headers: getRequestHeaders(r),
Method: r.Method,
Origin: getClientIP(r),
URL: getURL(r).String(),
})
Expand Down
32 changes: 32 additions & 0 deletions httpbin/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ func TestGet(t *testing.T) {
if 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 != "" {
t.Fatalf("expected empty origin, got %#v", resp.Origin)
}
Expand Down Expand Up @@ -179,6 +182,9 @@ func TestGet(t *testing.T) {
if 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) {
Expand Down Expand Up @@ -601,6 +607,9 @@ func testRequestWithBodyBinaryBody(t *testing.T, verb string, path string) {
if len(resp.Args) > 0 {
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 {
t.Fatalf("expected no form data, got %#v", resp.Form)
}
Expand Down Expand Up @@ -645,6 +654,9 @@ func testRequestWithBodyEmptyBody(t *testing.T, verb string, path string) {
if len(resp.Args) > 0 {
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 {
t.Fatalf("expected no form data, got %#v", resp.Form)
}
Expand Down Expand Up @@ -675,6 +687,9 @@ func testRequestWithBodyFormEncodedBody(t *testing.T, verb, path string) {
if len(resp.Args) > 0 {
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) {
t.Fatalf("expected %d form values, got %d", len(params), len(resp.Form))
}
Expand Down Expand Up @@ -731,6 +746,9 @@ func testRequestWithBodyFormEncodedBodyNoContentType(t *testing.T, verb, path st
if len(resp.Args) > 0 {
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 {
t.Fatalf("expected no form values, got %d", len(resp.Form))
}
Expand Down Expand Up @@ -781,6 +799,9 @@ func testRequestWithBodyMultiPartBody(t *testing.T, verb, path string) {
if len(resp.Args) > 0 {
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) {
t.Fatalf("expected %d form values, got %d", len(params), len(resp.Form))
}
Expand Down Expand Up @@ -846,6 +867,9 @@ func testRequestWithBodyJSON(t *testing.T, verb, path string) {
if len(resp.Args) > 0 {
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 {
t.Fatalf("expected no form values, got %d", len(resp.Form))
}
Expand Down Expand Up @@ -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())
}

if resp.Method != "POST" {
t.Fatalf("expected method to be POST, got %s", resp.Method)
}

if len(resp.Form) > 0 {
t.Fatalf("expected form data, got %#v", resp.Form)
}
Expand Down Expand Up @@ -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())
}

if resp.Method != "POST" {
t.Fatalf("expected method to be POST, got %s", resp.Method)
}

if len(resp.Form) != len(form) {
t.Fatalf("expected %d form values, got %d", len(form), len(resp.Form))
}
Expand Down
2 changes: 2 additions & 0 deletions httpbin/responses.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type userAgentResponse struct {
type noBodyResponse struct {
Args url.Values `json:"args"`
Headers http.Header `json:"headers"`
Method string `json:"method"`
Origin string `json:"origin"`
URL string `json:"url"`

Expand All @@ -39,6 +40,7 @@ type noBodyResponse struct {
type bodyResponse struct {
Args url.Values `json:"args"`
Headers http.Header `json:"headers"`
Method string `json:"method"`
Origin string `json:"origin"`
URL string `json:"url"`

Expand Down

0 comments on commit 1223a73

Please sign in to comment.