Skip to content

Commit 5809c31

Browse files
sapkThomasObenaus
authored andcommitted
Add build tag nomsgpack (gin-gonic#1852)
* add build tag nomsgpack * Update copyright * Update copyright
1 parent 3426957 commit 5809c31

12 files changed

+228
-69
lines changed

.travis.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ matrix:
88
- go: 1.12.x
99
env: GO111MODULE=on
1010
- go: 1.13.x
11+
- go: 1.13.x
12+
env:
13+
- TESTTAGS=nomsgpack
1114
- go: master
1215

1316
git:

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ PACKAGES ?= $(shell $(GO) list ./...)
44
VETPACKAGES ?= $(shell $(GO) list ./... | grep -v /examples/)
55
GOFILES := $(shell find . -name "*.go")
66
TESTFOLDER := $(shell $(GO) list ./... | grep -E 'gin$$|binding$$|render$$' | grep -v examples)
7+
TESTTAGS ?= ""
78

89
.PHONY: test
910
test:
1011
echo "mode: count" > coverage.out
1112
for d in $(TESTFOLDER); do \
12-
$(GO) test -v -covermode=count -coverprofile=profile.out $$d > tmp.out; \
13+
$(GO) test -tags $(TESTTAGS) -v -covermode=count -coverprofile=profile.out $$d > tmp.out; \
1314
cat tmp.out; \
1415
if grep -q "^--- FAIL" tmp.out; then \
1516
rm tmp.out; \

binding/binding.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// Use of this source code is governed by a MIT style
33
// license that can be found in the LICENSE file.
44

5+
// +build !nomsgpack
6+
57
package binding
68

79
import "net/http"

binding/binding_msgpack_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright 2020 Gin Core Team. All rights reserved.
2+
// Use of this source code is governed by a MIT style
3+
// license that can be found in the LICENSE file.
4+
5+
// +build !nomsgpack
6+
7+
package binding
8+
9+
import (
10+
"bytes"
11+
"testing"
12+
13+
"github.com/stretchr/testify/assert"
14+
"github.com/ugorji/go/codec"
15+
)
16+
17+
func TestBindingMsgPack(t *testing.T) {
18+
test := FooStruct{
19+
Foo: "bar",
20+
}
21+
22+
h := new(codec.MsgpackHandle)
23+
assert.NotNil(t, h)
24+
buf := bytes.NewBuffer([]byte{})
25+
assert.NotNil(t, buf)
26+
err := codec.NewEncoder(buf, h).Encode(test)
27+
assert.NoError(t, err)
28+
29+
data := buf.Bytes()
30+
31+
testMsgPackBodyBinding(t,
32+
MsgPack, "msgpack",
33+
"/", "/",
34+
string(data), string(data[1:]))
35+
}
36+
37+
func testMsgPackBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
38+
assert.Equal(t, name, b.Name())
39+
40+
obj := FooStruct{}
41+
req := requestWithBody("POST", path, body)
42+
req.Header.Add("Content-Type", MIMEMSGPACK)
43+
err := b.Bind(req, &obj)
44+
assert.NoError(t, err)
45+
assert.Equal(t, "bar", obj.Foo)
46+
47+
obj = FooStruct{}
48+
req = requestWithBody("POST", badPath, badBody)
49+
req.Header.Add("Content-Type", MIMEMSGPACK)
50+
err = MsgPack.Bind(req, &obj)
51+
assert.Error(t, err)
52+
}
53+
54+
func TestBindingDefaultMsgPack(t *testing.T) {
55+
assert.Equal(t, MsgPack, Default("POST", MIMEMSGPACK))
56+
assert.Equal(t, MsgPack, Default("PUT", MIMEMSGPACK2))
57+
}

