Exemple #1
0
        /// <summary>Gets the template information.</summary>
        /// <param name="context">The context.</param>
        /// <param name="resolver">The resolver.</param>
        /// <param name="routes">The routes.</param>
        /// <returns></returns>
        private static async Task <ApiRoutingTemplate> GetRoutingTemplate(
            this ApiRequestContext context,
            IUriRouteResolver resolver,
            IApiRoutingTable routes)
        {
            RouteMatch         result;
            ApiRoutingTemplate template = null;

            foreach (var route in routes.GetRoutes())
            {
                result = await resolver.ResolveRoute(route.Template, context.Request.Path).ConfigureAwait(false);

                if (result?.IsMatch ?? false)
                {
                    if (template == null)
                    {
                        template = new ApiRoutingTemplate(route.Template);
                    }

                    template.Locations.Add(new ApiEndpointLocation(
                                               controller: route.Location.Controller,
                                               methodInfo: route.Location.MethodInfo,
                                               httpMethod: route.Location.HttpMethod,
                                               bodyParameterType: route.Location.BodyParameterType,
                                               uriParameterType: route.Location.UriParameterType,
                                               simpleParameters: route.Location.SimpleParameters,
                                               methodReturnType: route.Location.MethodReturnType));
                }
            }

            return(template);
        }
Exemple #2
0
        /// <summary>Processes the HTTP request method.</summary>
        /// <param name="context">The context.</param>
        /// <param name="routes">The routes.</param>
        /// <param name="resolver">The resolver.</param>
        /// <param name="defaultRequestConfiguration">The default request configuration.</param>
        /// <returns></returns>
        internal static async Task <bool> ProcessHttpRequestMethod(this ApiRequestContext context,
                                                                   IApiRoutingTable routes,
                                                                   IUriRouteResolver resolver,
                                                                   IDeepSleepRequestConfiguration defaultRequestConfiguration)
        {
            if (!context.RequestAborted.IsCancellationRequested)
            {
                // Templates exist for thies route
                if ((context.Routing?.Template?.Locations?.Count ?? 0) > 0)
                {
                    // A route was not found for the template
                    if (context.Routing.Route == null)
                    {
                        var methods = context.Routing.Template.Locations
                                      .Where(e => !string.IsNullOrWhiteSpace(e?.HttpMethod))
                                      .Select(e => e.HttpMethod.ToUpper())
                                      .Distinct()
                                      .ToList();

                        if (methods.Contains("GET") && !methods.Contains("HEAD"))
                        {
                            if (resolver != null)
                            {
                                var match = await resolver.MatchRoute(
                                    routes,
                                    "GET",
                                    context.Request.Path).ConfigureAwait(false);

                                if (match != null)
                                {
                                    var enableHeadForGetRequests = match.Configuration?.EnableHeadForGetRequests
                                                                   ?? defaultRequestConfiguration?.EnableHeadForGetRequests
                                                                   ?? ApiRequestContext.GetDefaultRequestConfiguration().EnableHeadForGetRequests
                                                                   ?? true;

                                    if (enableHeadForGetRequests)
                                    {
                                        methods.Add("HEAD");
                                    }
                                }
                            }
                        }

                        context.Runtime.Internals.IsMethodNotFound = true;
                        context.Response.AddHeader("Allow", string.Join(", ", methods));
                        context.Response.StatusCode = 405;

                        return(false);
                    }
                }

                return(true);
            }

            return(false);
        }
