Exemplo n.º 1
0
        private async Task InvokeApi(HttpContext httpContext)
        {
            httpContext.Request.Headers.TryGetValue("Prefer", out StringValues preferHeader);
            OeRequestHeaders headers = OeRequestHeaders.Parse(httpContext.Request.Headers["Accept"], preferHeader);

            Uri baseUri    = UriHelper.GetBaseUri(httpContext.Request);
            Uri requestUri = UriHelper.GetUri(httpContext.Request);

            if (HttpMethods.IsGet(httpContext.Request.Method))
            {
                var parser = new OeParser(baseUri, EdmModel, GetModelBoundProvider(httpContext), OeParser.ServiceProvider);
                await parser.ExecuteGetAsync(requestUri, new OeHttpRequestHeaders(headers, httpContext.Response),
                                             httpContext.Response.Body, httpContext.RequestAborted).ConfigureAwait(false);
            }
            else if (HttpMethods.IsPost(httpContext.Request.Method) ||
                     HttpMethods.IsPut(httpContext.Request.Method) ||
                     HttpMethods.IsPatch(httpContext.Request.Method) ||
                     HttpMethods.IsDelete(httpContext.Request.Method))
            {
                ODataUri odataUri = OeParser.ParseUri(EdmModel, baseUri, requestUri, OeParser.ServiceProvider);
                if (odataUri.Path.LastSegment is OperationImportSegment)
                {
                    var parser = new OeParser(baseUri, EdmModel, GetModelBoundProvider(httpContext), OeParser.ServiceProvider);
                    await parser.ExecuteOperationAsync(odataUri, new OeHttpRequestHeaders(headers, httpContext.Response),
                                                       httpContext.Request.Body, httpContext.Response.Body, httpContext.RequestAborted).ConfigureAwait(false);
                }
                else
                {
                    httpContext.Response.ContentType = httpContext.Request.ContentType;
                    var batchParser = new OeBatchParser(baseUri, EdmModel, OeParser.ServiceProvider);
                    await batchParser.ExecuteOperationAsync(requestUri, httpContext.Request.Body, httpContext.Response.Body,
                                                            httpContext.Request.ContentType, httpContext.Request.Method, httpContext.RequestAborted).ConfigureAwait(false);
                }
            }
        }
Exemplo n.º 2
0
        public static async Task <(bool Exists, StringValues Value)> TryGetParamAsync(this HttpRequest httpRequest, string key, CancellationToken cancellationToken)
        {
            if (httpRequest == null)
            {
                throw new ArgumentNullException(nameof(httpRequest));
            }
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            var hasForm = (HttpMethods.IsPost(httpRequest.Method) ||
                           HttpMethods.IsPut(httpRequest.Method) ||
                           HttpMethods.IsDelete(httpRequest.Method) ||
                           HttpMethods.IsPatch(httpRequest.Method)) &&
                          httpRequest.HasFormContentType;

            var exists = httpRequest.Query.TryGetValue(key, out var value);

            if (!exists && hasForm)
            {
                var form = await httpRequest.ReadFormAsync(cancellationToken).ConfigureAwaitFalse();

                exists = form.TryGetValue(key, out value);
            }

            return(exists, value);
        }
Exemplo n.º 3
0
        public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            try
            {
                _requestMethod    = context.HttpContext.Request.Method;
                _apiRequestMethod = context.HttpContext.Request.Headers["ApiRequestMethod"].FirstOrDefault() ?? _requestMethod ?? "GET";

                _cacheReadEnabled   = HttpMethods.IsGet(_apiRequestMethod) || HttpMethods.IsPost(_apiRequestMethod);
                _cacheUpdateEnabled = HttpMethods.IsPut(_apiRequestMethod) ||
                                      HttpMethods.IsPatch(_apiRequestMethod) || HttpMethods.IsDelete(_apiRequestMethod) ||
                                      (HttpMethods.IsPost(_apiRequestMethod) &&
                                       _updateMethodStartNames.Any(x => ((ControllerActionDescriptor)context.ActionDescriptor).ActionName.ToLower().StartsWith(x)));

                if (!_cacheUpdateEnabled)
                {
                    _cacheKey       = _cacheService.CreateCacheKey(context.HttpContext.Request.Path, _modelType.Name);
                    _cacheKeyExists = _cacheService.ContainsKey(_cacheKey);
                }

                _cacheTypeExists = _cacheService.ContainsKeyType(_modelType.Name);
            }
            catch (Exception ex)
            {
                GeneralContext.Logger.Error(ex.GetApiMessageInfo());
                _cacheKeyExists = false;
            }

            if ((_cacheReadEnabled && !_cacheKeyExists) || _cacheUpdateEnabled)
            {
                await next();
            }
        }
