Exemplo n.º 1
0
        public override Task MatchAsync(HttpContext httpContext, EndpointFeature feature)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }

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

            var path = httpContext.Request.Path.Value;

            for (var i = 0; i < Matchers.Length; i++)
            {
                if (Matchers[i].TryMatch(path))
                {
                    feature.Endpoint    = Matchers[i].Endpoint;
                    feature.RouteValues = new RouteValueDictionary();
                }
            }

            return(Task.CompletedTask);
        }
Exemplo n.º 2
0
        public async Task MatchAsync_DuplicateTemplatesAndDifferentOrder_LowerOrderEndpointMatched()
        {
            // Arrange
            var higherOrderEndpoint = CreateEndpoint("/Teams", 1);
            var lowerOrderEndpoint  = CreateEndpoint("/Teams", 0);

            var endpointDataSource = new DefaultEndpointDataSource(new List <Endpoint>
            {
                higherOrderEndpoint,
                lowerOrderEndpoint
            });

            var treeMatcher = CreateTreeMatcher(endpointDataSource);

            var httpContext = new DefaultHttpContext();

            httpContext.Request.Path = "/Teams";

            var endpointFeature = new EndpointFeature();

            // Act
            await treeMatcher.MatchAsync(httpContext, endpointFeature);

            // Assert
            Assert.Equal(lowerOrderEndpoint, endpointFeature.Endpoint);
        }
Exemplo n.º 3
0
        public void RouteUrl_WithRouteName_UsesAmbientValues()
        {
            // Arrange
            var endpoint1 = CreateEndpoint(
                "api/orders/{id}",
                defaults: new { controller = "Orders", action = "GetById" },
                requiredValues: new { controller = "Orders", action = "GetById" },
                routeName: "OrdersApi");
            var endpoint2 = CreateEndpoint(
                "api/orders",
                defaults: new { controller = "Orders", action = "GetAll" },
                requiredValues: new { controller = "Orders", action = "GetAll" },
                routeName: "OrdersApi");
            var urlHelper = CreateUrlHelper(new[] { endpoint1, endpoint2 });

            // Set the endpoint feature and current context just as a normal request to MVC app would be
            var endpointFeature = new EndpointFeature();

            urlHelper.ActionContext.HttpContext.Features.Set <IEndpointFeature>(endpointFeature);
            endpointFeature.Endpoint = endpoint1;
            endpointFeature.Values   = new RouteValueDictionary
            {
                ["controller"] = "Orders",
                ["action"]     = "GetById",
                ["id"]         = "500"
            };

            // Act
            var url = urlHelper.RouteUrl(
                routeName: "OrdersApi",
                values: new { });

            // Assert
            Assert.Equal("/api/orders/500", url);
        }
