Skip to content

Commit

Permalink
Fix routing conflict for dynamic routes and static route with common …
Browse files Browse the repository at this point in the history
…prefix (#1509) (#1512)

* Add test for issue #1509 for dynamic routes and multiple static routes with common prefix

* Fix #1509: routing conflict for dynamic routes and static route with common prefix

* Improve routing performance for static only route trees
  • Loading branch information
lammel committed Feb 24, 2020
1 parent f4b5a90 commit 5ddc3a6
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 5 deletions.
13 changes: 8 additions & 5 deletions router.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,14 @@ func (r *Router) Find(method, path string, c Context) {
if l == pl {
// Continue search
search = search[l:]
} else {
// Finish routing if no remaining search and we are on an leaf node
if search == "" && (nn == nil || cn.parent == nil || cn.ppath != "") {
break
}
}

// Attempt to go back up the tree on no matching prefix or no remaining search
if l != pl || search == "" {
if nn == nil { // Issue #1348
return // Not found
}
Expand All @@ -360,10 +367,6 @@ func (r *Router) Find(method, path string, c Context) {
}
}

if search == "" {
break
}

// Static node
if child = cn.findChild(search[0], skind); child != nil {
// Save next
Expand Down
26 changes: 26 additions & 0 deletions router_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,32 @@ func TestRouterParamWithSlash(t *testing.T) {
})
}

// Issue #1509
func TestRouterParamStaticConflict(t *testing.T) {
e := New()
r := e.router
handler := func(c Context) error {
c.Set("path", c.Path())
return nil
}

g := e.Group("/g")
g.GET("/skills", handler)
g.GET("/status", handler)
g.GET("/:name", handler)

c := e.NewContext(nil, nil).(*context)
r.Find(http.MethodGet, "/g/s", c)
c.handler(c)
assert.Equal(t, "s", c.Param("name"))
assert.Equal(t, "/g/:name", c.Get("path"))

c = e.NewContext(nil, nil).(*context)
r.Find(http.MethodGet, "/g/status", c)
c.handler(c)
assert.Equal(t, "/g/status", c.Get("path"))
}

func TestRouterMatchAny(t *testing.T) {
e := New()
r := e.router
Expand Down

0 comments on commit 5ddc3a6

Please sign in to comment.