public void BuildEndpoints_JustHostWithWildcard_Works()
        {
            // Arrange
            var builder     = Create <RuntimeRouteBuilder>();
            var parsedRoute = new ParsedRoute
            {
                RouteId  = "route1",
                Host     = "*.example.com",
                Priority = 12,
            };
            var cluster   = new ClusterInfo("cluster1", new DestinationManager(), new Mock <IProxyHttpClientFactory>().Object);
            var routeInfo = new RouteInfo("route1");

            // Act
            var config = builder.Build(parsedRoute, cluster, routeInfo);

            // Assert
            Assert.Same(cluster, config.Cluster);
            Assert.Equal(12, config.Priority);
            Assert.Equal(parsedRoute.GetConfigHash(), config.ConfigHash);
            Assert.Single(config.Endpoints);
            var routeEndpoint = config.Endpoints[0] as AspNetCore.Routing.RouteEndpoint;

            Assert.Equal("route1", routeEndpoint.DisplayName);
            Assert.Same(config, routeEndpoint.Metadata.GetMetadata <RouteConfig>());
            Assert.Equal("/{**catchall}", routeEndpoint.RoutePattern.RawText);

            var hostMetadata = routeEndpoint.Metadata.GetMetadata <AspNetCore.Routing.HostAttribute>();

            Assert.NotNull(hostMetadata);
            Assert.Single(hostMetadata.Hosts);
            Assert.Equal("*.example.com", hostMetadata.Hosts[0]);
        }
Ejemplo n.º 2
0
        // Default ordering goes through segments one by one and tries to apply an ordering
        private static int Compare(RouteEntry entry1, RouteEntry entry2)
        {
            ParsedRoute parsedRoute1 = entry1.ParsedRoute;
            ParsedRoute parsedRoute2 = entry2.ParsedRoute;

            IList <PathContentSegment> segments1 = parsedRoute1.PathSegments.OfType <PathContentSegment>().ToArray();
            IList <PathContentSegment> segments2 = parsedRoute2.PathSegments.OfType <PathContentSegment>().ToArray();

            for (int i = 0; i < segments1.Count && i < segments2.Count; i++)
            {
                PathContentSegment segment1 = segments1[i];
                PathContentSegment segment2 = segments2[i];

                int order1 = GetPrecedenceDigit(segment1, entry1.Route.Constraints);
                int order2 = GetPrecedenceDigit(segment2, entry2.Route.Constraints);

                if (order1 > order2)
                {
                    return(1);
                }
                else if (order1 < order2)
                {
                    return(-1);
                }
            }

            return(0);
        }
Ejemplo n.º 3
0
        // Note this performs all validation steps without short circuiting in order to report all possible errors.
        public bool ValidateRoute(ParsedRoute route, IConfigErrorReporter errorReporter)
        {
            Contracts.CheckValue(route, nameof(route));
            Contracts.CheckValue(errorReporter, nameof(errorReporter));

            var success = true;

            if (string.IsNullOrEmpty(route.RouteId))
            {
                errorReporter.ReportError(ConfigErrors.ParsedRouteMissingId, route.RouteId, $"Route has no {nameof(route.RouteId)}.");
                success = false;
            }

            if (string.IsNullOrEmpty(route.Host) && string.IsNullOrEmpty(route.Path))
            {
                errorReporter.ReportError(ConfigErrors.ParsedRouteRuleHasNoMatchers, route.RouteId, $"Route requires {nameof(route.Host)} or {nameof(route.Path)} specified. Set the Path to `/{{**catchall}}` to match all requests.");
                success = false;
            }

            success &= ValidateHost(route.Host, route.RouteId, errorReporter);
            success &= ValidatePath(route.Path, route.RouteId, errorReporter);
            success &= ValidateMethods(route.Methods, route.RouteId, errorReporter);
            success &= _transformBuilder.Validate(route.Transforms, route.RouteId, errorReporter);

            return(success);
        }
