From c407afc81d44e5ca10434427d8b6ee6da24057e7 Mon Sep 17 00:00:00 2001 From: shifengbin Date: Tue, 9 Aug 2022 12:00:10 +0800 Subject: [PATCH] fix: in case url or form bind param error should return BadRequest (#2256) * fix: binding url or form convert type error should be return BadRequest * golint --- transport/http/binding/bind.go | 12 ++++++-- transport/http/binding/bind_test.go | 44 +++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/transport/http/binding/bind.go b/transport/http/binding/bind.go index 3155d61e7..100073673 100644 --- a/transport/http/binding/bind.go +++ b/transport/http/binding/bind.go @@ -4,13 +4,18 @@ import ( "net/http" "net/url" + "github.com/go-kratos/kratos/v2/errors" + "github.com/go-kratos/kratos/v2/encoding" "github.com/go-kratos/kratos/v2/encoding/form" ) // BindQuery bind vars parameters to target. func BindQuery(vars url.Values, target interface{}) error { - return encoding.GetCodec(form.Name).Unmarshal([]byte(vars.Encode()), target) + if err := encoding.GetCodec(form.Name).Unmarshal([]byte(vars.Encode()), target); err != nil { + return errors.BadRequest("CODEC", err.Error()) + } + return nil } // BindForm bind form parameters to target. @@ -18,5 +23,8 @@ func BindForm(req *http.Request, target interface{}) error { if err := req.ParseForm(); err != nil { return err } - return encoding.GetCodec(form.Name).Unmarshal([]byte(req.Form.Encode()), target) + if err := encoding.GetCodec(form.Name).Unmarshal([]byte(req.Form.Encode()), target); err != nil { + return errors.BadRequest("CODEC", err.Error()) + } + return nil } diff --git a/transport/http/binding/bind_test.go b/transport/http/binding/bind_test.go index 5e2552f90..20aadba7f 100644 --- a/transport/http/binding/bind_test.go +++ b/transport/http/binding/bind_test.go @@ -7,6 +7,8 @@ import ( "reflect" "strings" "testing" + + "github.com/go-kratos/kratos/v2/errors" ) func TestBindQuery(t *testing.T) { @@ -14,7 +16,12 @@ func TestBindQuery(t *testing.T) { Name string `json:"name"` URL string `json:"url"` } + + type TestBind2 struct { + Age int `json:"age"` + } p1 := TestBind{} + p2 := TestBind2{} type args struct { vars url.Values target interface{} @@ -34,11 +41,31 @@ func TestBindQuery(t *testing.T) { wantErr: false, want: &TestBind{"kratos", "https://go-kratos.dev/"}, }, + { + name: "test1", + args: args{ + vars: map[string][]string{"age": {"kratos"}, "url": {"https://go-kratos.dev/"}}, + target: &p2, + }, + wantErr: true, + want: errors.BadRequest("CODEC", ""), + }, + { + name: "test2", + args: args{ + vars: map[string][]string{"age": {"1"}, "url": {"https://go-kratos.dev/"}}, + target: &TestBind2{}, + }, + wantErr: false, + want: &TestBind2{Age: 1}, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if err := BindQuery(tt.args.vars, tt.args.target); (err != nil) != tt.wantErr { t.Errorf("BindQuery() error = %v, wantErr %v", err, tt.wantErr) + } else { + t.Log(err) } if !tt.wantErr && !reflect.DeepEqual(tt.args.target, tt.want) { t.Errorf("BindQuery() target = %v, want %v", tt.args.target, tt.want) @@ -52,6 +79,9 @@ func TestBindForm(t *testing.T) { Name string `json:"name"` URL string `json:"url"` } + type TestBind2 struct { + Age int `json:"age"` + } p1 := TestBind{} type args struct { req *http.Request @@ -85,6 +115,19 @@ func TestBindForm(t *testing.T) { wantErr: false, want: &TestBind{"kratos", "https://go-kratos.dev/"}, }, + { + name: "error BadRequest", + args: args{ + req: &http.Request{ + Method: "POST", + Header: http.Header{"Content-Type": {"application/x-www-form-urlencoded; param=value"}}, + Body: io.NopCloser(strings.NewReader("age=a")), + }, + target: &TestBind2{}, + }, + wantErr: true, + want: nil, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -92,6 +135,7 @@ func TestBindForm(t *testing.T) { if (err != nil) != tt.wantErr { t.Errorf("BindForm() error = %v, wantErr %v", err, tt.wantErr) } + t.Log(err) if !tt.wantErr && !reflect.DeepEqual(tt.args.target, tt.want) { t.Errorf("BindForm() target = %v, want %v", tt.args.target, tt.want) }