public override async Task SelectAsync(EndpointSelectorContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            EnsureServicesInitialized(context);

            var snapshot = context.CreateSnapshot();

            var fallbackEndpoints = new List <Endpoint>();

            for (var i = context.Endpoints.Count - 1; i >= 0; i--)
            {
                var endpoint = context.Endpoints[i] as IRoutePatternEndpoint;
                if (endpoint == null || endpoint.HttpMethod == null)
                {
                    // No metadata.
                    Logger.NoHttpMethodFound(context.Endpoints[i]);

                    fallbackEndpoints.Add(context.Endpoints[i]);
                    context.Endpoints.RemoveAt(i);
                }
                else if (string.Equals(endpoint.HttpMethod, context.HttpContext.Request.Method, StringComparison.OrdinalIgnoreCase))
                {
                    // The request method matches the endpoint's HTTP method.
                    Logger.RequestMethodMatchedEndpointMethod(endpoint.HttpMethod, context.Endpoints[i]);
                }
                else
                {
                    // Not a match.
                    Logger.RequestMethodDidNotMatchEndpointMethod(context.HttpContext.Request.Method, endpoint.HttpMethod, context.Endpoints[i]);
                    context.Endpoints.RemoveAt(i);
                }
            }

            // Now the list of endpoints only contains those that have an HTTP method preference AND match the current
            // request.
            await context.InvokeNextAsync();

            if (context.Endpoints.Count == 0)
            {
                Logger.NoEndpointMatchedRequestMethod(context.HttpContext.Request.Method);

                // Nothing matched, do the fallback.
                context.RestoreSnapshot(snapshot);

                context.Endpoints.Clear();

                for (var i = 0; i < fallbackEndpoints.Count; i++)
                {
                    context.Endpoints.Add(fallbackEndpoints[i]);
                }

                await context.InvokeNextAsync();
            }
        }
        protected void EnsureServicesInitialized(EndpointSelectorContext context)
        {
            if (Volatile.Read(ref _servicesInitialized))
            {
                return;
            }

            EnsureServicesInitializedSlow(context);
        }
Beispiel #3
0
            internal void Apply(EndpointSelectorContext context)
            {
                context._index = _index;

                context.Endpoints.Clear();
                for (var i = 0; i < _endpoints.Length; i++)
                {
                    context.Endpoints.Add(_endpoints[i]);
                }
            }
 private void EnsureServicesInitializedSlow(EndpointSelectorContext context)
 {
     lock (_lock)
     {
         if (!Volatile.Read(ref _servicesInitialized))
         {
             var services = context.HttpContext.RequestServices;
             Logger = services.GetRequiredService <ILoggerFactory>().CreateLogger(GetType());
         }
     }
 }
Beispiel #5
0
        protected virtual async Task SelectEndpointAsync(MatcherContext context, IEnumerable <Endpoint> endpoints)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (endpoints == null)
            {
                throw new ArgumentNullException(nameof(endpoints));
            }

            EnsureSelectorsInitialized();

            var selectorContext = new EndpointSelectorContext(context.HttpContext, context.Values, endpoints.ToList(), Selectors.ToList());
            await selectorContext.InvokeNextAsync();

            if (selectorContext.ShortCircuit != null)
            {
                context.ShortCircuit = selectorContext.ShortCircuit;
                Logger.RequestShortCircuitedMatcherBase(context);
                return;
            }

            switch (selectorContext.Endpoints.Count)
            {
            case 0:
                Logger.NoEndpointsMatched(context.HttpContext.Request.Path);
                return;

            case 1:
                context.Endpoint = selectorContext.Endpoints[0];

                Logger.EndpointMatchedMatcherBase(context.Endpoint);
                return;

            default:
                var endpointNames = string.Join(
                    Environment.NewLine,
                    selectorContext.Endpoints.Select(a => a.DisplayName));

                Logger.AmbiguousEndpoints(endpointNames);

                var message = Resources.FormatAmbiguousEndpoints(
                    Environment.NewLine,
                    endpointNames);

                throw new AmbiguousEndpointException(message);
            }
        }
        private (EndpointSelectorContext, EndpointSelector) CreateContextAndSelector(string httpMethod, List <Endpoint> endpoints)
        {
            // Add services to the collection
            var serviceCollection = new ServiceCollection();

            serviceCollection.AddLogging();

            var httpContext = new DefaultHttpContext();

            httpContext.Request.Method  = httpMethod;
            httpContext.RequestServices = serviceCollection.BuildServiceProvider();

            var selector  = new HttpMethodEndpointSelector();
            var selectors = new List <EndpointSelector>()
            {
                selector
            };

            var selectorContext = new EndpointSelectorContext(httpContext, new DispatcherValueCollection(), endpoints, selectors);

            return(selectorContext, selector);
        }
Beispiel #7
0
 public abstract Task SelectAsync(EndpointSelectorContext context);