protected void EnsureServicesInitialized(MatcherContext context) { if (Volatile.Read(ref _servicesInitialized)) { return; } EnsureServicesInitializedSlow(context); }
private void EnsureServicesInitializedSlow(MatcherContext context) { lock (_lock) { if (!Volatile.Read(ref _servicesInitialized)) { var services = context.HttpContext.RequestServices; Logger = services.GetRequiredService <ILoggerFactory>().CreateLogger(GetType()); InitializeServices(services); } } }
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); } }
public virtual async Task MatchAsync(MatcherContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } EnsureServicesInitialized(context); context.Values = await MatchRequestAsync(context.HttpContext); if (context.Values != null) { await SelectEndpointAsync(context, GetEndpoints()); } }
private void EnsureTreeMatcherServicesInitialized(MatcherContext context) { EnsureServicesInitialized(context); if (Volatile.Read(ref _onChange)) { return; } lock (_lock) { if (!Volatile.Read(ref _onChange)) { _onChange = true; Primitives.ChangeToken.OnChange(() => ChangeToken, () => Volatile.Write(ref _dataInitialized, false)); } } }
public async Task Invoke(HttpContext httpContext) { var feature = new DispatcherFeature(); httpContext.Features.Set <IDispatcherFeature>(feature); var context = new MatcherContext(httpContext); foreach (var entry in _options.Matchers) { await entry.Matcher.MatchAsync(context); if (context.ShortCircuit != null) { feature.Endpoint = context.Endpoint; feature.Values = context.Values; await context.ShortCircuit(httpContext); _logger.RequestShortCircuitedDispatcherMiddleware(context); return; } if (context.Endpoint != null) { _logger.EndpointMatchedDispatcherMiddleware(context.Endpoint); feature.Endpoint = context.Endpoint; feature.Values = context.Values; feature.Handler = entry.HandlerFactory.CreateHandler(feature.Endpoint); if (feature.Handler == null) { _logger.HandlerNotCreated(entry); throw new InvalidOperationException("Couldn't create a handler, that's bad."); } break; } _logger.NoEndpointsMatchedMatcher(entry.Matcher); } await _next(httpContext); }
public override async Task MatchAsync(MatcherContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } EnsureTreeMatcherServicesInitialized(context); var cache = LazyInitializer.EnsureInitialized(ref _cache, ref _dataInitialized, ref _lock, _initializer); var values = new DispatcherValueCollection(); context.Values = values; for (var i = 0; i < cache.Trees.Length; i++) { var tree = cache.Trees[i]; var tokenizer = new PathTokenizer(context.HttpContext.Request.Path); var treenumerator = new TreeEnumerator(tree.Root, tokenizer); while (treenumerator.MoveNext()) { var node = treenumerator.Current; foreach (var item in node.Matches) { var entry = item.Entry; var matcher = item.RoutePatternMatcher; values.Clear(); if (!matcher.TryMatch(context.HttpContext.Request.Path, values)) { continue; } Logger.MatchedRoute(entry.RoutePattern.RawText); if (!MatchConstraints(context.HttpContext, values, entry.Constraints)) { continue; } await SelectEndpointAsync(context, (entry.Endpoints)); if (context.ShortCircuit != null) { Logger.RequestShortCircuited(context); return; } if (context.Endpoint != null) { if (context.Endpoint is IRoutePatternEndpoint templateEndpoint) { foreach (var kvp in templateEndpoint.Values) { if (!context.Values.ContainsKey(kvp.Key)) { context.Values[kvp.Key] = kvp.Value; } } } return; } } } } }
public static void RequestShortCircuitedDispatcherMiddleware(this ILogger logger, MatcherContext matcherContext) { var requestPath = matcherContext.HttpContext.Request.Path; _requestShortCircuitedDispatcherMiddleware(logger, requestPath, null); }