diff options
Diffstat (limited to 'vendor/github.com/gin-gonic/gin/gin.go')
-rw-r--r-- | vendor/github.com/gin-gonic/gin/gin.go | 89 |
1 files changed, 53 insertions, 36 deletions
diff --git a/vendor/github.com/gin-gonic/gin/gin.go b/vendor/github.com/gin-gonic/gin/gin.go index 6ab2be66d..58e76f41f 100644 --- a/vendor/github.com/gin-gonic/gin/gin.go +++ b/vendor/github.com/gin-gonic/gin/gin.go @@ -11,6 +11,7 @@ import ( "net/http" "os" "path" + "reflect" "strings" "sync" @@ -27,6 +28,8 @@ var ( var defaultPlatform string +var defaultTrustedCIDRs = []*net.IPNet{{IP: net.IP{0x0, 0x0, 0x0, 0x0}, Mask: net.IPMask{0x0, 0x0, 0x0, 0x0}}} // 0.0.0.0/0 + // HandlerFunc defines the handler used by gin middleware as return value. type HandlerFunc func(*Context) @@ -56,10 +59,10 @@ type RoutesInfo []RouteInfo const ( // When running on Google App Engine. Trust X-Appengine-Remote-Addr // for determining the client's IP - PlatformGoogleAppEngine = "google-app-engine" + PlatformGoogleAppEngine = "X-Appengine-Remote-Addr" // When using Cloudflare's CDN. Trust CF-Connecting-IP for determining // the client's IP - PlatformCloudflare = "cloudflare" + PlatformCloudflare = "CF-Connecting-IP" ) // Engine is the framework's instance, it contains the muxer, middleware and configuration settings. @@ -119,15 +122,9 @@ type Engine struct { // List of headers used to obtain the client IP when // `(*gin.Engine).ForwardedByClientIP` is `true` and // `(*gin.Context).Request.RemoteAddr` is matched by at least one of the - // network origins of `(*gin.Engine).TrustedProxies`. + // network origins of list defined by `(*gin.Engine).SetTrustedProxies()`. RemoteIPHeaders []string - // List of network origins (IPv4 addresses, IPv4 CIDRs, IPv6 addresses or - // IPv6 CIDRs) from which to trust request's headers that contain - // alternative client IP when `(*gin.Engine).ForwardedByClientIP` is - // `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 @@ -147,6 +144,8 @@ type Engine struct { pool sync.Pool trees methodTrees maxParams uint16 + maxSections uint16 + trustedProxies []string trustedCIDRs []*net.IPNet } @@ -174,7 +173,6 @@ func New() *Engine { HandleMethodNotAllowed: false, ForwardedByClientIP: true, RemoteIPHeaders: []string{"X-Forwarded-For", "X-Real-IP"}, - TrustedProxies: []string{"0.0.0.0/0"}, TrustedPlatform: defaultPlatform, UseRawPath: false, RemoveExtraSlash: false, @@ -183,6 +181,8 @@ func New() *Engine { trees: make(methodTrees, 0, 9), delims: render.Delims{Left: "{{", Right: "}}"}, secureJSONPrefix: "while(1);", + trustedProxies: []string{"0.0.0.0/0"}, + trustedCIDRs: defaultTrustedCIDRs, } engine.RouterGroup.engine = engine engine.pool.New = func() interface{} { @@ -201,7 +201,8 @@ func Default() *Engine { func (engine *Engine) allocateContext() *Context { v := make(Params, 0, engine.maxParams) - return &Context{engine: engine, params: &v} + skippedNodes := make([]skippedNode, 0, engine.maxSections) + return &Context{engine: engine, params: &v, skippedNodes: &skippedNodes} } // Delims sets template left and right delims and returns a Engine instance. @@ -264,7 +265,7 @@ func (engine *Engine) NoRoute(handlers ...HandlerFunc) { engine.rebuild404Handlers() } -// NoMethod sets the handlers called when... TODO. +// NoMethod sets the handlers called when Engine.HandleMethodNotAllowed = true. func (engine *Engine) NoMethod(handlers ...HandlerFunc) { engine.noMethod = handlers engine.rebuild405Handlers() @@ -307,6 +308,10 @@ func (engine *Engine) addRoute(method, path string, handlers HandlersChain) { if paramsCount := countParams(path); paramsCount > engine.maxParams { engine.maxParams = paramsCount } + + if sectionsCount := countSections(path); sectionsCount > engine.maxSections { + engine.maxSections = sectionsCount + } } // Routes returns a slice of registered routes, including some useful information, such as: @@ -341,9 +346,9 @@ func iterate(path, method string, routes RoutesInfo, root *node) RoutesInfo { func (engine *Engine) Run(addr ...string) (err error) { defer func() { debugPrintError(err) }() - err = engine.parseTrustedProxies() - if err != nil { - return err + if engine.isUnsafeTrustedProxies() { + debugPrint("[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + + "Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.") } address := resolveAddress(addr) @@ -353,12 +358,12 @@ func (engine *Engine) Run(addr ...string) (err error) { } func (engine *Engine) prepareTrustedCIDRs() ([]*net.IPNet, error) { - if engine.TrustedProxies == nil { + if engine.trustedProxies == nil { return nil, nil } - cidr := make([]*net.IPNet, 0, len(engine.TrustedProxies)) - for _, trustedProxy := range engine.TrustedProxies { + cidr := make([]*net.IPNet, 0, len(engine.trustedProxies)) + for _, trustedProxy := range engine.trustedProxies { if !strings.Contains(trustedProxy, "/") { ip := parseIP(trustedProxy) if ip == nil { @@ -381,13 +386,25 @@ func (engine *Engine) prepareTrustedCIDRs() ([]*net.IPNet, error) { return cidr, nil } -// SetTrustedProxies set Engine.TrustedProxies +// SetTrustedProxies set a list of network origins (IPv4 addresses, +// IPv4 CIDRs, IPv6 addresses or IPv6 CIDRs) from which to trust +// request's headers that contain alternative client IP when +// `(*gin.Engine).ForwardedByClientIP` is `true`. `TrustedProxies` +// feature is enabled by default, and it also trusts all proxies +// by default. If you want to disable this feature, use +// Engine.SetTrustedProxies(nil), then Context.ClientIP() will +// return the remote address directly. func (engine *Engine) SetTrustedProxies(trustedProxies []string) error { - engine.TrustedProxies = trustedProxies + engine.trustedProxies = trustedProxies return engine.parseTrustedProxies() } -// parseTrustedProxies parse Engine.TrustedProxies to Engine.trustedCIDRs +// isUnsafeTrustedProxies compares Engine.trustedCIDRs and defaultTrustedCIDRs, it's not safe if equal (returns true) +func (engine *Engine) isUnsafeTrustedProxies() bool { + return reflect.DeepEqual(engine.trustedCIDRs, defaultTrustedCIDRs) +} + +// parseTrustedProxies parse Engine.trustedProxies to Engine.trustedCIDRs func (engine *Engine) parseTrustedProxies() error { trustedCIDRs, err := engine.prepareTrustedCIDRs() engine.trustedCIDRs = trustedCIDRs @@ -415,9 +432,9 @@ func (engine *Engine) RunTLS(addr, certFile, keyFile string) (err error) { debugPrint("Listening and serving HTTPS on %s\n", addr) defer func() { debugPrintError(err) }() - err = engine.parseTrustedProxies() - if err != nil { - return err + if engine.isUnsafeTrustedProxies() { + debugPrint("[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + + "Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.") } err = http.ListenAndServeTLS(addr, certFile, keyFile, engine) @@ -431,9 +448,9 @@ func (engine *Engine) RunUnix(file string) (err error) { debugPrint("Listening and serving HTTP on unix:/%s", file) defer func() { debugPrintError(err) }() - err = engine.parseTrustedProxies() - if err != nil { - return err + if engine.isUnsafeTrustedProxies() { + debugPrint("[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + + "Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.") } listener, err := net.Listen("unix", file) @@ -454,9 +471,9 @@ func (engine *Engine) RunFd(fd int) (err error) { debugPrint("Listening and serving HTTP on fd@%d", fd) defer func() { debugPrintError(err) }() - err = engine.parseTrustedProxies() - if err != nil { - return err + if engine.isUnsafeTrustedProxies() { + debugPrint("[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + + "Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.") } f := os.NewFile(uintptr(fd), fmt.Sprintf("fd@%d", fd)) @@ -475,9 +492,9 @@ func (engine *Engine) RunListener(listener net.Listener) (err error) { debugPrint("Listening and serving HTTP on listener what's bind with address@%s", listener.Addr()) defer func() { debugPrintError(err) }() - err = engine.parseTrustedProxies() - if err != nil { - return err + if engine.isUnsafeTrustedProxies() { + debugPrint("[WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.\n" + + "Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.") } err = http.Serve(listener, engine) @@ -528,7 +545,7 @@ func (engine *Engine) handleHTTPRequest(c *Context) { } root := t[i].root // Find route in tree - value := root.getValue(rPath, c.params, unescape) + value := root.getValue(rPath, c.params, c.skippedNodes, unescape) if value.params != nil { c.Params = *value.params } @@ -539,7 +556,7 @@ func (engine *Engine) handleHTTPRequest(c *Context) { c.writermem.WriteHeaderNow() return } - if httpMethod != http.MethodConnect && rPath != "/" { + if httpMethod != "CONNECT" && rPath != "/" { if value.tsr && engine.RedirectTrailingSlash { redirectTrailingSlash(c) return @@ -556,7 +573,7 @@ func (engine *Engine) handleHTTPRequest(c *Context) { if tree.method == httpMethod { continue } - if value := tree.root.getValue(rPath, nil, unescape); value.handlers != nil { + if value := tree.root.getValue(rPath, nil, c.skippedNodes, unescape); value.handlers != nil { c.handlers = engine.allNoMethod serveError(c, http.StatusMethodNotAllowed, default405Body) return |