Fix TSR for / nodes before param nodes Fixes #90
diff --git a/tree.go b/tree.go index a15bc2c..af95bd4 100644 --- a/tree.go +++ b/tree.go
@@ -33,9 +33,10 @@ type nodeType uint8 const ( - static nodeType = 0 - param nodeType = 1 - catchAll nodeType = 2 + static nodeType = iota // default + root + param + catchAll ) type node struct { @@ -195,6 +196,7 @@ } } else { // Empty tree n.insertChild(numParams, path, fullPath, handle) + n.nType = root } } @@ -411,6 +413,11 @@ return } + if path == "/" && n.wildChild && n.nType != root { + tsr = true + return + } + // No handle found. Check if a handle for this path + a // trailing slash exists for trailing slash recommendation for i := 0; i < len(n.indices); i++ {
diff --git a/tree_test.go b/tree_test.go index 64f26d1..46d3299 100644 --- a/tree_test.go +++ b/tree_test.go
@@ -89,7 +89,7 @@ maxParams = params } } - if n.nType != static && !n.wildChild { + if n.nType > root && !n.wildChild { maxParams++ } @@ -394,6 +394,9 @@ "/1/:id/2", "/aa", "/a/", + "/admin", + "/admin/:category", + "/admin/:category/:page", "/doc", "/doc/go_faq.html", "/doc/go1.html", @@ -423,6 +426,9 @@ "/0/go/", "/1/go", "/a", + "/admin/", + "/admin/config/", + "/admin/config/permissions/", "/doc/", } for _, route := range tsrRoutes { @@ -452,6 +458,24 @@ } } +func TestTreeRootTrailingSlashRedirect(t *testing.T) { + tree := &node{} + + recv := catchPanic(func() { + tree.addRoute("/:test", fakeHandler("/:test")) + }) + if recv != nil { + t.Fatalf("panic inserting test route: %v", recv) + } + + handler, _, tsr := tree.getValue("/") + if handler != nil { + t.Fatalf("non-nil handler") + } else if tsr { + t.Errorf("expected no TSR recommendation") + } +} + func TestTreeFindCaseInsensitivePath(t *testing.T) { tree := &node{}