Exemple #3
0
        /// <summary>Processes the HTTP request routing.</summary>
        /// <param name="context">The context.</param>
        /// <param name="routes">The routes.</param>
        /// <param name="resolver">The resolver.</param>
        /// <param name="defaultRequestConfig">The default request configuration.</param>
        /// <returns></returns>
        internal static async Task <bool> ProcessHttpRequestRouting(this ApiRequestContext context,
                                                                    IApiRoutingTable routes,
                                                                    IUriRouteResolver resolver,
                                                                    IDeepSleepRequestConfiguration defaultRequestConfig)
        {
            if (!context.RequestAborted.IsCancellationRequested)
            {
                if (routes != null && resolver != null)
                {
                    context.Routing.Route = await context.GetRoutingItem(resolver, routes, defaultRequestConfig).ConfigureAwait(false);

                    context.Routing.Template = await context.GetRoutingTemplate(resolver, routes).ConfigureAwait(false);
                }

                context.Configuration = MergeConfigurations(
                    serviceProvider: context?.RequestServices,
                    defaultConfig: defaultRequestConfig,
                    endpointConfig: context.Routing?.Route?.Configuration);

                if (context.Routing.Route?.Location?.MethodInfo != null)
                {
                    var attributes = context.Routing.Route.Location.MethodInfo.GetCustomAttributes();

                    // Find any attribute request pipeline components
                    // and add the to the final configuration of the request.
                    attributes
                    .Where(a => a as IRequestPipelineComponent != null)
                    .Select(a => a as IRequestPipelineComponent)
                    .ToList()
                    .ForEach(p => context.Configuration.PipelineComponents.Add(p));

                    // Find any attribute validator components
                    // and add the to the final configuration of the request.
                    attributes
                    .Where(a => a as IEndpointValidatorComponent != null)
                    .Select(a => a as IEndpointValidatorComponent)
                    .ToList()
                    .ForEach(v => context.Configuration.Validators.Add(v));

                    // Find any authentication components
                    // and add the to the final configuration of the request.
                    var authenticationComponents = attributes
                                                   .Where(a => a as IAuthenticationComponent != null)
                                                   .Select(a => a as IAuthenticationComponent)
                                                   .ToList();

                    if (authenticationComponents.Count > 0)
                    {
                        context.Configuration.AuthenticationProviders = authenticationComponents;
                    }

                    // Find any authorization components
                    // and add the to the final configuration of the request.
                    var authorizationComponents = attributes
                                                  .Where(a => a as IAuthorizationComponent != null)
                                                  .Select(a => a as IAuthorizationComponent)
                                                  .ToList();

                    if (authorizationComponents.Count > 0)
                    {
                        context.Configuration.AuthorizationProviders = authorizationComponents;
                    }
                }


                if (context.Configuration?.RequestValidation?.MaxRequestLength != null && context.ConfigureMaxRequestLength != null)
                {
                    try
                    {
                        context.ConfigureMaxRequestLength(context.Configuration.RequestValidation.MaxRequestLength.Value);
                    }
                    catch { }
                }

                return(true);
            }

            return(false);
        }
Exemple #4
0
        /// <summary>Gets the route information.</summary>
        /// <param name="context">The context.</param>
        /// <param name="resolver">The resolver.</param>
        /// <param name="routes">The routes.</param>
        /// <param name="defaultRequestConfiguration">The default request configuration.</param>
        /// <returns></returns>
        private static async Task <ApiRoutingItem> GetRoutingItem(this ApiRequestContext context,
                                                                  IUriRouteResolver resolver,
                                                                  IApiRoutingTable routes,
                                                                  IDeepSleepRequestConfiguration defaultRequestConfiguration)
        {
            // -----------------------------------------------------------------
            // We want to trick the routing engine to treat HEAD requests as GET
            // http://tools.ietf.org/html/rfc7231#section-4.3.2
            // -----------------------------------------------------------------
            ApiRoutingItem routeInfo;

            if (context.Request.Method.In(StringComparison.InvariantCultureIgnoreCase, "HEAD"))
            {
                routeInfo = await resolver.MatchRoute(
                    routes,
                    "HEAD",
                    context.Request.Path).ConfigureAwait(false);

                if (routeInfo == null)
                {
                    routeInfo = await resolver.MatchRoute(
                        routes,
                        "GET",
                        context.Request.Path).ConfigureAwait(false);

                    if (routeInfo != null)
                    {
                        var enableHeadForGetRequests = routeInfo.Configuration?.EnableHeadForGetRequests
                                                       ?? defaultRequestConfiguration?.EnableHeadForGetRequests
                                                       ?? ApiRequestContext.GetDefaultRequestConfiguration().EnableHeadForGetRequests
                                                       ?? true;

                        if (!enableHeadForGetRequests)
                        {
                            routeInfo = null;
                        }
                    }
                }
            }
            else if (context.Request.IsCorsPreflightRequest())
            {
                if (context.Request.CrossOriginRequest.AccessControlRequestMethod.In(StringComparison.InvariantCultureIgnoreCase, "HEAD"))
                {
                    routeInfo = await resolver.MatchRoute(
                        routes,
                        context.Request.CrossOriginRequest.AccessControlRequestMethod,
                        context.Request.Path).ConfigureAwait(false);

                    if (routeInfo == null)
                    {
                        routeInfo = await resolver.MatchRoute(
                            routes,
                            "GET",
                            context.Request.Path).ConfigureAwait(false);

                        if (routeInfo != null)
                        {
                            var enableHeadForGetRequests = routeInfo.Configuration?.EnableHeadForGetRequests
                                                           ?? defaultRequestConfiguration?.EnableHeadForGetRequests
                                                           ?? ApiRequestContext.GetDefaultRequestConfiguration().EnableHeadForGetRequests
                                                           ?? true;

                            if (!enableHeadForGetRequests)
                            {
                                routeInfo = null;
                            }
                        }
                    }
                }
                else
                {
                    routeInfo = await resolver.MatchRoute(
                        routes,
                        context.Request.CrossOriginRequest.AccessControlRequestMethod,
                        context.Request.Path).ConfigureAwait(false);
                }
            }
            else
            {
                routeInfo = await resolver.MatchRoute(
                    routes,
                    context.Request.Method,
                    context.Request.Path).ConfigureAwait(false);
            }

            return(routeInfo);
        }
