Skip to content

Commit 0553b3a

Browse files
committed
fix(subrouter): clear subPatterns on fallthrough handlers
1 parent 8b08126 commit 0553b3a

2 files changed

Lines changed: 75 additions & 0 deletions

File tree

fox.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,7 @@ func (fox *Router) serveSubRouter(c *Context, path string) {
818818

819819
if route.handleSlash == RedirectSlash {
820820
*c.params = (*c.params)[:0]
821+
*c.subPatterns = (*c.subPatterns)[:0]
821822
c.route = nil
822823
c.pattern = ""
823824
c.scope = RedirectSlashHandler
@@ -839,6 +840,7 @@ func (fox *Router) serveSubRouter(c *Context, path string) {
839840
case RedirectPath:
840841
if idx, n, tsr := tree.lookupByPath(r.Method, CleanPath(path), c, true); n != nil && (!tsr || n.routes[idx].handleSlash != StrictSlash) {
841842
*c.params = (*c.params)[:0]
843+
*c.subPatterns = (*c.subPatterns)[:0]
842844
c.route = nil
843845
c.pattern = ""
844846
c.scope = RedirectPathHandler
@@ -850,6 +852,7 @@ func (fox *Router) serveSubRouter(c *Context, path string) {
850852
}
851853

852854
*c.params = (*c.params)[:0]
855+
*c.subPatterns = (*c.subPatterns)[:0]
853856
c.route = nil
854857
c.pattern = ""
855858

fox_test.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,6 +1477,78 @@ func TestRouter_ServeHTTP_HandleSubRouter(t *testing.T) {
14771477
fx.ServeHTTP(w, req)
14781478
assert.Equal(t, http.StatusNotFound, w.Code)
14791479
})
1480+
1481+
t.Run("sub-router no route handler sees clean context", func(t *testing.T) {
1482+
var pat, tenant string
1483+
var route *Route
1484+
noRoute := HandlerFunc(func(c *Context) {
1485+
pat = c.Pattern()
1486+
tenant = c.Param("tenant")
1487+
route = c.Route()
1488+
http.Error(c.Writer(), "x", http.StatusNotFound)
1489+
})
1490+
1491+
sub := MustRouter(WithNoRouteHandler(noRoute))
1492+
sub.MustAdd(MethodGet, "/known", emptyHandler)
1493+
1494+
fx := MustRouter()
1495+
require.NoError(t, onlyError(fx.Add(MethodGet, "/api/{tenant}/+{rest}", Sub(sub))))
1496+
1497+
req := httptest.NewRequest(http.MethodGet, "/api/acme/notfound", nil)
1498+
w := httptest.NewRecorder()
1499+
fx.ServeHTTP(w, req)
1500+
1501+
assert.Equal(t, "", pat)
1502+
assert.Equal(t, "", tenant)
1503+
assert.Nil(t, route)
1504+
})
1505+
1506+
t.Run("sub-router no method handler sees clean context", func(t *testing.T) {
1507+
var pat, tenant string
1508+
noMethod := HandlerFunc(func(c *Context) {
1509+
pat = c.Pattern()
1510+
tenant = c.Param("tenant")
1511+
http.Error(c.Writer(), "x", http.StatusMethodNotAllowed)
1512+
})
1513+
1514+
sub := MustRouter(WithNoMethod(true), WithNoMethodHandler(noMethod))
1515+
sub.MustAdd(MethodGet, "/users", emptyHandler)
1516+
1517+
fx := MustRouter()
1518+
require.NoError(t, onlyError(fx.Add(MethodAny, "/api/{tenant}/+{rest}", Sub(sub))))
1519+
1520+
req := httptest.NewRequest(http.MethodPost, "/api/acme/users", nil)
1521+
w := httptest.NewRecorder()
1522+
fx.ServeHTTP(w, req)
1523+
1524+
assert.Equal(t, "", pat)
1525+
assert.Equal(t, "", tenant)
1526+
})
1527+
1528+
t.Run("sub-router redirect slash handler sees clean context", func(t *testing.T) {
1529+
var pat, tenant string
1530+
mw := WithMiddlewareFor(RedirectSlashHandler, func(next HandlerFunc) HandlerFunc {
1531+
return func(c *Context) {
1532+
pat = c.Pattern()
1533+
tenant = c.Param("tenant")
1534+
next(c)
1535+
}
1536+
})
1537+
1538+
sub := MustRouter(mw)
1539+
sub.MustAdd(MethodGet, "/users/", emptyHandler, WithHandleTrailingSlash(RedirectSlash))
1540+
1541+
fx := MustRouter()
1542+
require.NoError(t, onlyError(fx.Add(MethodGet, "/api/{tenant}/+{rest}", Sub(sub))))
1543+
1544+
req := httptest.NewRequest(http.MethodGet, "/api/acme/users", nil)
1545+
w := httptest.NewRecorder()
1546+
fx.ServeHTTP(w, req)
1547+
1548+
assert.Equal(t, http.StatusMovedPermanently, w.Code)
1549+
assert.Equal(t, "", pat)
1550+
assert.Equal(t, "", tenant)
1551+
})
14801552
}
14811553

14821554
func TestRouter_ServeHTTP_ParamsWithDomainMalloc(t *testing.T) {

0 commit comments

Comments
 (0)