Exemplo n.º 4
0
    /// <summary>
    /// Extension method for setting the <see cref="Endpoint"/> for the current request.
    /// </summary>
    /// <param name="context">The <see cref="HttpContext"/> context.</param>
    /// <param name="endpoint">The <see cref="Endpoint"/>.</param>
    public static void SetEndpoint(this HttpContext context, Endpoint?endpoint)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        var feature = context.Features.Get <IEndpointFeature>();

        if (endpoint != null)
        {
            if (feature == null)
            {
                feature = new EndpointFeature();
                context.Features.Set(feature);
            }

            feature.Endpoint = endpoint;
        }
        else
        {
            if (feature == null)
            {
                // No endpoint to set and no feature on context. Do nothing
                return;
            }

            feature.Endpoint = null;
        }
    }
        public async Task Endpoints_InvokeReturnedEndpoint_ActionInvokerProviderCalled()
        {
            // Arrange
            var endpointFeature = new EndpointFeature
            {
                RouteValues = new RouteValueDictionary()
            };

            var featureCollection = new FeatureCollection();

            featureCollection.Set <IEndpointFeature>(endpointFeature);
            featureCollection.Set <IRouteValuesFeature>(endpointFeature);
            featureCollection.Set <IRoutingFeature>(endpointFeature);

            var httpContextMock = new Mock <HttpContext>();

            httpContextMock.Setup(m => m.Features).Returns(featureCollection);

            var descriptorProviderMock = new Mock <IActionDescriptorCollectionProvider>();

            descriptorProviderMock.Setup(m => m.ActionDescriptors).Returns(new ActionDescriptorCollection(new List <ActionDescriptor>
            {
                new ActionDescriptor
                {
                    AttributeRouteInfo = new AttributeRouteInfo
                    {
                        Template = string.Empty
                    },
                    FilterDescriptors = new List <FilterDescriptor>()
                }
            }, 0));

            var actionInvokerCalled = false;
            var actionInvokerMock   = new Mock <IActionInvoker>();

            actionInvokerMock.Setup(m => m.InvokeAsync()).Returns(() =>
            {
                actionInvokerCalled = true;
                return(Task.CompletedTask);
            });

            var actionInvokerProviderMock = new Mock <IActionInvokerFactory>();

            actionInvokerProviderMock.Setup(m => m.CreateInvoker(It.IsAny <ActionContext>())).Returns(actionInvokerMock.Object);

            var dataSource = CreateMvcEndpointDataSource(
                descriptorProviderMock.Object,
                new MvcEndpointInvokerFactory(actionInvokerProviderMock.Object));

            // Act
            var endpoints = dataSource.Endpoints;

            // Assert
            var endpoint        = Assert.Single(endpoints);
            var matcherEndpoint = Assert.IsType <RouteEndpoint>(endpoint);

            await matcherEndpoint.RequestDelegate(httpContextMock.Object);

            Assert.True(actionInvokerCalled);
        }
        public async Task MatchAsync_MultipleMatches_EndpointSelectorCalled()
        {
            // Arrange
            var endpointWithoutConstraint = CreateEndpoint("/Teams", 0);
            var endpointWithConstraint    = CreateEndpoint(
                "/Teams",
                0,
                metadata: new EndpointMetadataCollection(new object[] { new HttpMethodEndpointConstraint(new[] { "POST" }) }));

            var endpointDataSource = new DefaultEndpointDataSource(new List <Endpoint>
            {
                endpointWithoutConstraint,
                endpointWithConstraint
            });

            var treeMatcher = CreateTreeMatcher(endpointDataSource);

            var httpContext = new DefaultHttpContext();

            httpContext.Request.Method = "POST";
            httpContext.Request.Path   = "/Teams";

            var endpointFeature = new EndpointFeature();

            // Act
            await treeMatcher.MatchAsync(httpContext, endpointFeature);

            // Assert
            Assert.Equal(endpointWithConstraint, endpointFeature.Endpoint);
        }
Exemplo n.º 7
0
 public static void AssertNotMatch(EndpointFeature feature, HttpContext context)
 {
     if (feature.Endpoint != null)
     {
         throw new XunitException(
                   $"Was expected not to match '{feature.Endpoint.DisplayName}' " +
                   $"but matched with values: {FormatRouteValues(context.Features.Get<IRouteValuesFeature>().RouteValues)}.");
     }
 }
Exemplo n.º 8
0
        public override Task MatchAsync(HttpContext httpContext, EndpointFeature feature)
        {
            if (_isHandled)
            {
                feature.RouteValues = new RouteValueDictionary(new { controller = "Home", action = "Index" });
                feature.Endpoint    = new Endpoint(TestConstants.EmptyRequestDelegate, EndpointMetadataCollection.Empty, "Test endpoint");
            }

            return(Task.CompletedTask);
        }
Exemplo n.º 9
0
            public override Task MatchAsync(HttpContext httpContext, EndpointFeature feature)
            {
                if (TryMatch(httpContext.Request.Path.Value))
                {
                    feature.Endpoint    = Endpoint;
                    feature.RouteValues = new RouteValueDictionary();
                }

                return(Task.CompletedTask);
            }
Exemplo n.º 10
0
        private static (HttpContext httpContext, EndpointFeature feature) CreateContext()
        {
            var feature     = new EndpointFeature();
            var httpContext = new DefaultHttpContext();

            httpContext.Features.Set <IEndpointFeature>(feature);
            httpContext.Features.Set <IRouteValuesFeature>(feature);

            return(httpContext, feature);
        }
