Yaml binding (#1618)
* Add YAML binding for application/x-yaml. * Add YAML binding methods to Context. * Review fixes. * Revert accidentally removed import.
This commit is contained in:
@ -18,6 +18,7 @@ const (
|
||||
MIMEPROTOBUF = "application/x-protobuf"
|
||||
MIMEMSGPACK = "application/x-msgpack"
|
||||
MIMEMSGPACK2 = "application/msgpack"
|
||||
MIMEYAML = "application/x-yaml"
|
||||
)
|
||||
|
||||
// Binding describes the interface which needs to be implemented for binding the
|
||||
@ -68,6 +69,7 @@ var (
|
||||
FormMultipart = formMultipartBinding{}
|
||||
ProtoBuf = protobufBinding{}
|
||||
MsgPack = msgpackBinding{}
|
||||
YAML = yamlBinding{}
|
||||
)
|
||||
|
||||
// Default returns the appropriate Binding instance based on the HTTP method
|
||||
@ -86,6 +88,8 @@ func Default(method, contentType string) Binding {
|
||||
return ProtoBuf
|
||||
case MIMEMSGPACK, MIMEMSGPACK2:
|
||||
return MsgPack
|
||||
case MIMEYAML:
|
||||
return YAML
|
||||
default: //case MIMEPOSTForm, MIMEMultipartPOSTForm:
|
||||
return Form
|
||||
}
|
||||
|
@ -19,12 +19,12 @@ func TestBindingBody(t *testing.T) {
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "JSON bidning",
|
||||
name: "JSON binding",
|
||||
binding: JSON,
|
||||
body: `{"foo":"FOO"}`,
|
||||
},
|
||||
{
|
||||
name: "XML bidning",
|
||||
name: "XML binding",
|
||||
binding: XML,
|
||||
body: `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<root>
|
||||
@ -36,6 +36,11 @@ func TestBindingBody(t *testing.T) {
|
||||
binding: MsgPack,
|
||||
body: msgPackBody(t),
|
||||
},
|
||||
{
|
||||
name: "YAML binding",
|
||||
binding: YAML,
|
||||
body: `foo: FOO`,
|
||||
},
|
||||
} {
|
||||
t.Logf("testing: %s", tt.name)
|
||||
req := requestWithBody("POST", "/", tt.body)
|
||||
|
@ -190,6 +190,9 @@ func TestBindingDefault(t *testing.T) {
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
func TestBindingJSON(t *testing.T) {
|
||||
@ -473,6 +476,20 @@ func TestBindingXMLFail(t *testing.T) {
|
||||
"<map><foo>bar<foo></map>", "<map><bar>foo</bar></map>")
|
||||
}
|
||||
|
||||
func TestBindingYAML(t *testing.T) {
|
||||
testBodyBinding(t,
|
||||
YAML, "yaml",
|
||||
"/", "/",
|
||||
`foo: bar`, `bar: foo`)
|
||||
}
|
||||
|
||||
func TestBindingYAMLFail(t *testing.T) {
|
||||
testBodyBindingFail(t,
|
||||
YAML, "yaml",
|
||||
"/", "/",
|
||||
`foo:\nbar`, `bar: foo`)
|
||||
}
|
||||
|
||||
func createFormPostRequest() *http.Request {
|
||||
req, _ := http.NewRequest("POST", "/?foo=getfoo&bar=getbar", bytes.NewBufferString("foo=bar&bar=foo"))
|
||||
req.Header.Set("Content-Type", MIMEPOSTForm)
|
||||
|
35
binding/yaml.go
Normal file
35
binding/yaml.go
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
package binding
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
type yamlBinding struct{}
|
||||
|
||||
func (yamlBinding) Name() string {
|
||||
return "yaml"
|
||||
}
|
||||
|
||||
func (yamlBinding) Bind(req *http.Request, obj interface{}) error {
|
||||
return decodeYAML(req.Body, obj)
|
||||
}
|
||||
|
||||
func (yamlBinding) BindBody(body []byte, obj interface{}) error {
|
||||
return decodeYAML(bytes.NewReader(body), obj)
|
||||
}
|
||||
|
||||
func decodeYAML(r io.Reader, obj interface{}) error {
|
||||
decoder := yaml.NewDecoder(r)
|
||||
if err := decoder.Decode(obj); err != nil {
|
||||
return err
|
||||
}
|
||||
return validate(obj)
|
||||
}
|
Reference in New Issue
Block a user