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); }
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()); } } }
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); }
public abstract Task SelectAsync(EndpointSelectorContext context);