Skip to content

Commit

Permalink
feat(decoderx): support decoding GET requests (#318)
Browse files Browse the repository at this point in the history
  • Loading branch information
aeneasr authored Apr 6, 2021
1 parent a0286f0 commit 44a3b19
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 7 deletions.
27 changes: 20 additions & 7 deletions decoderx/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,14 @@ func (t *HTTP) validateRequest(r *http.Request, c *httpDecoderOptions) error {
return errors.WithStack(herodot.ErrBadRequest.WithReasonf(`Unable to decode body because HTTP Request Method was "%s" but only %v are supported.`, method, c.allowedHTTPMethods))
}

if r.ContentLength == 0 {
return errors.WithStack(herodot.ErrBadRequest.WithReasonf(`Unable to decode HTTP Request Body because its HTTP Header "Content-Length" is zero.`))
}
if method != "GET" {
if r.ContentLength == 0 && method != "GET" {
return errors.WithStack(herodot.ErrBadRequest.WithReasonf(`Unable to decode HTTP Request Body because its HTTP Header "Content-Length" is zero.`))
}

if !httpx.HasContentType(r, c.allowedContentTypes...) {
return errors.WithStack(herodot.ErrBadRequest.WithReasonf(`HTTP %s Request used unknown HTTP Header "Content-Type: %s", only %v are supported.`, method, r.Header.Get("Content-Type"), c.allowedContentTypes))
if !httpx.HasContentType(r, c.allowedContentTypes...) {
return errors.WithStack(herodot.ErrBadRequest.WithReasonf(`HTTP %s Request used unknown HTTP Header "Content-Type: %s", only %v are supported.`, method, r.Header.Get("Content-Type"), c.allowedContentTypes))
}
}

return nil
Expand Down Expand Up @@ -256,7 +258,9 @@ func (t *HTTP) Decode(r *http.Request, destination interface{}, opts ...HTTPDeco
return err
}

if httpx.HasContentType(r, httpContentTypeJSON) {
if r.Method == "GET" {
return t.decodeForm(r, destination, c)
} else if httpx.HasContentType(r, httpContentTypeJSON) {
if c.expectJSONFlattened {
return t.decodeJSONForm(r, destination, c)
}
Expand All @@ -269,6 +273,10 @@ func (t *HTTP) Decode(r *http.Request, destination interface{}, opts ...HTTPDeco
}

func (t *HTTP) requestBody(r *http.Request, o *httpDecoderOptions) (reader io.ReadCloser, err error) {
if strings.ToUpper(r.Method) == "GET" {
return ioutil.NopCloser(bytes.NewBufferString(r.URL.Query().Encode())), nil
}

if !o.keepRequestBody {
return r.Body, nil
}
Expand Down Expand Up @@ -354,7 +362,12 @@ func (t *HTTP) decodeForm(r *http.Request, destination interface{}, o *httpDecod
return errors.WithStack(herodot.ErrInternalServerError.WithTrace(err).WithReasonf("Unable to prepare JSON Schema for HTTP Post Body Form parsing: %s", err).WithDebugf("%+v", err))
}

raw, err := t.decodeURLValues(r.PostForm, paths, o)
values := r.PostForm
if r.Method == "GET" {
values = r.Form
}

raw, err := t.decodeURLValues(values, paths, o)
if err != nil {
return err
}
Expand Down
22 changes: 22 additions & 0 deletions decoderx/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,28 @@ func TestHTTPFormDecoder(t *testing.T) {
"newsletter": true,
"consent": false,
"ratio": 0.9
}`,
},
{
d: "should pass JSON request GET request",
request: newRequest(t, "GET", "/?"+url.Values{
"name.first": {"Aeneas"},
"name.last": {"Rekkas"},
"age": {"29"},
"ratio": {"0.9"},
"consent": {"false"},
"newsletter": {"true"},
}.Encode(), nil, ""),
options: []HTTPDecoderOption{
HTTPJSONSchemaCompiler("stub/person.json", nil),
HTTPDecoderAllowedMethods("GET"),
},
expected: `{
"name": {"first": "Aeneas", "last": "Rekkas"},
"age": 29,
"newsletter": true,
"consent": false,
"ratio": 0.9
}`,
},
{
Expand Down

0 comments on commit 44a3b19

Please sign in to comment.