Skip to content

Commit

Permalink
Merge branch 'neotel-at-bugfix/1412-route-matchany-multilevel'
Browse files Browse the repository at this point in the history
  • Loading branch information
vishr committed Dec 30, 2019
2 parents 5c7c87d + 8f69b47 commit a64188c
Show file tree
Hide file tree
Showing 3 changed files with 273 additions and 56 deletions.
39 changes: 39 additions & 0 deletions group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,42 @@ func TestGroupRouteMiddleware(t *testing.T) {
c, _ = request(http.MethodGet, "/group/405", e)
assert.Equal(t, 405, c)
}

func TestGroupRouteMiddlewareWithMatchAny(t *testing.T) {
// Ensure middleware and match any routes do not conflict
e := New()
g := e.Group("/group")
m1 := func(next HandlerFunc) HandlerFunc {
return func(c Context) error {
return next(c)
}
}
m2 := func(next HandlerFunc) HandlerFunc {
return func(c Context) error {
return c.String(http.StatusOK, c.Path())
}
}
h := func(c Context) error {
return c.String(http.StatusOK, c.Path())
}
g.Use(m1)
g.GET("/help", h, m2)
g.GET("/*", h, m2)
g.GET("", h, m2)
e.GET("unrelated", h, m2)
e.GET("*", h, m2)

_, m := request(http.MethodGet, "/group/help", e)
assert.Equal(t, "/group/help", m)
_, m = request(http.MethodGet, "/group/help/other", e)
assert.Equal(t, "/group/*", m)
_, m = request(http.MethodGet, "/group/404", e)
assert.Equal(t, "/group/*", m)
_, m = request(http.MethodGet, "/group", e)
assert.Equal(t, "/group", m)
_, m = request(http.MethodGet, "/other", e)
assert.Equal(t, "/*", m)
_, m = request(http.MethodGet, "/", e)
assert.Equal(t, "/*", m)

}
49 changes: 36 additions & 13 deletions router.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package echo

import "net/http"
import (
"net/http"
"strings"
)

type (
// Router is the registry of all registered routes for an `Echo` instance for
Expand All @@ -20,8 +23,8 @@ type (
pnames []string
methodHandler *methodHandler
}
kind uint8
children []*node
kind uint8
children []*node
methodHandler struct {
connect HandlerFunc
delete HandlerFunc
Expand Down Expand Up @@ -133,6 +136,11 @@ func (r *Router) insert(method, path string, h HandlerFunc, t kind, ppath string
// Split node
n := newNode(cn.kind, cn.prefix[l:], cn, cn.children, cn.methodHandler, cn.ppath, cn.pnames)

// Update parent path for all children to new node
for _, child := range cn.children {
child.parent = n
}

// Reset parent node
cn.kind = skind
cn.label = cn.prefix[0]
Expand Down Expand Up @@ -336,7 +344,6 @@ func (r *Router) Find(method, path string, c Context) {
}
}


if l == pl {
// Continue search
search = search[l:]
Expand Down Expand Up @@ -398,16 +405,32 @@ func (r *Router) Find(method, path string, c Context) {
Any:
if cn = cn.findChildByKind(akind); cn == nil {
if nn != nil {
cn = nn
nn = cn.parent // Next (Issue #954)
if nn != nil {
nk = nn.kind
}
// No next node to go down in routing (issue #954)
// Find nearest "any" route going up the routing tree
search = ns
if nk == pkind {
goto Param
} else if nk == akind {
goto Any
np := nn.parent
// Consider param route one level up only
// if no slash is remaining in search string
if cn = nn.findChildByKind(pkind); cn != nil && strings.IndexByte(ns, '/') == -1 {
break
}
for {
np = nn.parent
if cn = nn.findChildByKind(akind); cn != nil {
break
}
if np == nil {
break // no further parent nodes in tree, abort
}
var str strings.Builder
str.WriteString(nn.prefix)
str.WriteString(search)
search = str.String()
nn = np
}
if cn != nil { // use the found "any" route and update path
pvalues[len(cn.pnames)-1] = search
break
}
}
return // Not found
Expand Down
Loading

0 comments on commit a64188c

Please sign in to comment.