Exemplo n.º 4
0
        public void Inspect(RequestAnalysisContext context, CancellationToken cancellationToken)
        {
            var method = context.Request.Method;

            if (!HttpMethods.IsGet(method) &&
                !HttpMethods.IsHead(method) &&
                !HttpMethods.IsOptions(method) &&
                !HttpMethods.IsPost(method) &&
                !HttpMethods.IsDelete(method) &&
                !HttpMethods.IsPut(method) &&
                !HttpMethods.IsPatch(method) &&
                !HttpMethods.IsConnect(method)
                )
            {
                // TRACE must be disabled
                if (HttpMethods.IsTrace(method))
                {
                    context.ReportDiagnostic(new Diagnostic(RuleTrace, Location.Method));
                    return;
                }

                // unknown method
                context.ReportDiagnostic(new Diagnostic(Rule, Location.Method));

                // Apache directory listing exploit
                if (method.Equals("GETS", StringComparison.OrdinalIgnoreCase))
                {
                    context.ReportDiagnostic(new Diagnostic(RuleGets, Location.Method));
                }
            }
        }
        public virtual Task <IActionResult> HandleAsync(HttpRequest request)
        {
            if (HttpMethods.IsGet(request.Method))
            {
                return(HandleGetAsync(request));
            }

            if (HttpMethods.IsPost(request.Method))
            {
                return(HandlePostAsync(request));
            }

            if (HttpMethods.IsPut(request.Method))
            {
                return(HandlePutAsync(request));
            }

            if (HttpMethods.IsPatch(request.Method))
            {
                return(HandlePatchAsync(request));
            }

            if (HttpMethods.IsDelete(request.Method))
            {
                return(HandleDeleteAsync(request));
            }

            return(methodNotAllowed);
        }
Exemplo n.º 6
0
        static bool SetupMethodAndContent(HttpRequest request, HttpRequestMessage proxiedMessage)
        {
            var hasContent    = false;
            var requestMethod = request.Method;

            // Try to use the static HttpMethods rather than creating a new one.
            if (HttpMethods.IsGet(requestMethod))
            {
                proxiedMessage.Method = HttpMethod.Get;
            }
            else if (HttpMethods.IsHead(requestMethod))
            {
                proxiedMessage.Method = HttpMethod.Head;
            }
            else if (HttpMethods.IsDelete(requestMethod))
            {
                proxiedMessage.Method = HttpMethod.Delete;
            }
            else if (HttpMethods.IsTrace(requestMethod))
            {
                proxiedMessage.Method = HttpMethod.Trace;
            }
            else
            {
                hasContent = true;

                if (HttpMethods.IsPost(requestMethod))
                {
                    proxiedMessage.Method = HttpMethod.Post;
                }
                else if (HttpMethods.IsOptions(requestMethod))
                {
                    proxiedMessage.Method = HttpMethod.Options;
                }
                else if (HttpMethods.IsPut(requestMethod))
                {
                    proxiedMessage.Method = HttpMethod.Put;
                }
                else if (HttpMethods.IsPatch(requestMethod))
                {
                    proxiedMessage.Method = HttpMethod.Patch;
                }
                else
                {
                    proxiedMessage.Method = new HttpMethod(request.Method);
                }

                proxiedMessage.Content = new StreamContent(request.Body);
            }

            return(hasContent);
        }
        /// <summary>
        /// Return a corresponding VerbsHttpMethod with the verb used in the request.
        /// </summary>
        /// <param name="context">ActionExecutingContext</param>
        /// <returns>Return VerbsHttpMethod corresponding to the request.</returns>
        public static VerbsHttpMethod GetVerbs(this ActionExecutingContext context)
        {
            var method = context.HttpContext.Request.Method;

            if (HttpMethods.IsGet(method))
            {
                return(VerbsHttpMethod.Get);
            }

            if (HttpMethods.IsPost(method))
            {
                return(VerbsHttpMethod.Post);
            }

            if (HttpMethods.IsDelete(method))
            {
                return(VerbsHttpMethod.Delete);
            }

            if (HttpMethods.IsPut(method))
            {
                return(VerbsHttpMethod.Put);
            }

            if (HttpMethods.IsHead(method))
            {
                return(VerbsHttpMethod.Head);
            }

            if (HttpMethods.IsOptions(method))
            {
                return(VerbsHttpMethod.Options);
            }

            if (HttpMethods.IsPatch(method))
            {
                return(VerbsHttpMethod.Patch);
            }

            if (HttpMethods.IsTrace(method))
            {
                return(VerbsHttpMethod.Trace);
            }

            if (HttpMethods.IsConnect(method))
            {
                return(VerbsHttpMethod.Connect);
            }

            throw new HttpMethodNotFoundException($"Could not find the HttpMethod '{method}'");
        }
