Advertisement
Guest User

OptionsHandler

a guest
Nov 15th, 2017
427
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.94 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Net.Http;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8. using System.Web.Http.Controllers;
  9. using System.Web.Http.Dispatcher;
  10.  
  11. namespace Handlers
  12. {
  13.     public class OptionsHandler : DelegatingHandler
  14.     {
  15.         protected override async Task<HttpResponseMessage> SendAsync(
  16.             HttpRequestMessage request, CancellationToken cancellationToken)
  17.         {
  18.             return await base.SendAsync(request, cancellationToken).ContinueWith(
  19.                 task =>
  20.                 {
  21.                     var response = task.Result;
  22.                     switch (GetResponseAction(request, response))
  23.                     {
  24.                         case ResponseAction.UseOriginal:
  25.                             return response;
  26.                         case ResponseAction.ReturnUnauthorized:
  27.                             return new HttpResponseMessage(HttpStatusCode.Unauthorized);
  28.                         case ResponseAction.RetrieveMethods:
  29.                             var methods = new ActionSelector(request).GetSupportedMethods();
  30.                             if (methods == null)
  31.                                 return response;
  32.  
  33.                             response = new HttpResponseMessage(HttpStatusCode.OK)
  34.                             {
  35.                                 Content = new StringContent(string.Empty)
  36.                             };
  37.  
  38.                             response.Content.Headers.Add("Allow", methods);
  39.                             response.Content.Headers.Add("Allow", "OPTIONS");
  40.                             return response;
  41.                         default:
  42.                             throw new InvalidOperationException(
  43.                                 "Unsupported response action code");
  44.                     }
  45.                 }, cancellationToken);
  46.         }
  47.  
  48.         private enum ResponseAction
  49.         {
  50.             UseOriginal,
  51.             RetrieveMethods,
  52.             ReturnUnauthorized
  53.         }
  54.  
  55.         private static ResponseAction GetResponseAction(
  56.             HttpRequestMessage request, HttpResponseMessage response)
  57.         {
  58.             if (request.Method != HttpMethod.Options)
  59.                 return ResponseAction.UseOriginal;
  60.  
  61.             if (response.StatusCode != HttpStatusCode.MethodNotAllowed)
  62.                 return ResponseAction.UseOriginal;
  63.  
  64.             return IsAuthenticated()
  65.                 ? ResponseAction.RetrieveMethods
  66.                 : ResponseAction.ReturnUnauthorized;
  67.         }
  68.  
  69.         private static bool IsAuthenticated()
  70.         {
  71.             // TODO: Check here whether current user is authenticated
  72.             //return Thread.CurrentPrincipal.Identity is MyIdentity;
  73.             return true;
  74.         }
  75.  
  76.         private class ActionSelector
  77.         {
  78.             private readonly HttpRequestMessage _request;
  79.             private readonly HttpControllerContext _context;
  80.             private readonly ApiControllerActionSelector _apiSelector;
  81.             private static readonly string[] Methods =
  82.                 { "GET", "PUT", "POST", "PATCH", "DELETE", "HEAD", "TRACE" };
  83.  
  84.             public ActionSelector(HttpRequestMessage request)
  85.             {
  86.                 try
  87.                 {
  88.                     var configuration = request.GetConfiguration();
  89.                     var requestContext = request.GetRequestContext();
  90.  
  91.                     var controllerDescriptor =
  92.                         new DefaultHttpControllerSelector(configuration)
  93.                             .SelectController(request);
  94.  
  95.                     _context = new HttpControllerContext
  96.                     {
  97.                         Request = request,
  98.                         RequestContext = requestContext,
  99.                         Configuration = configuration,
  100.                         ControllerDescriptor = controllerDescriptor
  101.                     };
  102.                 }
  103.                 catch
  104.                 {
  105.                     return;
  106.                 }
  107.  
  108.                 _request = _context.Request;
  109.                 _apiSelector = new ApiControllerActionSelector();
  110.             }
  111.  
  112.             public IEnumerable<string> GetSupportedMethods()
  113.             {
  114.                 return _request == null ? null : Methods.Where(IsMethodSupported);
  115.             }
  116.  
  117.             private bool IsMethodSupported(string method)
  118.             {
  119.                 _context.Request = new HttpRequestMessage(
  120.                     new HttpMethod(method), _request.RequestUri);
  121.                 var routeData = _context.RouteData;
  122.  
  123.                 try
  124.                 {
  125.                     return _apiSelector.SelectAction(_context) != null;
  126.                 }
  127.                 catch
  128.                 {
  129.                     return false;
  130.                 }
  131.                 finally
  132.                 {
  133.                     _context.RouteData = routeData;
  134.                 }
  135.             }
  136.         }
  137.     }
  138. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement