Пример #1
0
        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
            });
        }
Пример #2
0
        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
            };
        }