From ff434e26673d8d842bd11e9a848811a5424b5d66 Mon Sep 17 00:00:00 2001 From: youngblood <944168348@qq.com> Date: Sat, 28 Jul 2018 13:13:02 +0800 Subject: [PATCH 1/6] add RelativePath --- context.go | 3 +++ gin.go | 3 ++- tree.go | 9 ++++++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/context.go b/context.go index 720c4251..014801da 100644 --- a/context.go +++ b/context.go @@ -57,6 +57,9 @@ type Context struct { // Accepted defines a list of manually accepted formats for content negotiation. Accepted []string + + // save the route's relativePath + RelativePath string } /************************************/ diff --git a/gin.go b/gin.go index 3ee8018d..35b6b5e2 100644 --- a/gin.go +++ b/gin.go @@ -352,7 +352,8 @@ func (engine *Engine) handleHTTPRequest(c *Context) { if t[i].method == httpMethod { root := t[i].root // Find route in tree - handlers, params, tsr := root.getValue(path, c.Params, unescape) + handlers, params, relativePath, tsr := root.getValue(path, c.Params, unescape) + c.RelativePath = relativePath if handlers != nil { c.handlers = handlers c.Params = params diff --git a/tree.go b/tree.go index b6530665..4766177b 100644 --- a/tree.go +++ b/tree.go @@ -362,8 +362,9 @@ func (n *node) insertChild(numParams uint8, path string, fullPath string, handle // 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, po Params, unescape bool) (handlers HandlersChain, p Params, tsr bool) { +func (n *node) getValue(path string, po Params, unescape bool) (handlers HandlersChain, p Params, relativePath string, tsr bool) { p = po + relativePath = path walk: // Outer loop for walking the tree for { if len(path) > len(n.path) { @@ -415,6 +416,9 @@ walk: // Outer loop for walking the tree p[i].Value = val } + // replace p.value with p.key (pattern :) + relativePath = strings.Replace(relativePath, p[i].Value, ":"+p[i].Key, 1) + // we need to go deeper! if end < len(path) { if len(n.children) > 0 { @@ -457,6 +461,9 @@ walk: // Outer loop for walking the tree p[i].Value = path } + // replace p.value with p.key (pattern *) + relativePath = strings.Replace(relativePath, p[i].Value, "/*"+p[i].Key, 1) + handlers = n.handlers return From 7b86a6382da9562fd3565a5fef17e07e7c302e9b Mon Sep 17 00:00:00 2001 From: youngblood <944168348@qq.com> Date: Sat, 28 Jul 2018 13:14:47 +0800 Subject: [PATCH 2/6] add RelativePath --- gin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gin.go b/gin.go index 35b6b5e2..bc12265a 100644 --- a/gin.go +++ b/gin.go @@ -377,7 +377,7 @@ func (engine *Engine) handleHTTPRequest(c *Context) { if engine.HandleMethodNotAllowed { for _, tree := range engine.trees { if tree.method != httpMethod { - if handlers, _, _ := tree.root.getValue(path, nil, unescape); handlers != nil { + if handlers, _, _, _ := tree.root.getValue(path, nil, unescape); handlers != nil { c.handlers = engine.allNoMethod serveError(c, http.StatusMethodNotAllowed, default405Body) return From adbfb90327a9e219af8a3543da29f9f71bd8f5ee Mon Sep 17 00:00:00 2001 From: youngblood <944168348@qq.com> Date: Sat, 28 Jul 2018 14:41:16 +0800 Subject: [PATCH 3/6] tree_test --- tree_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tree_test.go b/tree_test.go index 5bc27171..4ceb5682 100644 --- a/tree_test.go +++ b/tree_test.go @@ -33,7 +33,7 @@ func checkRequests(t *testing.T, tree *node, requests testRequests, unescapes .. } for _, request := range requests { - handler, ps, _ := tree.getValue(request.path, nil, unescape) + handler, ps, _, _ := tree.getValue(request.path, nil, unescape) if handler == nil { if !request.nilHandler { @@ -463,7 +463,7 @@ func TestTreeTrailingSlashRedirect(t *testing.T) { "/doc/", } for _, route := range tsrRoutes { - handler, _, tsr := tree.getValue(route, nil, false) + handler, _, _, tsr := tree.getValue(route, nil, false) if handler != nil { t.Fatalf("non-nil handler for TSR route '%s", route) } else if !tsr { @@ -480,7 +480,7 @@ func TestTreeTrailingSlashRedirect(t *testing.T) { "/api/world/abc", } for _, route := range noTsrRoutes { - handler, _, tsr := tree.getValue(route, nil, false) + handler, _, _, tsr := tree.getValue(route, nil, false) if handler != nil { t.Fatalf("non-nil handler for No-TSR route '%s", route) } else if tsr { @@ -499,7 +499,7 @@ func TestTreeRootTrailingSlashRedirect(t *testing.T) { t.Fatalf("panic inserting test route: %v", recv) } - handler, _, tsr := tree.getValue("/", nil, false) + handler, _, _, tsr := tree.getValue("/", nil, false) if handler != nil { t.Fatalf("non-nil handler") } else if tsr { From b5847d0a7af0cff45a52a1e2fb74b0cabea64ec9 Mon Sep 17 00:00:00 2001 From: youngblood <944168348@qq.com> Date: Wed, 8 Aug 2018 17:21:42 +0800 Subject: [PATCH 4/6] add fullpath in node --- tree.go | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/tree.go b/tree.go index 4766177b..93be5d6d 100644 --- a/tree.go +++ b/tree.go @@ -94,6 +94,7 @@ type node struct { nType nodeType maxParams uint8 wildChild bool + fullPath string } // increments priority of the given child and reorders if necessary. @@ -247,6 +248,9 @@ func (n *node) addRoute(path string, handlers HandlersChain) { func (n *node) insertChild(numParams uint8, path string, fullPath string, handlers HandlersChain) { var offset int // already handled bytes of the path + // save the node's full path + var nodeFullPath string + // find prefix until first wildcard (beginning with ':' or '*') for i, max := 0, len(path); numParams > 0; i++ { c := path[i] @@ -285,6 +289,13 @@ func (n *node) insertChild(numParams uint8, path string, fullPath string, handle n.path = path[offset:i] offset = i } + if n.path[0] != '/' { + nodeFullPath = "/" + n.path + } else { + nodeFullPath += n.path + } + // save node's full path + n.fullPath = nodeFullPath child := &node{ nType: param, @@ -302,6 +313,9 @@ func (n *node) insertChild(numParams uint8, path string, fullPath string, handle n.path = path[offset:end] offset = end + nodeFullPath += n.path + n.fullPath = nodeFullPath + child := &node{ maxParams: numParams, priority: 1, @@ -326,6 +340,8 @@ func (n *node) insertChild(numParams uint8, path string, fullPath string, handle } n.path = path[offset:i] + nodeFullPath += n.path + n.fullPath = nodeFullPath // first node: catchAll node with empty path child := &node{ @@ -345,6 +361,7 @@ func (n *node) insertChild(numParams uint8, path string, fullPath string, handle maxParams: 1, handlers: handlers, priority: 1, + fullPath: nodeFullPath + path[i:], } n.children = []*node{child} @@ -354,6 +371,7 @@ func (n *node) insertChild(numParams uint8, path string, fullPath string, handle // insert remaining path part and handle to the leaf n.path = path[offset:] + n.fullPath = nodeFullPath + n.path n.handlers = handlers } @@ -364,7 +382,9 @@ func (n *node) insertChild(numParams uint8, path string, fullPath string, handle // given path. func (n *node) getValue(path string, po Params, unescape bool) (handlers HandlersChain, p Params, relativePath string, tsr bool) { p = po - relativePath = path + defer func() { + relativePath = n.fullPath + }() walk: // Outer loop for walking the tree for { if len(path) > len(n.path) { @@ -416,9 +436,6 @@ walk: // Outer loop for walking the tree p[i].Value = val } - // replace p.value with p.key (pattern :) - relativePath = strings.Replace(relativePath, p[i].Value, ":"+p[i].Key, 1) - // we need to go deeper! if end < len(path) { if len(n.children) > 0 { @@ -461,9 +478,6 @@ walk: // Outer loop for walking the tree p[i].Value = path } - // replace p.value with p.key (pattern *) - relativePath = strings.Replace(relativePath, p[i].Value, "/*"+p[i].Key, 1) - handlers = n.handlers return From 2fc9b15c7a19676deee4e60eed73dad1de0fcd45 Mon Sep 17 00:00:00 2001 From: youngblood <944168348@qq.com> Date: Wed, 8 Aug 2018 18:40:15 +0800 Subject: [PATCH 5/6] add fullpath in node --- tree.go | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/tree.go b/tree.go index 93be5d6d..f7187664 100644 --- a/tree.go +++ b/tree.go @@ -248,9 +248,6 @@ func (n *node) addRoute(path string, handlers HandlersChain) { func (n *node) insertChild(numParams uint8, path string, fullPath string, handlers HandlersChain) { var offset int // already handled bytes of the path - // save the node's full path - var nodeFullPath string - // find prefix until first wildcard (beginning with ':' or '*') for i, max := 0, len(path); numParams > 0; i++ { c := path[i] @@ -289,13 +286,6 @@ func (n *node) insertChild(numParams uint8, path string, fullPath string, handle n.path = path[offset:i] offset = i } - if n.path[0] != '/' { - nodeFullPath = "/" + n.path - } else { - nodeFullPath += n.path - } - // save node's full path - n.fullPath = nodeFullPath child := &node{ nType: param, @@ -313,9 +303,6 @@ func (n *node) insertChild(numParams uint8, path string, fullPath string, handle n.path = path[offset:end] offset = end - nodeFullPath += n.path - n.fullPath = nodeFullPath - child := &node{ maxParams: numParams, priority: 1, @@ -340,8 +327,6 @@ func (n *node) insertChild(numParams uint8, path string, fullPath string, handle } n.path = path[offset:i] - nodeFullPath += n.path - n.fullPath = nodeFullPath // first node: catchAll node with empty path child := &node{ @@ -361,7 +346,7 @@ func (n *node) insertChild(numParams uint8, path string, fullPath string, handle maxParams: 1, handlers: handlers, priority: 1, - fullPath: nodeFullPath + path[i:], + fullPath: fullPath, } n.children = []*node{child} @@ -371,7 +356,7 @@ func (n *node) insertChild(numParams uint8, path string, fullPath string, handle // insert remaining path part and handle to the leaf n.path = path[offset:] - n.fullPath = nodeFullPath + n.path + n.fullPath = fullPath n.handlers = handlers } From 45bb968ea84af9152bed7db896bba272c58ee7c4 Mon Sep 17 00:00:00 2001 From: youngblood <944168348@qq.com> Date: Wed, 8 Aug 2018 18:44:35 +0800 Subject: [PATCH 6/6] add fullpath in the end node --- tree.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tree.go b/tree.go index f7187664..bdd4b599 100644 --- a/tree.go +++ b/tree.go @@ -248,6 +248,11 @@ func (n *node) addRoute(path string, handlers HandlersChain) { func (n *node) insertChild(numParams uint8, path string, fullPath string, handlers HandlersChain) { var offset int // already handled bytes of the path + // add the prefix of the route + if fullPath[0] != '/' { + fullPath = "/" + fullPath + } + // find prefix until first wildcard (beginning with ':' or '*') for i, max := 0, len(path); numParams > 0; i++ { c := path[i]