private static List <RouteResult> BranchSearch(PathBranch branch, string method, IReadOnlyList <string> pathTokens) { var list = new List <RouteResult>(); var matchedTokens = new RequestDictionary(); return(BranchSearch(branch, method, pathTokens, 0, matchedTokens, list)); }
public RouteResult MatchPath(string path, string method) { var tokens = (path ?? "").Trim('/').Split('/'); var matchedResults = BranchSearch(Root, method, tokens); RouteResult result = null; switch (matchedResults.Count) { case 0: return(new RouteResult { Found = false }); case 1: result = matchedResults[0]; break; default: foreach (var matchedResult in matchedResults) { if (result == null) { result = matchedResult; continue; } var ctc = result.Route.LiteralTokenCount; var ntc = matchedResult.Route.LiteralTokenCount; if (ctc <= ntc || (ctc == ntc && result.Vars.Count < matchedResult.Vars.Count)) { result = matchedResult; } } break; } if (result == null) { return new RouteResult { Found = false } } ; result.Found = true; var vars = new RequestDictionary(result.Route?.Defaults ?? new Defaults()); // TODO: fix the branch searcher so that it doesn't glom on extra vars foreach (var pair in result.Route.ExtractVars(path)) { vars[pair.Key] = pair.Value; } result.Vars = vars; return(result); }
private static List <RouteResult> BranchSearch(PathBranch branch, string method, IReadOnlyList <string> pathTokens, int tokenIndex, RequestDictionary matchedTokens, List <RouteResult> matchedResults) { if (tokenIndex > pathTokens.Count - 1) { return(matchedResults); } var token = pathTokens[tokenIndex]; foreach (var child in branch.Children) { if (child.Token.Text != null) { if (child.Token.Text != token || child.Routes == null) { continue; } foreach (var route in child.Routes) { if (route.Methods.Contains(method)) { matchedResults.Add(new RouteResult { Route = route, Vars = matchedTokens }); } } BranchSearch(child, method, pathTokens, tokenIndex + 1, matchedTokens, matchedResults); } else if (child.Token.MatchAny || child.Token.Matcher != null) { if (child.Token.Matcher != null) { var match = child.Token.Matcher.Match(token); if (!match.Success) { continue; } } var name = child.Token.Name; if (child.Token.Greedy) { matchedTokens[name] = string.Join("/", pathTokens.Skip(tokenIndex)); } else { matchedTokens[name] = token; } if (child.Routes != null) { foreach (var route in child.Routes) { if (route.Methods.Contains(method)) { matchedResults.Add(new RouteResult { Route = route, Vars = matchedTokens }); } } } if (!child.Token.Greedy) { BranchSearch(child, method, pathTokens, tokenIndex + 1, new RequestDictionary(matchedTokens), matchedResults); } } } return(matchedResults); }