Exemplo n.º 11
0
        public sealed override Task MatchAsync(HttpContext httpContext, EndpointFeature feature)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }

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

            // The sequence of actions we take is optimized to avoid doing expensive work
            // like creating substrings, creating route value dictionaries, and calling
            // into policies like versioning.
            var path = httpContext.Request.Path.Value;

            // First tokenize the path into series of segments.
            Span <PathSegment> buffer = stackalloc PathSegment[_maxSegmentCount];
            var count    = FastPathTokenizer.Tokenize(path, buffer);
            var segments = buffer.Slice(0, count);

            // FindCandidateSet will process the DFA and return a candidate set. This does
            // some preliminary matching of the URL (mostly the literal segments).
            var candidates = FindCandidateSet(httpContext, path, segments);

            if (candidates.Length == 0)
            {
                return(Task.CompletedTask);
            }

            // At this point we have a candidate set, defined as a list of endpoints in
            // priority order.
            //
            // We don't yet know that any candidate can be considered a match, because
            // we haven't processed things like route constraints and complex segments.
            //
            // Now we'll iterate each endpoint to capture route values, process constraints,
            // and process complex segments.

            // `candidates` has all of our internal state that we use to process the
            // set of endpoints before we call the EndpointSelector.
            //
            // `candidateSet` is the mutable state that we pass to the EndpointSelector.
            var candidateSet = new CandidateSet(candidates);

            for (var i = 0; i < candidates.Length; i++)
            {
                // PERF: using ref here to avoid copying around big structs.
                //
                // Reminder!
                // candidate: readonly data about the endpoint and how to match
                // state: mutable storarge for our processing
                ref var candidate = ref candidates[i];
                ref var state     = ref candidateSet[i];
Exemplo n.º 12
0
        public void Setup()
        {
            SetupEndpoints();

            SetupRequests();

            _baseline = (BarebonesMatcher)SetupMatcher(new BarebonesMatcherBuilder());
            _dfa      = SetupMatcher(CreateDfaMatcherBuilder());

            _feature = new EndpointFeature();
        }
Exemplo n.º 13
0
        public void Setup()
        {
            SetupEndpoints();

            SetupRequests();

            _route = SetupMatcher(RouteMatcher.CreateBuilder());
            _tree  = SetupMatcher(TreeRouterMatcher.CreateBuilder());

            _feature = new EndpointFeature();
        }
        public void Setup()
        {
            SetupEndpoints();

            SetupRequests();

            _baseline = (TrivialMatcher)SetupMatcher(new TrivialMatcherBuilder());
            _dfa      = (DfaMatcher)SetupMatcher(CreateDfaMatcherBuilder());

            _feature = new EndpointFeature();
        }
        internal static (HttpContext httpContext, IEndpointFeature feature) CreateContext(string path)
        {
            var httpContext = new DefaultHttpContext();

            httpContext.Request.Method  = "TEST";
            httpContext.Request.Path    = path;
            httpContext.RequestServices = CreateServices();

            var feature = new EndpointFeature();

            httpContext.Features.Set <IEndpointFeature>(feature);

            return(httpContext, feature);
        }
Exemplo n.º 16
0
        public Task ApplyAsync(HttpContext httpContext, EndpointFeature endpointFeature, CandidateSet candidateSet)
        {
            // PERF: we can skip over action constraints if there aren't any app-wide.
            //
            // Running action constraints (or just checking for them) in a candidate set
            // is somewhat expensive compared to other routing operations. This should only
            // happen if user-code adds action constraints.
            if (ShouldRunActionConstraints)
            {
                ApplyActionConstraints(httpContext, candidateSet);
            }

            return(Task.CompletedTask);
        }
Exemplo n.º 17
0
        public static void AssertMatch(EndpointFeature feature, HttpContext context, Endpoint expected, string[] keys, string[] values)
        {
            keys   = keys ?? Array.Empty <string>();
            values = values ?? Array.Empty <string>();

            if (keys.Length != values.Length)
            {
                throw new XunitException($"Keys and Values must be the same length.");
            }

            var zipped = keys.Zip(values, (k, v) => new KeyValuePair <string, object>(k, v));

            AssertMatch(feature, context, expected, new RouteValueDictionary(zipped));
        }
Exemplo n.º 18
0
        public void Setup()
        {
            SetupEndpoints();

            SetupRequests();

            _baseline    = (BarebonesMatcher)SetupMatcher(new BarebonesMatcherBuilder());
            _dfa         = SetupMatcher(new DfaMatcherBuilder());
            _instruction = SetupMatcher(new InstructionMatcherBuilder());
            _route       = SetupMatcher(new RouteMatcherBuilder());
            _tree        = SetupMatcher(new TreeRouterMatcherBuilder());

            _feature = new EndpointFeature();
        }
Exemplo n.º 19
0
        public static void SetEndpoint(this HttpContext context, Endpoint endpoint)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var feature = new EndpointFeature
            {
                Endpoint = endpoint
            };

            context.Features.Set(typeof(IEndpointFeature), feature);
        }
