mirror of https://github.com/gin-gonic/gin.git
Fix: 404 bug with param
This commit is contained in:
parent
1c48977cca
commit
cee994f045
|
@ -463,6 +463,8 @@ func TestTreeRunDynamicRouting(t *testing.T) {
|
|||
testRequest(t, ts.URL+"/a/cc", "", "/:cc/cc")
|
||||
testRequest(t, ts.URL+"/c1/d/e", "", "/c1/:dd/e")
|
||||
testRequest(t, ts.URL+"/c1/d/e1", "", "/c1/:dd/e1")
|
||||
testRequest(t, ts.URL+"/c1/dd/ee", "", "/:cc/:dd/ee")
|
||||
testRequest(t, ts.URL+"/c1/dd/ee/", "", "/:cc/:dd/ee")
|
||||
testRequest(t, ts.URL+"/c1/d/ee", "", "/:cc/:dd/ee")
|
||||
testRequest(t, ts.URL+"/c1/d/f", "", "/:cc/:dd/f")
|
||||
testRequest(t, ts.URL+"/c/d/ee", "", "/:cc/:dd/ee")
|
||||
|
@ -480,6 +482,7 @@ func TestTreeRunDynamicRouting(t *testing.T) {
|
|||
testRequest(t, ts.URL+"/ab", "", "/:cc")
|
||||
testRequest(t, ts.URL+"/abb", "", "/:cc")
|
||||
testRequest(t, ts.URL+"/abb/cc", "", "/:cc/cc")
|
||||
testRequest(t, ts.URL+"/c1/cc", "", "/:cc/cc")
|
||||
testRequest(t, ts.URL+"/dddaa", "", "/:cc")
|
||||
testRequest(t, ts.URL+"/allxxxx", "", "/:cc")
|
||||
testRequest(t, ts.URL+"/alldd", "", "/:cc")
|
||||
|
|
60
tree.go
60
tree.go
|
@ -418,6 +418,23 @@ type skippedNode struct {
|
|||
func (n *node) getValue(path string, params *Params, skippedNodes *[]skippedNode, unescape bool) (value nodeValue) {
|
||||
var globalParamsCount int16
|
||||
|
||||
rollbackSkipped := func() bool {
|
||||
for l := len(*skippedNodes); l > 0; {
|
||||
skippedNode := (*skippedNodes)[l-1]
|
||||
*skippedNodes = (*skippedNodes)[:l-1]
|
||||
if strings.HasSuffix(skippedNode.path, path) {
|
||||
path = skippedNode.path
|
||||
n = skippedNode.node
|
||||
if value.params != nil {
|
||||
*value.params = (*value.params)[:skippedNode.paramsCount]
|
||||
}
|
||||
globalParamsCount = skippedNode.paramsCount
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
walk: // Outer loop for walking the tree
|
||||
for {
|
||||
prefix := n.path
|
||||
|
@ -457,20 +474,10 @@ walk: // Outer loop for walking the tree
|
|||
// If the path at the end of the loop is not equal to '/' and the current node has no child nodes
|
||||
// the current node needs to roll back to last valid skippedNode
|
||||
if path != "/" {
|
||||
for l := len(*skippedNodes); l > 0; {
|
||||
skippedNode := (*skippedNodes)[l-1]
|
||||
*skippedNodes = (*skippedNodes)[:l-1]
|
||||
if strings.HasSuffix(skippedNode.path, path) {
|
||||
path = skippedNode.path
|
||||
n = skippedNode.node
|
||||
if value.params != nil {
|
||||
*value.params = (*value.params)[:skippedNode.paramsCount]
|
||||
}
|
||||
globalParamsCount = skippedNode.paramsCount
|
||||
if rollbackSkipped() {
|
||||
continue walk
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing found.
|
||||
// We can recommend to redirect to the same URL without a
|
||||
|
@ -535,7 +542,11 @@ walk: // Outer loop for walking the tree
|
|||
// No handle found. Check if a handle for this path + a
|
||||
// trailing slash exists for TSR recommendation
|
||||
n = n.children[0]
|
||||
value.tsr = (n.path == "/" && n.handlers != nil) || (n.path == "" && n.indices == "/")
|
||||
if (n.path == "/" && n.handlers != nil) || (n.path == "" && n.indices == "/") {
|
||||
value.tsr = true
|
||||
} else if rollbackSkipped() {
|
||||
continue walk
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
|
@ -574,21 +585,10 @@ walk: // Outer loop for walking the tree
|
|||
// If the current path does not equal '/' and the node does not have a registered handle and the most recently matched node has a child node
|
||||
// the current node needs to roll back to last valid skippedNode
|
||||
if n.handlers == nil && path != "/" {
|
||||
for l := len(*skippedNodes); l > 0; {
|
||||
skippedNode := (*skippedNodes)[l-1]
|
||||
*skippedNodes = (*skippedNodes)[:l-1]
|
||||
if strings.HasSuffix(skippedNode.path, path) {
|
||||
path = skippedNode.path
|
||||
n = skippedNode.node
|
||||
if value.params != nil {
|
||||
*value.params = (*value.params)[:skippedNode.paramsCount]
|
||||
}
|
||||
globalParamsCount = skippedNode.paramsCount
|
||||
if rollbackSkipped() {
|
||||
continue walk
|
||||
}
|
||||
}
|
||||
// n = latestNode.children[len(latestNode.children)-1]
|
||||
}
|
||||
// We should have reached the node containing the handle.
|
||||
// Check if this node has a handle registered.
|
||||
if value.handlers = n.handlers; value.handlers != nil {
|
||||
|
@ -626,20 +626,10 @@ walk: // Outer loop for walking the tree
|
|||
|
||||
// roll back to last valid skippedNode
|
||||
if !value.tsr && path != "/" {
|
||||
for l := len(*skippedNodes); l > 0; {
|
||||
skippedNode := (*skippedNodes)[l-1]
|
||||
*skippedNodes = (*skippedNodes)[:l-1]
|
||||
if strings.HasSuffix(skippedNode.path, path) {
|
||||
path = skippedNode.path
|
||||
n = skippedNode.node
|
||||
if value.params != nil {
|
||||
*value.params = (*value.params)[:skippedNode.paramsCount]
|
||||
}
|
||||
globalParamsCount = skippedNode.paramsCount
|
||||
if rollbackSkipped() {
|
||||
continue walk
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
|
|
@ -240,6 +240,7 @@ func TestTreeWildcard(t *testing.T) {
|
|||
{"/aaa/cc", false, "/:cc/cc", Params{Param{Key: "cc", Value: "aaa"}}},
|
||||
{"/ab", false, "/:cc", Params{Param{Key: "cc", Value: "ab"}}},
|
||||
{"/abb", false, "/:cc", Params{Param{Key: "cc", Value: "abb"}}},
|
||||
{"/c1/cc", false, "/:cc/cc", Params{Param{Key: "cc", Value: "c1"}}},
|
||||
{"/abb/cc", false, "/:cc/cc", Params{Param{Key: "cc", Value: "abb"}}},
|
||||
{"/allxxxx", false, "/:cc", Params{Param{Key: "cc", Value: "allxxxx"}}},
|
||||
{"/alldd", false, "/:cc", Params{Param{Key: "cc", Value: "alldd"}}},
|
||||
|
@ -266,6 +267,8 @@ func TestTreeWildcard(t *testing.T) {
|
|||
{"/something/secondthingaaaa/thirdthing", false, "/something/:paramname/thirdthing", Params{Param{Key: "paramname", Value: "secondthingaaaa"}}},
|
||||
{"/something/se/thirdthing", false, "/something/:paramname/thirdthing", Params{Param{Key: "paramname", Value: "se"}}},
|
||||
{"/something/s/thirdthing", false, "/something/:paramname/thirdthing", Params{Param{Key: "paramname", Value: "s"}}},
|
||||
{"/c1/dd/ee", false, "/:cc/:dd/ee", Params{Param{Key: "cc", Value: "c1"}, Param{Key: "dd", Value: "dd"}}},
|
||||
{"/c1/dd/ee/", true, "/:cc/:dd/ee", Params{Param{Key: "cc", Value: "c1"}, Param{Key: "dd", Value: "dd"}}},
|
||||
{"/c/d/ee", false, "/:cc/:dd/ee", Params{Param{Key: "cc", Value: "c"}, Param{Key: "dd", Value: "d"}}},
|
||||
{"/c/d/e/ff", false, "/:cc/:dd/:ee/ff", Params{Param{Key: "cc", Value: "c"}, Param{Key: "dd", Value: "d"}, Param{Key: "ee", Value: "e"}}},
|
||||
{"/c/d/e/f/gg", false, "/:cc/:dd/:ee/:ff/gg", Params{Param{Key: "cc", Value: "c"}, Param{Key: "dd", Value: "d"}, Param{Key: "ee", Value: "e"}, Param{Key: "ff", Value: "f"}}},
|
||||
|
|
Loading…
Reference in New Issue