Skip to content

Commit a9df830

Browse files
authored
Do not handle special trailing slash case for partial prefix (#1741)
* Add tests for issue #1739 * Handle special trailing slash case only for a matching prefix Only handle the special trailing slash case if the whole prefix matches to avoid matching a wrong route for overlapping prefixes, e.g. /users/* for the path /users_prefix/ where the route is only a partial prefix of the requested path.
1 parent c7c792d commit a9df830

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

router.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -372,14 +372,14 @@ func (r *Router) Find(method, path string, c Context) {
372372
if search == "" && (nn == nil || cn.parent == nil || cn.ppath != "") {
373373
break
374374
}
375+
// Handle special case of trailing slash route with existing any route (see #1526)
376+
if search == "" && path[len(path)-1] == '/' && cn.anyChildren != nil {
377+
goto Any
378+
}
375379
}
376380

377381
// Attempt to go back up the tree on no matching prefix or no remaining search
378382
if l != pl || search == "" {
379-
// Handle special case of trailing slash route with existing any route (see #1526)
380-
if path[len(path)-1] == '/' && cn.anyChildren != nil {
381-
goto Any
382-
}
383383
if nn == nil { // Issue #1348
384384
return // Not found
385385
}

router_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,47 @@ func TestRouterMatchAny(t *testing.T) {
750750
assert.Equal(t, "joe", c.Param("*"))
751751
}
752752

753+
// Issue #1739
754+
func TestRouterMatchAnyPrefixIssue(t *testing.T) {
755+
e := New()
756+
r := e.router
757+
758+
// Routes
759+
r.Add(http.MethodGet, "/*", func(c Context) error {
760+
c.Set("path", c.Path())
761+
return nil
762+
})
763+
r.Add(http.MethodGet, "/users/*", func(c Context) error {
764+
c.Set("path", c.Path())
765+
return nil
766+
})
767+
c := e.NewContext(nil, nil).(*context)
768+
r.Find(http.MethodGet, "/", c)
769+
c.handler(c)
770+
assert.Equal(t, "/*", c.Get("path"))
771+
assert.Equal(t, "", c.Param("*"))
772+
773+
r.Find(http.MethodGet, "/users", c)
774+
c.handler(c)
775+
assert.Equal(t, "/*", c.Get("path"))
776+
assert.Equal(t, "users", c.Param("*"))
777+
778+
r.Find(http.MethodGet, "/users/", c)
779+
c.handler(c)
780+
assert.Equal(t, "/users/*", c.Get("path"))
781+
assert.Equal(t, "", c.Param("*"))
782+
783+
r.Find(http.MethodGet, "/users_prefix", c)
784+
c.handler(c)
785+
assert.Equal(t, "/*", c.Get("path"))
786+
assert.Equal(t, "users_prefix", c.Param("*"))
787+
788+
r.Find(http.MethodGet, "/users_prefix/", c)
789+
c.handler(c)
790+
assert.Equal(t, "/*", c.Get("path"))
791+
assert.Equal(t, "users_prefix/", c.Param("*"))
792+
}
793+
753794
// TestRouterMatchAnySlash shall verify finding the best route
754795
// for any routes with trailing slash requests
755796
func TestRouterMatchAnySlash(t *testing.T) {

0 commit comments

Comments
 (0)