CGC_Codes

Request Handler

May 28th, 2018
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.92 KB | None | 0 0
  1. using System;
  2. using System.Diagnostics;
  3. using System.Net;
  4. using System.Web;
  5. using BVNetwork.NotFound.Core.Configuration;
  6. using BVNetwork.NotFound.Core.CustomRedirects;
  7. using BVNetwork.NotFound.Core.Data;
  8. using BVNetwork.NotFound.Core.Logging;
  9. using BVNetwork.NotFound.Core.Web;
  10. using EPiServer.Logging;
  11.  
  12. namespace BVNetwork.NotFound.Core
  13. {
  14.     public class RequestHandler
  15.     {
  16.         private readonly IRedirectHandler _redirectHandler;
  17.         private readonly IRequestLogger _requestLogger;
  18.         private readonly IConfiguration _configuration;
  19.         private const string HandledRequestItemKey = "404handler:handled";
  20.  
  21.         private static readonly ILogger Logger = LogManager.GetLogger();
  22.  
  23.         public RequestHandler(
  24.             IRedirectHandler redirectHandler,
  25.             IRequestLogger requestLogger,
  26.             IConfiguration configuration)
  27.         {
  28.             _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
  29.             _requestLogger = requestLogger ?? throw new ArgumentNullException(nameof(requestLogger));
  30.             _redirectHandler = redirectHandler ?? throw new ArgumentNullException(nameof(redirectHandler));
  31.         }
  32.  
  33.         public virtual void Handle(HttpContextBase context)
  34.         {
  35.             if (context == null) return;
  36.  
  37.             if (IsHandled(context))
  38.             {
  39.                 LogDebug("Already handled.", context);
  40.                 return;
  41.             }
  42.  
  43.             if (context.Response.StatusCode != 404)
  44.             {
  45.                 LogDebug("Not a 404 response.", context);
  46.                 return;
  47.             }
  48.  
  49.            
  50.             if (_configuration.FileNotFoundHandlerMode == FileNotFoundMode.RemoteOnly)
  51.             {
  52.                
  53.                 var localHost = IsLocalhost(context);
  54.                 if (localHost)
  55.                 {
  56.                     LogDebug("Determined to be localhost, returning.", context);
  57.                     return;
  58.                 }
  59.                 LogDebug("Not a localhost, handling error.", context);
  60.             }
  61.  
  62.             LogDebug("Handling 404 request.", context);
  63.  
  64.             var notFoundUri = context.Request.Url;
  65.  
  66.             if (IsResourceFile(notFoundUri))
  67.             {
  68.                 LogDebug("Skipping resource file.", context);
  69.                 return;
  70.             }
  71.  
  72.             var query = context.Request.ServerVariables["QUERY_STRING"];
  73.  
  74.            
  75.             if (query != null && query.StartsWith("404;"))
  76.             {
  77.                 LogDebug("Skipping request with 404; in the query string.", context);
  78.                 return;
  79.             }
  80.  
  81.             var canHandleRedirect = HandleRequest(context.Request.UrlReferrer, notFoundUri, out var newUrl);
  82.             if (canHandleRedirect && newUrl.State == (int)DataStoreHandler.State.Saved)
  83.             {
  84.                 LogDebug("Handled saved URL", context);
  85.  
  86.                 context
  87.                     .ClearServerError()
  88.                     .RedirectPermanent(newUrl.NewUrl);
  89.             }
  90.             else if (canHandleRedirect && newUrl.State == (int)DataStoreHandler.State.Deleted)
  91.             {
  92.                 LogDebug("Handled deleted URL", context);
  93.  
  94.                 SetStatusCodeAndShow404(context, 410);
  95.             }
  96.             else
  97.             {
  98.                 LogDebug("Not handled. Current URL is ignored or no redirect found.", context);
  99.  
  100.                 SetStatusCodeAndShow404(context);
  101.             }
  102.  
  103.             MarkHandled(context);
  104.         }
  105.  
  106.         private bool IsHandled(HttpContextBase context)
  107.         {
  108.             return context.Items.Contains(HandledRequestItemKey)
  109.                 && (bool)context.Items[HandledRequestItemKey];
  110.         }
  111.  
  112.         private void MarkHandled(HttpContextBase context)
  113.         {
  114.             context.Items[HandledRequestItemKey] = true;
  115.         }
  116.  
  117.         public virtual bool HandleRequest(Uri referrer, Uri urlNotFound, out CustomRedirect foundRedirect)
  118.         {
  119.             var redirect = _redirectHandler.Find(urlNotFound);
  120.  
  121.             foundRedirect = null;
  122.             var pathAndQuery = urlNotFound.PathAndQuery;
  123.  
  124.             if (redirect != null)
  125.             {
  126.                
  127.                 if (redirect.State.Equals((int)DataStoreHandler.State.Deleted))
  128.                 {
  129.                     foundRedirect = redirect;
  130.                     return true;
  131.                 }
  132.  
  133.                 if (redirect.State.Equals((int)DataStoreHandler.State.Saved))
  134.                 {
  135.  
  136.                     if (string.Compare(redirect.NewUrl, pathAndQuery, StringComparison.InvariantCultureIgnoreCase) != 0)
  137.                     {
  138.  
  139.                         foundRedirect = redirect;
  140.                         return true;
  141.                     }
  142.                 }
  143.             }
  144.             else
  145.             {
  146.                
  147.                 if (_configuration.Logging == LoggerMode.On)
  148.                 {
  149.                    
  150.                     _requestLogger.LogRequest(pathAndQuery, referrer?.ToString());
  151.                 }
  152.             }
  153.             return false;
  154.         }
  155.  
  156.         public virtual void SetStatusCodeAndShow404(HttpContextBase context, int statusCode = 404)
  157.         {
  158.             context
  159.                 .ClearServerError()
  160.                 .SetStatusCode(statusCode);
  161.         }
  162.  
  163.  
  164.         public virtual bool IsResourceFile(Uri notFoundUri)
  165.         {
  166.             var extension = notFoundUri.AbsolutePath;
  167.             var extPos = extension.LastIndexOf('.');
  168.  
  169.             if (extPos <= 0) return false;
  170.  
  171.             extension = extension.Substring(extPos + 1);
  172.             if (_configuration.IgnoredResourceExtensions.Contains(extension))
  173.             {
  174.                
  175.                 Logger.Debug("Ignoring rewrite of '{0}'. '{1}' is a known resource extension", notFoundUri.ToString(), extension);
  176.                 return true;
  177.             }
  178.             return false;
  179.         }
  180.  
  181.         public virtual bool IsLocalhost(HttpContextBase context)
  182.         {
  183.             try
  184.             {
  185.                 var hostAddress = context.Request.UserHostAddress ?? string.Empty;
  186.                 var address = IPAddress.Parse(hostAddress);
  187.                 Debug.WriteLine("IP Address of user: " + address, "404Handler");
  188.  
  189.                 var host = Dns.GetHostEntry(Dns.GetHostName());
  190.                 Debug.WriteLine("Host Entry of local computer: " + host.HostName, "404Handler");
  191.                 return address.Equals(IPAddress.Loopback) || Array.IndexOf(host.AddressList, address) >= 0;
  192.             }
  193.             catch
  194.             {
  195.                 return false;
  196.             }
  197.         }
  198.  
  199.         private void LogDebug(string message, HttpContextBase context)
  200.         {
  201.             Logger.Debug(
  202.                 $"{{0}}{Environment.NewLine}Request URL: {{1}}{Environment.NewLine}Response status code: {{2}}",
  203.                 message, context?.Request.Url, context?.Response.StatusCode);
  204.         }
  205.     }
  206. }
Advertisement
Add Comment
Please, Sign In to add comment