Setting trusted platform using an enum-like (#2739)
This commit is contained in:
		
				
					committed by
					
						
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							fb8a113f8d
						
					
				
				
					commit
					dd8a27c0b6
				
			
							
								
								
									
										16
									
								
								context.go
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								context.go
									
									
									
									
									
								
							@ -9,6 +9,7 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"log"
 | 
			
		||||
	"math"
 | 
			
		||||
	"mime/multipart"
 | 
			
		||||
	"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,
 | 
			
		||||
// the remote IP (coming form Request.RemoteAddr) is returned.
 | 
			
		||||
func (c *Context) ClientIP() string {
 | 
			
		||||
	switch {
 | 
			
		||||
	case c.engine.AppEngine:
 | 
			
		||||
	// Check if we're running on a tursted platform
 | 
			
		||||
	switch c.engine.TrustedPlatform {
 | 
			
		||||
	case PlatformGoogleAppEngine:
 | 
			
		||||
		if addr := c.requestHeader("X-Appengine-Remote-Addr"); addr != "" {
 | 
			
		||||
			return addr
 | 
			
		||||
		}
 | 
			
		||||
	case c.engine.CloudflareProxy:
 | 
			
		||||
	case PlatformCloudflare:
 | 
			
		||||
		if addr := c.requestHeader("CF-Connecting-IP"); 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()
 | 
			
		||||
	if remoteIP == nil {
 | 
			
		||||
		return ""
 | 
			
		||||
 | 
			
		||||
@ -8,5 +8,5 @@
 | 
			
		||||
package gin
 | 
			
		||||
 | 
			
		||||
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-Real-IP")
 | 
			
		||||
	c.engine.AppEngine = true
 | 
			
		||||
	c.engine.TrustedPlatform = PlatformGoogleAppEngine
 | 
			
		||||
	assert.Equal(t, "50.50.50.50", c.ClientIP())
 | 
			
		||||
 | 
			
		||||
	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())
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
	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")
 | 
			
		||||
	assert.Equal(t, "40.40.40.40", c.ClientIP())
 | 
			
		||||
 | 
			
		||||
	c.engine.AppEngine = false
 | 
			
		||||
	c.engine.CloudflareProxy = true
 | 
			
		||||
	c.engine.TrustedPlatform = PlatformCloudflare
 | 
			
		||||
	assert.Equal(t, "60.60.60.60", c.ClientIP())
 | 
			
		||||
 | 
			
		||||
	c.Request.Header.Del("CF-Connecting-IP")
 | 
			
		||||
	assert.Equal(t, "40.40.40.40", c.ClientIP())
 | 
			
		||||
 | 
			
		||||
	c.engine.TrustedPlatform = ""
 | 
			
		||||
 | 
			
		||||
	// no port
 | 
			
		||||
	c.Request.RemoteAddr = "50.50.50.50"
 | 
			
		||||
	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("CF-Connecting-IP", "60.60.60.60")
 | 
			
		||||
	c.Request.RemoteAddr = "  40.40.40.40:42123 "
 | 
			
		||||
	c.engine.TrustedPlatform = ""
 | 
			
		||||
	c.engine.AppEngine = false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										23
									
								
								gin.go
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								gin.go
									
									
									
									
									
								
							@ -25,7 +25,7 @@ var (
 | 
			
		||||
	default405Body = []byte("405 method not allowed")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var defaultAppEngine bool
 | 
			
		||||
var defaultPlatform string
 | 
			
		||||
 | 
			
		||||
// HandlerFunc defines the handler used by gin middleware as return value.
 | 
			
		||||
type HandlerFunc func(*Context)
 | 
			
		||||
@ -52,6 +52,16 @@ type RouteInfo struct {
 | 
			
		||||
// RoutesInfo defines a RouteInfo array.
 | 
			
		||||
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.
 | 
			
		||||
// Create an instance of Engine, by using New() or Default()
 | 
			
		||||
type Engine struct {
 | 
			
		||||
@ -101,14 +111,15 @@ type Engine struct {
 | 
			
		||||
	// `true`.
 | 
			
		||||
	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
 | 
			
		||||
	// 'X-AppEngine...' for better integration with that PaaS.
 | 
			
		||||
	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.
 | 
			
		||||
	UseRawPath bool
 | 
			
		||||
 | 
			
		||||
@ -164,7 +175,7 @@ func New() *Engine {
 | 
			
		||||
		ForwardedByClientIP:    true,
 | 
			
		||||
		RemoteIPHeaders:        []string{"X-Forwarded-For", "X-Real-IP"},
 | 
			
		||||
		TrustedProxies:         []string{"0.0.0.0/0"},
 | 
			
		||||
		AppEngine:              defaultAppEngine,
 | 
			
		||||
		TrustedPlatform:        defaultPlatform,
 | 
			
		||||
		UseRawPath:             false,
 | 
			
		||||
		RemoveExtraSlash:       false,
 | 
			
		||||
		UnescapePathValues:     true,
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user