Ejemplo n.º 4
0
        public void BuildEndpoints_NullMatchers_Works()
        {
            // Arrange
            var builder     = Create <RuntimeRouteBuilder>();
            var parsedRoute = new ParsedRoute
            {
                RouteId  = "route1",
                Priority = 12,
            };
            var backend   = new BackendInfo("backend1", new EndpointManager(), new Mock <IProxyHttpClientFactory>().Object);
            var routeInfo = new RouteInfo("route1");

            // Act
            var config = builder.Build(parsedRoute, backend, routeInfo);

            // Assert
            Assert.Same(backend, config.BackendOrNull);
            Assert.Equal(12, config.Priority);
            Assert.Empty(config.MatcherSummary);
            Assert.Single(config.AspNetCoreEndpoints);
            var routeEndpoint = config.AspNetCoreEndpoints[0] as AspNetCore.Routing.RouteEndpoint;

            Assert.Equal("route1", routeEndpoint.DisplayName);
            Assert.Same(config, routeEndpoint.Metadata.GetMetadata <RouteConfig>());
            Assert.Equal("/{**catchall}", routeEndpoint.RoutePattern.RawText);

            var hostMetadata = routeEndpoint.Metadata.GetMetadata <AspNetCore.Routing.HostAttribute>();

            Assert.Null(hostMetadata);
        }
Ejemplo n.º 5
0
        public void BuildEndpoints_JustHostWithWildcard_Works()
        {
            // Arrange
            var builder     = Create <RuntimeRouteBuilder>();
            var parsedRoute = new ParsedRoute
            {
                RouteId  = "route1",
                Host     = "*.example.com",
                Priority = 12,
            };
            var backend   = new BackendInfo("backend1", new EndpointManager(), new Mock <IProxyHttpClientFactory>().Object);
            var routeInfo = new RouteInfo("route1");

            // Act
            var config = builder.Build(parsedRoute, backend, routeInfo);

            // Assert
            config.BackendOrNull.Should().BeSameAs(backend);
            config.Priority.Should().Be(12);
            config.MatcherSummary.Should().Be(parsedRoute.GetMatcherSummary());
            config.AspNetCoreEndpoints.Should().HaveCount(1);
            var routeEndpoint = config.AspNetCoreEndpoints[0] as AspNetCore.Routing.RouteEndpoint;

            routeEndpoint.DisplayName.Should().Be("route1");
            routeEndpoint.Metadata.GetMetadata <RouteConfig>().Should().BeSameAs(config);
            routeEndpoint.RoutePattern.RawText.Should().Be("/{**catchall}");

            var hostMetadata = routeEndpoint.Metadata.GetMetadata <AspNetCore.Routing.HostAttribute>();

            hostMetadata.Should().NotBeNull();
            hostMetadata.Hosts.Should().BeEquivalentTo("*.example.com");
        }
        public async Task BuildConfigAsync_RouteValidationError_SkipsRoute()
        {
            // Arrange
            var errorReporter = new TestConfigErrorReporter();

            Mock <IBackendsRepo>()
            .Setup(r => r.GetBackendsAsync(It.IsAny <CancellationToken>()))
            .ReturnsAsync(new Dictionary <string, Backend>());

            var route1 = new ProxyRoute {
                RouteId = "route1", Match = { Host = "example.com" }, Priority = 1, BackendId = "backend1"
            };

            Mock <IRoutesRepo>()
            .Setup(r => r.GetRoutesAsync(It.IsAny <CancellationToken>()))
            .ReturnsAsync(new[] { route1 });

            var parsedRoute1 = new ParsedRoute();

            Mock <IRouteValidator>()
            .Setup(r => r.ValidateRoute(parsedRoute1, errorReporter))
            .Returns(false);

            // Act
            var configManager = Create <DynamicConfigBuilder>();
            var result        = await configManager.BuildConfigAsync(errorReporter, CancellationToken.None);

            // Assert
            result.IsSuccess.Should().BeTrue();
            result.Value.Should().NotBeNull();
            result.Value.Backends.Should().BeEmpty();
            result.Value.Routes.Should().BeEmpty();
        }
