Exemple #1
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 #2
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 #3
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);
        }