diff options
| author | Shulhan <ms@kilabit.info> | 2019-08-07 15:07:54 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2019-08-07 15:07:54 +0700 |
| commit | c4468122196b768c71c0abe4edc57265905decdf (patch) | |
| tree | d64cbd64e3f42273b48e586ddefb67f3667ee250 | |
| parent | 3e38fa2394d9fce2552d03b610e3b24f896f366b (diff) | |
| download | pakakeh.go-c4468122196b768c71c0abe4edc57265905decdf.tar.xz | |
lib/http: make the request body always available even after ParseForm()
Previously, if the request type is query, form, or JSON, we call the
ParseForm() to let the http.Request read the Body POST form data and fill
the Form and/or PostForm fields. This method will cause the request
Body will become empty since its already read and closed.
One of use case of POST with form data is to check the integrity of POST
body using checksum, which is not possible using only ParseForm().
This commit read all the body first into reqBody and recreate the request
Body back using ioutil.NopCloser and bytes.Buffer.
| -rw-r--r-- | lib/http/endpoint.go | 28 | ||||
| -rw-r--r-- | lib/http/server_test.go | 2 |
2 files changed, 13 insertions, 17 deletions
diff --git a/lib/http/endpoint.go b/lib/http/endpoint.go index 2e9da168..db80990c 100644 --- a/lib/http/endpoint.go +++ b/lib/http/endpoint.go @@ -5,6 +5,7 @@ package http import ( + "bytes" "fmt" "io/ioutil" "log" @@ -39,29 +40,24 @@ type Endpoint struct { func (ep *Endpoint) call(res http.ResponseWriter, req *http.Request, evaluators []Evaluator, ) { - var ( - e error - reqBody []byte - ) + reqBody, e := ioutil.ReadAll(req.Body) + if e != nil { + log.Printf("endpoint.call: " + e.Error()) + res.WriteHeader(http.StatusBadRequest) + return + } - switch ep.RequestType { - case RequestTypeForm: - e = req.ParseForm() + req.Body.Close() + req.Body = ioutil.NopCloser(bytes.NewBuffer(reqBody)) - case RequestTypeQuery: + switch ep.RequestType { + case RequestTypeForm, RequestTypeQuery, RequestTypeJSON: e = req.ParseForm() case RequestTypeMultipartForm: e = req.ParseMultipartForm(0) - - case RequestTypeJSON: - e = req.ParseForm() - if e != nil { - res.WriteHeader(http.StatusBadRequest) - return - } - reqBody, e = ioutil.ReadAll(req.Body) } + if e != nil { log.Printf("endpoint.call: %d %s %s %s\n", http.StatusBadRequest, req.Method, req.URL.Path, e) diff --git a/lib/http/server_test.go b/lib/http/server_test.go index 04bf9b31..89055608 100644 --- a/lib/http/server_test.go +++ b/lib/http/server_test.go @@ -419,7 +419,7 @@ func TestRegisterPost(t *testing.T) { expBody: `map[k:[vv v]] map[k:[vv]] <nil> -`, +k=vv`, }} for _, c := range cases { |
