mirror of https://github.com/gin-gonic/gin.git
Merge branch 'gin-gonic:master' into options
This commit is contained in:
commit
72d213170f
|
@ -73,18 +73,18 @@ 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{}
|
||||
MsgPack = msgpackBinding{}
|
||||
YAML = yamlBinding{}
|
||||
Uri = uriBinding{}
|
||||
Header = headerBinding{}
|
||||
TOML = tomlBinding{}
|
||||
JSON BindingBody = jsonBinding{}
|
||||
XML BindingBody = xmlBinding{}
|
||||
Form Binding = formBinding{}
|
||||
Query Binding = queryBinding{}
|
||||
FormPost Binding = formPostBinding{}
|
||||
FormMultipart Binding = formMultipartBinding{}
|
||||
ProtoBuf BindingBody = protobufBinding{}
|
||||
MsgPack BindingBody = msgpackBinding{}
|
||||
YAML BindingBody = yamlBinding{}
|
||||
Uri BindingUri = uriBinding{}
|
||||
Header Binding = headerBinding{}
|
||||
TOML BindingBody = tomlBinding{}
|
||||
)
|
||||
|
||||
// Default returns the appropriate Binding instance based on the HTTP method
|
||||
|
|
20
context.go
20
context.go
|
@ -774,6 +774,26 @@ func (c *Context) ShouldBindBodyWith(obj any, bb binding.BindingBody) (err error
|
|||
return bb.BindBody(body, obj)
|
||||
}
|
||||
|
||||
// ShouldBindBodyWithJSON is a shortcut for c.ShouldBindBodyWith(obj, binding.JSON).
|
||||
func (c *Context) ShouldBindBodyWithJSON(obj any) error {
|
||||
return c.ShouldBindBodyWith(obj, binding.JSON)
|
||||
}
|
||||
|
||||
// ShouldBindBodyWithXML is a shortcut for c.ShouldBindBodyWith(obj, binding.XML).
|
||||
func (c *Context) ShouldBindBodyWithXML(obj any) error {
|
||||
return c.ShouldBindBodyWith(obj, binding.XML)
|
||||
}
|
||||
|
||||
// ShouldBindBodyWithYAML is a shortcut for c.ShouldBindBodyWith(obj, binding.YAML).
|
||||
func (c *Context) ShouldBindBodyWithYAML(obj any) error {
|
||||
return c.ShouldBindBodyWith(obj, binding.YAML)
|
||||
}
|
||||
|
||||
// ShouldBindBodyWithTOML is a shortcut for c.ShouldBindBodyWith(obj, binding.TOML).
|
||||
func (c *Context) ShouldBindBodyWithTOML(obj any) error {
|
||||
return c.ShouldBindBodyWith(obj, binding.TOML)
|
||||
}
|
||||
|
||||
// ClientIP implements one best effort algorithm to return the real client IP.
|
||||
// It calls c.RemoteIP() under the hood, to check if the remote IP is a trusted proxy or not.
|
||||
// If it is it will then try to parse the headers defined in Engine.RemoteIPHeaders (defaulting to [X-Forwarded-For, X-Real-Ip]).
|
||||
|
|
257
context_test.go
257
context_test.go
|
@ -1977,6 +1977,263 @@ func TestContextShouldBindBodyWith(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestContextShouldBindBodyWithJSON(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
bindingBody binding.BindingBody
|
||||
body string
|
||||
}{
|
||||
{
|
||||
name: " JSON & JSON-BODY ",
|
||||
bindingBody: binding.JSON,
|
||||
body: `{"foo":"FOO"}`,
|
||||
},
|
||||
{
|
||||
name: " JSON & XML-BODY ",
|
||||
bindingBody: binding.XML,
|
||||
body: `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<root>
|
||||
<foo>FOO</foo>
|
||||
</root>`,
|
||||
},
|
||||
{
|
||||
name: " JSON & YAML-BODY ",
|
||||
bindingBody: binding.YAML,
|
||||
body: `foo: FOO`,
|
||||
},
|
||||
{
|
||||
name: " JSON & TOM-BODY ",
|
||||
bindingBody: binding.TOML,
|
||||
body: `foo=FOO`,
|
||||
},
|
||||
} {
|
||||
t.Logf("testing: %s", tt.name)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(tt.body))
|
||||
|
||||
type typeJSON struct {
|
||||
Foo string `json:"foo" binding:"required"`
|
||||
}
|
||||
objJSON := typeJSON{}
|
||||
|
||||
if tt.bindingBody == binding.JSON {
|
||||
assert.NoError(t, c.ShouldBindBodyWithJSON(&objJSON))
|
||||
assert.Equal(t, typeJSON{"FOO"}, objJSON)
|
||||
}
|
||||
|
||||
if tt.bindingBody == binding.XML {
|
||||
assert.Error(t, c.ShouldBindBodyWithJSON(&objJSON))
|
||||
assert.Equal(t, typeJSON{}, objJSON)
|
||||
}
|
||||
|
||||
if tt.bindingBody == binding.YAML {
|
||||
assert.Error(t, c.ShouldBindBodyWithJSON(&objJSON))
|
||||
assert.Equal(t, typeJSON{}, objJSON)
|
||||
}
|
||||
|
||||
if tt.bindingBody == binding.TOML {
|
||||
assert.Error(t, c.ShouldBindBodyWithJSON(&objJSON))
|
||||
assert.Equal(t, typeJSON{}, objJSON)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextShouldBindBodyWithXML(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
bindingBody binding.BindingBody
|
||||
body string
|
||||
}{
|
||||
{
|
||||
name: " XML & JSON-BODY ",
|
||||
bindingBody: binding.JSON,
|
||||
body: `{"foo":"FOO"}`,
|
||||
},
|
||||
{
|
||||
name: " XML & XML-BODY ",
|
||||
bindingBody: binding.XML,
|
||||
body: `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<root>
|
||||
<foo>FOO</foo>
|
||||
</root>`,
|
||||
},
|
||||
{
|
||||
name: " XML & YAML-BODY ",
|
||||
bindingBody: binding.YAML,
|
||||
body: `foo: FOO`,
|
||||
},
|
||||
{
|
||||
name: " XML & TOM-BODY ",
|
||||
bindingBody: binding.TOML,
|
||||
body: `foo=FOO`,
|
||||
},
|
||||
} {
|
||||
t.Logf("testing: %s", tt.name)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(tt.body))
|
||||
|
||||
type typeXML struct {
|
||||
Foo string `xml:"foo" binding:"required"`
|
||||
}
|
||||
objXML := typeXML{}
|
||||
|
||||
if tt.bindingBody == binding.JSON {
|
||||
assert.Error(t, c.ShouldBindBodyWithXML(&objXML))
|
||||
assert.Equal(t, typeXML{}, objXML)
|
||||
}
|
||||
|
||||
if tt.bindingBody == binding.XML {
|
||||
assert.NoError(t, c.ShouldBindBodyWithXML(&objXML))
|
||||
assert.Equal(t, typeXML{"FOO"}, objXML)
|
||||
}
|
||||
|
||||
if tt.bindingBody == binding.YAML {
|
||||
assert.Error(t, c.ShouldBindBodyWithXML(&objXML))
|
||||
assert.Equal(t, typeXML{}, objXML)
|
||||
}
|
||||
|
||||
if tt.bindingBody == binding.TOML {
|
||||
assert.Error(t, c.ShouldBindBodyWithXML(&objXML))
|
||||
assert.Equal(t, typeXML{}, objXML)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextShouldBindBodyWithYAML(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
bindingBody binding.BindingBody
|
||||
body string
|
||||
}{
|
||||
{
|
||||
name: " YAML & JSON-BODY ",
|
||||
bindingBody: binding.JSON,
|
||||
body: `{"foo":"FOO"}`,
|
||||
},
|
||||
{
|
||||
name: " YAML & XML-BODY ",
|
||||
bindingBody: binding.XML,
|
||||
body: `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<root>
|
||||
<foo>FOO</foo>
|
||||
</root>`,
|
||||
},
|
||||
{
|
||||
name: " YAML & YAML-BODY ",
|
||||
bindingBody: binding.YAML,
|
||||
body: `foo: FOO`,
|
||||
},
|
||||
{
|
||||
name: " YAML & TOM-BODY ",
|
||||
bindingBody: binding.TOML,
|
||||
body: `foo=FOO`,
|
||||
},
|
||||
} {
|
||||
t.Logf("testing: %s", tt.name)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(tt.body))
|
||||
|
||||
type typeYAML struct {
|
||||
Foo string `yaml:"foo" binding:"required"`
|
||||
}
|
||||
objYAML := typeYAML{}
|
||||
|
||||
// YAML belongs to a super collection of JSON, so JSON can be parsed by YAML
|
||||
if tt.bindingBody == binding.JSON {
|
||||
assert.NoError(t, c.ShouldBindBodyWithYAML(&objYAML))
|
||||
assert.Equal(t, typeYAML{"FOO"}, objYAML)
|
||||
}
|
||||
|
||||
if tt.bindingBody == binding.XML {
|
||||
assert.Error(t, c.ShouldBindBodyWithYAML(&objYAML))
|
||||
assert.Equal(t, typeYAML{}, objYAML)
|
||||
}
|
||||
|
||||
if tt.bindingBody == binding.YAML {
|
||||
assert.NoError(t, c.ShouldBindBodyWithYAML(&objYAML))
|
||||
assert.Equal(t, typeYAML{"FOO"}, objYAML)
|
||||
}
|
||||
|
||||
if tt.bindingBody == binding.TOML {
|
||||
assert.Error(t, c.ShouldBindBodyWithYAML(&objYAML))
|
||||
assert.Equal(t, typeYAML{}, objYAML)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextShouldBindBodyWithTOML(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
name string
|
||||
bindingBody binding.BindingBody
|
||||
body string
|
||||
}{
|
||||
{
|
||||
name: " TOML & JSON-BODY ",
|
||||
bindingBody: binding.JSON,
|
||||
body: `{"foo":"FOO"}`,
|
||||
},
|
||||
{
|
||||
name: " TOML & XML-BODY ",
|
||||
bindingBody: binding.XML,
|
||||
body: `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<root>
|
||||
<foo>FOO</foo>
|
||||
</root>`,
|
||||
},
|
||||
{
|
||||
name: " TOML & YAML-BODY ",
|
||||
bindingBody: binding.YAML,
|
||||
body: `foo: FOO`,
|
||||
},
|
||||
{
|
||||
name: " TOML & TOM-BODY ",
|
||||
bindingBody: binding.TOML,
|
||||
body: `foo = 'FOO'`,
|
||||
},
|
||||
} {
|
||||
t.Logf("testing: %s", tt.name)
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
|
||||
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(tt.body))
|
||||
|
||||
type typeTOML struct {
|
||||
Foo string `toml:"foo" binding:"required"`
|
||||
}
|
||||
objTOML := typeTOML{}
|
||||
|
||||
if tt.bindingBody == binding.JSON {
|
||||
assert.Error(t, c.ShouldBindBodyWithTOML(&objTOML))
|
||||
assert.Equal(t, typeTOML{}, objTOML)
|
||||
}
|
||||
|
||||
if tt.bindingBody == binding.XML {
|
||||
assert.Error(t, c.ShouldBindBodyWithTOML(&objTOML))
|
||||
assert.Equal(t, typeTOML{}, objTOML)
|
||||
}
|
||||
|
||||
if tt.bindingBody == binding.YAML {
|
||||
assert.Error(t, c.ShouldBindBodyWithTOML(&objTOML))
|
||||
assert.Equal(t, typeTOML{}, objTOML)
|
||||
}
|
||||
|
||||
if tt.bindingBody == binding.TOML {
|
||||
assert.NoError(t, c.ShouldBindBodyWithTOML(&objTOML))
|
||||
assert.Equal(t, typeTOML{"FOO"}, objTOML)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextGolangContext(t *testing.T) {
|
||||
c, _ := CreateTestContext(httptest.NewRecorder())
|
||||
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
|
||||
|
|
|
@ -1956,7 +1956,12 @@ func SomeHandler(c *gin.Context) {
|
|||
}
|
||||
```
|
||||
|
||||
For this, you can use `c.ShouldBindBodyWith`.
|
||||
For this, you can use `c.ShouldBindBodyWith` or shortcuts.
|
||||
|
||||
- `c.ShouldBindBodyWithJSON` is a shortcut for c.ShouldBindBodyWith(obj, binding.JSON).
|
||||
- `c.ShouldBindBodyWithXML` is a shortcut for c.ShouldBindBodyWith(obj, binding.XML).
|
||||
- `c.ShouldBindBodyWithYAML` is a shortcut for c.ShouldBindBodyWith(obj, binding.YAML).
|
||||
- `c.ShouldBindBodyWithTOML` is a shortcut for c.ShouldBindBodyWith(obj, binding.TOML).
|
||||
|
||||
```go
|
||||
func SomeHandler(c *gin.Context) {
|
||||
|
@ -1969,7 +1974,7 @@ func SomeHandler(c *gin.Context) {
|
|||
} else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
|
||||
c.String(http.StatusOK, `the body should be formB JSON`)
|
||||
// And it can accepts other formats
|
||||
} else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
|
||||
} else if errB2 := c.ShouldBindBodyWithXML(&objB); errB2 == nil {
|
||||
c.String(http.StatusOK, `the body should be formB XML`)
|
||||
} else {
|
||||
...
|
||||
|
|
Loading…
Reference in New Issue