Ejemplo n.º 7
0
        // Note this performs all validation steps without short circuiting in order to report all possible errors.
        public async Task <bool> ValidateRouteAsync(ParsedRoute route)
        {
            _ = route ?? throw new ArgumentNullException(nameof(route));

            var success = true;

            if (string.IsNullOrEmpty(route.RouteId))
            {
                Log.MissingRouteId(_logger);
                success = false;
            }

            if ((route.Hosts == null || route.Hosts.Count == 0 || route.Hosts.Any(host => string.IsNullOrEmpty(host))) && string.IsNullOrEmpty(route.Path))
            {
                Log.MissingRouteMatchers(_logger, route.RouteId);
                success = false;
            }

            success &= ValidateHost(route.Hosts, route.RouteId);
            success &= ValidatePath(route.Path, route.RouteId);
            success &= ValidateMethods(route.Methods, route.RouteId);
            success &= _transformBuilder.Validate(route.Transforms, route.RouteId);
            success &= await ValidateAuthorizationPolicyAsync(route.AuthorizationPolicy, route.RouteId);

            success &= await ValidateCorsPolicyAsync(route.CorsPolicy, route.RouteId);

            return(success);
        }
        /// <inheritdoc/>
        public RouteConfig Build(ParsedRoute source, ClusterInfo cluster, RouteInfo runtimeRoute)
        {
            _ = source ?? throw new ArgumentNullException(nameof(source));
            _ = runtimeRoute ?? throw new ArgumentNullException(nameof(runtimeRoute));

            var transforms = _transformBuilder.Build(source.Transforms);

            // NOTE: `new RouteConfig(...)` needs a reference to the list of ASP .NET Core endpoints,
            // but the ASP .NET Core endpoints cannot be created without a `RouteConfig` metadata item.
            // We solve this chicken-egg problem by creating an (empty) list first
            // and passing a read-only wrapper of it to `RouteConfig.ctor`.
            // Recall that `List<T>.AsReadOnly()` creates a wrapper over the original list,
            // and changes to the underlying list *are* reflected on the read-only view.
            var aspNetCoreEndpoints = new List <Endpoint>(1);
            var newRouteConfig      = new RouteConfig(
                runtimeRoute,
                source.GetConfigHash(),
                source.Priority,
                cluster,
                aspNetCoreEndpoints.AsReadOnly(),
                transforms);

            // TODO: Handle arbitrary AST's properly
            // Catch-all pattern when no path was specified
            var pathPattern = string.IsNullOrEmpty(source.Path) ? "/{**catchall}" : source.Path;

            // TODO: Propagate route priority
            var endpointBuilder = new AspNetCore.Routing.RouteEndpointBuilder(
                requestDelegate: _pipeline ?? Invoke,
                routePattern: AspNetCore.Routing.Patterns.RoutePatternFactory.Parse(pathPattern),
                order: 0);

            endpointBuilder.DisplayName = source.RouteId;
            endpointBuilder.Metadata.Add(newRouteConfig);

            if (!string.IsNullOrEmpty(source.Host))
            {
                endpointBuilder.Metadata.Add(new AspNetCore.Routing.HostAttribute(source.Host));
            }

            if (source.Methods != null && source.Methods.Count > 0)
            {
                endpointBuilder.Metadata.Add(new AspNetCore.Routing.HttpMethodMetadata(source.Methods));
            }

            if (string.Equals(AuthorizationConstants.Default, source.AuthorizationPolicy, StringComparison.OrdinalIgnoreCase))
            {
                endpointBuilder.Metadata.Add(DefaultAuthorization);
            }
            else if (!string.IsNullOrEmpty(source.AuthorizationPolicy))
            {
                endpointBuilder.Metadata.Add(new AuthorizeAttribute(source.AuthorizationPolicy));
            }

            var endpoint = endpointBuilder.Build();

            aspNetCoreEndpoints.Add(endpoint);

            return(newRouteConfig);
        }
Ejemplo n.º 9
0
        // Note this performs all validation steps without short circuiting in order to report all possible errors.
        public async Task <bool> ValidateRouteAsync(ParsedRoute route, IConfigErrorReporter errorReporter)
        {
            _ = route ?? throw new ArgumentNullException(nameof(route));
            _ = errorReporter ?? throw new ArgumentNullException(nameof(errorReporter));

            var success = true;

            if (string.IsNullOrEmpty(route.RouteId))
            {
                errorReporter.ReportError(ConfigErrors.ParsedRouteMissingId, route.RouteId, $"Route has no {nameof(route.RouteId)}.");
                success = false;
            }

            if (string.IsNullOrEmpty(route.Host) && string.IsNullOrEmpty(route.Path))
            {
                errorReporter.ReportError(ConfigErrors.ParsedRouteRuleHasNoMatchers, route.RouteId, $"Route requires {nameof(route.Host)} or {nameof(route.Path)} specified. Set the Path to `/{{**catchall}}` to match all requests.");
                success = false;
            }

            success &= ValidateHost(route.Host, route.RouteId, errorReporter);
            success &= ValidatePath(route.Path, route.RouteId, errorReporter);
            success &= ValidateMethods(route.Methods, route.RouteId, errorReporter);
            success &= _transformBuilder.Validate(route.Transforms, route.RouteId, errorReporter);
            success &= await ValidateAuthorizationPolicyAsync(route.AuthorizationPolicy, route.RouteId, errorReporter);

            success &= await ValidateCorsPolicyAsync(route.CorsPolicy, route.RouteId, errorReporter);

            return(success);
        }
