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
|
// These implement the Binding interface and can be used to bind the data
|
||||||
// present in the request to struct instances.
|
// present in the request to struct instances.
|
||||||
var (
|
var (
|
||||||
JSON = jsonBinding{}
|
JSON BindingBody = jsonBinding{}
|
||||||
XML = xmlBinding{}
|
XML BindingBody = xmlBinding{}
|
||||||
Form = formBinding{}
|
Form Binding = formBinding{}
|
||||||
Query = queryBinding{}
|
Query Binding = queryBinding{}
|
||||||
FormPost = formPostBinding{}
|
FormPost Binding = formPostBinding{}
|
||||||
FormMultipart = formMultipartBinding{}
|
FormMultipart Binding = formMultipartBinding{}
|
||||||
ProtoBuf = protobufBinding{}
|
ProtoBuf BindingBody = protobufBinding{}
|
||||||
MsgPack = msgpackBinding{}
|
MsgPack BindingBody = msgpackBinding{}
|
||||||
YAML = yamlBinding{}
|
YAML BindingBody = yamlBinding{}
|
||||||
Uri = uriBinding{}
|
Uri BindingUri = uriBinding{}
|
||||||
Header = headerBinding{}
|
Header Binding = headerBinding{}
|
||||||
TOML = tomlBinding{}
|
TOML BindingBody = tomlBinding{}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Default returns the appropriate Binding instance based on the HTTP method
|
// 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)
|
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.
|
// 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.
|
// 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]).
|
// 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) {
|
func TestContextGolangContext(t *testing.T) {
|
||||||
c, _ := CreateTestContext(httptest.NewRecorder())
|
c, _ := CreateTestContext(httptest.NewRecorder())
|
||||||
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
|
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
|
```go
|
||||||
func SomeHandler(c *gin.Context) {
|
func SomeHandler(c *gin.Context) {
|
||||||
|
@ -1969,7 +1974,7 @@ func SomeHandler(c *gin.Context) {
|
||||||
} else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
|
} else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
|
||||||
c.String(http.StatusOK, `the body should be formB JSON`)
|
c.String(http.StatusOK, `the body should be formB JSON`)
|
||||||
// And it can accepts other formats
|
// 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`)
|
c.String(http.StatusOK, `the body should be formB XML`)
|
||||||
} else {
|
} else {
|
||||||
...
|
...
|
||||||
|
|
Loading…
Reference in New Issue