From 7ac12a8030da7cc0f403b54ebc56c03553a5e3eb Mon Sep 17 00:00:00 2001 From: Will McCutchen <will@mccutch.org> Date: Sun, 25 Jun 2017 21:25:20 -0700 Subject: [PATCH] Ensure request body is always captured --- httpbin/handlers_test.go | 4 +--- httpbin/helpers.go | 33 +++++++++++++++++++-------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/httpbin/handlers_test.go b/httpbin/handlers_test.go index f3835fb..3639e96 100644 --- a/httpbin/handlers_test.go +++ b/httpbin/handlers_test.go @@ -502,15 +502,13 @@ func TestPost__JSON(t *testing.T) { t.Fatalf("failed to unmarshal body %s from JSON: %s", w.Body, err) } + assertBytesEqual(t, resp.Data, inputBody) if len(resp.Args) > 0 { t.Fatalf("expected no query params, got %#v", resp.Args) } if len(resp.Form) != 0 { t.Fatalf("expected no form values, got %d", len(resp.Form)) } - if resp.Data != nil { - t.Fatalf("expected no data, got %#v", resp.Data) - } // Need to re-marshall just the JSON field from the response in order to // re-unmarshall it into our expected type diff --git a/httpbin/helpers.go b/httpbin/helpers.go index f513e39..e769e11 100644 --- a/httpbin/helpers.go +++ b/httpbin/helpers.go @@ -1,6 +1,7 @@ package httpbin import ( + "bytes" "crypto/sha1" "encoding/json" "errors" @@ -78,13 +79,25 @@ func parseBody(w http.ResponseWriter, r *http.Request, resp *bodyResponse) error if r.Body == nil { return nil } - defer r.Body.Close() + + // Always set resp.Data to the incoming request body, in case we don't know + // how to handle the content type + body, err := ioutil.ReadAll(r.Body) + if err != nil { + r.Body.Close() + return err + } + resp.Data = body + + // After reading the body to populate resp.Data, we need to re-wrap it in + // an io.Reader for further processing below + r.Body.Close() + r.Body = ioutil.NopCloser(bytes.NewBuffer(body)) ct := r.Header.Get("Content-Type") switch { case ct == "application/x-www-form-urlencoded": - err := r.ParseForm() - if err != nil { + if err := r.ParseForm(); err != nil { return err } resp.Form = r.PostForm @@ -92,24 +105,16 @@ func parseBody(w http.ResponseWriter, r *http.Request, resp *bodyResponse) error // The memory limit here only restricts how many parts will be kept in // memory before overflowing to disk: // http://localhost:8080/pkg/net/http/#Request.ParseMultipartForm - err := r.ParseMultipartForm(1024 * 1024) - if err != nil { + if err := r.ParseMultipartForm(1024); err != nil { return err } resp.Form = r.PostForm case strings.HasPrefix(ct, "application/json"): - dec := json.NewDecoder(r.Body) - err := dec.Decode(&resp.JSON) - if err != nil { - return err - } - default: - data, err := ioutil.ReadAll(r.Body) - if err != nil { + if err := json.NewDecoder(r.Body).Decode(&resp.JSON); err != nil { return err } - resp.Data = data } + return nil } -- GitLab