binding/binding_nomsgpack.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// Copyright 2020 Gin Core Team. All rights reserved.
2+
// Use of this source code is governed by a MIT style
3+
// license that can be found in the LICENSE file.
4+
5+
// +build nomsgpack
6+
7+
package binding
8+
9+
import "net/http"
10+
11+
// Content-Type MIME of the most common data formats.
12+
const (
13+
MIMEJSON = "application/json"
14+
MIMEHTML = "text/html"
15+
MIMEXML = "application/xml"
16+
MIMEXML2 = "text/xml"
17+
MIMEPlain = "text/plain"
18+
MIMEPOSTForm = "application/x-www-form-urlencoded"
19+
MIMEMultipartPOSTForm = "multipart/form-data"
20+
MIMEPROTOBUF = "application/x-protobuf"
21+
MIMEYAML = "application/x-yaml"
22+
)
23+
24+
// Binding describes the interface which needs to be implemented for binding the
25+
// data present in the request such as JSON request body, query parameters or
26+
// the form POST.
27+
type Binding interface {
28+
Name() string
29+
Bind(*http.Request, interface{}) error
30+
}
31+
32+
// BindingBody adds BindBody method to Binding. BindBody is similar with Bind,
33+
// but it reads the body from supplied bytes instead of req.Body.
34+
type BindingBody interface {
35+
Binding
36+
BindBody([]byte, interface{}) error
37+
}
38+
39+
// BindingUri adds BindUri method to Binding. BindUri is similar with Bind,
40+
// but it read the Params.
41+
type BindingUri interface {
42+
Name() string
43+
BindUri(map[string][]string, interface{}) error
44+
}
45+
46+
// StructValidator is the minimal interface which needs to be implemented in
47+
// order for it to be used as the validator engine for ensuring the correctness
48+
// of the request. Gin provides a default implementation for this using
49+
// https://github.com/go-playground/validator/tree/v8.18.2.
50+
type StructValidator interface {
51+
// ValidateStruct can receive any kind of type and it should never panic, even if the configuration is not right.
52+
// If the received type is not a struct, any validation should be skipped and nil must be returned.
53+
// If the received type is a struct or pointer to a struct, the validation should be performed.
54+
// If the struct is not valid or the validation itself fails, a descriptive error should be returned.
55+
// Otherwise nil must be returned.
56+
ValidateStruct(interface{}) error
57+
58+
// Engine returns the underlying validator engine which powers the
59+
// StructValidator implementation.
60+
Engine() interface{}
61+
}
62+
63+
// Validator is the default validator which implements the StructValidator
64+
// interface. It uses https://github.com/go-playground/validator/tree/v8.18.2
65+
// under the hood.
66+
var Validator StructValidator = &defaultValidator{}
67+
68+
// These implement the Binding interface and can be used to bind the data
69+
// present in the request to struct instances.
70+
var (
71+
JSON = jsonBinding{}
72+
XML = xmlBinding{}
73+
Form = formBinding{}
74+
Query = queryBinding{}
75+
FormPost = formPostBinding{}
76+
FormMultipart = formMultipartBinding{}
77+
ProtoBuf = protobufBinding{}
78+
YAML = yamlBinding{}
79+
Uri = uriBinding{}
80+
Header = headerBinding{}
81+
)
82+
83+
// Default returns the appropriate Binding instance based on the HTTP method
84+
// and the content type.
85+
func Default(method, contentType string) Binding {
86+
if method == "GET" {
87+
return Form
88+
}
89+
90+
switch contentType {
91+
case MIMEJSON:
92+
return JSON
93+
case MIMEXML, MIMEXML2:
94+
return XML
95+
case MIMEPROTOBUF:
96+
return ProtoBuf
97+
case MIMEYAML:
98+
return YAML
99+
case MIMEMultipartPOSTForm:
100+
return FormMultipart
101+
default: // case MIMEPOSTForm:
102+
return Form
103+
}
104+
}
105+
106+
func validate(obj interface{}) error {
107+
if Validator == nil {
108+
return nil
109+
}
110+
return Validator.ValidateStruct(obj)
111+
}

binding/binding_test.go

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121
"github.com/gin-gonic/gin/testdata/protoexample"
2222
"github.com/golang/protobuf/proto"
2323
"github.com/stretchr/testify/assert"
24-
"github.com/ugorji/go/codec"
2524
)
2625

