From b38da6ced02bc8830ff609e4228d108ba9c85c45 Mon Sep 17 00:00:00 2001 From: Vasiliy Tolstov Date: Fri, 27 Mar 2020 10:59:31 +0300 Subject: [PATCH] api/handler/rpc: process all methods and merge url params to json body (#1427) * api/handler/rpc: process all methods and merge url params to json body Signed-off-by: Vasiliy Tolstov * add merge json test Signed-off-by: Vasiliy Tolstov --- api/handler/rpc/rpc.go | 22 +++++++++++++++++++++- api/handler/rpc/rpc_test.go | 17 +++++++++++++++++ go.mod | 1 + go.sum | 2 ++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/api/handler/rpc/rpc.go b/api/handler/rpc/rpc.go index 3059207d..13c42070 100644 --- a/api/handler/rpc/rpc.go +++ b/api/handler/rpc/rpc.go @@ -8,6 +8,7 @@ import ( "strconv" "strings" + jsonpatch "github.com/evanphx/json-patch/v5" "github.com/joncalhoun/qson" "github.com/micro/go-micro/v2/api" "github.com/micro/go-micro/v2/api/handler" @@ -273,13 +274,32 @@ func requestPayload(r *http.Request) ([]byte, error) { if len(r.URL.RawQuery) > 0 { return qson.ToJSON(r.URL.RawQuery) } - case "PATCH", "POST": + case "PATCH", "POST", "PUT", "DELETE": + urlParams := []byte("{}") + bodyParams := []byte("{}") + var err error + if len(r.URL.RawQuery) > 0 { + if urlParams, err = qson.ToJSON(r.URL.RawQuery); err != nil { + return nil, err + } + } + buf := bufferPool.Get() defer bufferPool.Put(buf) if _, err := buf.ReadFrom(r.Body); err != nil { return nil, err } + if b := buf.Bytes(); len(b) > 0 { + bodyParams = b + } + + if out, err := jsonpatch.MergeMergePatches(urlParams, bodyParams); err == nil { + return out, nil + } + + //fallback to previous unknown behaviour return buf.Bytes(), nil + } return []byte{}, nil diff --git a/api/handler/rpc/rpc_test.go b/api/handler/rpc/rpc_test.go index ba943a4d..1b602f84 100644 --- a/api/handler/rpc/rpc_test.go +++ b/api/handler/rpc/rpc_test.go @@ -27,6 +27,23 @@ func TestRequestPayloadFromRequest(t *testing.T) { t.Fatal("Failed to marshal proto to JSON ", err) } + jsonUrlBytes := []byte(`{"key1":"val1","key2":"val2","name":"Test"}`) + + t.Run("extracting a json from a POST request with url params", func(t *testing.T) { + r, err := http.NewRequest("POST", "http://localhost/my/path?key1=val1&key2=val2", bytes.NewReader(jsonBytes)) + if err != nil { + t.Fatalf("Failed to created http.Request: %v", err) + } + + extByte, err := requestPayload(r) + if err != nil { + t.Fatalf("Failed to extract payload from request: %v", err) + } + if string(extByte) != string(jsonUrlBytes) { + t.Fatalf("Expected %v and %v to match", string(extByte), jsonUrlBytes) + } + }) + t.Run("extracting a proto from a POST request", func(t *testing.T) { r, err := http.NewRequest("POST", "http://localhost/my/path", bytes.NewReader(protoBytes)) if err != nil { diff --git a/go.mod b/go.mod index e862c8bb..88d291a8 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/ef-ds/deque v1.0.4-0.20190904040645-54cb57c252a1 + github.com/evanphx/json-patch/v5 v5.0.0 github.com/forestgiant/sliceutil v0.0.0-20160425183142-94783f95db6c github.com/fsnotify/fsnotify v1.4.7 github.com/fsouza/go-dockerclient v1.6.0 diff --git a/go.sum b/go.sum index 557728a2..07d12b66 100644 --- a/go.sum +++ b/go.sum @@ -129,6 +129,8 @@ github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch/v5 v5.0.0 h1:dKTrUeykyQwKb/kx7Z+4ukDs6l+4L41HqG1XHnhX7WE= +github.com/evanphx/json-patch/v5 v5.0.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/exoscale/egoscale v0.18.1/go.mod h1:Z7OOdzzTOz1Q1PjQXumlz9Wn/CddH0zSYdCF3rnBKXE= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=