in runtime/router/trie.go [249:309]
func (t *tnode) get(path string, lastKeyCharSlash, lastPathCharSlash, colonAsPattern, isWhitelistedPath bool) (http.Handler, []Param, error) {
keyLength, pathLength := len(t.key), len(path)
var params []Param
// find the longest matched prefix
var keyIdx, pathIdx int
for keyIdx < keyLength && pathIdx < pathLength {
if t.isGetWildCardPattern(path, keyIdx, pathIdx, lastKeyCharSlash, lastPathCharSlash, colonAsPattern, isWhitelistedPath) {
// wildcard starts - match until next slash
keyStartIdx, pathStartIdx := keyIdx+1, pathIdx
for keyIdx < keyLength && t.key[keyIdx] != '/' {
keyIdx++
}
for pathIdx < pathLength && path[pathIdx] != '/' {
pathIdx++
}
if t.key[keyStartIdx-1] == ':' {
params = append(params, Param{t.key[keyStartIdx:keyIdx], path[pathStartIdx:pathIdx]})
}
} else if t.key[keyIdx] == path[pathIdx] {
keyIdx++
pathIdx++
} else {
break
}
lastKeyCharSlash = t.key[keyIdx-1] == '/'
lastPathCharSlash = path[pathIdx-1] == '/'
}
if keyIdx < keyLength {
// path matches up to node key's second to last character,
// the last char of node key is "*" and path is no shorter than longest matched prefix
if t.key[keyIdx:] == "*" && pathIdx < pathLength {
return t.value, params, nil
}
return nil, nil, errNotFound
}
// ':' in path matches '*' in node key
if keyIdx > 0 && t.key[keyIdx-1] == '*' {
return t.value, params, nil
}
// longest matched prefix matches up to node key length and path length
if pathIdx == pathLength {
if t.value != nil {
return t.value, params, nil
}
return nil, nil, errNotFound
}
// longest matched prefix matches up to node key length but not path length
for _, c := range t.children {
if v, ps, err := c.get(path[pathIdx:], lastKeyCharSlash, lastPathCharSlash, colonAsPattern, isWhitelistedPath); err == nil {
return v, append(params, ps...), nil
}
}
return nil, nil, errNotFound
}