func()

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
}