Skip to content

Commit 447c92d

Browse files
authored
When route is registered with empty path it is normalized to /. Make sure that returned echo.Route structs reflect that behavior. (#2616)
1 parent d549290 commit 447c92d

File tree

3 files changed

+44
-15
lines changed

3 files changed

+44
-15
lines changed

echo_test.go

+5
Original file line numberDiff line numberDiff line change
@@ -1598,6 +1598,11 @@ func TestEchoReverse(t *testing.T) {
15981598
whenParams []interface{}
15991599
expect string
16001600
}{
1601+
{
1602+
name: "ok, not existing path returns empty url",
1603+
whenRouteName: "not-existing",
1604+
expect: "",
1605+
},
16011606
{
16021607
name: "ok,static with no params",
16031608
whenRouteName: "/static",

router.go

+23-15
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,18 @@ func (r *Router) Reverse(name string, params ...interface{}) string {
185185
return uri.String()
186186
}
187187

188+
func normalizePathSlash(path string) string {
189+
if path == "" {
190+
path = "/"
191+
} else if path[0] != '/' {
192+
path = "/" + path
193+
}
194+
return path
195+
}
196+
188197
func (r *Router) add(method, path, name string, h HandlerFunc) *Route {
189-
r.Add(method, path, h)
198+
path = normalizePathSlash(path)
199+
r.insert(method, path, h)
190200

191201
route := &Route{
192202
Method: method,
@@ -199,13 +209,11 @@ func (r *Router) add(method, path, name string, h HandlerFunc) *Route {
199209

200210
// Add registers a new route for method and path with matching handler.
201211
func (r *Router) Add(method, path string, h HandlerFunc) {
202-
// Validate path
203-
if path == "" {
204-
path = "/"
205-
}
206-
if path[0] != '/' {
207-
path = "/" + path
208-
}
212+
r.insert(method, normalizePathSlash(path), h)
213+
}
214+
215+
func (r *Router) insert(method, path string, h HandlerFunc) {
216+
path = normalizePathSlash(path)
209217
pnames := []string{} // Param names
210218
ppath := path // Pristine path
211219

@@ -224,7 +232,7 @@ func (r *Router) Add(method, path string, h HandlerFunc) {
224232
}
225233
j := i + 1
226234

227-
r.insert(method, path[:i], staticKind, routeMethod{})
235+
r.insertNode(method, path[:i], staticKind, routeMethod{})
228236
for ; i < lcpIndex && path[i] != '/'; i++ {
229237
}
230238

@@ -234,21 +242,21 @@ func (r *Router) Add(method, path string, h HandlerFunc) {
234242

235243
if i == lcpIndex {
236244
// path node is last fragment of route path. ie. `/users/:id`
237-
r.insert(method, path[:i], paramKind, routeMethod{ppath, pnames, h})
245+
r.insertNode(method, path[:i], paramKind, routeMethod{ppath, pnames, h})
238246
} else {
239-
r.insert(method, path[:i], paramKind, routeMethod{})
247+
r.insertNode(method, path[:i], paramKind, routeMethod{})
240248
}
241249
} else if path[i] == '*' {
242-
r.insert(method, path[:i], staticKind, routeMethod{})
250+
r.insertNode(method, path[:i], staticKind, routeMethod{})
243251
pnames = append(pnames, "*")
244-
r.insert(method, path[:i+1], anyKind, routeMethod{ppath, pnames, h})
252+
r.insertNode(method, path[:i+1], anyKind, routeMethod{ppath, pnames, h})
245253
}
246254
}
247255

248-
r.insert(method, path, staticKind, routeMethod{ppath, pnames, h})
256+
r.insertNode(method, path, staticKind, routeMethod{ppath, pnames, h})
249257
}
250258

251-
func (r *Router) insert(method, path string, t kind, rm routeMethod) {
259+
func (r *Router) insertNode(method, path string, t kind, rm routeMethod) {
252260
// Adjust max param
253261
paramLen := len(rm.pnames)
254262
if *r.echo.maxParam < paramLen {

router_test.go

+16
Original file line numberDiff line numberDiff line change
@@ -2770,6 +2770,22 @@ func TestRouter_Routes(t *testing.T) {
27702770
}
27712771
}
27722772

2773+
func TestRouter_addEmptyPathToSlashReverse(t *testing.T) {
2774+
e := New()
2775+
r := e.router
2776+
r.add(http.MethodGet, "", "empty", handlerFunc) // emtpy path is normalized to `/`
2777+
2778+
assert.Equal(t, "/", r.Reverse("empty"))
2779+
}
2780+
2781+
func TestRouter_ReverseNotFound(t *testing.T) {
2782+
e := New()
2783+
r := e.router
2784+
r.add(http.MethodGet, "", "empty", handlerFunc)
2785+
2786+
assert.Equal(t, "", r.Reverse("not-existing"))
2787+
}
2788+
27732789
func TestRouter_Reverse(t *testing.T) {
27742790
e := New()
27752791
r := e.router

0 commit comments

Comments
 (0)