Exemple #5
0
        /// <summary>Processes the HTTP request cross origin resource sharing preflight.</summary>
        /// <param name="context">The context.</param>
        /// <param name="routes">The routes.</param>
        /// <param name="resolver">The resolver.</param>
        /// <param name="defaultRequestConfiguration">The default request configuration.</param>
        /// <returns></returns>
        internal static async Task <bool> ProcessHttpRequestCrossOriginResourceSharingPreflight(
            this ApiRequestContext context,
            IApiRoutingTable routes,
            IUriRouteResolver resolver,
            IDeepSleepRequestConfiguration defaultRequestConfiguration)
        {
            if (!context.RequestAborted.IsCancellationRequested)
            {
                if (context.Request?.IsCorsPreflightRequest() ?? false)
                {
                    var methods = (context.Routing?.Template?.Locations ?? new List <ApiEndpointLocation>())
                                  .Where(r => !string.IsNullOrWhiteSpace(r.HttpMethod))
                                  .Select(r => r.HttpMethod.ToUpper())
                                  .Distinct()
                                  .ToList();

                    // Need to include the auto-enabled HEAD method if configured on the get endpoint (if available)
                    var hasGet = methods.FirstOrDefault(m => m.Equals("GET", StringComparison.InvariantCultureIgnoreCase)) != null;
                    if (hasGet)
                    {
                        var hasHead = methods.FirstOrDefault(m => m.Equals("HEAD", StringComparison.InvariantCultureIgnoreCase)) != null;
                        if (!hasHead)
                        {
                            if (resolver != null)
                            {
                                var getMatch = await resolver.MatchRoute(
                                    routes,
                                    "GET",
                                    context.Request.Path).ConfigureAwait(false);

                                if (getMatch != null)
                                {
                                    var enableHeadForGetRequests = getMatch.Configuration?.EnableHeadForGetRequests
                                                                   ?? defaultRequestConfiguration?.EnableHeadForGetRequests
                                                                   ?? ApiRequestContext.GetDefaultRequestConfiguration().EnableHeadForGetRequests
                                                                   ?? true;

                                    if (enableHeadForGetRequests)
                                    {
                                        methods.Add("HEAD");
                                    }
                                }
                            }
                        }
                    }


                    context.Response.StatusCode = 200;

                    context.Response.AddHeader("Access-Control-Allow-Methods", string.Join(", ", methods).Trim());

                    if (!string.IsNullOrWhiteSpace(context.Request?.CrossOriginRequest?.AccessControlRequestHeaders))
                    {
                        var allowHeaders = (context.Configuration?.CrossOriginConfig?.AllowedHeaders ?? new string[] { })
                                           .Distinct()
                                           .Where(i => !string.IsNullOrWhiteSpace(i))
                                           .Select(i => i.Trim())
                                           .ToList();

                        if (allowHeaders.Count > 0 && allowHeaders.Contains("*"))
                        {
                            context.Response.AddHeader("Access-Control-Allow-Headers", context.Request.CrossOriginRequest.AccessControlRequestHeaders);
                        }
                        else
                        {
                            context.Response.AddHeader("Access-Control-Allow-Headers", string.Join(", ", allowHeaders));
                        }
                    }

                    if (context.Configuration?.CrossOriginConfig?.MaxAgeSeconds.HasValue ?? false)
                    {
                        context.Response.AddHeader("Access-Control-Max-Age", $"{context.Configuration.CrossOriginConfig.MaxAgeSeconds.Value}");
                    }


                    return(false);
                }

                return(true);
            }

            return(false);
        }