Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Net;
- using System.Net.Http;
- using System.Threading;
- using System.Threading.Tasks;
- using System.Web.Http.Controllers;
- using System.Web.Http.Dispatcher;
- namespace Handlers
- {
- public class OptionsHandler : DelegatingHandler
- {
- protected override async Task<HttpResponseMessage> SendAsync(
- HttpRequestMessage request, CancellationToken cancellationToken)
- {
- return await base.SendAsync(request, cancellationToken).ContinueWith(
- task =>
- {
- var response = task.Result;
- switch (GetResponseAction(request, response))
- {
- case ResponseAction.UseOriginal:
- return response;
- case ResponseAction.ReturnUnauthorized:
- return new HttpResponseMessage(HttpStatusCode.Unauthorized);
- case ResponseAction.RetrieveMethods:
- var methods = new ActionSelector(request).GetSupportedMethods();
- if (methods == null)
- return response;
- response = new HttpResponseMessage(HttpStatusCode.OK)
- {
- Content = new StringContent(string.Empty)
- };
- response.Content.Headers.Add("Allow", methods);
- response.Content.Headers.Add("Allow", "OPTIONS");
- return response;
- default:
- throw new InvalidOperationException(
- "Unsupported response action code");
- }
- }, cancellationToken);
- }
- private enum ResponseAction
- {
- UseOriginal,
- RetrieveMethods,
- ReturnUnauthorized
- }
- private static ResponseAction GetResponseAction(
- HttpRequestMessage request, HttpResponseMessage response)
- {
- if (request.Method != HttpMethod.Options)
- return ResponseAction.UseOriginal;
- if (response.StatusCode != HttpStatusCode.MethodNotAllowed)
- return ResponseAction.UseOriginal;
- return IsAuthenticated()
- ? ResponseAction.RetrieveMethods
- : ResponseAction.ReturnUnauthorized;
- }
- private static bool IsAuthenticated()
- {
- // TODO: Check here whether current user is authenticated
- //return Thread.CurrentPrincipal.Identity is MyIdentity;
- return true;
- }
- private class ActionSelector
- {
- private readonly HttpRequestMessage _request;
- private readonly HttpControllerContext _context;
- private readonly ApiControllerActionSelector _apiSelector;
- private static readonly string[] Methods =
- { "GET", "PUT", "POST", "PATCH", "DELETE", "HEAD", "TRACE" };
- public ActionSelector(HttpRequestMessage request)
- {
- try
- {
- var configuration = request.GetConfiguration();
- var requestContext = request.GetRequestContext();
- var controllerDescriptor =
- new DefaultHttpControllerSelector(configuration)
- .SelectController(request);
- _context = new HttpControllerContext
- {
- Request = request,
- RequestContext = requestContext,
- Configuration = configuration,
- ControllerDescriptor = controllerDescriptor
- };
- }
- catch
- {
- return;
- }
- _request = _context.Request;
- _apiSelector = new ApiControllerActionSelector();
- }
- public IEnumerable<string> GetSupportedMethods()
- {
- return _request == null ? null : Methods.Where(IsMethodSupported);
- }
- private bool IsMethodSupported(string method)
- {
- _context.Request = new HttpRequestMessage(
- new HttpMethod(method), _request.RequestUri);
- var routeData = _context.RouteData;
- try
- {
- return _apiSelector.SelectAction(_context) != null;
- }
- catch
- {
- return false;
- }
- finally
- {
- _context.RouteData = routeData;
- }
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement