mirror of
https://github.com/labstack/echo.git
synced 2025-09-16 09:16:29 +02:00
fixed conflicting routes #22
Signed-off-by: Vishal Rana <vr@labstack.com>
This commit is contained in:
23
router.go
23
router.go
@@ -154,30 +154,35 @@ func (r *router) Find(method, path string, params Params) (h HandlerFunc, echo *
|
|||||||
n := 0 // Param count
|
n := 0 // Param count
|
||||||
|
|
||||||
// Search order static > param > catch-all
|
// Search order static > param > catch-all
|
||||||
// TODO: do we need continue???
|
|
||||||
for {
|
for {
|
||||||
if search == "" || search == cn.prefix { // Fix me
|
if search == "" || search == cn.prefix {
|
||||||
// Found
|
// Found
|
||||||
h = cn.handler
|
h = cn.handler
|
||||||
echo = cn.echo
|
echo = cn.echo
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var e *node
|
||||||
pl := len(cn.prefix)
|
pl := len(cn.prefix)
|
||||||
l := lcp(search, cn.prefix)
|
l := lcp(search, cn.prefix)
|
||||||
|
|
||||||
if l == pl {
|
if l == pl {
|
||||||
search = search[l:]
|
search = search[l:]
|
||||||
|
} else if l < pl {
|
||||||
|
if cn.label != ':' {
|
||||||
|
goto Up
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Static node
|
// Static node
|
||||||
e := cn.findEdge(search[0])
|
e = cn.findEdge(search[0])
|
||||||
if e != nil {
|
if e != nil {
|
||||||
cn = e
|
cn = e
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Param node
|
// Param node
|
||||||
param:
|
Param:
|
||||||
e = cn.findEdge(':')
|
e = cn.findEdge(':')
|
||||||
if e != nil {
|
if e != nil {
|
||||||
cn = e
|
cn = e
|
||||||
@@ -202,13 +207,19 @@ func (r *router) Find(method, path string, params Params) (h HandlerFunc, echo *
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Up:
|
||||||
|
tn := cn // Save current node
|
||||||
cn = cn.parent
|
cn = cn.parent
|
||||||
if cn == nil {
|
if cn == nil {
|
||||||
// Not found
|
// Not found
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Search backwards
|
// Search upwards
|
||||||
goto param
|
if l == pl {
|
||||||
|
// Reset search
|
||||||
|
search = tn.prefix + search
|
||||||
|
}
|
||||||
|
goto Param
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
173
router_test.go
173
router_test.go
@@ -299,7 +299,6 @@ func TestRouterStatic(t *testing.T) {
|
|||||||
func TestRouterParam(t *testing.T) {
|
func TestRouterParam(t *testing.T) {
|
||||||
r := New().Router
|
r := New().Router
|
||||||
r.Add(GET, "/users/:id", func(c *Context) {}, nil)
|
r.Add(GET, "/users/:id", func(c *Context) {}, nil)
|
||||||
|
|
||||||
h, _ := r.Find(GET, "/users/1", params)
|
h, _ := r.Find(GET, "/users/1", params)
|
||||||
if h == nil {
|
if h == nil {
|
||||||
t.Fatal("handler not found")
|
t.Fatal("handler not found")
|
||||||
@@ -354,68 +353,142 @@ func TestRouterMicroParam(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRouterMultiRoute(t *testing.T) {
|
||||||
|
r := New().Router
|
||||||
|
b := new(bytes.Buffer)
|
||||||
|
|
||||||
|
// Routes
|
||||||
|
r.Add(GET, "/users", func(*Context) {
|
||||||
|
b.WriteString("/users")
|
||||||
|
}, nil)
|
||||||
|
r.Add(GET, "/users/:id", func(c *Context) {}, nil)
|
||||||
|
|
||||||
|
// Route > /users
|
||||||
|
h, _ := r.Find(GET, "/users", params)
|
||||||
|
if h == nil {
|
||||||
|
t.Fatal("handler not found")
|
||||||
|
}
|
||||||
|
h(nil)
|
||||||
|
if b.String() != "/users" {
|
||||||
|
t.Errorf("buffer should be /users")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Route > /users/:id > /users/1
|
||||||
|
h, _ = r.Find(GET, "/users/1", params)
|
||||||
|
if h == nil {
|
||||||
|
t.Fatal("handler not found")
|
||||||
|
}
|
||||||
|
if params[0].Value != "1" {
|
||||||
|
t.Error("param id should be 1")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Route > /user
|
||||||
|
h, _ = r.Find(GET, "/user", params)
|
||||||
|
if h != nil {
|
||||||
|
t.Fatal("handler should be nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestRouterConflictingRoute(t *testing.T) {
|
func TestRouterConflictingRoute(t *testing.T) {
|
||||||
r := New().Router
|
r := New().Router
|
||||||
b := new(bytes.Buffer)
|
b := new(bytes.Buffer)
|
||||||
path := "/new"
|
|
||||||
|
|
||||||
r.Add(GET, path, func(*Context) {
|
// Routes
|
||||||
b.WriteString(path)
|
r.Add(GET, "/users", func(*Context) {
|
||||||
|
b.WriteString("/users")
|
||||||
}, nil)
|
}, nil)
|
||||||
h, _ := r.Find(GET, path, params)
|
r.Add(GET, "/users/new", func(*Context) {
|
||||||
if h == nil {
|
|
||||||
t.Fatal("handler not found")
|
|
||||||
}
|
|
||||||
h(nil)
|
|
||||||
if b.String() != path {
|
|
||||||
t.Errorf("buffer should be %s", path)
|
|
||||||
}
|
|
||||||
|
|
||||||
name := "joe"
|
|
||||||
r.Add(GET, "/new/:id", func(c *Context) {}, nil)
|
|
||||||
h, _ = r.Find(GET, "/new/"+name, params)
|
|
||||||
if h == nil {
|
|
||||||
t.Fatal("handler not found")
|
|
||||||
}
|
|
||||||
if params[0].Value != name {
|
|
||||||
t.Errorf("param id should be %s", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
path = "/new/name"
|
|
||||||
r.Add(GET, path, func(*Context) {
|
|
||||||
b.Reset()
|
b.Reset()
|
||||||
b.WriteString(path)
|
b.WriteString("/users/new")
|
||||||
}, nil)
|
}, nil)
|
||||||
h, _ = r.Find(GET, path, params)
|
r.Add(GET, "/users/:id", func(c *Context) {}, nil)
|
||||||
if h == nil {
|
r.Add(GET, "/users/new/moon", func(*Context) {
|
||||||
t.Fatal("handler not found")
|
|
||||||
}
|
|
||||||
h(nil)
|
|
||||||
if b.String() != path {
|
|
||||||
t.Errorf("buffer should be %s", path)
|
|
||||||
}
|
|
||||||
|
|
||||||
r.Add(GET, "/new/name/:id", func(c *Context) {}, nil)
|
|
||||||
h, _ = r.Find(GET, "/new/name/"+name, params)
|
|
||||||
if h == nil {
|
|
||||||
t.Fatal("handler not found")
|
|
||||||
}
|
|
||||||
if params[0].Value != name {
|
|
||||||
t.Errorf("param id should be %s", name)
|
|
||||||
}
|
|
||||||
|
|
||||||
path = "/new/name/joe"
|
|
||||||
r.Add(GET, path, func(c *Context) {
|
|
||||||
b.Reset()
|
b.Reset()
|
||||||
b.WriteString(path)
|
b.WriteString("/users/new/moon")
|
||||||
}, nil)
|
}, nil)
|
||||||
h, _ = r.Find(GET, "/new/name/joe", params)
|
r.Add(GET, "/users/new/:id", func(*Context) {}, nil)
|
||||||
|
|
||||||
|
// Route > /users
|
||||||
|
h, _ := r.Find(GET, "/users", params)
|
||||||
|
if h == nil {
|
||||||
|
t.Fatal("handler not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Route > /users/new
|
||||||
|
h, _ = r.Find(GET, "/users/new", params)
|
||||||
if h == nil {
|
if h == nil {
|
||||||
t.Fatal("handler not found")
|
t.Fatal("handler not found")
|
||||||
}
|
}
|
||||||
h(nil)
|
h(nil)
|
||||||
if b.String() != path {
|
if b.String() != "/users/new" {
|
||||||
t.Errorf("buffer should be %s", path)
|
t.Error("buffer should be /users/new")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Route > /users/:id > /users/1
|
||||||
|
h, _ = r.Find(GET, "/users/1", params)
|
||||||
|
if h == nil {
|
||||||
|
t.Fatal("handler not found")
|
||||||
|
}
|
||||||
|
if params[0].Value != "1" {
|
||||||
|
t.Error("param id should be 1")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Route > /users/:id > /users/nil
|
||||||
|
h, _ = r.Find(GET, "/users/nil", params)
|
||||||
|
if h == nil {
|
||||||
|
t.Fatal("handler not found")
|
||||||
|
}
|
||||||
|
if params[0].Value != "nil" {
|
||||||
|
t.Error("param id should be nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Route > /users/:id > /users/news
|
||||||
|
h, _ = r.Find(GET, "/users/news", params)
|
||||||
|
if h == nil {
|
||||||
|
t.Fatal("handler not found")
|
||||||
|
}
|
||||||
|
if params[0].Value != "news" {
|
||||||
|
t.Error("param id should be news")
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************//
|
||||||
|
// Two level //
|
||||||
|
//***************//
|
||||||
|
// Route > /users/new/moon > /users/new/moon
|
||||||
|
h, _ = r.Find(GET, "/users/new/moon", params)
|
||||||
|
if h == nil {
|
||||||
|
t.Fatal("handler not found")
|
||||||
|
}
|
||||||
|
h(nil)
|
||||||
|
if b.String() != "/users/new/moon" {
|
||||||
|
t.Error("buffer should be /users/new/moon")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Route > /users/new/:id > /users/new/1
|
||||||
|
h, _ = r.Find(GET, "/users/new/1", params)
|
||||||
|
if h == nil {
|
||||||
|
t.Fatal("handler not found")
|
||||||
|
}
|
||||||
|
if params[0].Value != "1" {
|
||||||
|
t.Error("param id should be 1")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Route > /users/new/:id > /users/new/me
|
||||||
|
h, _ = r.Find(GET, "/users/new/me", params)
|
||||||
|
if h == nil {
|
||||||
|
t.Fatal("handler not found")
|
||||||
|
}
|
||||||
|
if params[0].Value != "me" {
|
||||||
|
t.Error("param id should be me")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Route > /users/new/:id > /users/new/moons
|
||||||
|
h, _ = r.Find(GET, "/users/new/moons", params)
|
||||||
|
if h == nil {
|
||||||
|
t.Fatal("handler not found")
|
||||||
|
}
|
||||||
|
if params[0].Value != "moons" {
|
||||||
|
t.Error("param id should be moons")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user