1
0
mirror of https://github.com/labstack/echo.git synced 2025-04-15 11:56:51 +02:00

Fixed /folders/ & /folders/* routes

Signed-off-by: Vishal Rana <vr@labstack.com>
This commit is contained in:
Vishal Rana 2015-05-04 13:01:02 -07:00
parent ab1e479ada
commit fcbdaae620
2 changed files with 73 additions and 46 deletions

View File

@ -13,11 +13,9 @@ type (
prefix string
parent *node
children children
// pchild *node // Param child
// mchild *node // Match-any child
handler HandlerFunc
pnames []string
echo *Echo
handler HandlerFunc
pnames []string
echo *Echo
}
ntype uint8
children []*node
@ -64,8 +62,9 @@ func (r *router) Add(method, path string, h HandlerFunc, echo *Echo) {
}
r.insert(method, path[:i], nil, ptype, pnames, echo)
} else if path[i] == '*' {
r.insert(method, path[:i], nil, stype, nil, echo)
pnames = append(pnames, "_name")
r.insert(method, path[:i], h, mtype, pnames, echo)
r.insert(method, path[:i+1], h, mtype, pnames, echo)
return
}
}
@ -95,18 +94,11 @@ func (r *router) insert(method, path string, h HandlerFunc, t ntype, pnames []st
// Split node
n := newNode(cn.typ, cn.prefix[l:], cn, cn.children, cn.handler, cn.pnames, cn.echo)
cn.children = children{n} // Add to parent
// if n.typ == ptype {
// cn.pchild = n
// } else if n.typ == ctype {
// cn.cchild = n
// }
// Reset parent node
cn.typ = stype
cn.label = cn.prefix[0]
cn.prefix = cn.prefix[:l]
// cn.pchild = nil
// cn.cchild = nil
cn.handler = nil
cn.pnames = nil
cn.echo = nil
@ -119,13 +111,8 @@ func (r *router) insert(method, path string, h HandlerFunc, t ntype, pnames []st
cn.echo = echo
} else {
// Create child node
n = newNode(t, search[l:], cn, children{}, h, pnames, echo)
n = newNode(t, search[l:], cn, nil, h, pnames, echo)
cn.children = append(cn.children, n)
// if n.typ == ptype {
// cn.pchild = n
// } else if n.typ == ctype {
// cn.cchild = n
// }
}
} else if l < sl {
search = search[l:]
@ -136,13 +123,8 @@ func (r *router) insert(method, path string, h HandlerFunc, t ntype, pnames []st
continue
}
// Create child node
n := newNode(t, search, cn, children{}, h, pnames, echo)
n := newNode(t, search, cn, nil, h, pnames, echo)
cn.children = append(cn.children, n)
// if n.typ == ptype {
// cn.pchild = n
// } else if n.typ == ctype {
// cn.cchild = n
// }
} else {
// Node already exists
if h != nil {
@ -225,20 +207,15 @@ func (r *router) Find(method, path string, ctx *Context) (h HandlerFunc, echo *E
c := new(node) // Child node
n := 0 // Param counter
// TODO: Check empty path???
// Search order static > param > match-any
for {
// TODO flip condition???
if search == "" || search == cn.prefix || cn.typ == mtype {
if search == "" {
// Found
ctx.pnames = cn.pnames
h = cn.handler
echo = cn.echo
ctx.pnames = cn.pnames
// Match-any node
if cn.typ == mtype {
ctx.pvalues[0] = search[len(cn.prefix):]
}
return
}
@ -246,11 +223,21 @@ func (r *router) Find(method, path string, ctx *Context) (h HandlerFunc, echo *E
l := lcp(search, cn.prefix)
if l == pl {
// Continue search
search = search[l:]
} else if l < pl && cn.label != ':' {
goto Up
}
if search == "" {
// TODO: Needs improvement
if cn.findMchild() == nil {
continue
}
// Empty value
goto MatchAny
}
// Static node
c = cn.findSchild(search[0])
if c != nil {
@ -261,7 +248,6 @@ func (r *router) Find(method, path string, ctx *Context) (h HandlerFunc, echo *E
// Param node
Param:
c = cn.findPchild()
// c = cn.pchild
if c != nil {
cn = c
i, l := 0, len(search)
@ -273,10 +259,13 @@ func (r *router) Find(method, path string, ctx *Context) (h HandlerFunc, echo *E
continue
}
// Match-any
// Match-any node
MatchAny:
c = cn.findMchild()
if c != nil {
cn = c
ctx.pvalues[n] = search
search = "" // End search
continue
}

View File

@ -317,16 +317,16 @@ func TestRouterTwoParam(t *testing.T) {
return nil
}, nil)
h, _ := r.Find(GET, "/users/1/files/1", context)
if h == nil {
t.Fatal("handler not found")
}
if context.pvalues[0] != "1" {
t.Error("param uid should be 1")
}
if context.pvalues[1] != "1" {
t.Error("param fid should be 1")
}
h, _ := r.Find(GET, "/users/1/files/1", context)
if h == nil {
t.Fatal("handler not found")
}
if context.pvalues[0] != "1" {
t.Error("param uid should be 1")
}
if context.pvalues[1] != "1" {
t.Error("param fid should be 1")
}
h, _ = r.Find(GET, "/users/1", context)
if h != nil {
@ -622,6 +622,44 @@ func TestRouterServeHTTP(t *testing.T) {
r.ServeHTTP(w, req)
}
func TestRouterExperiment(t *testing.T) {
r := New().Router
r.Add(GET, "/use", func(*Context) error {
return nil
}, nil)
r.Add(GET, "/users/*", func(*Context) error {
return nil
}, nil)
r.Add(GET, "/users/", func(*Context) error {
return nil
}, nil)
r.Add(GET, "/users/new/*", func(*Context) error {
return nil
}, nil)
r.Add(GET, "/users/new", func(*Context) error {
return nil
}, nil)
r.Add(GET, "/users/:uid", func(*Context) error {
return nil
}, nil)
r.Add(GET, "/users/new/:id", func(*Context) error {
return nil
}, nil)
r.Add(GET, "/users/wen", func(*Context) error {
return nil
}, nil)
r.Add(GET, "/users/:uid/files/:fid", func(*Context) error {
return nil
}, nil)
r.trees[GET].printTree("", true)
h, _ := r.Find(GET, "/users/", context)
if h == nil {
t.Fatal("handler not found")
}
}
func (n *node) printTree(pfx string, tail bool) {
p := prefix(tail, pfx, "└── ", "├── ")
fmt.Printf("%s%s, %p: type=%d, parent=%p, handler=%v\n", p, n.prefix, n, n.typ, n.parent, n.handler)