From ae1d1e8546eb343f2e4fc11a376dcb7eb6833e55 Mon Sep 17 00:00:00 2001 From: QianChengLong Date: Wed, 14 Nov 2018 16:12:59 +0800 Subject: [PATCH] add cleanPath and use it on request path --- gin.go | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/gin.go b/gin.go index b7c77e1f..efd18e63 100644 --- a/gin.go +++ b/gin.go @@ -10,6 +10,8 @@ import ( "net" "net/http" "os" + "path" + "strings" "sync" "github.com/gin-gonic/gin/render" @@ -361,7 +363,7 @@ func (engine *Engine) HandleContext(c *Context) { func (engine *Engine) handleHTTPRequest(c *Context) { httpMethod := c.Request.Method - path := c.Request.URL.Path + path := cleanPath(c.Request.URL.Path) unescape := false if engine.UseRawPath && len(c.Request.URL.RawPath) > 0 { path = c.Request.URL.RawPath @@ -463,3 +465,25 @@ func redirectFixedPath(c *Context, root *node, trailingSlash bool) bool { } return false } + +// cleanPath returns the canonical path for p, eliminating . and .. elements. +func cleanPath(p string) string { + if p == "" { + return "/" + } + if p[0] != '/' { + p = "/" + p + } + np := path.Clean(p) + // path.Clean removes trailing slash except for root; + // put the trailing slash back if necessary. + if p[len(p)-1] == '/' && np != "/" { + // Fast path for common case of p being the string we want: + if len(p) == len(np)+1 && strings.HasPrefix(p, np) { + np = p + } else { + np += "/" + } + } + return np +}