Exemplo n.º 20
0
        public void Setup()
        {
            SetupEndpoints();

            SetupRequests();

            // The perf is kinda slow for these benchmarks, so we do some sampling
            // of the request data.
            _samples = SampleRequests(EndpointCount, SampleCount);

            _route = SetupMatcher(RouteMatcher.CreateBuilder());
            _tree  = SetupMatcher(TreeRouterMatcher.CreateBuilder());

            _feature = new EndpointFeature();
        }
Exemplo n.º 21
0
        public void Setup()
        {
            SetupEndpoints();

            SetupRequests();

            // The perf is kinda slow for these benchmarks, so we do some sampling
            // of the request data.
            _samples = SampleRequests(EndpointCount, SampleCount);

            _baseline = (BarebonesMatcher)SetupMatcher(new BarebonesMatcherBuilder());
            _dfa      = SetupMatcher(CreateDfaMatcherBuilder());

            _feature = new EndpointFeature();
        }
Exemplo n.º 22
0
        public async Task MatchAsync_MultipleMatches_EndpointSelectorCalled()
        {
            // Arrange
            var endpoint1 = CreateEndpoint("/Teams", 0);
            var endpoint2 = CreateEndpoint("/Teams", 1);

            var endpointSelector = new Mock <EndpointSelector>();

            endpointSelector
            .Setup(s => s.SelectAsync(It.IsAny <HttpContext>(), It.IsAny <IEndpointFeature>(), It.IsAny <CandidateSet>()))
            .Callback <HttpContext, IEndpointFeature, CandidateSet>((c, f, cs) =>
            {
                Assert.Equal(2, cs.Count);

                Assert.Same(endpoint1, cs[0].Endpoint);
                Assert.True(cs[0].IsValidCandidate);
                Assert.Equal(0, cs[0].Score);
                Assert.Empty(cs[0].Values);

                Assert.Same(endpoint2, cs[1].Endpoint);
                Assert.True(cs[1].IsValidCandidate);
                Assert.Equal(1, cs[1].Score);
                Assert.Empty(cs[1].Values);

                f.Endpoint = endpoint2;
            })
            .Returns(Task.CompletedTask);

            var endpointDataSource = new DefaultEndpointDataSource(new List <Endpoint>
            {
                endpoint1,
                endpoint2
            });

            var matcher = CreateDfaMatcher(endpointDataSource, endpointSelector.Object);

            var httpContext = new DefaultHttpContext();

            httpContext.Request.Path = "/Teams";

            var endpointFeature = new EndpointFeature();

            // Act
            await matcher.MatchAsync(httpContext, endpointFeature);

            // Assert
            Assert.Equal(endpoint2, endpointFeature.Endpoint);
        }
Exemplo n.º 23
0
    public void Setup()
    {
        var policyProvider = new DefaultAuthorizationPolicyProvider(Options.Create(new AuthorizationOptions()));

        _authorizationMiddleware = new AuthorizationMiddleware((context) => Task.CompletedTask, policyProvider);

        _httpContextNoEndpoint = new DefaultHttpContext();

        var feature = new EndpointFeature
        {
            Endpoint = new Endpoint((context) => Task.CompletedTask, EndpointMetadataCollection.Empty, "Test endpoint")
        };

        _httpContextHasEndpoint = new DefaultHttpContext();
        _httpContextHasEndpoint.Features.Set <IEndpointFeature>(feature);
    }
