Add build tag nomsgpack (#1852)
* add build tag nomsgpack * Update copyright * Update copyright
This commit is contained in:
		@ -8,6 +8,9 @@ matrix:
 | 
			
		||||
  - go: 1.12.x
 | 
			
		||||
    env: GO111MODULE=on
 | 
			
		||||
  - go: 1.13.x
 | 
			
		||||
  - go: 1.13.x
 | 
			
		||||
    env: 
 | 
			
		||||
      - TESTTAGS=nomsgpack
 | 
			
		||||
  - go: master
 | 
			
		||||
 | 
			
		||||
git:
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								Makefile
									
									
									
									
									
								
							@ -4,12 +4,13 @@ PACKAGES ?= $(shell $(GO) list ./...)
 | 
			
		||||
VETPACKAGES ?= $(shell $(GO) list ./... | grep -v /examples/)
 | 
			
		||||
GOFILES := $(shell find . -name "*.go")
 | 
			
		||||
TESTFOLDER := $(shell $(GO) list ./... | grep -E 'gin$$|binding$$|render$$' | grep -v examples)
 | 
			
		||||
TESTTAGS ?= ""
 | 
			
		||||
 | 
			
		||||
.PHONY: test
 | 
			
		||||
test:
 | 
			
		||||
	echo "mode: count" > coverage.out
 | 
			
		||||
	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; \
 | 
			
		||||
		if grep -q "^--- FAIL" tmp.out; then \
 | 
			
		||||
			rm tmp.out; \
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,8 @@
 | 
			
		||||
// 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"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										57
									
								
								binding/binding_msgpack_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								binding/binding_msgpack_test.go
									
									
									
									
									
										Normal file
									
								
							@ -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))
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										111
									
								
								binding/binding_nomsgpack.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								binding/binding_nomsgpack.go
									
									
									
									
									
										Normal file
									
								
							@ -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/golang/protobuf/proto"
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
	"github.com/ugorji/go/codec"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type appkey struct {
 | 
			
		||||
@ -163,9 +162,6 @@ func TestBindingDefault(t *testing.T) {
 | 
			
		||||
	assert.Equal(t, ProtoBuf, Default("POST", 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("PUT", MIMEYAML))
 | 
			
		||||
}
 | 
			
		||||
@ -633,26 +629,6 @@ func TestBindingProtoBufFail(t *testing.T) {
 | 
			
		||||
		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) {
 | 
			
		||||
	var obj FooStruct
 | 
			
		||||
	req := requestWithBody("POST", "/", `{"bar": "foo"}`)
 | 
			
		||||
@ -1250,23 +1226,6 @@ func testProtoBodyBindingFail(t *testing.T, b Binding, name, path, badPath, body
 | 
			
		||||
	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) {
 | 
			
		||||
	req, _ = http.NewRequest(method, path, bytes.NewBufferString(body))
 | 
			
		||||
	return
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,8 @@
 | 
			
		||||
// 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 (
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,8 @@
 | 
			
		||||
// 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 (
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,8 @@
 | 
			
		||||
// 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 (
 | 
			
		||||
@ -10,6 +12,10 @@ import (
 | 
			
		||||
	"github.com/ugorji/go/codec"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	_ Render = MsgPack{}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// MsgPack contains the given interface object.
 | 
			
		||||
type MsgPack struct {
 | 
			
		||||
	Data interface{}
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,6 @@ var (
 | 
			
		||||
	_ HTMLRender = HTMLDebug{}
 | 
			
		||||
	_ HTMLRender = HTMLProduction{}
 | 
			
		||||
	_ Render     = YAML{}
 | 
			
		||||
	_ Render     = MsgPack{}
 | 
			
		||||
	_ Render     = Reader{}
 | 
			
		||||
	_ Render     = AsciiJSON{}
 | 
			
		||||
	_ Render     = ProtoBuf{}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										43
									
								
								render/render_msgpack_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								render/render_msgpack_test.go
									
									
									
									
									
										Normal file
									
								
							@ -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
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"encoding/xml"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"html/template"
 | 
			
		||||
@ -17,7 +16,6 @@ import (
 | 
			
		||||
 | 
			
		||||
	"github.com/golang/protobuf/proto"
 | 
			
		||||
	"github.com/stretchr/testify/assert"
 | 
			
		||||
	"github.com/ugorji/go/codec"
 | 
			
		||||
 | 
			
		||||
	testdata "github.com/gin-gonic/gin/testdata/protoexample"
 | 
			
		||||
)
 | 
			
		||||
@ -25,30 +23,6 @@ import (
 | 
			
		||||
// 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(), buf.String())
 | 
			
		||||
	assert.Equal(t, "application/msgpack; charset=utf-8", w.Header().Get("Content-Type"))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestRenderJSON(t *testing.T) {
 | 
			
		||||
	w := httptest.NewRecorder()
 | 
			
		||||
	data := map[string]interface{}{
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user