From 4b4d00e446110ff5f406a695e72e99fddc90d3ab Mon Sep 17 00:00:00 2001 From: joeriddles Date: Mon, 23 Sep 2024 07:57:21 -0700 Subject: [PATCH 1/3] Fix Mux.Find not correctly handling nested routes --- mux.go | 19 +++++++++++-------- mux_test.go | 38 +++++++++++++++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/mux.go b/mux.go index a6a287d2..23f39818 100644 --- a/mux.go +++ b/mux.go @@ -378,18 +378,21 @@ func (mx *Mux) Find(rctx *Context, method, path string) string { } node, _, _ := mx.tree.FindRoute(rctx, m, path) - - if node != nil && node.subroutes != nil { - rctx.RoutePath = mx.nextRoutePath(rctx) - return node.subroutes.Find(rctx, method, rctx.RoutePath) - } + pattern := rctx.routePattern if node != nil { - e := node.endpoints[m] - return e.pattern + if node.subroutes == nil { + e := node.endpoints[m] + return e.pattern + } + + rctx.RoutePath = mx.nextRoutePath(rctx) + subPattern := node.subroutes.Find(rctx, method, rctx.RoutePath) + pattern = strings.TrimSuffix(pattern, "/*") + pattern += subPattern } - return "" + return pattern } // NotFoundHandler returns the default Mux 404 responder whenever a route diff --git a/mux_test.go b/mux_test.go index 52f3a461..ac4a0f05 100644 --- a/mux_test.go +++ b/mux_test.go @@ -1850,6 +1850,11 @@ func TestMuxFind(t *testing.T) { w.Header().Set("X-Test", "yes") w.Write([]byte("bye")) }) + r.Route("/yo", func(r Router) { + r.Get("/sup", func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("sup")) + }) + }) r.Route("/articles", func(r Router) { r.Get("/{id}", func(w http.ResponseWriter, r *http.Request) { id := URLParam(r, "id") @@ -1868,17 +1873,44 @@ func TestMuxFind(t *testing.T) { w.Write([]byte("user:" + id)) }) }) + r.Route("/api", func(r Router) { + r.Route("/groups", func(r Router) { + r.Route("/v2", func(r Router) { + r.Get("/", func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("groups")) + }) + r.Post("/{id}", func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("POST groups")) + }) + }) + }) + }) tctx := NewRouteContext() tctx.Reset() - if r.Find(tctx, "GET", "/users/1") == "/users/{id}" { - t.Fatal("expecting to find match for route:", "GET", "/users/1") + if pattern := r.Find(tctx, "GET", "/users/1"); pattern != "/users/{id}" { + t.Fatal("expecting to find pattern /users/{id} for route: GET /users/1") } tctx.Reset() if r.Find(tctx, "HEAD", "/articles/10") == "/articles/{id}" { - t.Fatal("not expecting to find match for route:", "HEAD", "/articles/10") + t.Fatal("not expecting to find pattern for route: HEAD /articles/10") + } + + tctx.Reset() + if r.Find(tctx, "GET", "/yo/sup") != "/yo/sup" { + t.Fatal("expecting to find pattern /yo/sup for route: GET /yo/sup") + } + + tctx.Reset() + if r.Find(tctx, "GET", "/api/groups/v2/") != "/api/groups/v2/" { + t.Fatal("expecting to find pattern /api/groups/v2/ for route: GET /api/groups/v2/") + } + + tctx.Reset() + if r.Find(tctx, "POST", "/api/groups/v2/1") != "/api/groups/v2/{id}" { + t.Fatal("expecting to find pattern /api/groups/v2/{id} for route: POST /api/groups/v2/1") } } From e470ce0c93fab4438ccccd0903f6ae61a5c8aa41 Mon Sep 17 00:00:00 2001 From: joeriddles Date: Mon, 23 Sep 2024 08:02:21 -0700 Subject: [PATCH 2/3] Add more test cases for TextMuxFind --- mux_test.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/mux_test.go b/mux_test.go index ac4a0f05..2cf01ea8 100644 --- a/mux_test.go +++ b/mux_test.go @@ -1889,7 +1889,22 @@ func TestMuxFind(t *testing.T) { tctx := NewRouteContext() tctx.Reset() - if pattern := r.Find(tctx, "GET", "/users/1"); pattern != "/users/{id}" { + if r.Find(tctx, "GET", "") == "/" { + t.Fatal("expecting to find pattern / for route: GET") + } + + tctx.Reset() + if r.Find(tctx, "GET", "/") != "/" { + t.Fatal("expecting to find pattern / for route: GET /") + } + + tctx.Reset() + if r.Find(tctx, "GET", "/nope") == "/nope" { + t.Fatal("not expecting to find pattern for route: GET /nope") + } + + tctx.Reset() + if r.Find(tctx, "GET", "/users/1") != "/users/{id}" { t.Fatal("expecting to find pattern /users/{id} for route: GET /users/1") } From 5a7133e0acbf79366deb520ee9556404940b09d1 Mon Sep 17 00:00:00 2001 From: joeriddles Date: Mon, 23 Sep 2024 08:10:10 -0700 Subject: [PATCH 3/3] Fix Mux.Find returning partial path for failing cases --- mux.go | 4 ++++ mux_test.go | 9 ++------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/mux.go b/mux.go index 23f39818..91daf691 100644 --- a/mux.go +++ b/mux.go @@ -388,6 +388,10 @@ func (mx *Mux) Find(rctx *Context, method, path string) string { rctx.RoutePath = mx.nextRoutePath(rctx) subPattern := node.subroutes.Find(rctx, method, rctx.RoutePath) + if subPattern == "" { + return "" + } + pattern = strings.TrimSuffix(pattern, "/*") pattern += subPattern } diff --git a/mux_test.go b/mux_test.go index 2cf01ea8..d1706ece 100644 --- a/mux_test.go +++ b/mux_test.go @@ -1894,12 +1894,7 @@ func TestMuxFind(t *testing.T) { } tctx.Reset() - if r.Find(tctx, "GET", "/") != "/" { - t.Fatal("expecting to find pattern / for route: GET /") - } - - tctx.Reset() - if r.Find(tctx, "GET", "/nope") == "/nope" { + if r.Find(tctx, "GET", "/nope") != "" { t.Fatal("not expecting to find pattern for route: GET /nope") } @@ -1909,7 +1904,7 @@ func TestMuxFind(t *testing.T) { } tctx.Reset() - if r.Find(tctx, "HEAD", "/articles/10") == "/articles/{id}" { + if r.Find(tctx, "HEAD", "/articles/10") != "" { t.Fatal("not expecting to find pattern for route: HEAD /articles/10") }