/// <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);
        }
        /// <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);
        }
示例#3
0
        /// <inheritdoc/>
        public RouteConfig Build(ProxyRoute 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,
                cluster,
                aspNetCoreEndpoints.AsReadOnly(),
                transforms);

            // Catch-all pattern when no path was specified
            var pathPattern = string.IsNullOrEmpty(source.Match.Path) ? "/{**catchall}" : source.Match.Path;

            var endpointBuilder = new AspNetCore.Routing.RouteEndpointBuilder(
                requestDelegate: _pipeline,
                routePattern: AspNetCore.Routing.Patterns.RoutePatternFactory.Parse(pathPattern),
                order: source.Order.GetValueOrDefault());

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

            if (source.Match.Hosts != null && source.Match.Hosts.Count != 0)
            {
                endpointBuilder.Metadata.Add(new AspNetCore.Routing.HostAttribute(source.Match.Hosts.ToArray()));
            }

            if (source.Match.Headers != null && source.Match.Headers.Count > 0)
            {
                var matchers = new List <HeaderMatcher>(source.Match.Headers.Count);
                foreach (var header in source.Match.Headers)
                {
                    matchers.Add(new HeaderMatcher(header.Name, header.Values, header.Mode, header.IsCaseSensitive));
                }

                endpointBuilder.Metadata.Add(new HeaderMetadata(matchers));
            }

            bool acceptCorsPreflight;

            if (string.Equals(CorsConstants.Default, source.CorsPolicy, StringComparison.OrdinalIgnoreCase))
            {
                endpointBuilder.Metadata.Add(DefaultCors);
                acceptCorsPreflight = true;
            }
            else if (string.Equals(CorsConstants.Disable, source.CorsPolicy, StringComparison.OrdinalIgnoreCase))
            {
                endpointBuilder.Metadata.Add(DisableCors);
                acceptCorsPreflight = true;
            }
            else if (!string.IsNullOrEmpty(source.CorsPolicy))
            {
                endpointBuilder.Metadata.Add(new EnableCorsAttribute(source.CorsPolicy));
                acceptCorsPreflight = true;
            }
            else
            {
                acceptCorsPreflight = false;
            }

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

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