From fe436bf2c07e310864f9016ea2215520645d47ee Mon Sep 17 00:00:00 2001 From: Bo-Yi Wu Date: Fri, 8 May 2020 13:12:41 +0800 Subject: [PATCH] udpate Signed-off-by: Bo-Yi Wu --- gin.go | 5 +- tree.go | 244 ++++++++++++++++++++++++++++---------------------------- 2 files changed, 124 insertions(+), 125 deletions(-) diff --git a/gin.go b/gin.go index 292aea3c..ce12219e 100644 --- a/gin.go +++ b/gin.go @@ -253,6 +253,7 @@ func (engine *Engine) rebuild405Handlers() { } func (engine *Engine) addRoute(method, path string, handlers HandlersChain) { + // log.Println(method, path) assert1(path[0] == '/', "path must begin with '/'") assert1(method != "", "HTTP method can not be empty") assert1(len(handlers) > 0, "there must be at least one handler") @@ -269,13 +270,15 @@ func (engine *Engine) addRoute(method, path string, handlers HandlersChain) { root.addRoute(path, handlers) // Update maxParams - if paramsCount := countParams(path); paramsCount+varsCount > root.maxParams { + // log.Println("countParams(path):", countParams(path)) + if paramsCount := countParams(path); paramsCount+varsCount > engine.maxParams { engine.maxParams = paramsCount + varsCount } // Lazy-init paramsPool alloc func if engine.paramsPool.New == nil && engine.maxParams > 0 { engine.paramsPool.New = func() interface{} { + // log.Println("engine.maxParams:", engine.maxParams) ps := make(Params, 0, engine.maxParams) return &ps } diff --git a/tree.go b/tree.go index c4ccc71c..cd376c33 100644 --- a/tree.go +++ b/tree.go @@ -5,7 +5,6 @@ package gin import ( - "log" "strings" "unicode" "unicode/utf8" @@ -424,146 +423,143 @@ func (n *node) getValue(path string, params func() *Params, unescape bool) (valu walk: // Outer loop for walking the tree for { prefix := n.path - - if len(path) > len(prefix) && path[:len(prefix)] == prefix { - path = path[len(prefix):] - // If this node does not have a wildcard (param or catchAll) - // child, we can just look up the next child node and continue - // to walk down the tree - if !n.wildChild { - idxc := path[0] - for i, c := range []byte(n.indices) { - if c == idxc { - n = n.children[i] - continue walk + if len(path) > len(prefix) { + if path[:len(prefix)] == prefix { + path = path[len(prefix):] + // If this node does not have a wildcard (param or catchAll) + // child, we can just look up the next child node and continue + // to walk down the tree + if !n.wildChild { + idxc := path[0] + for i, c := range []byte(n.indices) { + if c == idxc { + n = n.children[i] + continue walk + } } + + // Nothing found. + // We can recommend to redirect to the same URL without a + // trailing slash if a leaf exists for that path. + value.tsr = (path == "/" && n.handlers != nil) + return } - // Nothing found. - // We can recommend to redirect to the same URL without a - // trailing slash if a leaf exists for that path. - value.tsr = (path == "/" && n.handlers != nil) - return - } - - // handle wildcard child - n = n.children[0] - switch n.nType { - case param: - // find param end (either '/' or path end) - end := 0 - for end < len(path) && path[end] != '/' { - end++ - } - - // save param value - // if cap(value.params) < int(n.maxParams) { - // value.params = make(Params, 0, n.maxParams) - // } - // i := len(value.params) - // value.params = value.params[:i+1] // expand slice within preallocated capacity - // value.params[i].Key = n.path[1:] - // val := path[:end] - // if unescape { - // var err error - // if value.params[i].Value, err = url.QueryUnescape(val); err != nil { - // value.params[i].Value = val // fallback, in case of error - // } - // } else { - // value.params[i].Value = val - // } - if params != nil { - if value.params == nil { - value.params = params() + // handle wildcard child + n = n.children[0] + switch n.nType { + case param: + // find param end (either '/' or path end) + end := 0 + for end < len(path) && path[end] != '/' { + end++ } - // Expand slice within preallocated capacity - i := len(*value.params) - log.Println(i) - log.Println(*value.params) - *value.params = (*value.params)[:i+1] + + // save param value + // if cap(value.params) < int(n.maxParams) { + // value.params = make(Params, 0, n.maxParams) + // } + // i := len(value.params) + // value.params = value.params[:i+1] // expand slice within preallocated capacity + // value.params[i].Key = n.path[1:] // val := path[:end] // if unescape { - // if v, err := url.QueryUnescape(val); err == nil { - // val = v + // var err error + // if value.params[i].Value, err = url.QueryUnescape(val); err != nil { + // value.params[i].Value = val // fallback, in case of error // } + // } else { + // value.params[i].Value = val // } - (*value.params)[i] = Param{ - Key: n.path[1:], - Value: path, + if params != nil { + if value.params == nil { + value.params = params() + } + // Expand slice within preallocated capacity + i := len(*value.params) + *value.params = (*value.params)[:i+1] + // val := path[:end] + // if unescape { + // if v, err := url.QueryUnescape(val); err == nil { + // val = v + // } + // } + (*value.params)[i] = Param{ + Key: n.path[1:], + Value: path[:end], + } } - } - // we need to go deeper! - if end < len(path) { - if len(n.children) > 0 { - path = path[end:] + // we need to go deeper! + if end < len(path) { + if len(n.children) > 0 { + path = path[end:] + n = n.children[0] + continue walk + } + + // ... but we can't + value.tsr = (len(path) == end+1) + return + } + + if value.handlers = n.handlers; value.handlers != nil { + // value.fullPath = n.fullPath + return + } + if len(n.children) == 1 { + // No handle found. Check if a handle for this path + a + // trailing slash exists for TSR recommendation n = n.children[0] - continue walk + value.tsr = (n.path == "/" && n.handlers != nil) + } + return + + case catchAll: + // // save param value + // if cap(value.params) < int(n.maxParams) { + // value.params = make(Params, 0, n.maxParams) + // } + // i := len(value.params) + // value.params = value.params[:i+1] // expand slice within preallocated capacity + // value.params[i].Key = n.path[2:] + // if unescape { + // var err error + // if value.params[i].Value, err = url.QueryUnescape(path); err != nil { + // value.params[i].Value = path // fallback, in case of error + // } + // } else { + // value.params[i].Value = path + // } + + // Save param value + if params != nil { + if value.params == nil { + value.params = params() + } + // Expand slice within preallocated capacity + i := len(*value.params) + *value.params = (*value.params)[:i+1] + // if unescape { + // if v, err := url.QueryUnescape(path); err == nil { + // path = v + // } + // } + (*value.params)[i] = Param{ + Key: n.path[2:], + Value: path, + } } - // ... but we can't - value.tsr = (len(path) == end+1) - return - } - - if value.handlers = n.handlers; value.handlers != nil { + value.handlers = n.handlers // value.fullPath = n.fullPath return + + default: + panic("invalid node type") } - if len(n.children) == 1 { - // 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) - } - return - - case catchAll: - // // save param value - // if cap(value.params) < int(n.maxParams) { - // value.params = make(Params, 0, n.maxParams) - // } - // i := len(value.params) - // value.params = value.params[:i+1] // expand slice within preallocated capacity - // value.params[i].Key = n.path[2:] - // if unescape { - // var err error - // if value.params[i].Value, err = url.QueryUnescape(path); err != nil { - // value.params[i].Value = path // fallback, in case of error - // } - // } else { - // value.params[i].Value = path - // } - - // Save param value - if params != nil { - if value.params == nil { - value.params = params() - } - // Expand slice within preallocated capacity - i := len(*value.params) - *value.params = (*value.params)[:i+1] - // if unescape { - // if v, err := url.QueryUnescape(path); err == nil { - // path = v - // } - // } - (*value.params)[i] = Param{ - Key: n.path[2:], - Value: path, - } - } - - value.handlers = n.handlers - // value.fullPath = n.fullPath - return - - default: - panic("invalid node type") } - } - - if path == prefix { + } else if path == prefix { // 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 {