Exemplo n.º 8
0
        /// <summary>
        /// Converts the given HTTP method (usually obtained from <see cref="HttpRequest.Method"/>)
        /// into the corresponding <see cref="HttpMethod"/> static instance.
        /// </summary>
        public static HttpMethod GetHttpMethod(string method)
        {
            if (HttpMethods.IsGet(method))
            {
                return(HttpMethod.Get);
            }

            if (HttpMethods.IsPost(method))
            {
                return(HttpMethod.Post);
            }

            if (HttpMethods.IsPut(method))
            {
                return(HttpMethod.Put);
            }

            if (HttpMethods.IsDelete(method))
            {
                return(HttpMethod.Delete);
            }

            if (HttpMethods.IsOptions(method))
            {
                return(HttpMethod.Options);
            }

            if (HttpMethods.IsHead(method))
            {
                return(HttpMethod.Head);
            }

            if (HttpMethods.IsPatch(method))
            {
                return(HttpMethod.Patch);
            }

            if (HttpMethods.IsTrace(method))
            {
                return(HttpMethod.Trace);
            }

            // NOTE: Proxying "CONNECT" is not supported (by design!)
            //if (HttpMethods.IsConnect(method))
            //{
            //    return new HttpMethod("CONNECT");
            //}

            throw new InvalidOperationException($"Unsupported request method '{method}'.");
        }
Exemplo n.º 9
0
        public async Task Invoke(HttpContext context, IIdentityService identityService)
        {
            var method = context.Request.Method;

            _telemetry.TrackTrace(new TraceTelemetry(identityService.GetScope(), SeverityLevel.Information));

            if (HttpMethods.IsPost(method) || HttpMethods.IsPut(method) || HttpMethods.IsPatch(method))
            {
                var body = await FormatRequestBody(context.Request);

                _telemetry.TrackTrace(new TraceTelemetry(body, SeverityLevel.Information));
            }

            await _next(context);
        }
Exemplo n.º 10
0
        public async Task Invoke(HttpContext context, IIdentityService identityService)
        {
            var method    = context.Request.Method;
            var telemetry = new TelemetryClient(new TelemetryConfiguration(_applicationInsights.InstrumentationKey));

            telemetry.TrackTrace(new TraceTelemetry(identityService.GetScope(), SeverityLevel.Information));

            if (HttpMethods.IsPost(method) || HttpMethods.IsPut(method) || HttpMethods.IsPatch(method))
            {
                var body = await FormatRequestBody(context.Request);

                telemetry.TrackTrace(new TraceTelemetry(body, SeverityLevel.Information));
            }

            await _next(context);
        }
Exemplo n.º 11
0
        internal static List <ActionDescriptor> SelectCandidates(IReadOnlyList <ActionDescriptor> actionDescriptors,
                                                                 HttpContext httpContext, RouteValueDictionary values, String path, String httpMethod)
        {
            var selectCandidates = new List <ActionDescriptor>();

            for (int i = 0; i < actionDescriptors.Count; i++)
            {
                ActionDescriptor actionDescriptor = actionDescriptors[i];
                if (actionDescriptor.AttributeRouteInfo != null && actionDescriptor.AttributeRouteInfo.Template != null)
                {
                    RouteTemplate template = TemplateParser.Parse(actionDescriptor.AttributeRouteInfo.Template);
                    var           matcher  = new TemplateMatcher(template, new RouteValueDictionary());
                    if (matcher.TryMatch(path, values) && ActionConstaint(actionDescriptor, httpContext, values, httpMethod))
                    {
                        selectCandidates.Add(actionDescriptor);
                    }
                }
            }

            if (selectCandidates.Count == 0)
            {
                if (HttpMethods.IsGet(httpMethod))
                {
                    for (int i = 0; i < actionDescriptors.Count; i++)
                    {
                        ActionDescriptor actionDescriptor = actionDescriptors[i];
                        if (actionDescriptor.AttributeRouteInfo != null && actionDescriptor.AttributeRouteInfo.Template != null && path != null &&
                            path.IndexOf(actionDescriptor.AttributeRouteInfo.Template, StringComparison.OrdinalIgnoreCase) == 1 &&
                            path[actionDescriptor.AttributeRouteInfo.Template.Length + 1] == '/' &&
                            ActionConstaint(actionDescriptor, httpContext, values, httpMethod))
                        {
                            selectCandidates.Add(actionDescriptor);
                            break;
                        }
                    }
                    return(selectCandidates);
                }

                if (HttpMethods.IsPatch(httpMethod) || HttpMethods.IsDelete(httpMethod) || HttpMethods.IsPut(httpMethod))
                {
                    return(SelectCandidates(actionDescriptors, httpContext, values, path, HttpMethods.Post));
                }
            }

            return(selectCandidates);
        }
