Skip to content

Commit 8b6130a

Browse files
committed
Allow colon in route after path param
1 parent 612967a commit 8b6130a

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

router.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,17 @@ func (r *Router) insert(method, path string, h HandlerFunc) {
231231
}
232232
j := i + 1
233233

234+
startingPoint := i
234235
r.insertNode(method, path[:i], staticKind, routeMethod{})
235-
for ; i < lcpIndex && path[i] != '/'; i++ {
236+
for ; i < lcpIndex; i++ {
237+
if path[i] == '/' {
238+
break
239+
}
240+
241+
if i > startingPoint && path[i-1] == '\\' && string(path[i]) == ":" {
242+
i--
243+
break
244+
}
236245
}
237246

238247
pnames = append(pnames, path[j:i])
@@ -672,7 +681,13 @@ func (r *Router) Find(method, path string, c Context) {
672681
// act similarly to any node - consider all remaining search as match
673682
i = l
674683
} else {
675-
for ; i < l && search[i] != '/'; i++ {
684+
for ; i < l; i++ {
685+
if search[i] == '/' {
686+
break
687+
}
688+
if i > 0 && search[i-1] != '/' && string(search[i]) == ":" {
689+
break
690+
}
676691
}
677692
}
678693

router_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,6 +1458,8 @@ func TestRouterParam_escapeColon(t *testing.T) {
14581458
e.POST("/multilevel\\:undelete/second\\:something", handlerFunc)
14591459
e.POST("/mixed/:id/second\\:something", handlerFunc)
14601460
e.POST("/v1/some/resource/name:customVerb", handlerFunc)
1461+
e.POST("/files/:fileId\\:delete", handlerFunc)
1462+
e.POST("/files/:fileId\\:restore", handlerFunc)
14611463

14621464
var testCases = []struct {
14631465
whenURL string
@@ -1491,6 +1493,16 @@ func TestRouterParam_escapeColon(t *testing.T) {
14911493
expectRoute: "/v1/some/resource/name:customVerb",
14921494
expectParam: map[string]string{"customVerb": ":PATCH"},
14931495
},
1496+
{
1497+
whenURL: "/files/1234:delete",
1498+
expectRoute: "/files/:fileId\\:delete",
1499+
expectParam: map[string]string{"fileId": "1234"},
1500+
},
1501+
{
1502+
whenURL: "/files/1234:restore",
1503+
expectRoute: "/files/:fileId\\:restore",
1504+
expectParam: map[string]string{"fileId": "1234"},
1505+
},
14941506
}
14951507
for _, tc := range testCases {
14961508
t.Run(tc.whenURL, func(t *testing.T) {

0 commit comments

Comments
 (0)