mirror of
https://github.com/gin-gonic/gin.git
synced 2026-06-11 07:58:14 +08:00
Compare commits
3 Commits
695e2acec0
...
be63befeb2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be63befeb2 | ||
|
|
b2b489dbf4 | ||
|
|
f2443d1877 |
@ -231,19 +231,24 @@ func setByForm(value reflect.Value, field reflect.StructField, form map[string][
|
||||
|
||||
switch value.Kind() {
|
||||
case reflect.Slice:
|
||||
if len(vs) == 0 {
|
||||
if vs == nil {
|
||||
if !opt.isDefaultExists {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
vs = []string{opt.defaultValue}
|
||||
// pre-process the default value for multi if present
|
||||
cfTag := field.Tag.Get("collection_format")
|
||||
if cfTag == "" || cfTag == "multi" {
|
||||
vs = strings.Split(opt.defaultValue, ",")
|
||||
} else {
|
||||
vs = []string{opt.defaultValue}
|
||||
}
|
||||
}
|
||||
|
||||
if len(vs) == 0 {
|
||||
return true, setSlice(vs, value, field)
|
||||
}
|
||||
|
||||
if ok, err = trySetCustom(vs[0], value); ok {
|
||||
return ok, err
|
||||
}
|
||||
@ -259,11 +264,12 @@ func setByForm(value reflect.Value, field reflect.StructField, form map[string][
|
||||
return false, nil
|
||||
}
|
||||
|
||||
vs = []string{opt.defaultValue}
|
||||
// pre-process the default value for multi if present
|
||||
cfTag := field.Tag.Get("collection_format")
|
||||
if cfTag == "" || cfTag == "multi" {
|
||||
vs = strings.Split(opt.defaultValue, ",")
|
||||
} else {
|
||||
vs = []string{opt.defaultValue}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -689,7 +689,7 @@ func TestMappingEmptyValues(t *testing.T) {
|
||||
// field present but empty
|
||||
err = mappingByPtr(&s, formSource{"slice": {}}, "form")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []int{5}, s.Slice)
|
||||
assert.Equal(t, []int{}, s.Slice)
|
||||
|
||||
// field present with values
|
||||
err = mappingByPtr(&s, formSource{"slice": {"1", "2", "3"}}, "form")
|
||||
@ -718,10 +718,15 @@ func TestMappingEmptyValues(t *testing.T) {
|
||||
Slice []int `form:"slice"`
|
||||
}
|
||||
|
||||
// field present but empty
|
||||
err := mappingByPtr(&s, formSource{"slice": {}}, "form")
|
||||
// field not present
|
||||
err := mappingByPtr(&s, formSource{}, "form")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []int(nil), s.Slice)
|
||||
|
||||
// field present but empty
|
||||
err = mappingByPtr(&s, formSource{"slice": {}}, "form")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []int{}, s.Slice)
|
||||
})
|
||||
|
||||
t.Run("array without default", func(t *testing.T) {
|
||||
@ -750,7 +755,7 @@ func TestMappingEmptyValues(t *testing.T) {
|
||||
// field present but empty
|
||||
err = mappingByPtr(&s, formSource{"slice_multi": {}, "slice_csv": {}}, "form")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []int{1, 2, 3}, s.SliceMulti)
|
||||
assert.Equal(t, []int{1, 2, 3}, s.SliceCsv)
|
||||
assert.Equal(t, []int{}, s.SliceMulti)
|
||||
assert.Equal(t, []int{}, s.SliceCsv)
|
||||
})
|
||||
}
|
||||
|
||||
27
context.go
27
context.go
@ -978,14 +978,27 @@ func (c *Context) ClientIP() string {
|
||||
}
|
||||
}
|
||||
|
||||
// It also checks if the remoteIP is a trusted proxy or not.
|
||||
// In order to perform this validation, it will see if the IP is contained within at least one of the CIDR blocks
|
||||
// defined by Engine.SetTrustedProxies()
|
||||
remoteIP := net.ParseIP(c.RemoteIP())
|
||||
if remoteIP == nil {
|
||||
return ""
|
||||
var (
|
||||
trusted bool
|
||||
remoteIP net.IP
|
||||
)
|
||||
// If gin is listening a unix socket, always trust it.
|
||||
localAddr, ok := c.Request.Context().Value(http.LocalAddrContextKey).(net.Addr)
|
||||
if ok && strings.HasPrefix(localAddr.Network(), "unix") {
|
||||
trusted = true
|
||||
}
|
||||
|
||||
// Fallback
|
||||
if !trusted {
|
||||
// It also checks if the remoteIP is a trusted proxy or not.
|
||||
// In order to perform this validation, it will see if the IP is contained within at least one of the CIDR blocks
|
||||
// defined by Engine.SetTrustedProxies()
|
||||
remoteIP = net.ParseIP(c.RemoteIP())
|
||||
if remoteIP == nil {
|
||||
return ""
|
||||
}
|
||||
trusted = c.engine.isTrustedProxy(remoteIP)
|
||||
}
|
||||
trusted := c.engine.isTrustedProxy(remoteIP)
|
||||
|
||||
if trusted && c.engine.ForwardedByClientIP && c.engine.RemoteIPHeaders != nil {
|
||||
for _, headerName := range c.engine.RemoteIPHeaders {
|
||||
|
||||
@ -1915,6 +1915,16 @@ func TestContextClientIP(t *testing.T) {
|
||||
c.engine.trustedCIDRs, _ = c.engine.prepareTrustedCIDRs()
|
||||
resetContextForClientIPTests(c)
|
||||
|
||||
// unix address
|
||||
addr := &net.UnixAddr{Net: "unix", Name: "@"}
|
||||
c.Request = c.Request.WithContext(context.WithValue(c.Request.Context(), http.LocalAddrContextKey, addr))
|
||||
c.Request.RemoteAddr = addr.String()
|
||||
assert.Equal(t, "20.20.20.20", c.ClientIP())
|
||||
|
||||
// reset
|
||||
c.Request = c.Request.WithContext(context.Background())
|
||||
resetContextForClientIPTests(c)
|
||||
|
||||
// Legacy tests (validating that the defaults don't break the
|
||||
// (insecure!) old behaviour)
|
||||
assert.Equal(t, "20.20.20.20", c.ClientIP())
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user