Exemplo n.º 12
0
        internal static List <ActionDescriptor> SelectCandidates(IReadOnlyList <ActionDescriptor> actionDescriptors, String[] segments, String httpMethod)
        {
            var selectCandidates = new List <ActionDescriptor>();

            for (int i = 0; i < actionDescriptors.Count; i++)
            {
                ActionDescriptor actionDescriptor = actionDescriptors[i];
                if (actionDescriptor.AttributeRouteInfo == null)
                {
                    actionDescriptor.RouteValues.TryGetValue("controller", out String value);
                    if (String.Compare(value, segments[0], StringComparison.OrdinalIgnoreCase) == 0 && ActionConstaint(actionDescriptor, httpMethod))
                    {
                        selectCandidates.Add(actionDescriptor);
                    }
                }
                else
                {
                    String[] controllerSegments = actionDescriptor.AttributeRouteInfo.Template.Split('/');
                    if (controllerSegments.Length != segments.Length)
                    {
                        continue;
                    }

                    bool match = false;
                    for (int j = 0; j < controllerSegments.Length; j++)
                    {
                        match = String.Compare(controllerSegments[j], segments[j], StringComparison.OrdinalIgnoreCase) == 0;
                        if (!match)
                        {
                            break;
                        }
                    }
                    if (match && ActionConstaint(actionDescriptor, httpMethod))
                    {
                        selectCandidates.Add(actionDescriptor);
                    }
                }
            }

            if (selectCandidates.Count == 0 && (HttpMethods.IsPatch(httpMethod) || HttpMethods.IsDelete(httpMethod) || HttpMethods.IsPut(httpMethod)))
            {
                return(SelectCandidates(actionDescriptors, segments, HttpMethods.Post));
            }
            return(selectCandidates);
        }
Exemplo n.º 13
0
        internal static HttpRequestConditions GetRequestConditions(this HttpRequest request)
        {
            HttpRequestConditions requestConditions = new HttpRequestConditions();

            RequestHeaders requestHeaders = request.GetTypedHeaders();

            if (HttpMethods.IsGet(request.Method) || HttpMethods.IsHead(request.Method))
            {
                requestConditions.IfNoneMatch     = requestHeaders.IfNoneMatch?.Select(v => v.Tag.ToString());
                requestConditions.IfModifiedSince = requestHeaders.IfModifiedSince;
            }
            else if (HttpMethods.IsPut(request.Method) || HttpMethods.IsPatch(request.Method))
            {
                requestConditions.IfMatch           = requestHeaders.IfMatch?.Select(v => v.Tag.ToString());
                requestConditions.IfUnmodifiedSince = requestHeaders.IfUnmodifiedSince;
            }

            return(requestConditions);
        }
Exemplo n.º 14
0
        private static Method GetMethod(string method)
        {
            if (HttpMethods.IsDelete(method))
            {
                return(Method.DELETE);
            }

            if (HttpMethods.IsGet(method))
            {
                return(Method.GET);
            }

            if (HttpMethods.IsHead(method))
            {
                return(Method.HEAD);
            }

            if (HttpMethods.IsOptions(method))
            {
                return(Method.OPTIONS);
            }

            if (HttpMethods.IsPatch(method))
            {
                return(Method.PATCH);
            }

            if (HttpMethods.IsPost(method))
            {
                return(Method.POST);
            }

            if (HttpMethods.IsPut(method))
            {
                return(Method.PUT);
            }

            throw new NotSupportedException($"Http Method {method} is not supported in {typeof(Method)}.");
        }
