From 305d2205532d47ab086f13b929dbcf2ccf95f1bc Mon Sep 17 00:00:00 2001 From: byene0923 Date: Thu, 15 Apr 2021 14:44:57 +0800 Subject: [PATCH 1/6] improve code quality --- server/web/tree.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/web/tree.go b/server/web/tree.go index 79f3da7a..2a8ca489 100644 --- a/server/web/tree.go +++ b/server/web/tree.go @@ -294,8 +294,8 @@ func (t *Tree) Match(pattern string, ctx *context.Context) (runObject interface{ func (t *Tree) match(treePattern string, pattern string, wildcardValues []string, ctx *context.Context) (runObject interface{}) { if len(pattern) > 0 { - i := 0 - for ; i < len(pattern) && pattern[i] == '/'; i++ { + i, l := 0, len(pattern) + for ; i < l && pattern[i] == '/'; i++ { } pattern = pattern[i:] } From 69e50c6675495f9c5a99eb033ce644b70c532a5e Mon Sep 17 00:00:00 2001 From: byene0923 Date: Thu, 15 Apr 2021 15:30:08 +0800 Subject: [PATCH 2/6] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4712dc6..cc660b72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ - Feat: add token bucket ratelimit filter [4508](https://github.com/beego/beego/pull/4508) - Improve: Avoid ignoring mistakes that need attention [4548](https://github.com/beego/beego/pull/4548) - Integration: DeepSource [4560](https://github.com/beego/beego/pull/4560) +- Integration: Remove unnecessary function call [4577](https://github.com/beego/beego/pull/4577) From 8b92ed65049fcac384ae80c0eaa706481c347f41 Mon Sep 17 00:00:00 2001 From: byene0923 Date: Fri, 16 Apr 2021 22:12:06 +0800 Subject: [PATCH 3/6] Proposal:Add Bind() method for web.Controller --- CHANGELOG.md | 4 +-- server/web/controller.go | 52 +++++++++++++++++++++++++++++++++++ server/web/controller_test.go | 50 +++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9417ee6..59efffc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,8 +33,8 @@ - Improve: Avoid ignoring mistakes that need attention [4548](https://github.com/beego/beego/pull/4548) - Integration: DeepSource [4560](https://github.com/beego/beego/pull/4560) - Integration: Remove unnecessary function call [4577](https://github.com/beego/beego/pull/4577) - - +- Feature issue #4402 finish router get example. [4416](https://github.com/beego/beego/pull/4416) +- Proposal: Add Bind() method for web.Controller [4491](https://github.com/beego/beego/issues/4491) ## Fix Sonar - [4473](https://github.com/beego/beego/pull/4473) diff --git a/server/web/controller.go b/server/web/controller.go index 32378829..eb8b9c68 100644 --- a/server/web/controller.go +++ b/server/web/controller.go @@ -17,8 +17,12 @@ package web import ( "bytes" context2 "context" + "encoding/json" + "encoding/xml" "errors" "fmt" + "github.com/gogo/protobuf/proto" + "gopkg.in/yaml.v2" "html/template" "io" "mime/multipart" @@ -147,6 +151,12 @@ type ControllerInterface interface { CheckXSRFCookie() bool HandlerFunc(fn string) bool URLMapping() + Bind(obj interface{}) error + BindJson(obj interface{}) error + BindXML(obj interface{}) error + BindForm(obj interface{}) error + BindProtobuf(obj interface{}) error + BindYAML(obj interface{}) error } // Init generates default values of controller operations. @@ -239,6 +249,48 @@ func (c *Controller) HandlerFunc(fnname string) bool { // URLMapping register the internal Controller router. func (c *Controller) URLMapping() {} +func (c *Controller) Bind(obj interface{}) error { + ct := c.Ctx.Request.Header["Content-Type"] + i, l := 0, len(ct[0]) + for ; i < l && ct[0][i] != ';'; i++ { + } + switch ct[0][0:i] { + case "application/json": + return c.BindJson(obj) + case "application/xml", "text/xml": + return c.BindXML(obj) + case "application/x-www-form-urlencoded": + return c.BindForm(obj) + case "application/x-protobuf": + return c.BindProtobuf(obj) + case "application/x-yaml": + return c.BindYAML(obj) + default: + return errors.New("Unsupported Content-Type:" + ct[0]) + } +} + +func (c *Controller) BindYAML(obj interface{}) error { + return yaml.Unmarshal(c.Ctx.Input.RequestBody, obj) +} + +func (c *Controller) BindForm(obj interface{}) error { + return c.ParseForm(obj) +} + +func (c *Controller) BindJson(obj interface{}) error { + return json.Unmarshal(c.Ctx.Input.RequestBody, obj) +} + +func (c *Controller) BindProtobuf(obj interface{}) error { + return proto.Unmarshal(c.Ctx.Input.RequestBody, obj.(proto.Message)) +} + +func (c *Controller) BindXML(obj interface{}) error { + return xml.Unmarshal(c.Ctx.Input.RequestBody, obj) +} + + // Mapping the method to function func (c *Controller) Mapping(method string, fn func()) { c.methodMapping[method] = fn diff --git a/server/web/controller_test.go b/server/web/controller_test.go index 4f8b6d1c..f3f5f321 100644 --- a/server/web/controller_test.go +++ b/server/web/controller_test.go @@ -15,7 +15,10 @@ package web import ( + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "math" + "net/http" "os" "path/filepath" "strconv" @@ -180,3 +183,50 @@ func TestAdditionalViewPaths(t *testing.T) { ctrl.ViewPath = dir2 ctrl.RenderString() } + +func TestBindJson(t *testing.T) { + var s struct { + Foo string `json:"foo"` + } + header := map[string][]string{"Content-Type": {"application/json"}} + request := &http.Request{Header: header} + input := &context.BeegoInput{RequestBody: []byte(`{"foo": "FOO"}`)} + ctx := &context.Context{Request: request, Input: input} + ctrlr := Controller{Ctx: ctx} + err := ctrlr.Bind(&s) + require.NoError(t, err) + assert.Equal(t, "FOO", s.Foo) +} + +func TestBindXML(t *testing.T) { + + var s struct { + Foo string `xml:"foo"` + } + xmlBody := ` + + FOO +` + header := map[string][]string{"Content-Type": {"text/xml"}} + request := &http.Request{Header: header} + input := &context.BeegoInput{RequestBody: []byte(xmlBody)} + ctx := &context.Context{Request: request, Input: input} + ctrlr := Controller{Ctx: ctx} + err := ctrlr.Bind(&s) + require.NoError(t, err) + assert.Equal(t, "FOO", s.Foo) +} + +func TestBindYAML(t *testing.T) { + var s struct { + Foo string `yaml:"foo"` + } + header := map[string][]string{"Content-Type": {"application/x-yaml"}} + request := &http.Request{Header: header} + input := &context.BeegoInput{RequestBody: []byte("foo: FOO")} + ctx := &context.Context{Request: request, Input: input} + ctrlr := Controller{Ctx: ctx} + err := ctrlr.Bind(&s) + require.NoError(t, err) + assert.Equal(t, "FOO", s.Foo) +} \ No newline at end of file From 89c2b85471114f981234a7bf78d6d23579bb6f59 Mon Sep 17 00:00:00 2001 From: byene0923 Date: Sun, 18 Apr 2021 23:59:14 +0800 Subject: [PATCH 4/6] Modify bind() method that users do not pass "Content Type" --- server/web/controller.go | 11 ++++------- server/web/controller_test.go | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/server/web/controller.go b/server/web/controller.go index eb8b9c68..9720ac4b 100644 --- a/server/web/controller.go +++ b/server/web/controller.go @@ -151,12 +151,6 @@ type ControllerInterface interface { CheckXSRFCookie() bool HandlerFunc(fn string) bool URLMapping() - Bind(obj interface{}) error - BindJson(obj interface{}) error - BindXML(obj interface{}) error - BindForm(obj interface{}) error - BindProtobuf(obj interface{}) error - BindYAML(obj interface{}) error } // Init generates default values of controller operations. @@ -250,7 +244,10 @@ func (c *Controller) HandlerFunc(fnname string) bool { func (c *Controller) URLMapping() {} func (c *Controller) Bind(obj interface{}) error { - ct := c.Ctx.Request.Header["Content-Type"] + ct, exist := c.Ctx.Request.Header["Content-Type"] + if exist == false || len(ct) == 0 { + return c.BindJson(obj) + } i, l := 0, len(ct[0]) for ; i < l && ct[0][i] != ';'; i++ { } diff --git a/server/web/controller_test.go b/server/web/controller_test.go index f3f5f321..1f82698e 100644 --- a/server/web/controller_test.go +++ b/server/web/controller_test.go @@ -198,6 +198,21 @@ func TestBindJson(t *testing.T) { assert.Equal(t, "FOO", s.Foo) } +func TestBindNoContentType(t *testing.T) { + var s struct { + Foo string `json:"foo"` + } + header := map[string][]string{} + request := &http.Request{Header: header} + input := &context.BeegoInput{RequestBody: []byte(`{"foo": "FOO"}`)} + ctx := &context.Context{Request: request, Input: input} + ctrlr := Controller{Ctx: ctx} + err := ctrlr.Bind(&s) + require.NoError(t, err) + assert.Equal(t, "FOO", s.Foo) +} + + func TestBindXML(t *testing.T) { var s struct { From c349775c492b7a8bbae1f255cb30893149a54bfe Mon Sep 17 00:00:00 2001 From: byene0923 Date: Mon, 19 Apr 2021 00:03:30 +0800 Subject: [PATCH 5/6] format the code --- server/web/controller.go | 1 - server/web/controller_test.go | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/server/web/controller.go b/server/web/controller.go index 9720ac4b..08224fc8 100644 --- a/server/web/controller.go +++ b/server/web/controller.go @@ -287,7 +287,6 @@ func (c *Controller) BindXML(obj interface{}) error { return xml.Unmarshal(c.Ctx.Input.RequestBody, obj) } - // Mapping the method to function func (c *Controller) Mapping(method string, fn func()) { c.methodMapping[method] = fn diff --git a/server/web/controller_test.go b/server/web/controller_test.go index 1f82698e..8a52f097 100644 --- a/server/web/controller_test.go +++ b/server/web/controller_test.go @@ -198,7 +198,7 @@ func TestBindJson(t *testing.T) { assert.Equal(t, "FOO", s.Foo) } -func TestBindNoContentType(t *testing.T) { +func TestBindNoContentType(t *testing.T) { var s struct { Foo string `json:"foo"` } @@ -212,7 +212,6 @@ func TestBindNoContentType(t *testing.T) { assert.Equal(t, "FOO", s.Foo) } - func TestBindXML(t *testing.T) { var s struct { @@ -244,4 +243,4 @@ func TestBindYAML(t *testing.T) { err := ctrlr.Bind(&s) require.NoError(t, err) assert.Equal(t, "FOO", s.Foo) -} \ No newline at end of file +} From 0748cc5c356c8eb9a5c0925a5902ed669edbe228 Mon Sep 17 00:00:00 2001 From: byene0923 Date: Mon, 19 Apr 2021 00:08:01 +0800 Subject: [PATCH 6/6] format the code --- server/web/controller.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/web/controller.go b/server/web/controller.go index 08224fc8..6a29c79e 100644 --- a/server/web/controller.go +++ b/server/web/controller.go @@ -245,7 +245,7 @@ func (c *Controller) URLMapping() {} func (c *Controller) Bind(obj interface{}) error { ct, exist := c.Ctx.Request.Header["Content-Type"] - if exist == false || len(ct) == 0 { + if !exist || len(ct) == 0 { return c.BindJson(obj) } i, l := 0, len(ct[0])