diff --git a/echo.go b/echo.go index a6ac0fa8..3869dc6c 100644 --- a/echo.go +++ b/echo.go @@ -227,7 +227,7 @@ const ( const ( // Version of Echo - Version = "4.1.13" + Version = "4.1.14" website = "https://echo.labstack.com" // http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo banner = ` diff --git a/router.go b/router.go index 08145973..9db9ea92 100644 --- a/router.go +++ b/router.go @@ -414,6 +414,10 @@ func (r *Router) Find(method, path string, c Context) { if cn = nn.findChildByKind(pkind); cn != nil && strings.IndexByte(ns, '/') == -1 { pvalues[len(cn.pnames)-1] = search break + } else if cn != nil && strings.IndexByte(ns, '/') != 1 { + // If slash is present, it means that this is a parameterized route. + cn = cn.parent + goto Param } for { np = nn.parent diff --git a/router_test.go b/router_test.go index 449af910..f47225d2 100644 --- a/router_test.go +++ b/router_test.go @@ -1141,6 +1141,16 @@ func TestRouterParam1466(t *testing.T) { r.Add(http.MethodGet, "/skills/:name/users", func(c Context) error { return nil }) + // Additional routes for Issue 1479 + r.Add(http.MethodGet, "/users/:username/likes/projects/ids", func(c Context) error { + return nil + }) + r.Add(http.MethodGet, "/users/:username/profile", func(c Context) error { + return nil + }) + r.Add(http.MethodGet, "/users/:username/uploads/:type", func(c Context) error { + return nil + }) c := e.NewContext(nil, nil).(*context) @@ -1152,6 +1162,26 @@ func TestRouterParam1466(t *testing.T) { r.Find(http.MethodGet, "/users/signup", c) assert.Equal(t, "", c.Param("username")) + // Additional assertions for #1479 + r.Find(http.MethodGet, "/users/sharewithme/likes/projects/ids", c) + assert.Equal(t, "sharewithme", c.Param("username")) + + r.Find(http.MethodGet, "/users/ajitem/likes/projects/ids", c) + assert.Equal(t, "ajitem", c.Param("username")) + + r.Find(http.MethodGet, "/users/sharewithme/profile", c) + assert.Equal(t, "sharewithme", c.Param("username")) + + r.Find(http.MethodGet, "/users/ajitem/profile", c) + assert.Equal(t, "ajitem", c.Param("username")) + + r.Find(http.MethodGet, "/users/sharewithme/uploads/self", c) + assert.Equal(t, "sharewithme", c.Param("username")) + assert.Equal(t, "self", c.Param("type")) + + r.Find(http.MethodGet, "/users/ajitem/uploads/self", c) + assert.Equal(t, "ajitem", c.Param("username")) + assert.Equal(t, "self", c.Param("type")) } func benchmarkRouterRoutes(b *testing.B, routes []*Route) {