mirror of https://github.com/gin-gonic/gin.git
Setting trusted platform using an enum-like (#2739)
This commit is contained in:
parent
fb8a113f8d
commit
dd8a27c0b6
16
context.go
16
context.go
|
@ -9,6 +9,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"math"
|
"math"
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
"net"
|
"net"
|
||||||
|
@ -731,17 +732,26 @@ func (c *Context) ShouldBindBodyWith(obj interface{}, bb binding.BindingBody) (e
|
||||||
// If the headers are nots syntactically valid OR the remote IP does not correspong to a trusted proxy,
|
// If the headers are nots syntactically valid OR the remote IP does not correspong to a trusted proxy,
|
||||||
// the remote IP (coming form Request.RemoteAddr) is returned.
|
// the remote IP (coming form Request.RemoteAddr) is returned.
|
||||||
func (c *Context) ClientIP() string {
|
func (c *Context) ClientIP() string {
|
||||||
switch {
|
// Check if we're running on a tursted platform
|
||||||
case c.engine.AppEngine:
|
switch c.engine.TrustedPlatform {
|
||||||
|
case PlatformGoogleAppEngine:
|
||||||
if addr := c.requestHeader("X-Appengine-Remote-Addr"); addr != "" {
|
if addr := c.requestHeader("X-Appengine-Remote-Addr"); addr != "" {
|
||||||
return addr
|
return addr
|
||||||
}
|
}
|
||||||
case c.engine.CloudflareProxy:
|
case PlatformCloudflare:
|
||||||
if addr := c.requestHeader("CF-Connecting-IP"); addr != "" {
|
if addr := c.requestHeader("CF-Connecting-IP"); addr != "" {
|
||||||
return addr
|
return addr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Legacy "AppEngine" flag
|
||||||
|
if c.engine.AppEngine {
|
||||||
|
log.Println(`The AppEngine flag is going to be deprecated. Please check issues #2723 and #2739 and use 'TrustedPlatform: gin.PlatformGoogleAppEngine' instead.`)
|
||||||
|
if addr := c.requestHeader("X-Appengine-Remote-Addr"); addr != "" {
|
||||||
|
return addr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
remoteIP, trusted := c.RemoteIP()
|
remoteIP, trusted := c.RemoteIP()
|
||||||
if remoteIP == nil {
|
if remoteIP == nil {
|
||||||
return ""
|
return ""
|
||||||
|
|
|
@ -8,5 +8,5 @@
|
||||||
package gin
|
package gin
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
defaultAppEngine = true
|
defaultPlatform = PlatformGoogleAppEngine
|
||||||
}
|
}
|
||||||
|
|
|
@ -1410,7 +1410,7 @@ func TestContextClientIP(t *testing.T) {
|
||||||
|
|
||||||
c.Request.Header.Del("X-Forwarded-For")
|
c.Request.Header.Del("X-Forwarded-For")
|
||||||
c.Request.Header.Del("X-Real-IP")
|
c.Request.Header.Del("X-Real-IP")
|
||||||
c.engine.AppEngine = true
|
c.engine.TrustedPlatform = PlatformGoogleAppEngine
|
||||||
assert.Equal(t, "50.50.50.50", c.ClientIP())
|
assert.Equal(t, "50.50.50.50", c.ClientIP())
|
||||||
|
|
||||||
c.Request.Header.Del("X-Appengine-Remote-Addr")
|
c.Request.Header.Del("X-Appengine-Remote-Addr")
|
||||||
|
@ -1470,19 +1470,27 @@ func TestContextClientIP(t *testing.T) {
|
||||||
assert.Equal(t, "10.10.10.10", c.ClientIP())
|
assert.Equal(t, "10.10.10.10", c.ClientIP())
|
||||||
|
|
||||||
c.engine.RemoteIPHeaders = []string{}
|
c.engine.RemoteIPHeaders = []string{}
|
||||||
|
c.engine.TrustedPlatform = PlatformGoogleAppEngine
|
||||||
|
assert.Equal(t, "50.50.50.50", c.ClientIP())
|
||||||
|
|
||||||
|
// Test the legacy flag
|
||||||
|
c.engine.TrustedPlatform = ""
|
||||||
c.engine.AppEngine = true
|
c.engine.AppEngine = true
|
||||||
assert.Equal(t, "50.50.50.50", c.ClientIP())
|
assert.Equal(t, "50.50.50.50", c.ClientIP())
|
||||||
|
c.engine.AppEngine = false
|
||||||
|
c.engine.TrustedPlatform = PlatformGoogleAppEngine
|
||||||
|
|
||||||
c.Request.Header.Del("X-Appengine-Remote-Addr")
|
c.Request.Header.Del("X-Appengine-Remote-Addr")
|
||||||
assert.Equal(t, "40.40.40.40", c.ClientIP())
|
assert.Equal(t, "40.40.40.40", c.ClientIP())
|
||||||
|
|
||||||
c.engine.AppEngine = false
|
c.engine.TrustedPlatform = PlatformCloudflare
|
||||||
c.engine.CloudflareProxy = true
|
|
||||||
assert.Equal(t, "60.60.60.60", c.ClientIP())
|
assert.Equal(t, "60.60.60.60", c.ClientIP())
|
||||||
|
|
||||||
c.Request.Header.Del("CF-Connecting-IP")
|
c.Request.Header.Del("CF-Connecting-IP")
|
||||||
assert.Equal(t, "40.40.40.40", c.ClientIP())
|
assert.Equal(t, "40.40.40.40", c.ClientIP())
|
||||||
|
|
||||||
|
c.engine.TrustedPlatform = ""
|
||||||
|
|
||||||
// no port
|
// no port
|
||||||
c.Request.RemoteAddr = "50.50.50.50"
|
c.Request.RemoteAddr = "50.50.50.50"
|
||||||
assert.Empty(t, c.ClientIP())
|
assert.Empty(t, c.ClientIP())
|
||||||
|
@ -1494,6 +1502,7 @@ func resetContextForClientIPTests(c *Context) {
|
||||||
c.Request.Header.Set("X-Appengine-Remote-Addr", "50.50.50.50")
|
c.Request.Header.Set("X-Appengine-Remote-Addr", "50.50.50.50")
|
||||||
c.Request.Header.Set("CF-Connecting-IP", "60.60.60.60")
|
c.Request.Header.Set("CF-Connecting-IP", "60.60.60.60")
|
||||||
c.Request.RemoteAddr = " 40.40.40.40:42123 "
|
c.Request.RemoteAddr = " 40.40.40.40:42123 "
|
||||||
|
c.engine.TrustedPlatform = ""
|
||||||
c.engine.AppEngine = false
|
c.engine.AppEngine = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
23
gin.go
23
gin.go
|
@ -25,7 +25,7 @@ var (
|
||||||
default405Body = []byte("405 method not allowed")
|
default405Body = []byte("405 method not allowed")
|
||||||
)
|
)
|
||||||
|
|
||||||
var defaultAppEngine bool
|
var defaultPlatform string
|
||||||
|
|
||||||
// HandlerFunc defines the handler used by gin middleware as return value.
|
// HandlerFunc defines the handler used by gin middleware as return value.
|
||||||
type HandlerFunc func(*Context)
|
type HandlerFunc func(*Context)
|
||||||
|
@ -52,6 +52,16 @@ type RouteInfo struct {
|
||||||
// RoutesInfo defines a RouteInfo array.
|
// RoutesInfo defines a RouteInfo array.
|
||||||
type RoutesInfo []RouteInfo
|
type RoutesInfo []RouteInfo
|
||||||
|
|
||||||
|
// Trusted platforms
|
||||||
|
const (
|
||||||
|
// When running on Google App Engine. Trust X-Appengine-Remote-Addr
|
||||||
|
// for determining the client's IP
|
||||||
|
PlatformGoogleAppEngine = "google-app-engine"
|
||||||
|
// When using Cloudflare's CDN. Trust CF-Connecting-IP for determining
|
||||||
|
// the client's IP
|
||||||
|
PlatformCloudflare = "cloudflare"
|
||||||
|
)
|
||||||
|
|
||||||
// Engine is the framework's instance, it contains the muxer, middleware and configuration settings.
|
// Engine is the framework's instance, it contains the muxer, middleware and configuration settings.
|
||||||
// Create an instance of Engine, by using New() or Default()
|
// Create an instance of Engine, by using New() or Default()
|
||||||
type Engine struct {
|
type Engine struct {
|
||||||
|
@ -101,14 +111,15 @@ type Engine struct {
|
||||||
// `true`.
|
// `true`.
|
||||||
TrustedProxies []string
|
TrustedProxies []string
|
||||||
|
|
||||||
|
// If set to a constant of value gin.Platform*, trusts the headers set by
|
||||||
|
// that platform, for example to determine the client IP
|
||||||
|
TrustedPlatform string
|
||||||
|
|
||||||
|
// DEPRECATED: USE `TrustedPlatform` WITH VALUE `gin.GoogleAppEngine` INSTEAD
|
||||||
// #726 #755 If enabled, it will trust some headers starting with
|
// #726 #755 If enabled, it will trust some headers starting with
|
||||||
// 'X-AppEngine...' for better integration with that PaaS.
|
// 'X-AppEngine...' for better integration with that PaaS.
|
||||||
AppEngine bool
|
AppEngine bool
|
||||||
|
|
||||||
// If enabled, it will trust the CF-Connecting-IP header to determine the
|
|
||||||
// IP of the client.
|
|
||||||
CloudflareProxy bool
|
|
||||||
|
|
||||||
// If enabled, the url.RawPath will be used to find parameters.
|
// If enabled, the url.RawPath will be used to find parameters.
|
||||||
UseRawPath bool
|
UseRawPath bool
|
||||||
|
|
||||||
|
@ -164,7 +175,7 @@ func New() *Engine {
|
||||||
ForwardedByClientIP: true,
|
ForwardedByClientIP: true,
|
||||||
RemoteIPHeaders: []string{"X-Forwarded-For", "X-Real-IP"},
|
RemoteIPHeaders: []string{"X-Forwarded-For", "X-Real-IP"},
|
||||||
TrustedProxies: []string{"0.0.0.0/0"},
|
TrustedProxies: []string{"0.0.0.0/0"},
|
||||||
AppEngine: defaultAppEngine,
|
TrustedPlatform: defaultPlatform,
|
||||||
UseRawPath: false,
|
UseRawPath: false,
|
||||||
RemoveExtraSlash: false,
|
RemoveExtraSlash: false,
|
||||||
UnescapePathValues: true,
|
UnescapePathValues: true,
|
||||||
|
|
Loading…
Reference in New Issue