Exemplo n.º 15
0
 private static HttpMethod GetHttpMethod(string method, out bool?hasBody)
 {
     if (HttpMethods.IsDelete(method))
     {
         hasBody = null; return(HttpMethod.Delete);
     }
     else if (HttpMethods.IsGet(method))
     {
         hasBody = false; return(HttpMethod.Get);
     }
     else if (HttpMethods.IsHead(method))
     {
         hasBody = false; return(HttpMethod.Head);
     }
     else if (HttpMethods.IsOptions(method))
     {
         hasBody = null; return(HttpMethod.Options);
     }
     else if (HttpMethods.IsPost(method))
     {
         hasBody = true; return(HttpMethod.Post);
     }
     else if (HttpMethods.IsPut(method))
     {
         hasBody = true; return(HttpMethod.Put);
     }
     else if (HttpMethods.IsPatch(method))
     {
         hasBody = true; return(HttpMethod.Patch);
     }
     else if (HttpMethods.IsTrace(method))
     {
         hasBody = null; return(HttpMethod.Trace);
     }
     hasBody = null;
     return(new HttpMethod(method));
 }
        private string SelectActionImpl(RouteContext routeContext, SelectControllerResult controllerResult, IEnumerable <ControllerActionDescriptor> actionDescriptors)
        {
            Microsoft.AspNet.OData.Routing.ODataPath odataPath = routeContext.HttpContext.ODataFeature().Path;
            HttpRequest request = routeContext.HttpContext.Request;

            if (odataPath.PathTemplate.EndsWith("$ref"))
            {
                if (HttpMethods.IsDelete(request.Method))
                {
                    return(actionDescriptors.FindMatchingAction("DeleteRef"));
                }
                else if (HttpMethods.IsPost("$ref") || HttpMethods.IsPut("$ref"))
                {
                    return(actionDescriptors.FindMatchingAction("CreateRef"));
                }
            }
            else if (odataPath.PathTemplate.EndsWith("$count"))
            {
                // $count is only supported for GET requests
                if (HttpMethods.IsGet(request.Method))
                {
                    return(actionDescriptors.FindMatchingAction("Get"));
                }
            }
            else if (HttpMethods.IsGet(request.Method))
            {
                // A single Get method will handle all Get requests.
                // It should contain the logic for traversing potenially nested path
                // and extract the relevant keys and navigation properties
                return(actionDescriptors.FindMatchingAction("Get"));
            }
            // TODO: we currently do not support nested paths for Create/Update/Delete requests
            // TODO: verify whether we support casts
            else if (HttpMethods.IsPost(request.Method))
            {
                if (odataPath.PathTemplate == "~/entityset" ||
                    odataPath.PathTemplate == "~/entityset/cast")
                {
                    return(actionDescriptors.FindMatchingAction("Post"));
                }
            }
            else if (odataPath.PathTemplate == "~/entityset/key" ||
                     odataPath.PathTemplate == "~/entityset/key/cast" ||
                     odataPath.PathTemplate == "~/singleton" ||
                     odataPath.PathTemplate == "~/singleton/cast")
            {
                if (HttpMethods.IsPut(request.Method))
                {
                    return(actionDescriptors.FindMatchingAction("Put"));
                }
                else if (HttpMethods.IsPatch(request.Method))
                {
                    // TODO: we should filter support for navigation properties / nested paths
                    return(actionDescriptors.FindMatchingAction("Patch"));
                }
                else if (HttpMethods.IsDelete(request.Method))
                {
                    // TODO: we should filter support for navigation properties / nested paths
                    return(actionDescriptors.FindMatchingAction("Delete"));
                }
            }

            return(null);
        }
        private string SelectActionImpl(RouteContext routeContext, SelectControllerResult controllerResult, IEnumerable <ControllerActionDescriptor> actionDescriptors)
        {
            Microsoft.AspNet.OData.Routing.ODataPath odataPath = routeContext.HttpContext.ODataFeature().Path;
            HttpRequest request = routeContext.HttpContext.Request;

            if (odataPath.PathTemplate == "~/entityset")
            {
                EntitySetSegment  entitySetSegment = (EntitySetSegment)odataPath.Segments[0];
                IEdmEntitySetBase entitySet        = entitySetSegment.EntitySet;

                if (HttpMethods.IsGet(request.Method))
                {
                    // e.g. Try GetCustomers first, then fall back to Get action name
                    return(actionDescriptors.FindMatchingAction(
                               "Get" + entitySet.Name,
                               "Get"));
                }
                else if (HttpMethods.IsPost(request.Method))
                {
                    // e.g. Try PostCustomer first, then fall back to Post action name
                    return(actionDescriptors.FindMatchingAction(
                               "Post" + entitySet.EntityType().Name,
                               "Post"));
                }
            }
            else if (odataPath.PathTemplate == "~/entityset/key" ||
                     odataPath.PathTemplate == "~/entityset/key/cast")
            {
                string httpMethodName;

                if (HttpMethods.IsGet(request.Method))
                {
                    httpMethodName = "Get";
                }
                else if (HttpMethods.IsPut(request.Method))
                {
                    httpMethodName = "Put";
                }
                else if (HttpMethods.IsPatch(request.Method))
                {
                    httpMethodName = "Patch";
                }
                else if (HttpMethods.IsDelete(request.Method))
                {
                    httpMethodName = "Delete";
                }
                else
                {
                    return(null);
                }

                Contract.Assert(httpMethodName != null);

                IEdmEntityType entityType = (IEdmEntityType)odataPath.EdmType;

                // e.g. Try GetCustomer first, then fallback on Get action name
                string actionName = actionDescriptors.FindMatchingAction(
                    httpMethodName + entityType.Name,
                    httpMethodName);

                if (actionName != null)
                {
                    KeySegment keySegment = (KeySegment)odataPath.Segments[1];
                    // TODO: Add key/value to RouteData
                    return(actionName);
                }
            }
            else if (odataPath.PathTemplate == "~/entityset/$count" &&
                     HttpMethods.IsGet(request.Method))
            {
                EntitySetSegment  entitySetSegment = (EntitySetSegment)odataPath.Segments[0];
                IEdmEntitySetBase entitySet        = entitySetSegment.EntitySet;

                // e.g. Try GetCustomers first, then fall back to Get action name
                return(actionDescriptors.FindMatchingAction(
                           "Get" + entitySet.Name,
                           "Get"));
            }
            else if (odataPath.PathTemplate == "~/entityset/cast")
            {
                EntitySetSegment   entitySetSegment = (EntitySetSegment)odataPath.Segments[0];
                IEdmEntitySetBase  entitySet        = entitySetSegment.EntitySet;
                IEdmCollectionType collectionType   = (IEdmCollectionType)odataPath.EdmType;
                IEdmEntityType     entityType       = (IEdmEntityType)collectionType.ElementType.Definition;

                if (HttpMethods.IsGet(request.Method))
                {
                    // e.g. Try GetCustomersFromSpecialCustomer first, then fall back to GetFromSpecialCustomer
                    return(actionDescriptors.FindMatchingAction(
                               "Get" + entitySet.Name + "From" + entityType.Name,
                               "GetFrom" + entityType.Name));
                }
                else if (HttpMethods.IsPost(request.Method))
                {
                    // e.g. Try PostCustomerFromSpecialCustomer first, then fall back to PostFromSpecialCustomer
                    return(actionDescriptors.FindMatchingAction(
                               "Post" + entitySet.EntityType().Name + "From" + entityType.Name,
                               "PostFrom" + entityType.Name));
                }
            }
            else if (odataPath.PathTemplate == "~/entityset/cast/$count" &&
                     HttpMethods.IsGet(request.Method))
            {
                EntitySetSegment   entitySetSegment = (EntitySetSegment)odataPath.Segments[0];
                IEdmEntitySetBase  entitySet        = entitySetSegment.EntitySet;
                IEdmCollectionType collectionType   = (IEdmCollectionType)odataPath.Segments[1].EdmType;
                IEdmEntityType     entityType       = (IEdmEntityType)collectionType.ElementType.Definition;

                // e.g. Try GetCustomersFromSpecialCustomer first, then fall back to GetFromSpecialCustomer
                return(actionDescriptors.FindMatchingAction(
                           "Get" + entitySet.Name + "From" + entityType.Name,
                           "GetFrom" + entityType.Name));
            }

            return(null);
        }
