mirror of
https://github.com/gin-gonic/gin.git
synced 2025-10-17 14:12:16 +08:00
Merge 745be4178607666f02c819a3e421ef36e6a9e0b1 into 863248034b46c8292bf53681730fa033292710fa
This commit is contained in:
commit
21aa1216c2
40
Godeps/Godeps.json
generated
Normal file
40
Godeps/Godeps.json
generated
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"ImportPath": "github.com/gin-gonic/gin",
|
||||||
|
"GoVersion": "go1.5.1",
|
||||||
|
"Deps": [
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/davecgh/go-spew/spew",
|
||||||
|
"Rev": "5215b55f46b2b919f50a1df0eaa5886afe4e3b3d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/golang/protobuf/proto",
|
||||||
|
"Rev": "2402d76f3d41f928c7902a765dfc872356dd3aad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/manucorporat/sse",
|
||||||
|
"Rev": "ee05b128a739a0fb76c7ebd3ae4810c1de808d6d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/pmezard/go-difflib/difflib",
|
||||||
|
"Rev": "792786c7400a136282c1664665ae0a8db921c6c2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/stretchr/testify/assert",
|
||||||
|
"Comment": "v1.1.3",
|
||||||
|
"Rev": "f390dcf405f7b83c997eac1b06768bb9f44dec18"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/net/context",
|
||||||
|
"Rev": "f315505cf3349909cdf013ea56690da34e96a451"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "gopkg.in/go-playground/validator.v8",
|
||||||
|
"Comment": "v8.15.1",
|
||||||
|
"Rev": "c193cecd124b5cc722d7ee5538e945bdb3348435"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/ugorji/go/codec",
|
||||||
|
"Rev": "c88ee250d0221a57af388746f5cf03768c21d6e2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -15,6 +15,8 @@ const (
|
|||||||
MIMEPOSTForm = "application/x-www-form-urlencoded"
|
MIMEPOSTForm = "application/x-www-form-urlencoded"
|
||||||
MIMEMultipartPOSTForm = "multipart/form-data"
|
MIMEMultipartPOSTForm = "multipart/form-data"
|
||||||
MIMEPROTOBUF = "application/x-protobuf"
|
MIMEPROTOBUF = "application/x-protobuf"
|
||||||
|
MIMEMSGPACK = "application/x-msgpack"
|
||||||
|
MIMEMSGPACK2 = "application/msgpack"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Binding interface {
|
type Binding interface {
|
||||||
@ -40,6 +42,7 @@ var (
|
|||||||
FormPost = formPostBinding{}
|
FormPost = formPostBinding{}
|
||||||
FormMultipart = formMultipartBinding{}
|
FormMultipart = formMultipartBinding{}
|
||||||
ProtoBuf = protobufBinding{}
|
ProtoBuf = protobufBinding{}
|
||||||
|
MsgPack = msgpackBinding{}
|
||||||
)
|
)
|
||||||
|
|
||||||
func Default(method, contentType string) Binding {
|
func Default(method, contentType string) Binding {
|
||||||
@ -53,6 +56,8 @@ func Default(method, contentType string) Binding {
|
|||||||
return XML
|
return XML
|
||||||
case MIMEPROTOBUF:
|
case MIMEPROTOBUF:
|
||||||
return ProtoBuf
|
return ProtoBuf
|
||||||
|
case MIMEMSGPACK, MIMEMSGPACK2:
|
||||||
|
return MsgPack
|
||||||
default: //case MIMEPOSTForm, MIMEMultipartPOSTForm:
|
default: //case MIMEPOSTForm, MIMEMultipartPOSTForm:
|
||||||
return Form
|
return Form
|
||||||
}
|
}
|
||||||
|
@ -12,17 +12,18 @@ import (
|
|||||||
|
|
||||||
"github.com/gin-gonic/gin/binding/example"
|
"github.com/gin-gonic/gin/binding/example"
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
|
"github.com/ugorji/go/codec"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FooStruct struct {
|
type FooStruct struct {
|
||||||
Foo string `json:"foo" form:"foo" xml:"foo" binding:"required"`
|
Foo string `msgpack:"foo" json:"foo" form:"foo" xml:"foo" binding:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FooBarStruct struct {
|
type FooBarStruct struct {
|
||||||
FooStruct
|
FooStruct
|
||||||
Bar string `json:"bar" form:"bar" xml:"bar" binding:"required"`
|
Bar string `msgpack:"bar" json:"bar" form:"bar" xml:"bar" binding:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBindingDefault(t *testing.T) {
|
func TestBindingDefault(t *testing.T) {
|
||||||
@ -43,6 +44,9 @@ func TestBindingDefault(t *testing.T) {
|
|||||||
|
|
||||||
assert.Equal(t, Default("POST", MIMEPROTOBUF), ProtoBuf)
|
assert.Equal(t, Default("POST", MIMEPROTOBUF), ProtoBuf)
|
||||||
assert.Equal(t, Default("PUT", MIMEPROTOBUF), ProtoBuf)
|
assert.Equal(t, Default("PUT", MIMEPROTOBUF), ProtoBuf)
|
||||||
|
|
||||||
|
assert.Equal(t, Default("POST", MIMEMSGPACK), MsgPack)
|
||||||
|
assert.Equal(t, Default("PUT", MIMEMSGPACK2), MsgPack)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBindingJSON(t *testing.T) {
|
func TestBindingJSON(t *testing.T) {
|
||||||
@ -121,6 +125,26 @@ func TestBindingProtoBuf(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"}`)
|
||||||
@ -213,6 +237,23 @@ func testProtoBodyBinding(t *testing.T, b Binding, name, path, badPath, body, ba
|
|||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testMsgPackBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
|
||||||
|
assert.Equal(t, b.Name(), 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, obj.Foo, "bar")
|
||||||
|
|
||||||
|
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
|
||||||
|
28
binding/msgpack.go
Normal file
28
binding/msgpack.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
package binding
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ugorji/go/codec"
|
||||||
|
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type msgpackBinding struct{}
|
||||||
|
|
||||||
|
func (msgpackBinding) Name() string {
|
||||||
|
return "msgpack"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msgpackBinding) Bind(req *http.Request, obj interface{}) error {
|
||||||
|
|
||||||
|
if err := codec.NewDecoder(req.Body, new(codec.MsgpackHandle)).Decode(&obj); err != nil {
|
||||||
|
//var decoder *codec.Decoder = codec.NewDecoder(req.Body, &codec.MsgpackHandle)
|
||||||
|
//if err := decoder.Decode(&obj); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return validate(obj)
|
||||||
|
|
||||||
|
}
|
27
render/msgpack.go
Normal file
27
render/msgpack.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
package render
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/ugorji/go/codec"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MsgPack struct {
|
||||||
|
Data interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
var msgpackContentType = []string{"application/msgpack; charset=utf-8"}
|
||||||
|
|
||||||
|
func (r MsgPack) Render(w http.ResponseWriter) error {
|
||||||
|
return WriteMsgPack(w, r.Data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func WriteMsgPack(w http.ResponseWriter, obj interface{}) error {
|
||||||
|
writeContentType(w, msgpackContentType)
|
||||||
|
var h codec.Handle = new(codec.MsgpackHandle)
|
||||||
|
return codec.NewEncoder(w, h).Encode(obj)
|
||||||
|
}
|
@ -22,6 +22,8 @@ var (
|
|||||||
_ HTMLRender = HTMLDebug{}
|
_ HTMLRender = HTMLDebug{}
|
||||||
_ HTMLRender = HTMLProduction{}
|
_ HTMLRender = HTMLProduction{}
|
||||||
_ Render = YAML{}
|
_ Render = YAML{}
|
||||||
|
_ Render = MsgPack{}
|
||||||
|
_ Render = MsgPack{}
|
||||||
)
|
)
|
||||||
|
|
||||||
func writeContentType(w http.ResponseWriter, value []string) {
|
func writeContentType(w http.ResponseWriter, value []string) {
|
||||||
|
@ -5,17 +5,40 @@
|
|||||||
package render
|
package render
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/ugorji/go/codec"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO unit tests
|
// TODO unit tests
|
||||||
// test errors
|
// test errors
|
||||||
|
|
||||||
|
func TestRenderMsgPack(t *testing.T) {
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
data := map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
}
|
||||||
|
|
||||||
|
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, w.Header().Get("Content-Type"), "application/msgpack; charset=utf-8")
|
||||||
|
}
|
||||||
|
|
||||||
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…
x
Reference in New Issue
Block a user