Skip to content

Commit 5ddc3a6

Browse files
authored
Fix routing conflict for dynamic routes and static route with common 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
1 parent f4b5a90 commit 5ddc3a6

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

router.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,14 @@ func (r *Router) Find(method, path string, c Context) {
347347
if l == pl {
348348
// Continue search
349349
search = search[l:]
350-
} else {
350+
// Finish routing if no remaining search and we are on an leaf node
351+
if search == "" && (nn == nil || cn.parent == nil || cn.ppath != "") {
352+
break
353+
}
354+
}
355+
356+
// Attempt to go back up the tree on no matching prefix or no remaining search
357+
if l != pl || search == "" {
351358
if nn == nil { // Issue #1348
352359
return // Not found
353360
}
@@ -360,10 +367,6 @@ func (r *Router) Find(method, path string, c Context) {
360367
}
361368
}
362369

363-
if search == "" {
364-
break
365-
}
366-
367370
// Static node
368371
if child = cn.findChild(search[0], skind); child != nil {
369372
// Save next

router_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,32 @@ func TestRouterParamWithSlash(t *testing.T) {
567567
})
568568
}
569569

570+
// Issue #1509
571+
func TestRouterParamStaticConflict(t *testing.T) {
572+
e := New()
573+
r := e.router
574+
handler := func(c Context) error {
575+
c.Set("path", c.Path())
576+
return nil
577+
}
578+
579+
g := e.Group("/g")
580+
g.GET("/skills", handler)
581+
g.GET("/status", handler)
582+
g.GET("/:name", handler)
583+
584+
c := e.NewContext(nil, nil).(*context)
585+
r.Find(http.MethodGet, "/g/s", c)
586+
c.handler(c)
587+
assert.Equal(t, "s", c.Param("name"))
588+
assert.Equal(t, "/g/:name", c.Get("path"))
589+
590+
c = e.NewContext(nil, nil).(*context)
591+
r.Find(http.MethodGet, "/g/status", c)
592+
c.handler(c)
593+
assert.Equal(t, "/g/status", c.Get("path"))
594+
}
595+
570596
func TestRouterMatchAny(t *testing.T) {
571597
e := New()
572598
r := e.router

0 commit comments

Comments
 (0)