mirror of
https://github.com/gin-gonic/gin.git
synced 2025-10-16 21:32:11 +08:00
refactor for c.ClientIP() and c.RemoteIP()
This commit is contained in:
parent
eb75ce0ff5
commit
cab1bb9a40
53
context.go
53
context.go
@ -757,11 +757,16 @@ func (c *Context) ClientIP() string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
remoteIP, trusted := c.RemoteIP()
|
remoteIP := net.ParseIP(c.RemoteIP())
|
||||||
if remoteIP == nil {
|
if remoteIP == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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()
|
||||||
|
trusted := c.engine.isTrustedProxy(remoteIP)
|
||||||
|
|
||||||
if trusted && c.engine.ForwardedByClientIP && c.engine.RemoteIPHeaders != nil {
|
if trusted && c.engine.ForwardedByClientIP && c.engine.RemoteIPHeaders != nil {
|
||||||
for _, headerName := range c.engine.RemoteIPHeaders {
|
for _, headerName := range c.engine.RemoteIPHeaders {
|
||||||
ip, valid := c.engine.validateHeader(c.requestHeader(headerName))
|
ip, valid := c.engine.validateHeader(c.requestHeader(headerName))
|
||||||
@ -773,53 +778,15 @@ func (c *Context) ClientIP() string {
|
|||||||
return remoteIP.String()
|
return remoteIP.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) isTrustedProxy(ip net.IP) bool {
|
|
||||||
if e.trustedCIDRs != nil {
|
|
||||||
for _, cidr := range e.trustedCIDRs {
|
|
||||||
if cidr.Contains(ip) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoteIP parses the IP from Request.RemoteAddr, normalizes and returns the IP (without the port).
|
// RemoteIP parses the IP from Request.RemoteAddr, normalizes and returns the IP (without the port).
|
||||||
// It also checks if the remoteIP is a trusted proxy or not.
|
// And it will return empty string if error.
|
||||||
// In order to perform this validation, it will see if the IP is contained within at least one of the CIDR blocks
|
func (c *Context) RemoteIP() string {
|
||||||
// defined by Engine.SetTrustedProxies()
|
|
||||||
func (c *Context) RemoteIP() (net.IP, bool) {
|
|
||||||
ip, _, err := net.SplitHostPort(strings.TrimSpace(c.Request.RemoteAddr))
|
ip, _, err := net.SplitHostPort(strings.TrimSpace(c.Request.RemoteAddr))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false
|
return ""
|
||||||
}
|
|
||||||
remoteIP := net.ParseIP(ip)
|
|
||||||
if remoteIP == nil {
|
|
||||||
return nil, false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return remoteIP, c.engine.isTrustedProxy(remoteIP)
|
return ip
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Engine) validateHeader(header string) (clientIP string, valid bool) {
|
|
||||||
if header == "" {
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
items := strings.Split(header, ",")
|
|
||||||
for i := len(items) - 1; i >= 0; i-- {
|
|
||||||
ipStr := strings.TrimSpace(items[i])
|
|
||||||
ip := net.ParseIP(ipStr)
|
|
||||||
if ip == nil {
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
|
|
||||||
// X-Forwarded-For is appended by proxy
|
|
||||||
// Check IPs in reverse order and stop when find untrusted proxy
|
|
||||||
if (i == 0) || (!e.isTrustedProxy(ip)) {
|
|
||||||
return ipStr, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContentType returns the Content-Type header of the request.
|
// ContentType returns the Content-Type header of the request.
|
||||||
|
32
gin.go
32
gin.go
@ -404,6 +404,38 @@ func (engine *Engine) isUnsafeTrustedProxies() bool {
|
|||||||
return reflect.DeepEqual(engine.trustedCIDRs, defaultTrustedCIDRs)
|
return reflect.DeepEqual(engine.trustedCIDRs, defaultTrustedCIDRs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (engine *Engine) isTrustedProxy(ip net.IP) bool {
|
||||||
|
if engine.trustedCIDRs != nil {
|
||||||
|
for _, cidr := range engine.trustedCIDRs {
|
||||||
|
if cidr.Contains(ip) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (engine *Engine) validateHeader(header string) (clientIP string, valid bool) {
|
||||||
|
if header == "" {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
items := strings.Split(header, ",")
|
||||||
|
for i := len(items) - 1; i >= 0; i-- {
|
||||||
|
ipStr := strings.TrimSpace(items[i])
|
||||||
|
ip := net.ParseIP(ipStr)
|
||||||
|
if ip == nil {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
// X-Forwarded-For is appended by proxy
|
||||||
|
// Check IPs in reverse order and stop when find untrusted proxy
|
||||||
|
if (i == 0) || (!engine.isTrustedProxy(ip)) {
|
||||||
|
return ipStr, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// parseTrustedProxies parse Engine.trustedProxies to Engine.trustedCIDRs
|
// parseTrustedProxies parse Engine.trustedProxies to Engine.trustedCIDRs
|
||||||
func (engine *Engine) parseTrustedProxies() error {
|
func (engine *Engine) parseTrustedProxies() error {
|
||||||
trustedCIDRs, err := engine.prepareTrustedCIDRs()
|
trustedCIDRs, err := engine.prepareTrustedCIDRs()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user