Exemplo n.º 18
0
 private static bool MethodHasBody(string method)
 => HttpMethods.IsPost(method) ||
 HttpMethods.IsPut(method) ||
 HttpMethods.IsPatch(method);
Exemplo n.º 19
0
        protected override async Task <bool> ProcessInternal(HttpContext context, CancellationToken ct)
        {
            var request = context.Request;

            PathString partialPath;

            if (!request.Path.StartsWithSegments(_options.Value.MountPoint, out partialPath))
            {
                return(false);
            }

            var pathSegments = partialPath.Value?.Split('/').Where(x => !x.Trim().IsNullOrEmpty()).ToArray();

            if (pathSegments == null || pathSegments.Length < 2)
            {
                return(false);
            }

            var model = await MetaService.GetModel(pathSegments[0], ct);

            pathSegments = pathSegments.Skip(1).ToArray();

            var headers            = context.Request.GetTypedHeaders();
            var requestSerializer  = _serializerFactory.GetByMediaType(headers.ContentType?.MediaType);
            var responseSerializer = headers.Accept.IsNullOrEmpty()
                                ? requestSerializer
                                : _serializerFactory.GetByMediaType(headers.Accept.Safe().Select(x => x.MediaType));
            var processParams = new RestProcessParameters(context, headers, pathSegments, model, requestSerializer,
                                                          responseSerializer);

            if (HttpMethods.IsGet(request.Method))
            {
                await ProcessQuery(processParams, ct);

                return(true);
            }

            if (HttpMethods.IsPost(request.Method))
            {
                await ProcessPostCommand(processParams, ct);

                return(true);
            }

            if (HttpMethods.IsPut(request.Method))
            {
                await ProcessPutCommand(processParams, ct);

                return(true);
            }

            if (HttpMethods.IsPatch(request.Method))
            {
                await ProcessPatchCommand(processParams, ct);

                return(true);
            }

            if (HttpMethods.IsDelete(request.Method))
            {
                await ProcessDeleteCommand(processParams, ct);

                return(true);
            }

            throw new NotSupportedException();
        }
