mirror of
https://github.com/gin-gonic/gin.git
synced 2025-10-15 21:06:39 +08:00
Merge 3f436fce7eaaf109defa67c8646e69ba971015a1 into 857db39f82fb82456af2906ccea972ae1d65ff57
This commit is contained in:
commit
c1e4457e58
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,3 +5,4 @@ count.out
|
||||
test
|
||||
profile.out
|
||||
tmp.out
|
||||
*.iml
|
||||
|
4
gin.go
4
gin.go
@ -609,7 +609,7 @@ func (engine *Engine) handleHTTPRequest(c *Context) {
|
||||
}
|
||||
root := t[i].root
|
||||
// Find route in tree
|
||||
value := root.getValue(rPath, c.params, c.skippedNodes, unescape)
|
||||
value := root.getValue(rPath, c.params, c.skippedNodes, unescape, engine.RedirectFixedPath)
|
||||
if value.params != nil {
|
||||
c.Params = *value.params
|
||||
}
|
||||
@ -637,7 +637,7 @@ func (engine *Engine) handleHTTPRequest(c *Context) {
|
||||
if tree.method == httpMethod {
|
||||
continue
|
||||
}
|
||||
if value := tree.root.getValue(rPath, nil, c.skippedNodes, unescape); value.handlers != nil {
|
||||
if value := tree.root.getValue(rPath, nil, c.skippedNodes, unescape, engine.RedirectFixedPath); value.handlers != nil {
|
||||
c.handlers = engine.allNoMethod
|
||||
serveError(c, http.StatusMethodNotAllowed, default405Body)
|
||||
return
|
||||
|
35
tree.go
35
tree.go
@ -417,7 +417,7 @@ type skippedNode struct {
|
||||
// If no handle can be found, a TSR (trailing slash redirect) recommendation is
|
||||
// made if a handle exists with an extra (without the) trailing slash for the
|
||||
// given path.
|
||||
func (n *node) getValue(path string, params *Params, skippedNodes *[]skippedNode, unescape bool) (value nodeValue) {
|
||||
func (n *node) getValue(path string, params *Params, skippedNodes *[]skippedNode, unescape, redirectFixedPath bool) (value nodeValue) {
|
||||
var globalParamsCount int16
|
||||
|
||||
walk: // Outer loop for walking the tree
|
||||
@ -513,8 +513,20 @@ walk: // Outer loop for walking the tree
|
||||
*value.params = (*value.params)[:i+1]
|
||||
val := path[:end]
|
||||
if unescape {
|
||||
if v, err := url.QueryUnescape(val); err == nil {
|
||||
val = v
|
||||
v := val
|
||||
for {
|
||||
beforeDecoding := v
|
||||
decoded, err := url.QueryUnescape(v)
|
||||
if err == nil {
|
||||
v = decoded
|
||||
}
|
||||
if beforeDecoding == v || err != nil {
|
||||
val = v
|
||||
break
|
||||
}
|
||||
}
|
||||
if redirectFixedPath {
|
||||
val = cleanPath(val)
|
||||
}
|
||||
}
|
||||
(*value.params)[i] = Param{
|
||||
@ -566,8 +578,21 @@ walk: // Outer loop for walking the tree
|
||||
*value.params = (*value.params)[:i+1]
|
||||
val := path
|
||||
if unescape {
|
||||
if v, err := url.QueryUnescape(path); err == nil {
|
||||
val = v
|
||||
v := val
|
||||
for {
|
||||
beforeDecoding := v
|
||||
if decoded, err := url.QueryUnescape(v); err == nil {
|
||||
v = decoded
|
||||
} else {
|
||||
break
|
||||
}
|
||||
if beforeDecoding == v {
|
||||
val = v
|
||||
break
|
||||
}
|
||||
}
|
||||
if redirectFixedPath {
|
||||
val = cleanPath(val)
|
||||
}
|
||||
}
|
||||
(*value.params)[i] = Param{
|
||||
|
23
tree_test.go
23
tree_test.go
@ -38,14 +38,15 @@ func getSkippedNodes() *[]skippedNode {
|
||||
return &ps
|
||||
}
|
||||
|
||||
func checkRequests(t *testing.T, tree *node, requests testRequests, unescapes ...bool) {
|
||||
func checkRequests(t *testing.T, tree *node, requests testRequests, redirectFixedPath bool, unescapes ...bool) {
|
||||
unescape := false
|
||||
|
||||
if len(unescapes) >= 1 {
|
||||
unescape = unescapes[0]
|
||||
}
|
||||
|
||||
for _, request := range requests {
|
||||
value := tree.getValue(request.path, getParams(), getSkippedNodes(), unescape)
|
||||
value := tree.getValue(request.path, getParams(), getSkippedNodes(), unescape, redirectFixedPath)
|
||||
|
||||
if value.handlers == nil {
|
||||
if !request.nilHandler {
|
||||
@ -130,7 +131,7 @@ func TestTreeAddAndGet(t *testing.T) {
|
||||
{"/ab", false, "/ab", nil},
|
||||
{"/α", false, "/α", nil},
|
||||
{"/β", false, "/β", nil},
|
||||
})
|
||||
}, false)
|
||||
|
||||
checkPriorities(t, tree)
|
||||
}
|
||||
@ -315,7 +316,7 @@ func TestTreeWildcard(t *testing.T) {
|
||||
{"/get/abc/123abg/test", false, "/get/abc/123abg/:param", Params{Param{Key: "param", Value: "test"}}},
|
||||
{"/get/abc/123abf/testss", false, "/get/abc/123abf/:param", Params{Param{Key: "param", Value: "testss"}}},
|
||||
{"/get/abc/123abfff/te", false, "/get/abc/123abfff/:param", Params{Param{Key: "param", Value: "te"}}},
|
||||
})
|
||||
}, false)
|
||||
|
||||
checkPriorities(t, tree)
|
||||
}
|
||||
@ -352,7 +353,7 @@ func TestUnescapeParameters(t *testing.T) {
|
||||
{"/info/slash%2Fgordon/project/Project%20%231", false, "/info/:user/project/:project", Params{Param{Key: "user", Value: "slash/gordon"}, Param{Key: "project", Value: "Project #1"}}},
|
||||
{"/info/slash%%%%", false, "/info/:user", Params{Param{Key: "user", Value: "slash%%%%"}}},
|
||||
{"/info/slash%%%%2Fgordon/project/Project%%%%20%231", false, "/info/:user/project/:project", Params{Param{Key: "user", Value: "slash%%%%2Fgordon"}, Param{Key: "project", Value: "Project%%%%20%231"}}},
|
||||
}, unescape)
|
||||
}, false, unescape)
|
||||
|
||||
checkPriorities(t, tree)
|
||||
}
|
||||
@ -482,7 +483,7 @@ func TestTreeDuplicatePath(t *testing.T) {
|
||||
{"/src/some/file.png", false, "/src/*filepath", Params{Param{"filepath", "/some/file.png"}}},
|
||||
{"/search/someth!ng+in+ünìcodé", false, "/search/:query", Params{Param{"query", "someth!ng+in+ünìcodé"}}},
|
||||
{"/user_gopher", false, "/user_:name", Params{Param{"name", "gopher"}}},
|
||||
})
|
||||
}, false)
|
||||
}
|
||||
|
||||
func TestEmptyWildcardName(t *testing.T) {
|
||||
@ -636,7 +637,7 @@ func TestTreeTrailingSlashRedirect(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, route := range tsrRoutes {
|
||||
value := tree.getValue(route, nil, getSkippedNodes(), false)
|
||||
value := tree.getValue(route, nil, getSkippedNodes(), false, false)
|
||||
if value.handlers != nil {
|
||||
t.Fatalf("non-nil handler for TSR route '%s", route)
|
||||
} else if !value.tsr {
|
||||
@ -657,7 +658,7 @@ func TestTreeTrailingSlashRedirect(t *testing.T) {
|
||||
"/foo/p/p",
|
||||
}
|
||||
for _, route := range noTsrRoutes {
|
||||
value := tree.getValue(route, nil, getSkippedNodes(), false)
|
||||
value := tree.getValue(route, nil, getSkippedNodes(), false, false)
|
||||
if value.handlers != nil {
|
||||
t.Fatalf("non-nil handler for No-TSR route '%s", route)
|
||||
} else if value.tsr {
|
||||
@ -676,7 +677,7 @@ func TestTreeRootTrailingSlashRedirect(t *testing.T) {
|
||||
t.Fatalf("panic inserting test route: %v", recv)
|
||||
}
|
||||
|
||||
value := tree.getValue("/", nil, getSkippedNodes(), false)
|
||||
value := tree.getValue("/", nil, getSkippedNodes(), false, false)
|
||||
if value.handlers != nil {
|
||||
t.Fatalf("non-nil handler")
|
||||
} else if value.tsr {
|
||||
@ -876,7 +877,7 @@ func TestTreeInvalidNodeType(t *testing.T) {
|
||||
|
||||
// normal lookup
|
||||
recv := catchPanic(func() {
|
||||
tree.getValue("/test", nil, getSkippedNodes(), false)
|
||||
tree.getValue("/test", nil, getSkippedNodes(), false, false)
|
||||
})
|
||||
if rs, ok := recv.(string); !ok || rs != panicMsg {
|
||||
t.Fatalf("Expected panic '"+panicMsg+"', got '%v'", recv)
|
||||
@ -901,7 +902,7 @@ func TestTreeInvalidParamsType(t *testing.T) {
|
||||
params := make(Params, 0)
|
||||
|
||||
// try to trigger slice bounds out of range with capacity 0
|
||||
tree.getValue("/test", ¶ms, getSkippedNodes(), false)
|
||||
tree.getValue("/test", ¶ms, getSkippedNodes(), false, false)
|
||||
}
|
||||
|
||||
func TestTreeExpandParamsCapacity(t *testing.T) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user