Ejemplo n.º 10
0
        public void BuildEndpoints_HostAndPath_Works()
        {
            // Arrange
            var builder     = Create <RuntimeRouteBuilder>();
            var parsedRoute = new ParsedRoute
            {
                RouteId  = "route1",
                Host     = "example.com",
                Path     = "/a",
                Priority = 12,
            };
            var backend   = new BackendInfo("backend1", new DestinationManager(), new Mock <IProxyHttpClientFactory>().Object);
            var routeInfo = new RouteInfo("route1");

            // Act
            var config = builder.Build(parsedRoute, backend, routeInfo);

            // Assert
            Assert.Same(backend, config.BackendOrNull);
            Assert.Equal(12, config.Priority);
            Assert.Equal(parsedRoute.GetConfigHash(), config.ConfigHash);
            Assert.Single(config.Endpoints);
            var routeEndpoint = config.Endpoints[0] as AspNetCore.Routing.RouteEndpoint;

            Assert.Equal("route1", routeEndpoint.DisplayName);
            Assert.Same(config, routeEndpoint.Metadata.GetMetadata <RouteConfig>());
            Assert.Equal("/a", routeEndpoint.RoutePattern.RawText);

            var hostMetadata = routeEndpoint.Metadata.GetMetadata <AspNetCore.Routing.HostAttribute>();

            Assert.NotNull(hostMetadata);
            Assert.Single(hostMetadata.Hosts);
            Assert.Equal("example.com", hostMetadata.Hosts[0]);
        }
Ejemplo n.º 11
0
Archivo: Page.cs Proyecto: zhq0131/CMS
 internal ParsedRoute ToParsedRoute()
 {
     if (parsedRoute == null)
     {
         parsedRoute = RouteParser.Parse(GetRouteUrl());
     }
     return(parsedRoute);
 }
        private async Task <IList <ParsedRoute> > GetRoutesAsync(IConfigErrorReporter errorReporter, CancellationToken cancellation)
        {
            var routes = await _routesRepo.GetRoutesAsync(cancellation);

            var seenRouteIds = new HashSet <string>();
            var sortedRoutes = new SortedList <(int, string), ParsedRoute>(routes?.Count ?? 0);

            if (routes == null)
            {
                return(sortedRoutes.Values);
            }

            foreach (var route in routes)
            {
                if (seenRouteIds.Contains(route.RouteId))
                {
                    errorReporter.ReportError(ConfigErrors.RouteDuplicateId, route.RouteId, $"Duplicate route '{route.RouteId}'.");
                    continue;
                }

                try
                {
                    foreach (var filter in _filters)
                    {
                        await filter.ConfigureRouteAsync(route, cancellation);
                    }
                }
                catch (Exception ex)
                {
                    errorReporter.ReportError(ConfigErrors.ConfigBuilderClusterException, route.RouteId, "An exception was thrown from the configuration callbacks.", ex);
                    continue;
                }

                var parsedRoute = new ParsedRoute
                {
                    RouteId             = route.RouteId,
                    Methods             = route.Match.Methods,
                    Host                = route.Match.Host,
                    Path                = route.Match.Path,
                    Priority            = route.Priority,
                    ClusterId           = route.ClusterId,
                    AuthorizationPolicy = route.AuthorizationPolicy,
                    CorsPolicy          = route.CorsPolicy,
                    Metadata            = route.Metadata,
                    Transforms          = route.Transforms,
                };

                if (!await _parsedRouteValidator.ValidateRouteAsync(parsedRoute, errorReporter))
                {
                    // parsedRouteValidator already reported error message
                    continue;
                }

                sortedRoutes.Add((parsedRoute.Priority ?? 0, parsedRoute.RouteId), parsedRoute);
            }

            return(sortedRoutes.Values);
        }
        private async Task <IList <ParsedRoute> > GetRoutesAsync(CancellationToken cancellation)
        {
            var routes = await _routesRepo.GetRoutesAsync(cancellation);

            var seenRouteIds = new HashSet <string>();
            var sortedRoutes = new SortedList <(int, string), ParsedRoute>(routes?.Count ?? 0);

            if (routes == null)
            {
                return(sortedRoutes.Values);
            }

            foreach (var route in routes)
            {
                if (seenRouteIds.Contains(route.RouteId))
                {
                    Log.DuplicateRouteId(_logger, route.RouteId);
                    continue;
                }

                try
                {
                    foreach (var filter in _filters)
                    {
                        await filter.ConfigureRouteAsync(route, cancellation);
                    }
                }
                catch (Exception ex)
                {
                    Log.RouteConfigException(_logger, route.RouteId, ex);
                    continue;
                }

                var parsedRoute = new ParsedRoute
                {
                    RouteId             = route.RouteId,
                    Methods             = route.Match.Methods,
                    Hosts               = route.Match.Hosts,
                    Path                = route.Match.Path,
                    Priority            = route.Priority,
                    ClusterId           = route.ClusterId,
                    AuthorizationPolicy = route.AuthorizationPolicy,
                    CorsPolicy          = route.CorsPolicy,
                    Metadata            = route.Metadata,
                    Transforms          = route.Transforms,
                };

                if (!await _parsedRouteValidator.ValidateRouteAsync(parsedRoute))
                {
                    // parsedRouteValidator already reported error message
                    continue;
                }

                sortedRoutes.Add((parsedRoute.Priority ?? 0, parsedRoute.RouteId), parsedRoute);
            }

            return(sortedRoutes.Values);
        }
