/// <summary> /// Gets the route, and the corresponding parameter dictionary from the URL /// </summary> /// <param name="context">Current context</param> /// <param name="routeCache">Route cache</param> /// <returns>Tuple - Item1 being the Route, Item2 being the parameters dictionary, Item3 being the prereq, Item4 being the postreq</returns> public ResolveResult Resolve(NancyContext context, IRouteCache routeCache) { if (routeCache.IsEmpty()) { return new ResolveResult(new NotFoundRoute(context.Request.Method, context.Request.Uri), DynamicDictionary.Empty, null, null); } var routesThatMatchRequestedPath = this.GetRoutesThatMatchRequestedPath(routeCache, context); if (NoRoutesWereAbleToBeMatchedInRouteCache(routesThatMatchRequestedPath)) { return new ResolveResult(new NotFoundRoute(context.Request.Method, context.Request.Uri), DynamicDictionary.Empty, null, null); } var routesWithCorrectRequestMethod = GetRoutesWithCorrectRequestMethod(context.Request, routesThatMatchRequestedPath); if (NoRoutesWereForTheRequestedMethod(routesWithCorrectRequestMethod)) { return new ResolveResult(new MethodNotAllowedRoute(context.Request.Uri, context.Request.Method), DynamicDictionary.Empty, null, null); } var routeMatchesWithMostParameterCaptures = GetRouteMatchesWithMostParameterCaptures(routesWithCorrectRequestMethod); var routeMatchToReturn = GetSingleRouteToReturn(routeMatchesWithMostParameterCaptures); return this.CreateRouteAndParametersFromMatch(context, routeMatchToReturn); }
/// <summary> /// Gets the route, and the corresponding parameter dictionary from the URL /// </summary> /// <param name="context">Current context</param> /// <param name="routeCache">Route cache</param> /// <returns>Tuple - Item1 being the Route, Item2 being the parameters dictionary, Item3 being the prereq, Item4 being the postreq</returns> public ResolveResult Resolve(NancyContext context, IRouteCache routeCache) { if (routeCache.IsEmpty()) { return(new ResolveResult(new NotFoundRoute(context.Request.Method, context.Request.Uri), DynamicDictionary.Empty, null, null)); } var routesThatMatchRequestedPath = this.GetRoutesThatMatchRequestedPath(routeCache, context); if (NoRoutesWereAbleToBeMatchedInRouteCache(routesThatMatchRequestedPath)) { return(new ResolveResult(new NotFoundRoute(context.Request.Method, context.Request.Uri), DynamicDictionary.Empty, null, null)); } var routesWithCorrectRequestMethod = GetRoutesWithCorrectRequestMethod(context.Request, routesThatMatchRequestedPath); if (NoRoutesWereForTheRequestedMethod(routesWithCorrectRequestMethod)) { var allowedMethods = routesThatMatchRequestedPath.Select(x => x.Item3.Method); return(new ResolveResult(new MethodNotAllowedRoute(context.Request.Uri, context.Request.Method, allowedMethods), DynamicDictionary.Empty, null, null)); } var routeMatchesWithMostParameterCaptures = GetRouteMatchesWithMostParameterCaptures(routesWithCorrectRequestMethod); var routeMatchToReturn = GetSingleRouteToReturn(routeMatchesWithMostParameterCaptures); return(this.CreateRouteAndParametersFromMatch(context, routeMatchToReturn)); }
/// <summary> /// Gets the route, and the corresponding parameter dictionary from the URL /// </summary> /// <param name="context">Current context</param> /// <param name="routeCache">Route cache</param> /// <returns>Tuple - Item1 being the Route, Item2 being the parameters dictionary, Item3 being the prereq, Item4 being the postreq</returns> public ResolveResult Resolve(NancyContext context, IRouteCache routeCache) { if (routeCache.IsEmpty()) { return new ResolveResult(new NotFoundRoute(context.Request.Method, context.Request.Path), DynamicDictionary.Empty, null, null); } var routesThatMatchRequestedPath = this.GetRoutesThatMatchRequestedPath(routeCache, context); if (NoRoutesWereAbleToBeMatchedInRouteCache(routesThatMatchRequestedPath)) { return new ResolveResult(new NotFoundRoute(context.Request.Method, context.Request.Path), DynamicDictionary.Empty, null, null); } var routesWithCorrectRequestMethod = GetRoutesWithCorrectRequestMethod(context.Request, routesThatMatchRequestedPath); if (NoRoutesWereForTheRequestedMethod(routesWithCorrectRequestMethod)) { var allowedMethods = routesThatMatchRequestedPath.Select(x => x.Item3.Method); return new ResolveResult(new MethodNotAllowedRoute(context.Request.Path, context.Request.Method, allowedMethods), DynamicDictionary.Empty, null, null); } var exactMatch = GetRouteMatchesWithExactPathMatch(routesWithCorrectRequestMethod).FirstOrDefault(); if (exactMatch != null) { return this.CreateRouteAndParametersFromMatch(context, exactMatch); } var routeMatchesWithMostParameterCaptures = GetTopRouteMatches(routesWithCorrectRequestMethod); var routeMatchToReturn = GetSingleRouteToReturn(routeMatchesWithMostParameterCaptures); return this.CreateRouteAndParametersFromMatch(context, routeMatchToReturn); }
private ResolveResults Resolve(string path, NancyContext context, IRouteCache routeCache) { if (routeCache.IsEmpty()) { context.Trace.TraceLog.WriteLog(s => s.AppendLine("[DefaultRouteResolver] No routes available")); return(new ResolveResults { Selected = new ResolveResult(new NotFoundRoute(context.Request.Method, path), DynamicDictionary.Empty, null, null, null) }); } var routes = routeCache.GetRouteCandidates(); // Condition routes = routes.Filter(context, "Invalid condition", (ctx, route) => { var validCondition = ((route.Item3.Condition == null) || (route.Item3.Condition(ctx))); return(new Tuple <bool, RouteCandidate>( validCondition, route )); }); if (!routes.Item1.Any()) { context.Trace.TraceLog.WriteLog(s => s.AppendLine("[DefaultRouteResolver] No route had a valid condition")); return(new ResolveResults { Selected = new ResolveResult(new NotFoundRoute(context.Request.Method, path), DynamicDictionary.Empty, null, null, null), Rejected = routes.Item2 }); } // Path routes = routes.Filter(context, "Path did not match", (ctx, route) => { var validationResult = this.routePatternMatcher.Match(path, route.Item3.Path, route.Item3.Segments, context); var routeToReturn = (validationResult.IsMatch) ? new RouteCandidate(route.Item1, route.Item2, route.Item3, validationResult) : route; return(new Tuple <bool, RouteCandidate>( validationResult.IsMatch, routeToReturn )); }); if (!routes.Item1.Any()) { context.Trace.TraceLog.WriteLog(s => s.AppendLine("[DefaultRouteResolver] No route matched the requested path")); return(new ResolveResults { Selected = new ResolveResult(new NotFoundRoute(context.Request.Method, path), DynamicDictionary.Empty, null, null, null), Rejected = routes.Item2 }); } // Method routes = routes.Filter(context, "Request method did not match", (ctx, route) => { var routeMethod = route.Item3.Method.ToUpperInvariant(); var requestMethod = ctx.Request.Method.ToUpperInvariant(); var methodIsValid = routeMethod.Equals(requestMethod) || (routeMethod.Equals("GET") && requestMethod.Equals("HEAD")); return(new Tuple <bool, RouteCandidate>( methodIsValid, route )); }); if (!routes.Item1.Any()) { var allowedMethods = routes.Item2.Values.SelectMany(x => x.Select(y => y.Item3.Method)).Distinct(); if (context.Request.Method.Equals("OPTIONS")) { return(new ResolveResults { Selected = new ResolveResult(new OptionsRoute(context.Request.Path, allowedMethods), DynamicDictionary.Empty, null, null, null), Rejected = routes.Item2 }); } context.Trace.TraceLog.WriteLog(s => s.AppendLine("[DefaultRouteResolver] Route Matched But Method Not Allowed")); return(new ResolveResults { Selected = new ResolveResult(new MethodNotAllowedRoute(path, context.Request.Method, allowedMethods), DynamicDictionary.Empty, null, null, null), Rejected = routes.Item2 }); } // Exact match var exactMatchResults = routes.Filter(context, "No exact match", (ctx, route) => { var routeIsExactMatch = !route.Item4.Parameters.GetDynamicMemberNames().Any(); return(new Tuple <bool, RouteCandidate>( routeIsExactMatch, route )); }); if (exactMatchResults.Item1.Any()) { context.Trace.TraceLog.WriteLog(s => s.AppendLine("[DefaultRouteResolver] Found exact match route")); return(new ResolveResults { Selected = this.CreateRouteAndParametersFromMatch(context, exactMatchResults.Item1.First()), Rejected = exactMatchResults.Item2 }); } // First match out of multiple candidates var selected = GetTopRouteMatchesNew(routes).First(); context.Trace.TraceLog.WriteLog(s => s.AppendLine("[DefaultRouteResolver] Selected best match")); return(new ResolveResults { Selected = this.CreateRouteAndParametersFromMatch(context, selected), Rejected = exactMatchResults.Item2 }); }
private ResolveResults Resolve(string path, NancyContext context, IRouteCache routeCache) { if (routeCache.IsEmpty()) { context.Trace.TraceLog.WriteLog(s => s.AppendLine("[DefaultRouteResolver] No routes available")); return new ResolveResults { Selected = new ResolveResult(new NotFoundRoute(context.Request.Method, path), DynamicDictionary.Empty, null, null, null) }; } var routes = routeCache.GetRouteCandidates(); // Condition routes = routes.Filter(context, "Invalid condition", (ctx, route) => { var validCondition = ((route.Item3.Condition == null) || (route.Item3.Condition(ctx))); return new Tuple<bool, RouteCandidate>( validCondition, route ); }); if (!routes.Item1.Any()) { context.Trace.TraceLog.WriteLog(s => s.AppendLine("[DefaultRouteResolver] No route had a valid condition")); return new ResolveResults { Selected = new ResolveResult(new NotFoundRoute(context.Request.Method, path), DynamicDictionary.Empty, null, null, null), Rejected = routes.Item2 }; } // Path routes = routes.Filter(context, "Path did not match", (ctx, route) => { var validationResult = this.routePatternMatcher.Match(path, route.Item3.Path, route.Item3.Segments, context); var routeToReturn = (validationResult.IsMatch) ? new RouteCandidate(route.Item1, route.Item2, route.Item3, validationResult) : route; return new Tuple<bool, RouteCandidate>( validationResult.IsMatch, routeToReturn ); }); if (!routes.Item1.Any()) { context.Trace.TraceLog.WriteLog(s => s.AppendLine("[DefaultRouteResolver] No route matched the requested path")); return new ResolveResults { Selected = new ResolveResult(new NotFoundRoute(context.Request.Method, path), DynamicDictionary.Empty, null, null, null), Rejected = routes.Item2 }; } // Method routes = routes.Filter(context, "Request method did not match", (ctx, route) => { var routeMethod = route.Item3.Method.ToUpperInvariant(); var requestMethod = ctx.Request.Method.ToUpperInvariant(); var methodIsValid = routeMethod.Equals(requestMethod) || (routeMethod.Equals("GET") && requestMethod.Equals("HEAD")); return new Tuple<bool, RouteCandidate>( methodIsValid, route ); }); if (!routes.Item1.Any()) { var allowedMethods = routes.Item2.Values.SelectMany(x => x.Select(y => y.Item3.Method)).Distinct(); if (context.Request.Method.Equals("OPTIONS")) { return new ResolveResults { Selected = new ResolveResult(new OptionsRoute(context.Request.Path, allowedMethods), DynamicDictionary.Empty, null, null, null), Rejected = routes.Item2 }; } context.Trace.TraceLog.WriteLog(s => s.AppendLine("[DefaultRouteResolver] Route Matched But Method Not Allowed")); return new ResolveResults { Selected = new ResolveResult(new MethodNotAllowedRoute(path, context.Request.Method, allowedMethods), DynamicDictionary.Empty, null, null, null), Rejected = routes.Item2 }; } // Exact match var exactMatchResults = routes.Filter(context, "No exact match", (ctx, route) => { var routeIsExactMatch = !route.Item4.Parameters.GetDynamicMemberNames().Any(); return new Tuple<bool, RouteCandidate>( routeIsExactMatch, route ); }); if (exactMatchResults.Item1.Any()) { context.Trace.TraceLog.WriteLog(s => s.AppendLine("[DefaultRouteResolver] Found exact match route")); return new ResolveResults { Selected = this.CreateRouteAndParametersFromMatch(context, exactMatchResults.Item1.First()), Rejected = exactMatchResults.Item2 }; } // First match out of multiple candidates var selected = GetTopRouteMatchesNew(routes).First(); context.Trace.TraceLog.WriteLog(s => s.AppendLine("[DefaultRouteResolver] Selected best match")); return new ResolveResults { Selected = this.CreateRouteAndParametersFromMatch(context, selected), Rejected = exactMatchResults.Item2 }; }