aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2019-08-07 15:07:54 +0700
committerShulhan <ms@kilabit.info>2019-08-07 15:07:54 +0700
commitc4468122196b768c71c0abe4edc57265905decdf (patch)
treed64cbd64e3f42273b48e586ddefb67f3667ee250
parent3e38fa2394d9fce2552d03b610e3b24f896f366b (diff)
downloadpakakeh.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.go28
-rw-r--r--lib/http/server_test.go2
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 {