Ejemplo n.º 14
0
        private (bool IsSuccess, TestConfigErrorReporter ErrorReporter) RunScenario(ParsedRoute parsedRoute)
        {
            var errorReporter = new TestConfigErrorReporter();

            var validator = Create <RouteValidator>();
            var isSuccess = validator.ValidateRoute(parsedRoute, errorReporter);

            return(isSuccess, errorReporter);
        }
Ejemplo n.º 15
0
        private (bool IsSuccess, TestConfigErrorReporter ErrorReporter) RunScenario(ParsedRoute parsedRoute)
        {
            var errorReporter = new TestConfigErrorReporter();

            Mock <ITransformBuilder>().Setup(builder
                                             => builder.Validate(It.IsAny <IList <IDictionary <string, string> > >(), It.IsAny <string>(), It.IsAny <IConfigErrorReporter>())).Returns(true);
            var validator = Create <RouteValidator>();
            var isSuccess = validator.ValidateRoute(parsedRoute, errorReporter);

            return(isSuccess, errorReporter);
        }
        public async Task ApplyConfigurationsAsync_OneClusterOneDestinationOneRoute_Works()
        {
            // Arrange
            const string TestAddress = "https://localhost:123/";

            var cluster = new Cluster
            {
                Destinations = {
                    { "d1", new Destination { Address = TestAddress } }
                }
            };
            var route = new ParsedRoute
            {
                RouteId = "route1",
                ClusterId = "cluster1",
            };

            var dynamicConfigRoot = new DynamicConfigRoot
            {
                Clusters = new Dictionary<string, Cluster> { { "cluster1", cluster }  },
                Routes = new[] { route },
            };
            Mock<IDynamicConfigBuilder>()
                .Setup(d => d.BuildConfigAsync(It.IsAny<CancellationToken>()))
                .ReturnsAsync(dynamicConfigRoot);

            var proxyManager = Create<ReverseProxyConfigManager>();

            // Act
            await proxyManager.ApplyConfigurationsAsync(CancellationToken.None);

            // Assert

            var actualClusters = _clusterManager.GetItems();
            Assert.Single(actualClusters);
            Assert.Equal("cluster1", actualClusters[0].ClusterId);
            Assert.NotNull(actualClusters[0].DestinationManager);
            Assert.NotNull(actualClusters[0].Config.Value);

            var actualDestinations = actualClusters[0].DestinationManager.GetItems();
            Assert.Single(actualDestinations);
            Assert.Equal("d1", actualDestinations[0].DestinationId);
            Assert.NotNull(actualDestinations[0].Config);
            Assert.Equal(TestAddress, actualDestinations[0].Config.Address);

            var actualRoutes = _routeManager.GetItems();
            Assert.Single(actualRoutes);
            Assert.Equal("route1", actualRoutes[0].RouteId);
            Assert.NotNull(actualRoutes[0].Config.Value);
            Assert.Same(actualClusters[0], actualRoutes[0].Config.Value.Cluster);
        }