Exemplo n.º 24
0
        public void Setup()
        {
            Endpoints    = new RouteEndpoint[1];
            Endpoints[0] = CreateEndpoint("/plaintext");

            Requests    = new HttpContext[1];
            Requests[0] = new DefaultHttpContext();
            Requests[0].RequestServices = CreateServices();
            Requests[0].Request.Path    = "/plaintext";

            _baseline = (BarebonesMatcher)SetupMatcher(new BarebonesMatcherBuilder());
            _dfa      = SetupMatcher(CreateDfaMatcherBuilder());
            _route    = SetupMatcher(new RouteMatcherBuilder());
            _tree     = SetupMatcher(new TreeRouterMatcherBuilder());

            _feature = new EndpointFeature();
        }
        public void Setup()
        {
            _endpoints    = new MatcherEndpoint[1];
            _endpoints[0] = CreateEndpoint("/plaintext");

            _requests    = new HttpContext[1];
            _requests[0] = new DefaultHttpContext();
            _requests[0].RequestServices = CreateServices();
            _requests[0].Request.Path    = "/plaintext";

            _minimal     = SetupMatcher(MinimalMatcher.CreateBuilder());
            _dfa         = SetupMatcher(DfaMatcher.CreateBuilder());
            _instruction = SetupMatcher(InstructionMatcher.CreateBuilder());
            _route       = SetupMatcher(RouteMatcher.CreateBuilder());
            _tree        = SetupMatcher(TreeRouterMatcher.CreateBuilder());

            _feature = new EndpointFeature();
        }
Exemplo n.º 26
0
        public override async Task SelectAsync(
            HttpContext httpContext,
            EndpointFeature feature,
            CandidateSet candidateSet)
        {
            var selectorPolicies = _selectorPolicies;

            for (var i = 0; i < _selectorPolicies.Length; i++)
            {
                await selectorPolicies[i].ApplyAsync(httpContext, feature, candidateSet);
                if (feature.Endpoint != null)
                {
                    // This is a short circuit, the selector chose an endpoint.
                    return;
                }
            }

            ProcessFinalCandidates(httpContext, feature, candidateSet);
        }
Exemplo n.º 27
0
        private static void ProcessFinalCandidates(
            HttpContext httpContext,
            EndpointFeature feature,
            CandidateSet candidateSet)
        {
            Endpoint             endpoint = null;
            RouteValueDictionary values   = null;
            int?foundScore = null;

            for (var i = 0; i < candidateSet.Count; i++)
            {
                ref var state = ref candidateSet[i];

                var isValid = state.IsValidCandidate;
                if (isValid && foundScore == null)
                {
                    // This is the first match we've seen - speculatively assign it.
                    endpoint   = state.Endpoint;
                    values     = state.Values;
                    foundScore = state.Score;
                }
                else if (isValid && foundScore < state.Score)
                {
                    // This candidate is lower priority than the one we've seen
                    // so far, we can stop.
                    //
                    // Don't worry about the 'null < state.Score' case, it returns false.
                    break;
                }
                else if (isValid && foundScore == state.Score)
                {
                    // This is the second match we've found of the same score, so there
                    // must be an ambiguity.
                    //
                    // Don't worry about the 'null == state.Score' case, it returns false.

                    ReportAmbiguity(candidateSet);

                    // Unreachable, ReportAmbiguity always throws.
                    throw new NotSupportedException();
                }
            }
Exemplo n.º 28
0
        public async override Task MatchAsync(HttpContext httpContext, EndpointFeature feature)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }

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

            var context = new RouteContext(httpContext);
            await _inner.RouteAsync(context);

            if (context.Handler != null)
            {
                feature.RouteValues = context.RouteData.Values;
                await context.Handler(httpContext);
            }
        }
        public void SetEndpoint_NullOnContextWithFeature_NullSetOnExistingFeature()
        {
            // Arrange
            var context         = new DefaultHttpContext();
            var initialEndpoint = new Endpoint(c => Task.CompletedTask, EndpointMetadataCollection.Empty, "Test endpoint");
            var initialFeature  = new EndpointFeature
            {
                Endpoint = initialEndpoint
            };

            context.Features.Set <IEndpointFeature>(initialFeature);

            // Act
            context.SetEndpoint(null);

            // Assert
            var feature = context.Features.Get <IEndpointFeature>();

            Assert.Equal(initialFeature, feature);
            Assert.Null(context.GetEndpoint());
        }
Exemplo n.º 30
0
        public sealed override Task MatchAsync(HttpContext httpContext, EndpointFeature feature)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }

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

            var path = httpContext.Request.Path.Value;

            if (string.Equals(_endpoint.RoutePattern.RawText, path, StringComparison.OrdinalIgnoreCase))
            {
                feature.Endpoint    = _endpoint;
                feature.RouteValues = new RouteValueDictionary();
            }

            return(Task.CompletedTask);
        }