diff --git a/router.go b/router.go index 0be1c3bb..74bee53d 100644 --- a/router.go +++ b/router.go @@ -34,7 +34,7 @@ type ( const ( skind kind = iota pkind - mkind + akind ) func NewRouter(e *Echo) *Router { @@ -84,7 +84,7 @@ func (r *Router) Add(method, path string, h Handler, e *Echo) { } else if path[i] == '*' { r.insert(method, path[:i], nil, skind, "", nil, e) pnames = append(pnames, "_*") - r.insert(method, path[:i+1], h, mkind, ppath, pnames, e) + r.insert(method, path[:i+1], h, akind, ppath, pnames, e) return } } @@ -295,7 +295,7 @@ func (r *Router) Find(method, path string, context Context) { ns string // Next search ) - // Search order static > param > match-any + // Search order static > param > any for { if search == "" { goto End @@ -325,12 +325,11 @@ func (r *Router) Find(method, path string, context Context) { search = ns if nk == pkind { goto Param - } else if nk == mkind { - goto MatchAny - } else { - // Not found - return + } else if nk == akind { + goto Any } + // Not found + return } if search == "" { @@ -338,8 +337,7 @@ func (r *Router) Find(method, path string, context Context) { } // Static node - c = cn.findChild(search[0], skind) - if c != nil { + if c = cn.findChild(search[0], skind); c != nil { // Save next if cn.label == '/' { nk = pkind @@ -352,11 +350,10 @@ func (r *Router) Find(method, path string, context Context) { // Param node Param: - c = cn.findChildByKind(pkind) - if c != nil { + if c = cn.findChildByKind(pkind); c != nil { // Save next if cn.label == '/' { - nk = mkind + nk = akind nn = cn ns = search } @@ -370,10 +367,19 @@ func (r *Router) Find(method, path string, context Context) { continue } - // Match-any node - MatchAny: - // c = cn.getChild() - if cn = cn.findChildByKind(mkind); cn == nil { + // Any node + Any: + if cn = cn.findChildByKind(akind); cn == nil { + if nn != nil { + cn = nn + nn = nil // Next + search = ns + if nk == pkind { + goto Param + } else if nk == akind { + goto Any + } + } // Not found return } @@ -390,9 +396,9 @@ End: if ctx.handler == nil { ctx.handler = cn.check405() - // Dig further for match-any, might have an empty value for *, e.g. + // Dig further for any, might have an empty value for *, e.g. // serving a directory. Issue #207. - if cn = cn.findChildByKind(mkind); cn == nil { + if cn = cn.findChildByKind(akind); cn == nil { return } ctx.pvalues[len(cn.pnames)-1] = "" diff --git a/router_test.go b/router_test.go index 77d311c3..4906502d 100644 --- a/router_test.go +++ b/router_test.go @@ -391,10 +391,8 @@ func TestRouterMultiRoute(t *testing.T) { // Route > /user c = NewContext(nil, nil, e) r.Find(GET, "/user", c) - if assert.IsType(t, new(HTTPError), c.Handle(c)) { - he := c.Handle(c).(*HTTPError) - assert.Equal(t, http.StatusNotFound, he.code) - } + he := c.Handle(c).(*HTTPError) + assert.Equal(t, http.StatusNotFound, he.code) } func TestRouterPriority(t *testing.T) { @@ -469,6 +467,37 @@ func TestRouterPriority(t *testing.T) { assert.Equal(t, "joe/books", c.Param("_*")) } +// Issue #372 +func TestRouterPriorityNotFound(t *testing.T) { + e := New() + r := e.router + c := NewContext(nil, nil, e) + + // Add + r.Add(GET, "/a/foo", HandlerFunc(func(c Context) error { + c.Set("a", 1) + return nil + }), e) + r.Add(GET, "/a/bar", HandlerFunc(func(c Context) error { + c.Set("b", 2) + return nil + }), e) + + // Find + r.Find(GET, "/a/foo", c) + c.Handle(c) + assert.Equal(t, 1, c.Get("a")) + + r.Find(GET, "/a/bar", c) + c.Handle(c) + assert.Equal(t, 2, c.Get("b")) + + c = NewContext(nil, nil, e) + r.Find(GET, "/abc/def", c) + he := c.Handle(c).(*HTTPError) + assert.Equal(t, http.StatusNotFound, he.Code()) +} + func TestRouterParamNames(t *testing.T) { e := New() r := e.router @@ -521,7 +550,6 @@ func TestRouterAPI(t *testing.T) { assert.Equal(t, ":"+n, c.P(i)) } } - c.Handle(c) } }