Compare commits

...

5 Commits

Author SHA1 Message Date
hooting
cab6920af5
Merge 84a97ef73e13c71e757aaefddbaf9213e6bc3442 into b2b489dbf4826c2c630717a77fd5e42774625410 2026-01-18 14:22:35 +08:00
WeidiDeng
b2b489dbf4
chore(context): always trust xff headers from unix socket (#3359)
Co-authored-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2026-01-18 12:56:22 +08:00
Bo-Yi Wu
84a97ef73e
Merge branch 'master' into master 2021-05-02 10:06:14 +08:00
thinkerou
81c4110cb4
Merge branch 'master' into master 2021-04-09 19:53:43 +08:00
unknown
24cea05888 1. add ShouldBindMsgPack; 2. seriallize the given struct as MsgPack into the response body. 2021-03-30 15:07:39 +08:00
2 changed files with 41 additions and 7 deletions

View File

@ -857,6 +857,11 @@ func (c *Context) ShouldBindJSON(obj any) error {
return c.ShouldBindWith(obj, binding.JSON)
}
// ShouldBindMsgPack is a shortcut for c.ShouldBindWith(obj, binding.MsgPack).
func (c *Context) ShouldBindMsgPack(obj interface{}) error {
return c.ShouldBindWith(obj, binding.MsgPack)
}
// ShouldBindXML is a shortcut for c.ShouldBindWith(obj, binding.XML).
// It works like ShouldBindJSON but binds the request body as XML data.
func (c *Context) ShouldBindXML(obj any) error {
@ -978,14 +983,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 {
@ -1181,6 +1199,12 @@ func (c *Context) JSON(code int, obj any) {
c.Render(code, render.JSON{Data: obj})
}
// MsgPack serializes the given struct as MsgPack into the response body.
// It also sets the Content-Type as "application/msgpack".
func (c *Context) MsgPack(code int, obj interface{}) {
c.Render(code, render.MsgPack{Data: obj})
}
// AsciiJSON serializes the given struct as JSON into the response body with unicode to ASCII string.
// It also sets the Content-Type as "application/json".
func (c *Context) AsciiJSON(code int, obj any) {

View File

@ -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())