diff --git a/router.go b/router.go index 749dbf4f..5010659a 100644 --- a/router.go +++ b/router.go @@ -372,14 +372,14 @@ func (r *Router) Find(method, path string, c Context) { if search == "" && (nn == nil || cn.parent == nil || cn.ppath != "") { break } + // Handle special case of trailing slash route with existing any route (see #1526) + if search == "" && path[len(path)-1] == '/' && cn.anyChildren != nil { + goto Any + } } // Attempt to go back up the tree on no matching prefix or no remaining search if l != pl || search == "" { - // Handle special case of trailing slash route with existing any route (see #1526) - if path[len(path)-1] == '/' && cn.anyChildren != nil { - goto Any - } if nn == nil { // Issue #1348 return // Not found } diff --git a/router_test.go b/router_test.go index aafc622c..a5e53c05 100644 --- a/router_test.go +++ b/router_test.go @@ -750,6 +750,47 @@ func TestRouterMatchAny(t *testing.T) { assert.Equal(t, "joe", c.Param("*")) } +// Issue #1739 +func TestRouterMatchAnyPrefixIssue(t *testing.T) { + e := New() + r := e.router + + // Routes + r.Add(http.MethodGet, "/*", func(c Context) error { + c.Set("path", c.Path()) + return nil + }) + r.Add(http.MethodGet, "/users/*", func(c Context) error { + c.Set("path", c.Path()) + return nil + }) + c := e.NewContext(nil, nil).(*context) + r.Find(http.MethodGet, "/", c) + c.handler(c) + assert.Equal(t, "/*", c.Get("path")) + assert.Equal(t, "", c.Param("*")) + + r.Find(http.MethodGet, "/users", c) + c.handler(c) + assert.Equal(t, "/*", c.Get("path")) + assert.Equal(t, "users", c.Param("*")) + + r.Find(http.MethodGet, "/users/", c) + c.handler(c) + assert.Equal(t, "/users/*", c.Get("path")) + assert.Equal(t, "", c.Param("*")) + + r.Find(http.MethodGet, "/users_prefix", c) + c.handler(c) + assert.Equal(t, "/*", c.Get("path")) + assert.Equal(t, "users_prefix", c.Param("*")) + + r.Find(http.MethodGet, "/users_prefix/", c) + c.handler(c) + assert.Equal(t, "/*", c.Get("path")) + assert.Equal(t, "users_prefix/", c.Param("*")) +} + // TestRouterMatchAnySlash shall verify finding the best route // for any routes with trailing slash requests func TestRouterMatchAnySlash(t *testing.T) {