2726
type appkey struct {
@@ -163,9 +162,6 @@ func TestBindingDefault(t *testing.T) {
163162
assert.Equal(t, ProtoBuf, Default("POST", MIMEPROTOBUF))
164163
assert.Equal(t, ProtoBuf, Default("PUT", MIMEPROTOBUF))
165164

166-
assert.Equal(t, MsgPack, Default("POST", MIMEMSGPACK))
167-
assert.Equal(t, MsgPack, Default("PUT", MIMEMSGPACK2))
168-
169165
assert.Equal(t, YAML, Default("POST", MIMEYAML))
170166
assert.Equal(t, YAML, Default("PUT", MIMEYAML))
171167
}
@@ -633,26 +629,6 @@ func TestBindingProtoBufFail(t *testing.T) {
633629
string(data), string(data[1:]))
634630
}
635631

636-
func TestBindingMsgPack(t *testing.T) {
637-
test := FooStruct{
638-
Foo: "bar",
639-
}
640-
641-
h := new(codec.MsgpackHandle)
642-
assert.NotNil(t, h)
643-
buf := bytes.NewBuffer([]byte{})
644-
assert.NotNil(t, buf)
645-
err := codec.NewEncoder(buf, h).Encode(test)
646-
assert.NoError(t, err)
647-
648-
data := buf.Bytes()
649-
650-
testMsgPackBodyBinding(t,
651-
MsgPack, "msgpack",
652-
"/", "/",
653-
string(data), string(data[1:]))
654-
}
655-
656632
func TestValidationFails(t *testing.T) {
657633
var obj FooStruct
658634
req := requestWithBody("POST", "/", `{"bar": "foo"}`)
@@ -1250,23 +1226,6 @@ func testProtoBodyBindingFail(t *testing.T, b Binding, name, path, badPath, body
12501226
assert.Error(t, err)
12511227
}
12521228

1253-
func testMsgPackBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
1254-
assert.Equal(t, name, b.Name())
1255-
1256-
obj := FooStruct{}
1257-
req := requestWithBody("POST", path, body)
1258-
req.Header.Add("Content-Type", MIMEMSGPACK)
1259-
err := b.Bind(req, &obj)
1260-
assert.NoError(t, err)
1261-
assert.Equal(t, "bar", obj.Foo)
1262-
1263-
obj = FooStruct{}
1264-
req = requestWithBody("POST", badPath, badBody)
1265-
req.Header.Add("Content-Type", MIMEMSGPACK)
1266-
err = MsgPack.Bind(req, &obj)
1267-
assert.Error(t, err)
1268-
}
1269-
12701229
func requestWithBody(method, path, body string) (req *http.Request) {
12711230
req, _ = http.NewRequest(method, path, bytes.NewBufferString(body))
12721231
return

binding/msgpack.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// Use of this source code is governed by a MIT style
33
// license that can be found in the LICENSE file.
44

5+
// +build !nomsgpack
6+
57
package binding
68

79
import (

binding/msgpack_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// Use of this source code is governed by a MIT style
33
// license that can be found in the LICENSE file.
44

5+
// +build !nomsgpack
6+
57
package binding
68

79
import (

render/msgpack.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// Use of this source code is governed by a MIT style
33
// license that can be found in the LICENSE file.
44

5+
// +build !nomsgpack
6+
57
package render
68

79
import (
@@ -10,6 +12,10 @@ import (
1012
"github.com/ugorji/go/codec"
1113
)
1214

15+
var (
16+
_ Render = MsgPack{}
17+
)
18+
1319
// MsgPack contains the given interface object.
1420
type MsgPack struct {
1521
Data interface{}

render/render.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ var (
2727
_ HTMLRender = HTMLDebug{}
2828
_ HTMLRender = HTMLProduction{}
2929
_ Render = YAML{}
30-
_ Render = MsgPack{}
3130
_ Render = Reader{}
3231
_ Render = AsciiJSON{}
3332
_ Render = ProtoBuf{}

0 commit comments

Comments
 (0)