Skip to content

Commit

Permalink
Allow escaping of colon in route path so Google Cloud API "custom met…
Browse files Browse the repository at this point in the history
…hods" https://cloud.google.com/apis/design/custom_methods can be implemented (resolves #1987) (#1988)

Allow escaping of colon in route path so Google Cloud API "custom methods" https://cloud.google.com/apis/design/custom_methods could be implemented (resolves #1987)
  • Loading branch information
aldas committed Sep 19, 2021
1 parent f6b45f2 commit 9fc4672
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
3 changes: 3 additions & 0 deletions router.go
Expand Up @@ -98,6 +98,9 @@ func (r *Router) Add(method, path string, h HandlerFunc) {

for i, lcpIndex := 0, len(path); i < lcpIndex; i++ {
if path[i] == ':' {
if i > 0 && path[i-1] == '\\' {
continue
}
j := i + 1

r.insert(method, path[:i], nil, staticKind, "", nil)
Expand Down
52 changes: 52 additions & 0 deletions router_test.go
Expand Up @@ -1118,6 +1118,58 @@ func TestRouterParamStaticConflict(t *testing.T) {
}
}

func TestRouterParam_escapeColon(t *testing.T) {
// to allow Google cloud API like route paths with colon in them
// i.e. https://service.name/v1/some/resource/name:customVerb <- that `:customVerb` is not path param. It is just a string
e := New()

e.POST("/files/a/long/file\\:undelete", handlerFunc)
e.POST("/v1/some/resource/name:customVerb", handlerFunc)

var testCases = []struct {
whenURL string
expectRoute interface{}
expectParam map[string]string
expectError string
}{
{
whenURL: "/files/a/long/file\\:undelete",
expectRoute: "/files/a/long/file\\:undelete",
expectParam: map[string]string{},
},
{
whenURL: "/files/a/long/file\\:notMatching",
expectRoute: nil,
expectError: "code=404, message=Not Found",
expectParam: nil,
},
{
whenURL: "/v1/some/resource/name:PATCH",
expectRoute: "/v1/some/resource/name:customVerb",
expectParam: map[string]string{"customVerb": ":PATCH"},
},
}
for _, tc := range testCases {
t.Run(tc.whenURL, func(t *testing.T) {
c := e.NewContext(nil, nil).(*context)

e.router.Find(http.MethodPost, tc.whenURL, c)
err := c.handler(c)

assert.Equal(t, tc.expectRoute, c.Get("path"))
if tc.expectError != "" {
assert.EqualError(t, err, tc.expectError)
} else {
assert.NoError(t, err)
}
for param, expectedValue := range tc.expectParam {
assert.Equal(t, expectedValue, c.Param(param))
}
checkUnusedParamValues(t, c, tc.expectParam)
})
}
}

func TestRouterMatchAny(t *testing.T) {
e := New()
r := e.router
Expand Down

0 comments on commit 9fc4672

Please sign in to comment.