mirror of
https://github.com/kataras/iris.git
synced 2025-12-23 12:57:05 +00:00
improve remote addr parsing as requested at: https://github.com/kataras/iris/issues/1453
Former-commit-id: e5fde988eda9bf582b04285a1c77ba123910a699
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
package context
|
||||
|
||||
import (
|
||||
"github.com/kataras/iris/v12/core/netutil"
|
||||
)
|
||||
|
||||
// ConfigurationReadOnly can be implemented
|
||||
// by Configuration, it's being used inside the Context.
|
||||
// All methods that it contains should be "safe" to be called by the context
|
||||
@@ -91,7 +95,19 @@ type ConfigurationReadOnly interface {
|
||||
//
|
||||
// Look `context.RemoteAddr()` for more.
|
||||
GetRemoteAddrHeaders() map[string]bool
|
||||
|
||||
// GetRemoteAddrPrivateSubnets returns the configuration's private sub-networks.
|
||||
// They are used to be compared against
|
||||
// IP Addresses fetched through `RemoteAddrHeaders` or `Request.RemoteAddr`.
|
||||
// For details please navigate through: https://github.com/kataras/iris/issues/1453
|
||||
// Defaults to an empty slice, usage:
|
||||
//
|
||||
// RemoteAddrPrivateSubnets {
|
||||
// {Start: "10.0.0.0", End: "10.255.255.255"},
|
||||
// {Start: "100.64.0.0", End: "100.127.255.255"},
|
||||
// }
|
||||
//
|
||||
// Look `context.RemoteAddr()` for more.
|
||||
GetRemoteAddrPrivateSubnets() []netutil.IPRange
|
||||
// GetOther returns the configuration.Other map.
|
||||
GetOther() map[string]interface{}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/kataras/iris/v12/core/memstore"
|
||||
"github.com/kataras/iris/v12/core/netutil"
|
||||
|
||||
"github.com/Shopify/goreferrer"
|
||||
"github.com/fatih/structs"
|
||||
@@ -358,7 +359,8 @@ type Context interface {
|
||||
//
|
||||
// Look `Configuration.RemoteAddrHeaders`,
|
||||
// `Configuration.WithRemoteAddrHeader(...)`,
|
||||
// `Configuration.WithoutRemoteAddrHeader(...)` for more.
|
||||
// `Configuration.WithoutRemoteAddrHeader(...)`and
|
||||
// `Configuration.RemoteAddrPrivateSubnets` for more.
|
||||
RemoteAddr() string
|
||||
// GetHeader returns the request header's value based on its name.
|
||||
GetHeader(name string) string
|
||||
@@ -1753,25 +1755,20 @@ const xForwardedForHeaderKey = "X-Forwarded-For"
|
||||
//
|
||||
// Look `Configuration.RemoteAddrHeaders`,
|
||||
// `Configuration.WithRemoteAddrHeader(...)`,
|
||||
// `Configuration.WithoutRemoteAddrHeader(...)` for more.
|
||||
// `Configuration.WithoutRemoteAddrHeader(...)` and
|
||||
// `Configuration.RemoteAddrPrivateSubnets` for more.
|
||||
func (ctx *context) RemoteAddr() string {
|
||||
remoteHeaders := ctx.Application().ConfigurationReadOnly().GetRemoteAddrHeaders()
|
||||
privateSubnets := ctx.Application().ConfigurationReadOnly().GetRemoteAddrPrivateSubnets()
|
||||
|
||||
for headerName, enabled := range remoteHeaders {
|
||||
if enabled {
|
||||
headerValue := ctx.GetHeader(headerName)
|
||||
// exception needed for 'X-Forwarded-For' only , if enabled.
|
||||
if headerName == xForwardedForHeaderKey {
|
||||
idx := strings.IndexByte(headerValue, ',')
|
||||
if idx >= 0 {
|
||||
headerValue = headerValue[0:idx]
|
||||
}
|
||||
}
|
||||
if !enabled {
|
||||
continue
|
||||
}
|
||||
|
||||
realIP := strings.TrimSpace(headerValue)
|
||||
if realIP != "" {
|
||||
return realIP
|
||||
}
|
||||
ipAddresses := strings.Split(ctx.GetHeader(headerName), ",")
|
||||
if ip, ok := netutil.GetIPAddress(ipAddresses, privateSubnets); ok {
|
||||
return ip
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user