// add each path matcher to the path tree. If a matcher is a subtree, add it with the // additional paths. func addTreeMatchers(pathTree *pathmux.Tree, matchers map[string]*pathMatcher, subtree bool) []*definitionError { var errors []*definitionError for p, m := range matchers { // sort leaves during construction time, based on their priority sort.Sort(m.leaves) if p == "" { p = "/" } if subtree { if err := addSubtreeMatcher(pathTree, p, m); err != nil { errors = append(errors, &definitionError{Index: -1, Original: err}) } } else { if err := pathTree.Add(p, m); err != nil { errors = append(errors, &definitionError{Index: -1, Original: err}) continue } } } return errors }
// matches a path in the path trie structure. func matchPathTree(tree *pathmux.Tree, path string, lrm *leafRequestMatcher) (map[string]string, *leafMatcher) { v, params, value := tree.LookupMatcher(path, lrm) if v == nil { return nil, nil } // prepend slash in case of free form wildcards path segments (`/*name`), pm := v.(*pathMatcher) if pm.freeWildcardParam != "" { freeParam := params[pm.freeWildcardParam] freeParam = "/" + freeParam params[pm.freeWildcardParam] = freeParam } return params, value.(*leafMatcher) }
// matches a path in the path trie structure. func matchPathTree(tree *pathmux.Tree, path string) (leafMatchers, map[string]string) { v, params := tree.Lookup(path) if v == nil { return nil, nil } // prepend slash in case of free form wildcards path segments (`/*name`), pm := v.(*pathMatcher) if pm.freeWildcardParam != "" { freeParam := params[pm.freeWildcardParam] freeParam = "/" + freeParam params[pm.freeWildcardParam] = freeParam } return pm.leaves, params }
// add all required tree entries for a subtree with patching the path and // the wildcard name if required func addSubtreeMatcher(pathTree *pathmux.Tree, path string, m *pathMatcher) error { // if has named free wildcard, use its name and take the path only // otherwise set the free wildcard name by convention to "*", as in "/foo/**" fwp := m.freeWildcardParam if fwp == "" { fwp = "*" m.freeWildcardParam = "*" } else { path = path[:len(path)-len(fwp)-1] } // if ends with '/' then set one without // otherwise set one with '/' // // the subtree will be represented as "/foo/**" or "/foo/*wildcard" var pathAlt, pathSubtree string if path[len(path)-1] == '/' { pathAlt = path[:len(path)-1] pathSubtree = path + "*" + fwp } else { pathAlt = path + "/" pathSubtree = pathAlt + "*" + fwp } if err := pathTree.Add(path, m); err != nil { return err } if pathAlt != "" { if err := pathTree.Add(pathAlt, m); err != nil { return err } } return pathTree.Add(pathSubtree, m) }