Skip to content

Commit 6a1c4df

Browse files
authored
Fix sub default propagate params (#110)
* fix(subrouter): propagate parent params in Sub default branch * refactor!(matcher): drop Pattern from RequestContext interface * refactor(context): use new(make) for context slice allocation
1 parent 7f20568 commit 6a1c4df

4 files changed

Lines changed: 26 additions & 10 deletions

File tree

context.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@ type RequestContext interface {
6262
QueryParam(name string) string
6363
// Header retrieves the value of the request header for the given key.
6464
Header(key string) string
65-
// Pattern returns the registered route pattern or an empty string if the handler is called in a scope other than [RouteHandler].
66-
Pattern() string
6765
}
6866

6967
// Context represents the context of the current HTTP request. It provides methods to access request data and

fox.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,8 @@ func Sub(router *Router) HandlerFunc {
10031003
// gracefully as a defensive measure: if the parent registers /api and the sub-router registers /,
10041004
// we treat it similarly to /api*{any} (optional wildcard), matching /api with the pattern /api/.
10051005
*subCtx.subPatterns = append(*subCtx.subPatterns, strings.TrimSuffix(c.pattern, "/"))
1006+
*subCtx.params = append(*subCtx.params, *c.params...)
1007+
*subCtx.paramsKeys = append((*subCtx.paramsKeys)[:0], keys...)
10061008
router.serveSubRouter(subCtx, "/")
10071009
return
10081010
}

fox_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,6 +1434,26 @@ func TestRouter_ServeHTTP_HandleSubRouter(t *testing.T) {
14341434
assert.Equal(t, http.StatusNotFound, w.Code)
14351435
})
14361436

1437+
t.Run("sub-router with parent param and static suffix propagates params", func(t *testing.T) {
1438+
var paramSeen, patternSeen string
1439+
sub := MustRouter()
1440+
sub.MustAdd(MethodGet, "/", func(c *Context) {
1441+
paramSeen = c.Param("ver")
1442+
patternSeen = c.Pattern()
1443+
})
1444+
1445+
fx := MustRouter()
1446+
require.NoError(t, onlyError(fx.Add(MethodGet, "/api/{ver}/admin", Sub(sub))))
1447+
1448+
req := httptest.NewRequest(http.MethodGet, "/api/v1/admin", nil)
1449+
w := httptest.NewRecorder()
1450+
fx.ServeHTTP(w, req)
1451+
1452+
assert.Equal(t, http.StatusOK, w.Code)
1453+
assert.Equal(t, "v1", paramSeen)
1454+
assert.Equal(t, "/api/{ver}/admin/", patternSeen)
1455+
})
1456+
14371457
t.Run("sub-router registered in non route handler", func(t *testing.T) {
14381458
sub := MustRouter()
14391459
sub.MustAdd(MethodGet, "/users", patternHandler)

tree.go

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,11 @@ func (t *iTree) lookupByPath(method, path string, c *Context, lazy bool) (int, *
4747
}
4848

4949
func (t *iTree) allocateContext() *Context {
50-
patterns := make([]string, 0)
51-
params := make([]string, 0, t.maxParams)
52-
keys := make([]string, 0, t.maxParams)
53-
stacks := make(skipStack, 0, t.maxDepth)
5450
return &Context{
55-
params: &params,
56-
skipStack: &stacks,
57-
paramsKeys: &keys,
58-
subPatterns: &patterns,
51+
params: new(make([]string, 0, t.maxParams)),
52+
skipStack: new(make(skipStack, 0, t.maxDepth)),
53+
paramsKeys: new(make([]string, 0, t.maxParams)),
54+
subPatterns: new(make([]string, 0)),
5955
// This is a read only value, no reset. It's always the
6056
// owner of the pool.
6157
tree: t,

0 commit comments

Comments
 (0)