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:
Bo-Yi Wu 2019-11-29 00:02:02 +08:00 committed by GitHub
parent 231ff00d1f
commit 352d69c71f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 9 deletions

8
gin.go
View File

@ -97,6 +97,10 @@ type Engine struct {
// method call.
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
secureJsonPrefix string
HTMLRender render.HTMLRender
@ -134,6 +138,7 @@ func New() *Engine {
ForwardedByClientIP: true,
AppEngine: defaultAppEngine,
UseRawPath: false,
RemoveExtraSlash: false,
UnescapePathValues: true,
MaxMultipartMemory: defaultMultipartMemory,
trees: make(methodTrees, 0, 9),
@ -385,7 +390,10 @@ func (engine *Engine) handleHTTPRequest(c *Context) {
rPath = c.Request.URL.RawPath
unescape = engine.UnescapePathValues
}
if engine.RemoveExtraSlash {
rPath = cleanPath(rPath)
}
// Find root of the tree for the given HTTP method
t := engine.trees

View File

@ -263,6 +263,7 @@ func TestRouteParamsByNameWithExtraSlash(t *testing.T) {
lastName := ""
wild := ""
router := New()
router.RemoveExtraSlash = true
router.GET("/test/:name/:last_name/*wild", func(c *Context) {
name = c.Params.ByName("name")
lastName = c.Params.ByName("last_name")
@ -407,6 +408,29 @@ func TestRouteNotAllowedDisabled(t *testing.T) {
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) {
router := New()
router.RedirectFixedPath = true
@ -425,7 +449,7 @@ func TestRouterNotFound(t *testing.T) {
{"/DIR/", http.StatusMovedPermanently, "/dir/"}, // Fixed Case
{"/PATH/", http.StatusMovedPermanently, "/path"}, // Fixed Case -/
{"/DIR", http.StatusMovedPermanently, "/dir/"}, // Fixed Case +/
{"/../path", http.StatusOK, ""}, // CleanPath
{"/../path", http.StatusMovedPermanently, "/path"}, // Without CleanPath
{"/nope", http.StatusNotFound, ""}, // NotFound
}
for _, tr := range testRoutes {