Skip to content

Commit 6ceb498

Browse files
authored
Fix Mux.Find not correctly handling nested routes (#954)
* Fix Mux.Find not correctly handling nested routes * Add more test cases for TextMuxFind * Fix Mux.Find returning partial path for failing cases
1 parent 882c15e commit 6ceb498

File tree

2 files changed

+60
-11
lines changed

2 files changed

+60
-11
lines changed

mux.go

+14-7
Original file line numberDiff line numberDiff line change
@@ -378,18 +378,25 @@ func (mx *Mux) Find(rctx *Context, method, path string) string {
378378
}
379379

380380
node, _, _ := mx.tree.FindRoute(rctx, m, path)
381+
pattern := rctx.routePattern
382+
383+
if node != nil {
384+
if node.subroutes == nil {
385+
e := node.endpoints[m]
386+
return e.pattern
387+
}
381388

382-
if node != nil && node.subroutes != nil {
383389
rctx.RoutePath = mx.nextRoutePath(rctx)
384-
return node.subroutes.Find(rctx, method, rctx.RoutePath)
385-
}
390+
subPattern := node.subroutes.Find(rctx, method, rctx.RoutePath)
391+
if subPattern == "" {
392+
return ""
393+
}
386394

387-
if node != nil {
388-
e := node.endpoints[m]
389-
return e.pattern
395+
pattern = strings.TrimSuffix(pattern, "/*")
396+
pattern += subPattern
390397
}
391398

392-
return ""
399+
return pattern
393400
}
394401

395402
// NotFoundHandler returns the default Mux 404 responder whenever a route

mux_test.go

+46-4
Original file line numberDiff line numberDiff line change
@@ -1850,6 +1850,11 @@ func TestMuxFind(t *testing.T) {
18501850
w.Header().Set("X-Test", "yes")
18511851
w.Write([]byte("bye"))
18521852
})
1853+
r.Route("/yo", func(r Router) {
1854+
r.Get("/sup", func(w http.ResponseWriter, r *http.Request) {
1855+
w.Write([]byte("sup"))
1856+
})
1857+
})
18531858
r.Route("/articles", func(r Router) {
18541859
r.Get("/{id}", func(w http.ResponseWriter, r *http.Request) {
18551860
id := URLParam(r, "id")
@@ -1868,17 +1873,54 @@ func TestMuxFind(t *testing.T) {
18681873
w.Write([]byte("user:" + id))
18691874
})
18701875
})
1876+
r.Route("/api", func(r Router) {
1877+
r.Route("/groups", func(r Router) {
1878+
r.Route("/v2", func(r Router) {
1879+
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
1880+
w.Write([]byte("groups"))
1881+
})
1882+
r.Post("/{id}", func(w http.ResponseWriter, r *http.Request) {
1883+
w.Write([]byte("POST groups"))
1884+
})
1885+
})
1886+
})
1887+
})
18711888

18721889
tctx := NewRouteContext()
18731890

18741891
tctx.Reset()
1875-
if r.Find(tctx, "GET", "/users/1") == "/users/{id}" {
1876-
t.Fatal("expecting to find match for route:", "GET", "/users/1")
1892+
if r.Find(tctx, "GET", "") == "/" {
1893+
t.Fatal("expecting to find pattern / for route: GET")
18771894
}
18781895

18791896
tctx.Reset()
1880-
if r.Find(tctx, "HEAD", "/articles/10") == "/articles/{id}" {
1881-
t.Fatal("not expecting to find match for route:", "HEAD", "/articles/10")
1897+
if r.Find(tctx, "GET", "/nope") != "" {
1898+
t.Fatal("not expecting to find pattern for route: GET /nope")
1899+
}
1900+
1901+
tctx.Reset()
1902+
if r.Find(tctx, "GET", "/users/1") != "/users/{id}" {
1903+
t.Fatal("expecting to find pattern /users/{id} for route: GET /users/1")
1904+
}
1905+
1906+
tctx.Reset()
1907+
if r.Find(tctx, "HEAD", "/articles/10") != "" {
1908+
t.Fatal("not expecting to find pattern for route: HEAD /articles/10")
1909+
}
1910+
1911+
tctx.Reset()
1912+
if r.Find(tctx, "GET", "/yo/sup") != "/yo/sup" {
1913+
t.Fatal("expecting to find pattern /yo/sup for route: GET /yo/sup")
1914+
}
1915+
1916+
tctx.Reset()
1917+
if r.Find(tctx, "GET", "/api/groups/v2/") != "/api/groups/v2/" {
1918+
t.Fatal("expecting to find pattern /api/groups/v2/ for route: GET /api/groups/v2/")
1919+
}
1920+
1921+
tctx.Reset()
1922+
if r.Find(tctx, "POST", "/api/groups/v2/1") != "/api/groups/v2/{id}" {
1923+
t.Fatal("expecting to find pattern /api/groups/v2/{id} for route: POST /api/groups/v2/1")
18821924
}
18831925
}
18841926

0 commit comments

Comments
 (0)