Exemplo n.º 20
0
        /// <summary>
        /// Excludes a mapped path, optionally based on the given HTTP method. If HTTP method is not specified, every request to this path will not be used by <see cref="HttpSignatureMiddleware"/>.
        /// </summary>
        /// <param name="pathString">The path to exclude.</param>
        /// <param name="httpMethods">The HTTP methods to exclude for the given path.</param>
        public HttpSignatureOptions IgnorePath(PathString pathString, params string[] httpMethods)
        {
            if (pathString == null)
            {
                throw new ArgumentNullException(nameof(pathString), "Cannot ignore a null path.");
            }
            var path = pathString.Value.EnsureLeadingSlash().ToTemplatedDynamicPath();

            // No HTTP methods specified, so exclude just the path (implies that all HTTP methods will be excluded for this path).
            if (httpMethods?.Length == 0)
            {
                IgnoredPaths.Add(path, "*");
                return(this);
            }
            // Validate HTTP method.
            // There are more of course, but this seems enough for our needs.
            foreach (var method in httpMethods)
            {
                var isValidHttpMethod = HttpMethods.IsGet(method) || HttpMethods.IsPost(method) || HttpMethods.IsPut(method) || HttpMethods.IsDelete(method) || HttpMethods.IsPatch(method);
                if (!isValidHttpMethod)
                {
                    throw new ArgumentException($"HTTP method {method} is not valid.");
                }
            }
            if (!IgnoredPaths.ContainsKey(path))
            {
                IgnoredPaths.Add(path, string.Join('|', httpMethods));
            }
            else
            {
                var methods = IgnoredPaths[path].Split('|').Union(httpMethods);
                IgnoredPaths[path] = string.Join('|', methods);
            }
            return(this);
        }