Ejemplo n.º 17
0
        public async Task Rejects_UnknownCorsPolicy()
        {
            var route = new ParsedRoute
            {
                RouteId    = "route1",
                CorsPolicy = "unknown",
                ClusterId  = "cluster1",
            };

            var result = await RunScenarioAsync(route);

            Assert.False(result.IsSuccess);
            Assert.Contains(result.Logger.Errors, err => err.eventId == EventIds.CorsPolicyNotFound);
        }
Ejemplo n.º 18
0
        public async Task Rejects_MissingRouteId(string routeId)
        {
            // Arrange
            var parsedRoute = new ParsedRoute {
                RouteId = routeId
            };

            // Act
            var result = await RunScenarioAsync(parsedRoute);

            // Assert
            Assert.False(result.IsSuccess);
            Assert.Contains(result.Logger.Errors, err => err.eventId == EventIds.MissingRouteId);
        }
Ejemplo n.º 19
0
        public async Task Rejects_UnknownAuthorizationPolicy()
        {
            var route = new ParsedRoute
            {
                RouteId             = "route1",
                AuthorizationPolicy = "unknown",
                ClusterId           = "cluster1",
            };

            var result = await RunScenarioAsync(route);

            Assert.False(result.IsSuccess);
            Assert.Contains(result.ErrorReporter.Errors, err => err.ErrorCode == ConfigErrors.ParsedRouteRuleInvalidAuthorizationPolicy && err.Message.Contains("Authorization policy 'unknown' not found"));
        }
Ejemplo n.º 20
0
        public async Task Accepts_ReservedAuthorizationPolicy(string policy)
        {
            var route = new ParsedRoute
            {
                RouteId             = "route1",
                AuthorizationPolicy = policy,
                Host      = "localhost",
                ClusterId = "cluster1",
            };

            var result = await RunScenarioAsync(route);

            Assert.True(result.IsSuccess);
            Assert.Empty(result.ErrorReporter.Errors);
        }
Ejemplo n.º 21
0
        public async Task Accepts_ReservedCorsPolicy(string policy)
        {
            var route = new ParsedRoute
            {
                RouteId    = "route1",
                CorsPolicy = policy,
                Hosts      = new[] { "localhost" },
                ClusterId  = "cluster1",
            };

            var result = await RunScenarioAsync(route);

            Assert.True(result.IsSuccess);
            Assert.Empty(result.Logger.Errors);
        }
Ejemplo n.º 22
0
        private async Task <(bool IsSuccess, TestLogger Logger)> RunScenarioAsync(ParsedRoute parsedRoute)
        {
            Mock <ITransformBuilder>().Setup(builder
                                             => builder.Validate(It.IsAny <IList <IDictionary <string, string> > >(), It.IsAny <string>())).Returns(true);

            var loggerFactory = new TestLoggerFactory();
            var logger        = loggerFactory.CreateLogger <RouteValidator>();

            Provide(logger);

            var validator = Create <RouteValidator>();
            var isSuccess = await validator.ValidateRouteAsync(parsedRoute);

            return(isSuccess, loggerFactory.Logger);
        }
Ejemplo n.º 23
0
        /// <inheritdoc/>
        public RouteConfig Build(ParsedRoute source, BackendInfo backendOrNull, RouteInfo runtimeRoute)
        {
            Contracts.CheckValue(source, nameof(source));
            Contracts.CheckValue(runtimeRoute, nameof(runtimeRoute));

            // NOTE: `new RouteConfig(...)` needs a reference to the list of ASP .NET Core endpoints,
            // but the ASP .NET Core endpoints cannot be created without a `RouteConfig` metadata item.
            // We solve this chicken-egg problem by creating an (empty) list first
            // and passing a read-only wrapper of it to `RouteConfig.ctor`.
            // Recall that `List<T>.AsReadOnly()` creates a wrapper over the original list,
            // and changes to the underlying list *are* reflected on the read-only view.
            var aspNetCoreEndpoints = new List <Endpoint>(1);
            var newRouteConfig      = new RouteConfig(
                route: runtimeRoute,
                matcherSummary: source.GetMatcherSummary(),
                priority: source.Priority,
                backendOrNull: backendOrNull,
                aspNetCoreEndpoints: aspNetCoreEndpoints.AsReadOnly());

            // TODO: Handle arbitrary AST's properly
            // Catch-all pattern when no path was specified
            var pathPattern = string.IsNullOrEmpty(source.Path) ? "/{**catchall}" : source.Path;

            // TODO: Propagate route priority
            var endpointBuilder = new AspNetCore.Routing.RouteEndpointBuilder(
                requestDelegate: _pipeline ?? Invoke,
                routePattern: AspNetCore.Routing.Patterns.RoutePatternFactory.Parse(pathPattern),
                order: 0);

            endpointBuilder.DisplayName = source.RouteId;
            endpointBuilder.Metadata.Add(newRouteConfig);

            if (source.Host != null)
            {
                endpointBuilder.Metadata.Add(new AspNetCore.Routing.HostAttribute(source.Host));
            }

            if (source.Methods != null && source.Methods.Count > 0)
            {
                endpointBuilder.Metadata.Add(new AspNetCore.Routing.HttpMethodMetadata(source.Methods));
            }

            var endpoint = endpointBuilder.Build();

            aspNetCoreEndpoints.Add(endpoint);

            return(newRouteConfig);
        }
