mirror of
https://github.com/labstack/echo.git
synced 2025-03-23 21:29:26 +02:00
parent
0a075ce7c5
commit
67b1dfea04
83
router.go
83
router.go
@ -13,11 +13,11 @@ type (
|
|||||||
prefix string
|
prefix string
|
||||||
parent *node
|
parent *node
|
||||||
children children
|
children children
|
||||||
// pchild *node // Param child
|
pchild *node // Param child
|
||||||
// cchild *node // Catch-all child
|
cchild *node // Catch-all child
|
||||||
handler HandlerFunc
|
handler HandlerFunc
|
||||||
pnames []string
|
pnames []string
|
||||||
echo *Echo
|
echo *Echo
|
||||||
}
|
}
|
||||||
ntype uint8
|
ntype uint8
|
||||||
children []*node
|
children []*node
|
||||||
@ -96,11 +96,18 @@ func (r *router) insert(method, path string, h HandlerFunc, t ntype, pnames []st
|
|||||||
// Split node
|
// Split node
|
||||||
n := newNode(t, cn.prefix[l:], cn, cn.children, cn.handler, cn.pnames, cn.echo)
|
n := newNode(t, cn.prefix[l:], cn, cn.children, cn.handler, cn.pnames, cn.echo)
|
||||||
cn.children = children{n} // Add to parent
|
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
|
// Reset parent node
|
||||||
cn.typ = stype
|
cn.typ = stype
|
||||||
cn.label = cn.prefix[0]
|
cn.label = cn.prefix[0]
|
||||||
cn.prefix = cn.prefix[:l]
|
cn.prefix = cn.prefix[:l]
|
||||||
|
// cn.pchild = nil
|
||||||
|
// cn.cchild = nil
|
||||||
cn.handler = nil
|
cn.handler = nil
|
||||||
cn.pnames = nil
|
cn.pnames = nil
|
||||||
cn.echo = nil
|
cn.echo = nil
|
||||||
@ -115,6 +122,11 @@ func (r *router) insert(method, path string, h HandlerFunc, t ntype, pnames []st
|
|||||||
// Create child node
|
// Create child node
|
||||||
n = newNode(t, search[l:], cn, children{}, h, pnames, echo)
|
n = newNode(t, search[l:], cn, children{}, h, pnames, echo)
|
||||||
cn.children = append(cn.children, n)
|
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 {
|
} else if l < sl {
|
||||||
search = search[l:]
|
search = search[l:]
|
||||||
@ -127,6 +139,11 @@ func (r *router) insert(method, path string, h HandlerFunc, t ntype, pnames []st
|
|||||||
// Create child node
|
// Create child node
|
||||||
n := newNode(t, search, cn, children{}, h, pnames, echo)
|
n := newNode(t, search, cn, children{}, h, pnames, echo)
|
||||||
cn.children = append(cn.children, n)
|
cn.children = append(cn.children, n)
|
||||||
|
// if n.typ == ptype {
|
||||||
|
// cn.pchild = n
|
||||||
|
// } else if n.typ == ctype {
|
||||||
|
// cn.cchild = n
|
||||||
|
// }
|
||||||
} else {
|
} else {
|
||||||
// Node already exists
|
// Node already exists
|
||||||
if h != nil {
|
if h != nil {
|
||||||
@ -139,8 +156,8 @@ func (r *router) insert(method, path string, h HandlerFunc, t ntype, pnames []st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newNode(t ntype, pfx string, p *node, c children, h HandlerFunc, pnames []string, echo *Echo) (n *node) {
|
func newNode(t ntype, pfx string, p *node, c children, h HandlerFunc, pnames []string, echo *Echo) *node {
|
||||||
n = &node{
|
return &node{
|
||||||
typ: t,
|
typ: t,
|
||||||
label: pfx[0],
|
label: pfx[0],
|
||||||
prefix: pfx,
|
prefix: pfx,
|
||||||
@ -150,7 +167,9 @@ func newNode(t ntype, pfx string, p *node, c children, h HandlerFunc, pnames []s
|
|||||||
pnames: pnames,
|
pnames: pnames,
|
||||||
echo: echo,
|
echo: echo,
|
||||||
}
|
}
|
||||||
return
|
}
|
||||||
|
|
||||||
|
func (n *node) addChild(c *node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *node) findChild(l byte) *node {
|
func (n *node) findChild(l byte) *node {
|
||||||
@ -201,20 +220,22 @@ func lcp(a, b string) (i int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *router) Find(method, path string, c *Context) (h HandlerFunc, echo *Echo) {
|
func (r *router) Find(method, path string, ctx *Context) (h HandlerFunc, echo *Echo) {
|
||||||
cn := r.trees[method] // Current node as root
|
cn := r.trees[method] // Current node as root
|
||||||
search := path
|
search := path
|
||||||
chn := new(node) // Child node
|
c := new(node) // Child node
|
||||||
n := 0 // Param counter
|
n := 0 // Param counter
|
||||||
|
|
||||||
// Search order static > param > catch-all
|
// Search order static > param > catch-all
|
||||||
for {
|
for {
|
||||||
if search == "" || search == cn.prefix {
|
if search == "" || search == cn.prefix {
|
||||||
// Found
|
if cn.handler != nil {
|
||||||
h = cn.handler
|
// Found
|
||||||
c.pnames = cn.pnames
|
h = cn.handler
|
||||||
echo = cn.echo
|
ctx.pnames = cn.pnames
|
||||||
return
|
echo = cn.echo
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pl := len(cn.prefix)
|
pl := len(cn.prefix)
|
||||||
@ -226,32 +247,40 @@ func (r *router) Find(method, path string, c *Context) (h HandlerFunc, echo *Ech
|
|||||||
goto Up
|
goto Up
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for catch-all with empty string
|
||||||
|
if len(search) == 0 {
|
||||||
|
goto CatchAll
|
||||||
|
}
|
||||||
|
|
||||||
// Static node
|
// Static node
|
||||||
chn = cn.findSchild(search[0])
|
c = cn.findSchild(search[0])
|
||||||
if chn != nil {
|
if c != nil {
|
||||||
cn = chn
|
cn = c
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Param node
|
// Param node
|
||||||
Param:
|
Param:
|
||||||
chn = cn.findPchild()
|
c = cn.findPchild()
|
||||||
if chn != nil {
|
// c = cn.pchild
|
||||||
cn = chn
|
if c != nil {
|
||||||
|
cn = c
|
||||||
i, l := 0, len(search)
|
i, l := 0, len(search)
|
||||||
for ; i < l && search[i] != '/'; i++ {
|
for ; i < l && search[i] != '/'; i++ {
|
||||||
}
|
}
|
||||||
c.pvalues[n] = search[:i]
|
ctx.pvalues[n] = search[:i]
|
||||||
n++
|
n++
|
||||||
search = search[i:]
|
search = search[i:]
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Catch-all node
|
// Catch-all node
|
||||||
chn = cn.findCchild()
|
CatchAll:
|
||||||
if chn != nil {
|
// c = cn.cchild
|
||||||
cn = chn
|
c = cn.findCchild()
|
||||||
c.pvalues[n] = search
|
if c != nil {
|
||||||
|
cn = c
|
||||||
|
ctx.pvalues[n] = search
|
||||||
search = "" // End search
|
search = "" // End search
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -344,7 +344,15 @@ func TestRouterCatchAll(t *testing.T) {
|
|||||||
return nil
|
return nil
|
||||||
}, nil)
|
}, nil)
|
||||||
|
|
||||||
h, _ := r.Find(GET, "/users/joe", context)
|
h, _ := r.Find(GET, "/users/", context)
|
||||||
|
if h == nil {
|
||||||
|
t.Fatal("handler not found")
|
||||||
|
}
|
||||||
|
if context.pvalues[0] != "" {
|
||||||
|
t.Error("value should be joe")
|
||||||
|
}
|
||||||
|
|
||||||
|
h, _ = r.Find(GET, "/users/joe", context)
|
||||||
if h == nil {
|
if h == nil {
|
||||||
t.Fatal("handler not found")
|
t.Fatal("handler not found")
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user