Exemplo n.º 21
0
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IAntiforgery antiforgery)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseMiddleware <StrictSameSiteMiddleware>();
            app.UseAuthentication();
            app.UseResponseCompression();

            app.Use(async(context, next) =>
            {
                if (!context.User.Identity.IsAuthenticated)
                {
                    await context.ChallengeAsync();
                    return;
                }

                await next();
            });

            app.Use(async(context, next) =>
            {
                if (HttpMethods.IsPost(context.Request.Method) ||
                    HttpMethods.IsPatch(context.Request.Method) ||
                    HttpMethods.IsPut(context.Request.Method) ||
                    HttpMethods.IsDelete(context.Request.Method))
                {
                    await antiforgery.ValidateRequestAsync(context);
                }

                await next();
            });

            app.Use(next => context =>
            {
                string path = context.Request.Path.Value;

                if (
                    string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) ||
                    string.Equals(path, "/index.html", StringComparison.OrdinalIgnoreCase))
                {
                    var tokens = antiforgery.GetAndStoreTokens(context);
                    context.Response.Headers.Append("X-XSRF-TOKEN", tokens.RequestToken);
                }

                return(next(context));
            });

            app.Map("/api", api =>
            {
                api.RunProxy(async context =>
                {
                    var forwardContext = context.ForwardTo(Env.GetString("API_HTTPS_URL"));

                    try
                    {
                        var token = await context.GetUserAccessTokenAsync();
                        forwardContext.UpstreamRequest.SetBearerToken(token);

                        return(await forwardContext.Send());
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                });
            });

            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapDefaultControllerRoute().RequireAuthorization();
            });

            app.UseSpaStaticFiles();
            app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "Resources";

                if (env.IsDevelopment())
                {
                    spa.UseVueDevelopmentServer(Env.GetString("APP_VUE_DEVELOPMENT_SERVER_URL"));
                }
            });
        }
Exemplo n.º 22
0
        public static async Task <JsonApiRequest> FromHttpRequestAsync(HttpRequest request)
        {
            var body = await new StreamReader(request.Body).ReadToEndAsync();

            return(new JsonApiRequest(GetUserName(), GetAction(), body, ParseDictionary(request.Headers), ParseDictionary(request.Query)));

            RequestAction GetAction() =>
            (HttpMethods.IsGet(request.Method)) ? RequestAction.Get :
            (HttpMethods.IsPost(request.Method) || HttpMethods.IsPut(request.Method) || HttpMethods.IsPatch(request.Method)) ? RequestAction.Save :
            (HttpMethods.IsDelete(request.Method)) ? RequestAction.Delete :
            throw new Exception($"Unsupported method: {request.Method}");

            string GetUserName()
            {
                try
                {
                    return(request.HttpContext.User.Identity.Name);
                }
                catch
                {
                    return(null);
                }
            }

            Dictionary <string, StringValues> ParseDictionary(IEnumerable <KeyValuePair <string, StringValues> > collection) =>
            collection
            .GroupBy(item => item.Key)
            .ToDictionary(
                grp => grp.Key,
                grp => new StringValues(grp.SelectMany(item => item.Value).ToArray()));
        }
Exemplo n.º 23
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="request"></param>
        /// <returns>Cache Validation Status</returns>
        public static CacheValidationStatus GetCacheValidationStatus(this HttpRequest request)
        {
            var typedHeaders = request.GetTypedHeadersWithCaching();

            if (HttpMethods.IsGet(request.Method))
            {
                if (typedHeaders.IfModifiedSince.HasValue)
                {
                    return(CacheValidationStatus.GetIfModifiedSince);
                }
                if (typedHeaders.IfNoneMatch != null && typedHeaders.IfNoneMatch.Count > 0)
                {
                    return(CacheValidationStatus.GetIfNoneMatch);
                }
            }

            if (HttpMethods.IsPut(request.Method) || HttpMethods.IsDelete(request.Method) || HttpMethods.IsPatch(request.Method))
            {
                if (typedHeaders.IfUnmodifiedSince.HasValue)
                {
                    return(CacheValidationStatus.PutPatchDeleteIfUnModifiedSince);
                }
                if (typedHeaders.IfMatch != null && typedHeaders.IfMatch.Count > 0)
                {
                    return(CacheValidationStatus.PutPatchDeleteIfMatch);
                }
            }

            return(CacheValidationStatus.None);
        }
Exemplo n.º 24
0
        /// <summary>
        /// Takes a snapshot of the current request body.
        /// </summary>
        /// <returns></returns>
        internal async Task SnapRequestBody()
        {
            var method = HttpContext.Request.Method;

            HttpContext.Request.EnableBuffering();
            // Only if we are dealing with POST or PUT, GET and others shouldn't have a body.
            if (HttpContext.Request.Body.CanRead && (HttpMethods.IsPost(method) || HttpMethods.IsPut(method) || HttpMethods.IsPatch(method)))
            {
                // Leave stream open so next middleware can read it.
                using var reader = new StreamReader(HttpContext.Request.Body, Encoding.UTF8, detectEncodingFromByteOrderMarks: false, bufferSize: 512, leaveOpen: true);
                RequestBody      = await reader.ReadToEndAsync();

                // Reset stream position, so next middleware can read it.
                HttpContext.Request.Body.Seek(0, SeekOrigin.Begin);
            }
        }