Ejemplo n.º 24
0
 /// <summary>
 /// Initializes a new instance of the <see cref="HttpDirectRoute" /> class.
 /// </summary>
 /// <param name="routeTemplate">The route template.</param>
 /// <param name="order">The subroute order.</param>
 /// <param name="defaults">The default values.</param>
 /// <param name="constraints">The route constraints.</param>
 /// <param name="actions">The actions that are reachable via this route.</param>
 public HttpDirectRoute(
     string routeTemplate,
     int order,
     HttpRouteValueDictionary defaults,
     HttpRouteValueDictionary constraints,
     IEnumerable <ReflectedHttpActionDescriptor> actions)
     : base(routeTemplate, defaults : defaults, constraints : constraints, dataTokens : null, handler : null)
 {
     if (actions != null)
     {
         Actions = actions.AsArray();
         DataTokens[RouteKeys.OrderDataTokenKey]      = order;
         DataTokens[RouteKeys.PrecedenceDataTokenKey] = ParsedRoute.GetPrecedence(constraints);
         DataTokens[RouteKeys.ActionsDataTokenKey]    = Actions;
     }
 }
Ejemplo n.º 25
0
        public void Rejects_MissingHostAndPath()
        {
            // Arrange
            var route = new ParsedRoute
            {
                RouteId   = "route1",
                ClusterId = "be1",
            };

            // Act
            var result = RunScenario(route);

            // Assert
            Assert.False(result.IsSuccess);
            Assert.Contains(result.ErrorReporter.Errors, err => err.ErrorCode == ConfigErrors.ParsedRouteRuleHasNoMatchers);
        }
Ejemplo n.º 26
0
        public void Rejects_MissingRouteId(string routeId)
        {
            // Arrange
            var errorReporter = new TestConfigErrorReporter();
            var parsedRoute   = new ParsedRoute {
                RouteId = routeId
            };
            var validator = Create <RouteValidator>();

            // Act
            var isSuccess = validator.ValidateRoute(parsedRoute, errorReporter);

            // Assert
            Assert.False(isSuccess);
            Assert.Contains(errorReporter.Errors, err => err.ErrorCode == ConfigErrors.ParsedRouteMissingId);
        }
Ejemplo n.º 27
0
        public async Task Rejects_MissingHostAndPath(string host)
        {
            // Arrange
            var route = new ParsedRoute
            {
                RouteId   = "route1",
                ClusterId = "cluster1",
                Hosts     = host?.Split(",")
            };

            // Act
            var result = await RunScenarioAsync(route);

            // Assert
            Assert.False(result.IsSuccess);
            Assert.Contains(result.Logger.Errors, err => err.eventId == EventIds.MissingRouteMatchers);
        }
Ejemplo n.º 28
0
        public void Rejects_InvalidMethod(string methods)
        {
            // Arrange
            var route = new ParsedRoute
            {
                RouteId   = "route1",
                Methods   = methods.Split(","),
                ClusterId = "be1",
            };

            // Act
            var result = RunScenario(route);

            // Assert
            Assert.False(result.IsSuccess);
            Assert.Contains(result.ErrorReporter.Errors, err => err.ErrorCode == ConfigErrors.ParsedRouteRuleInvalidMatcher && err.Message.Contains("verb"));
        }
Ejemplo n.º 29
0
        public void Rejects_InvalidPath(string path)
        {
            // Arrange
            var route = new ParsedRoute
            {
                RouteId   = "route1",
                Path      = path,
                ClusterId = "be1",
            };

            // Act
            var result = RunScenario(route);

            // Assert
            Assert.False(result.IsSuccess);
            Assert.Contains(result.ErrorReporter.Errors, err => err.ErrorCode == ConfigErrors.ParsedRouteRuleInvalidMatcher && err.Message.Contains("Invalid path pattern"));
        }
