Exemple #1
0
        protected void EnsureServicesInitialized(MatcherContext context)
        {
            if (Volatile.Read(ref _servicesInitialized))
            {
                return;
            }

            EnsureServicesInitializedSlow(context);
        }
Exemple #2
0
 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);
         }
     }
 }
Exemple #3
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);
            }
        }
Exemple #4
0
        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());
            }
        }
Exemple #5
0
        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);
        }
Exemple #7
0
        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);
        }