// 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 }
// 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) }