Ejemplo n.º 30
0
        public async Task Rejects_InvalidHost(string host)
        {
            // Arrange
            var route = new ParsedRoute
            {
                RouteId   = "route1",
                Host      = host,
                ClusterId = "cluster1",
            };

            // Act
            var result = await RunScenarioAsync(route);

            // Assert
            Assert.False(result.IsSuccess);
            Assert.Contains(result.ErrorReporter.Errors, err => err.ErrorCode == ConfigErrors.ParsedRouteRuleInvalidMatcher && err.Message.Contains("Invalid host name"));
        }
Ejemplo n.º 31
0
        /// <summary>
        /// Parses routes.
        /// </summary>
        /// <param name="content">Content.</param>
        /// <param name="currentPage">Current page.</param>
        /// <param name="startOrder">Start order.</param>
        /// <returns>Parsed routes.</returns>
        private IList<ParsedRoute> ParseRoutes(string content, int currentPage, int startOrder)
        {
            int end = -1;
            Match m = null;
            ParsedRoute r = null;
            MatchCollection matches = null;
            string subContent = string.Empty;
            string routeDetails = string.Empty;
            List<ParsedRoute> ret = new List<ParsedRoute>();

            Func<Match, string> getSubContent = (ms) =>
                {
                    int st = -1, ed = -1;
                    string result = string.Empty;

                    st = ms.Index;
                    ed = content.IndexOf("</td>", st, StringComparison.InvariantCultureIgnoreCase);

                    if (ed > 0)
                        result = content.Substring(st, ed - st);

                    return result;
                };

            m = Regex.Match(content, "<h3[^>]+>Routes</h3>", RegexOptions.IgnoreCase);

            if (m != null && m.Success)
            {
                content = content.Substring(m.Index + m.Length);

                m = Regex.Match(content, "<table[^>]+class=\"ftable\">", RegexOptions.IgnoreCase);

                if (m != null && m.Success)
                {
                    content = content.Substring(m.Index);
                    end = content.IndexOf("</table>", StringComparison.InvariantCultureIgnoreCase);

                    if (end > 0)
                    {
                        content = content.Substring(0, end);
                        matches = Regex.Matches(content, "<td", RegexOptions.IgnoreCase);

                        if (matches != null && matches.Count > 0)
                        {
                            for (int i = 0; i < matches.Count; i += 5)
                            {
                                subContent = getSubContent(matches[i + 2]);
                                m = Regex.Match(subContent, "<a\\s+href=\"([^\"]+)\">([^<]+)</a>", RegexOptions.IgnoreCase);

                                if (m != null && m.Success)
                                {
                                    r = new ParsedRoute();

                                    r.Name = RockClimbingComWiki.NormalizeName(m.Groups[2].Value.Trim(), false);

                                    if (!string.IsNullOrEmpty(r.Name))
                                    {
                                        r.Description = RockClimbingComWiki.FixPunctiation(m.Groups[1].Value.Trim());

                                        subContent = getSubContent(matches[i + 3]);
                                        m = Regex.Match(subContent, ">([^<]+)", RegexOptions.IgnoreCase);

                                        if (m != null && m.Success)
                                            r.Grade = Models.RouteGrade.Parse(m.Groups[1].Value.Trim());

                                        if (!string.IsNullOrEmpty(r.Description))
                                        {
                                            routeDetails = Load(r.Description);
                                            r.Description = string.Empty;

                                            m = Regex.Match(routeDetails, "<span\\s+class=\"description\">([^<]+)</span>", RegexOptions.IgnoreCase);

                                            if (m != null && m.Success)
                                                r.Description = RockClimbingComWiki.FixPunctiation(m.Groups[1].Value.Trim());
                                        }

                                        if (r.Grade != null)
                                        {
                                            r.Order = startOrder;
                                            r.Climbing = r.Grade.ParsedClimbing;

                                            ret.Add(r);

                                            startOrder += 1;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            m = Regex.Match(content, string.Format("href=\"([^\"]+more{0}.html)\"", currentPage + 1), RegexOptions.IgnoreCase);

            if (m != null && m.Success)
                ret.AddRange(ParseRoutes(Load(m.Groups[1].Value.Trim()), currentPage + 1, startOrder + 1));

            return ret;
        }