forked from mirror/gin
Add build tag nomsgpack (#1852)
* add build tag nomsgpack * Update copyright * Update copyright
This commit is contained in:
parent
b8a7b6d194
commit
fd8a65b252
|
@ -8,6 +8,9 @@ matrix:
|
||||||
- go: 1.12.x
|
- go: 1.12.x
|
||||||
env: GO111MODULE=on
|
env: GO111MODULE=on
|
||||||
- go: 1.13.x
|
- go: 1.13.x
|
||||||
|
- go: 1.13.x
|
||||||
|
env:
|
||||||
|
- TESTTAGS=nomsgpack
|
||||||
- go: master
|
- go: master
|
||||||
|
|
||||||
git:
|
git:
|
||||||
|
|
3
Makefile
3
Makefile
|
@ -4,12 +4,13 @@ PACKAGES ?= $(shell $(GO) list ./...)
|
||||||
VETPACKAGES ?= $(shell $(GO) list ./... | grep -v /examples/)
|
VETPACKAGES ?= $(shell $(GO) list ./... | grep -v /examples/)
|
||||||
GOFILES := $(shell find . -name "*.go")
|
GOFILES := $(shell find . -name "*.go")
|
||||||
TESTFOLDER := $(shell $(GO) list ./... | grep -E 'gin$$|binding$$|render$$' | grep -v examples)
|
TESTFOLDER := $(shell $(GO) list ./... | grep -E 'gin$$|binding$$|render$$' | grep -v examples)
|
||||||
|
TESTTAGS ?= ""
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test:
|
test:
|
||||||
echo "mode: count" > coverage.out
|
echo "mode: count" > coverage.out
|
||||||
for d in $(TESTFOLDER); do \
|
for d in $(TESTFOLDER); do \
|
||||||
$(GO) test -v -covermode=count -coverprofile=profile.out $$d > tmp.out; \
|
$(GO) test -tags $(TESTTAGS) -v -covermode=count -coverprofile=profile.out $$d > tmp.out; \
|
||||||
cat tmp.out; \
|
cat tmp.out; \
|
||||||
if grep -q "^--- FAIL" tmp.out; then \
|
if grep -q "^--- FAIL" tmp.out; then \
|
||||||
rm tmp.out; \
|
rm tmp.out; \
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
// Use of this source code is governed by a MIT style
|
// Use of this source code is governed by a MIT style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !nomsgpack
|
||||||
|
|
||||||
package binding
|
package binding
|
||||||
|
|
||||||
import "net/http"
|
import "net/http"
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
// Copyright 2020 Gin Core Team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !nomsgpack
|
||||||
|
|
||||||
|
package binding
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/ugorji/go/codec"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBindingMsgPack(t *testing.T) {
|
||||||
|
test := FooStruct{
|
||||||
|
Foo: "bar",
|
||||||
|
}
|
||||||
|
|
||||||
|
h := new(codec.MsgpackHandle)
|
||||||
|
assert.NotNil(t, h)
|
||||||
|
buf := bytes.NewBuffer([]byte{})
|
||||||
|
assert.NotNil(t, buf)
|
||||||
|
err := codec.NewEncoder(buf, h).Encode(test)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
data := buf.Bytes()
|
||||||
|
|
||||||
|
testMsgPackBodyBinding(t,
|
||||||
|
MsgPack, "msgpack",
|
||||||
|
"/", "/",
|
||||||
|
string(data), string(data[1:]))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testMsgPackBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
|
||||||
|
assert.Equal(t, name, b.Name())
|
||||||
|
|
||||||
|
obj := FooStruct{}
|
||||||
|
req := requestWithBody("POST", path, body)
|
||||||
|
req.Header.Add("Content-Type", MIMEMSGPACK)
|
||||||
|
err := b.Bind(req, &obj)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "bar", obj.Foo)
|
||||||
|
|
||||||
|
obj = FooStruct{}
|
||||||
|
req = requestWithBody("POST", badPath, badBody)
|
||||||
|
req.Header.Add("Content-Type", MIMEMSGPACK)
|
||||||
|
err = MsgPack.Bind(req, &obj)
|
||||||
|
assert.Error(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBindingDefaultMsgPack(t *testing.T) {
|
||||||
|
assert.Equal(t, MsgPack, Default("POST", MIMEMSGPACK))
|
||||||
|
assert.Equal(t, MsgPack, Default("PUT", MIMEMSGPACK2))
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
// Copyright 2020 Gin Core Team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build nomsgpack
|
||||||
|
|
||||||
|
package binding
|
||||||
|
|
||||||
|
import "net/http"
|
||||||
|
|
||||||
|
// Content-Type MIME of the most common data formats.
|
||||||
|
const (
|
||||||
|
MIMEJSON = "application/json"
|
||||||
|
MIMEHTML = "text/html"
|
||||||
|
MIMEXML = "application/xml"
|
||||||
|
MIMEXML2 = "text/xml"
|
||||||
|
MIMEPlain = "text/plain"
|
||||||
|
MIMEPOSTForm = "application/x-www-form-urlencoded"
|
||||||
|
MIMEMultipartPOSTForm = "multipart/form-data"
|
||||||
|
MIMEPROTOBUF = "application/x-protobuf"
|
||||||
|
MIMEYAML = "application/x-yaml"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Binding describes the interface which needs to be implemented for binding the
|
||||||
|
// data present in the request such as JSON request body, query parameters or
|
||||||
|
// the form POST.
|
||||||
|
type Binding interface {
|
||||||
|
Name() string
|
||||||
|
Bind(*http.Request, interface{}) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// BindingBody adds BindBody method to Binding. BindBody is similar with Bind,
|
||||||
|
// but it reads the body from supplied bytes instead of req.Body.
|
||||||
|
type BindingBody interface {
|
||||||
|
Binding
|
||||||
|
BindBody([]byte, interface{}) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// BindingUri adds BindUri method to Binding. BindUri is similar with Bind,
|
||||||
|
// but it read the Params.
|
||||||
|
type BindingUri interface {
|
||||||
|
Name() string
|
||||||
|
BindUri(map[string][]string, interface{}) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// StructValidator is the minimal interface which needs to be implemented in
|
||||||
|
// order for it to be used as the validator engine for ensuring the correctness
|
||||||
|
// of the request. Gin provides a default implementation for this using
|
||||||
|
// https://github.com/go-playground/validator/tree/v8.18.2.
|
||||||
|
type StructValidator interface {
|
||||||
|
// ValidateStruct can receive any kind of type and it should never panic, even if the configuration is not right.
|
||||||
|
// If the received type is not a struct, any validation should be skipped and nil must be returned.
|
||||||
|
// If the received type is a struct or pointer to a struct, the validation should be performed.
|
||||||
|
// If the struct is not valid or the validation itself fails, a descriptive error should be returned.
|
||||||
|
// Otherwise nil must be returned.
|
||||||
|
ValidateStruct(interface{}) error
|
||||||
|
|
||||||
|
// Engine returns the underlying validator engine which powers the
|
||||||
|
// StructValidator implementation.
|
||||||
|
Engine() interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validator is the default validator which implements the StructValidator
|
||||||
|
// interface. It uses https://github.com/go-playground/validator/tree/v8.18.2
|
||||||
|
// under the hood.
|
||||||
|
var Validator StructValidator = &defaultValidator{}
|
||||||
|
|
||||||
|
// These implement the Binding interface and can be used to bind the data
|
||||||
|
// present in the request to struct instances.
|
||||||
|
var (
|
||||||
|
JSON = jsonBinding{}
|
||||||
|
XML = xmlBinding{}
|
||||||
|
Form = formBinding{}
|
||||||
|
Query = queryBinding{}
|
||||||
|
FormPost = formPostBinding{}
|
||||||
|
FormMultipart = formMultipartBinding{}
|
||||||
|
ProtoBuf = protobufBinding{}
|
||||||
|
YAML = yamlBinding{}
|
||||||
|
Uri = uriBinding{}
|
||||||
|
Header = headerBinding{}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Default returns the appropriate Binding instance based on the HTTP method
|
||||||
|
// and the content type.
|
||||||
|
func Default(method, contentType string) Binding {
|
||||||
|
if method == "GET" {
|
||||||
|
return Form
|
||||||
|
}
|
||||||
|
|
||||||
|
switch contentType {
|
||||||
|
case MIMEJSON:
|
||||||
|
return JSON
|
||||||
|
case MIMEXML, MIMEXML2:
|
||||||
|
return XML
|
||||||
|
case MIMEPROTOBUF:
|
||||||
|
return ProtoBuf
|
||||||
|
case MIMEYAML:
|
||||||
|
return YAML
|
||||||
|
case MIMEMultipartPOSTForm:
|
||||||
|
return FormMultipart
|
||||||
|
default: // case MIMEPOSTForm:
|
||||||
|
return Form
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func validate(obj interface{}) error {
|
||||||
|
if Validator == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return Validator.ValidateStruct(obj)
|
||||||
|
}
|
|
@ -21,7 +21,6 @@ import (
|
||||||
"github.com/gin-gonic/gin/testdata/protoexample"
|
"github.com/gin-gonic/gin/testdata/protoexample"
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/ugorji/go/codec"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type appkey struct {
|
type appkey struct {
|
||||||
|
@ -163,9 +162,6 @@ func TestBindingDefault(t *testing.T) {
|
||||||
assert.Equal(t, ProtoBuf, Default("POST", MIMEPROTOBUF))
|
assert.Equal(t, ProtoBuf, Default("POST", MIMEPROTOBUF))
|
||||||
assert.Equal(t, ProtoBuf, Default("PUT", MIMEPROTOBUF))
|
assert.Equal(t, ProtoBuf, Default("PUT", MIMEPROTOBUF))
|
||||||
|
|
||||||
assert.Equal(t, MsgPack, Default("POST", MIMEMSGPACK))
|
|
||||||
assert.Equal(t, MsgPack, Default("PUT", MIMEMSGPACK2))
|
|
||||||
|
|
||||||
assert.Equal(t, YAML, Default("POST", MIMEYAML))
|
assert.Equal(t, YAML, Default("POST", MIMEYAML))
|
||||||
assert.Equal(t, YAML, Default("PUT", MIMEYAML))
|
assert.Equal(t, YAML, Default("PUT", MIMEYAML))
|
||||||
}
|
}
|
||||||
|
@ -633,26 +629,6 @@ func TestBindingProtoBufFail(t *testing.T) {
|
||||||
string(data), string(data[1:]))
|
string(data), string(data[1:]))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBindingMsgPack(t *testing.T) {
|
|
||||||
test := FooStruct{
|
|
||||||
Foo: "bar",
|
|
||||||
}
|
|
||||||
|
|
||||||
h := new(codec.MsgpackHandle)
|
|
||||||
assert.NotNil(t, h)
|
|
||||||
buf := bytes.NewBuffer([]byte{})
|
|
||||||
assert.NotNil(t, buf)
|
|
||||||
err := codec.NewEncoder(buf, h).Encode(test)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
data := buf.Bytes()
|
|
||||||
|
|
||||||
testMsgPackBodyBinding(t,
|
|
||||||
MsgPack, "msgpack",
|
|
||||||
"/", "/",
|
|
||||||
string(data), string(data[1:]))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestValidationFails(t *testing.T) {
|
func TestValidationFails(t *testing.T) {
|
||||||
var obj FooStruct
|
var obj FooStruct
|
||||||
req := requestWithBody("POST", "/", `{"bar": "foo"}`)
|
req := requestWithBody("POST", "/", `{"bar": "foo"}`)
|
||||||
|
@ -1250,23 +1226,6 @@ func testProtoBodyBindingFail(t *testing.T, b Binding, name, path, badPath, body
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testMsgPackBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
|
|
||||||
assert.Equal(t, name, b.Name())
|
|
||||||
|
|
||||||
obj := FooStruct{}
|
|
||||||
req := requestWithBody("POST", path, body)
|
|
||||||
req.Header.Add("Content-Type", MIMEMSGPACK)
|
|
||||||
err := b.Bind(req, &obj)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, "bar", obj.Foo)
|
|
||||||
|
|
||||||
obj = FooStruct{}
|
|
||||||
req = requestWithBody("POST", badPath, badBody)
|
|
||||||
req.Header.Add("Content-Type", MIMEMSGPACK)
|
|
||||||
err = MsgPack.Bind(req, &obj)
|
|
||||||
assert.Error(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func requestWithBody(method, path, body string) (req *http.Request) {
|
func requestWithBody(method, path, body string) (req *http.Request) {
|
||||||
req, _ = http.NewRequest(method, path, bytes.NewBufferString(body))
|
req, _ = http.NewRequest(method, path, bytes.NewBufferString(body))
|
||||||
return
|
return
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
// Use of this source code is governed by a MIT style
|
// Use of this source code is governed by a MIT style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !nomsgpack
|
||||||
|
|
||||||
package binding
|
package binding
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
// Use of this source code is governed by a MIT style
|
// Use of this source code is governed by a MIT style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !nomsgpack
|
||||||
|
|
||||||
package binding
|
package binding
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
// Use of this source code is governed by a MIT style
|
// Use of this source code is governed by a MIT style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !nomsgpack
|
||||||
|
|
||||||
package render
|
package render
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -10,6 +12,10 @@ import (
|
||||||
"github.com/ugorji/go/codec"
|
"github.com/ugorji/go/codec"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
_ Render = MsgPack{}
|
||||||
|
)
|
||||||
|
|
||||||
// MsgPack contains the given interface object.
|
// MsgPack contains the given interface object.
|
||||||
type MsgPack struct {
|
type MsgPack struct {
|
||||||
Data interface{}
|
Data interface{}
|
||||||
|
|
|
@ -27,7 +27,6 @@ var (
|
||||||
_ HTMLRender = HTMLDebug{}
|
_ HTMLRender = HTMLDebug{}
|
||||||
_ HTMLRender = HTMLProduction{}
|
_ HTMLRender = HTMLProduction{}
|
||||||
_ Render = YAML{}
|
_ Render = YAML{}
|
||||||
_ Render = MsgPack{}
|
|
||||||
_ Render = Reader{}
|
_ Render = Reader{}
|
||||||
_ Render = AsciiJSON{}
|
_ Render = AsciiJSON{}
|
||||||
_ Render = ProtoBuf{}
|
_ Render = ProtoBuf{}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !nomsgpack
|
||||||
|
|
||||||
|
package render
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/ugorji/go/codec"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO unit tests
|
||||||
|
// test errors
|
||||||
|
|
||||||
|
func TestRenderMsgPack(t *testing.T) {
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
data := map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
}
|
||||||
|
|
||||||
|
(MsgPack{data}).WriteContentType(w)
|
||||||
|
assert.Equal(t, "application/msgpack; charset=utf-8", w.Header().Get("Content-Type"))
|
||||||
|
|
||||||
|
err := (MsgPack{data}).Render(w)
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
h := new(codec.MsgpackHandle)
|
||||||
|
assert.NotNil(t, h)
|
||||||
|
buf := bytes.NewBuffer([]byte{})
|
||||||
|
assert.NotNil(t, buf)
|
||||||
|
err = codec.NewEncoder(buf, h).Encode(data)
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, w.Body.String(), string(buf.Bytes()))
|
||||||
|
assert.Equal(t, "application/msgpack; charset=utf-8", w.Header().Get("Content-Type"))
|
||||||
|
}
|
|
@ -5,7 +5,6 @@
|
||||||
package render
|
package render
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"errors"
|
"errors"
|
||||||
"html/template"
|
"html/template"
|
||||||
|
@ -17,7 +16,6 @@ import (
|
||||||
|
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/ugorji/go/codec"
|
|
||||||
|
|
||||||
testdata "github.com/gin-gonic/gin/testdata/protoexample"
|
testdata "github.com/gin-gonic/gin/testdata/protoexample"
|
||||||
)
|
)
|
||||||
|
@ -25,30 +23,6 @@ import (
|
||||||
// TODO unit tests
|
// TODO unit tests
|
||||||
// test errors
|
// test errors
|
||||||
|
|
||||||
func TestRenderMsgPack(t *testing.T) {
|
|
||||||
w := httptest.NewRecorder()
|
|
||||||
data := map[string]interface{}{
|
|
||||||
"foo": "bar",
|
|
||||||
}
|
|
||||||
|
|
||||||
(MsgPack{data}).WriteContentType(w)
|
|
||||||
assert.Equal(t, "application/msgpack; charset=utf-8", w.Header().Get("Content-Type"))
|
|
||||||
|
|
||||||
err := (MsgPack{data}).Render(w)
|
|
||||||
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
h := new(codec.MsgpackHandle)
|
|
||||||
assert.NotNil(t, h)
|
|
||||||
buf := bytes.NewBuffer([]byte{})
|
|
||||||
assert.NotNil(t, buf)
|
|
||||||
err = codec.NewEncoder(buf, h).Encode(data)
|
|
||||||
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, w.Body.String(), buf.String())
|
|
||||||
assert.Equal(t, "application/msgpack; charset=utf-8", w.Header().Get("Content-Type"))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRenderJSON(t *testing.T) {
|
func TestRenderJSON(t *testing.T) {
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
data := map[string]interface{}{
|
data := map[string]interface{}{
|
||||||
|
|
Loading…
Reference in New Issue