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{}