mirror of https://github.com/gin-gonic/gin.git
chore(performance): Improve performance for adding RemoveExtraS… (#2159)
* chore: Add RemoveExtraSlash flag * fix testing Signed-off-by: Bo-Yi Wu <appleboy.tw@gmail.com>
This commit is contained in:
parent
231ff00d1f
commit
352d69c71f
10
gin.go
10
gin.go
|
@ -97,6 +97,10 @@ type Engine struct {
|
||||||
// method call.
|
// method call.
|
||||||
MaxMultipartMemory int64
|
MaxMultipartMemory int64
|
||||||
|
|
||||||
|
// RemoveExtraSlash a parameter can be parsed from the URL even with extra slashes.
|
||||||
|
// See the PR #1817 and issue #1644
|
||||||
|
RemoveExtraSlash bool
|
||||||
|
|
||||||
delims render.Delims
|
delims render.Delims
|
||||||
secureJsonPrefix string
|
secureJsonPrefix string
|
||||||
HTMLRender render.HTMLRender
|
HTMLRender render.HTMLRender
|
||||||
|
@ -134,6 +138,7 @@ func New() *Engine {
|
||||||
ForwardedByClientIP: true,
|
ForwardedByClientIP: true,
|
||||||
AppEngine: defaultAppEngine,
|
AppEngine: defaultAppEngine,
|
||||||
UseRawPath: false,
|
UseRawPath: false,
|
||||||
|
RemoveExtraSlash: false,
|
||||||
UnescapePathValues: true,
|
UnescapePathValues: true,
|
||||||
MaxMultipartMemory: defaultMultipartMemory,
|
MaxMultipartMemory: defaultMultipartMemory,
|
||||||
trees: make(methodTrees, 0, 9),
|
trees: make(methodTrees, 0, 9),
|
||||||
|
@ -385,7 +390,10 @@ func (engine *Engine) handleHTTPRequest(c *Context) {
|
||||||
rPath = c.Request.URL.RawPath
|
rPath = c.Request.URL.RawPath
|
||||||
unescape = engine.UnescapePathValues
|
unescape = engine.UnescapePathValues
|
||||||
}
|
}
|
||||||
rPath = cleanPath(rPath)
|
|
||||||
|
if engine.RemoveExtraSlash {
|
||||||
|
rPath = cleanPath(rPath)
|
||||||
|
}
|
||||||
|
|
||||||
// Find root of the tree for the given HTTP method
|
// Find root of the tree for the given HTTP method
|
||||||
t := engine.trees
|
t := engine.trees
|
||||||
|
|
|
@ -263,6 +263,7 @@ func TestRouteParamsByNameWithExtraSlash(t *testing.T) {
|
||||||
lastName := ""
|
lastName := ""
|
||||||
wild := ""
|
wild := ""
|
||||||
router := New()
|
router := New()
|
||||||
|
router.RemoveExtraSlash = true
|
||||||
router.GET("/test/:name/:last_name/*wild", func(c *Context) {
|
router.GET("/test/:name/:last_name/*wild", func(c *Context) {
|
||||||
name = c.Params.ByName("name")
|
name = c.Params.ByName("name")
|
||||||
lastName = c.Params.ByName("last_name")
|
lastName = c.Params.ByName("last_name")
|
||||||
|
@ -407,6 +408,29 @@ func TestRouteNotAllowedDisabled(t *testing.T) {
|
||||||
assert.Equal(t, http.StatusNotFound, w.Code)
|
assert.Equal(t, http.StatusNotFound, w.Code)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRouterNotFoundWithRemoveExtraSlash(t *testing.T) {
|
||||||
|
router := New()
|
||||||
|
router.RemoveExtraSlash = true
|
||||||
|
router.GET("/path", func(c *Context) {})
|
||||||
|
router.GET("/", func(c *Context) {})
|
||||||
|
|
||||||
|
testRoutes := []struct {
|
||||||
|
route string
|
||||||
|
code int
|
||||||
|
location string
|
||||||
|
}{
|
||||||
|
{"/../path", http.StatusOK, ""}, // CleanPath
|
||||||
|
{"/nope", http.StatusNotFound, ""}, // NotFound
|
||||||
|
}
|
||||||
|
for _, tr := range testRoutes {
|
||||||
|
w := performRequest(router, "GET", tr.route)
|
||||||
|
assert.Equal(t, tr.code, w.Code)
|
||||||
|
if w.Code != http.StatusNotFound {
|
||||||
|
assert.Equal(t, tr.location, fmt.Sprint(w.Header().Get("Location")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestRouterNotFound(t *testing.T) {
|
func TestRouterNotFound(t *testing.T) {
|
||||||
router := New()
|
router := New()
|
||||||
router.RedirectFixedPath = true
|
router.RedirectFixedPath = true
|
||||||
|
@ -419,14 +443,14 @@ func TestRouterNotFound(t *testing.T) {
|
||||||
code int
|
code int
|
||||||
location string
|
location string
|
||||||
}{
|
}{
|
||||||
{"/path/", http.StatusMovedPermanently, "/path"}, // TSR -/
|
{"/path/", http.StatusMovedPermanently, "/path"}, // TSR -/
|
||||||
{"/dir", http.StatusMovedPermanently, "/dir/"}, // TSR +/
|
{"/dir", http.StatusMovedPermanently, "/dir/"}, // TSR +/
|
||||||
{"/PATH", http.StatusMovedPermanently, "/path"}, // Fixed Case
|
{"/PATH", http.StatusMovedPermanently, "/path"}, // Fixed Case
|
||||||
{"/DIR/", http.StatusMovedPermanently, "/dir/"}, // Fixed Case
|
{"/DIR/", http.StatusMovedPermanently, "/dir/"}, // Fixed Case
|
||||||
{"/PATH/", http.StatusMovedPermanently, "/path"}, // Fixed Case -/
|
{"/PATH/", http.StatusMovedPermanently, "/path"}, // Fixed Case -/
|
||||||
{"/DIR", http.StatusMovedPermanently, "/dir/"}, // Fixed Case +/
|
{"/DIR", http.StatusMovedPermanently, "/dir/"}, // Fixed Case +/
|
||||||
{"/../path", http.StatusOK, ""}, // CleanPath
|
{"/../path", http.StatusMovedPermanently, "/path"}, // Without CleanPath
|
||||||
{"/nope", http.StatusNotFound, ""}, // NotFound
|
{"/nope", http.StatusNotFound, ""}, // NotFound
|
||||||
}
|
}
|
||||||
for _, tr := range testRoutes {
|
for _, tr := range testRoutes {
|
||||||
w := performRequest(router, "GET", tr.route)
|
w := performRequest(router, "GET", tr.route)
|
||||||
|
|
Loading…
Reference in New Issue