Guest User

Untitled

a guest
May 8th, 2013
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.53 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.Specialized;
  4. using System.Configuration;
  5. using System.Linq;
  6. using System.Text.RegularExpressions;
  7. using System.Web;
  8. using umbraco.BusinessLogic;
  9. using umbraco.cms.businesslogic.web;
  10. using umbraco.DataLayer;
  11. using umbraco.interfaces;
  12. using umbraco.NodeFactory;
  13.  
  14. namespace InfoCaster.Umbraco._301UrlTracker
  15. {
  16.     public class Handler301URLTracker : INotFoundHandler
  17.     {
  18.         #region Members
  19.         ISqlHelper _sqlHelper { get { return Application.SqlHelper; } }
  20.         int _redirectID = -1;
  21.         #endregion
  22.  
  23.         #region INotFoundHandler Members
  24.  
  25.         #region Properties
  26.         public bool CacheUrl { get { return false; } }
  27.         public int redirectID { get { return _redirectID; } }
  28.         #endregion
  29.  
  30.         public bool Execute(string url)
  31.         {
  32.             bool disabled = false;            
  33.  
  34.             if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["infocasterDisable301URLTracker"]))
  35.             {
  36.                 bool config;
  37.                 if (bool.TryParse(ConfigurationManager.AppSettings["infocasterDisable301URLTracker"], out config))
  38.                     disabled = config;
  39.             }
  40.             if (!disabled)
  41.             {
  42.                 if (!url.StartsWith("/"))
  43.                     url = string.Concat("/", url);
  44.  
  45.                 bool queryStringExists = HttpContext.Current.Request.QueryString.HasKeys();
  46.  
  47.                 bool ignoreDomain = false;
  48.                 string ignoreDomainString = ConfigurationManager.AppSettings["301:ignoreDomain"];
  49.                 if (!string.IsNullOrEmpty(ignoreDomainString) && ignoreDomainString.ToLower() == "true")
  50.                     ignoreDomain = true;
  51.                 bool disableQueryStringPassThrough = false;
  52.                 string disableQueryStringPassThroughString = ConfigurationManager.AppSettings["301:disableQueryStringPassThrough"];
  53.                 if (!string.IsNullOrEmpty(disableQueryStringPassThroughString) && disableQueryStringPassThroughString.ToLower() == "true")
  54.                     disableQueryStringPassThrough = true;
  55.                 int root = Domain.GetRootFromDomain(HttpContext.Current.Request.Url.DnsSafeHost);
  56.  
  57.                 if (queryStringExists)
  58.                 {
  59.                     // Url matching with querystring
  60.                     if (MatchUrl(url, root, HttpContext.Current.Request.QueryString, ignoreDomain, disableQueryStringPassThrough: true))
  61.                         return true;
  62.                 }
  63.                 // Url matching without querystring
  64.                 if (MatchUrl(url, root, ignoreDomain: ignoreDomain, disableQueryStringPassThrough: disableQueryStringPassThrough))
  65.                     return true;
  66.  
  67.                 if (queryStringExists)
  68.                 {
  69.                     // Regex matching with querystring
  70.                     if (MatchRegex(HttpContext.Current.Request.RawUrl, root, ignoreDomain, disableQueryStringPassThrough: true))
  71.                         return true;
  72.                 }
  73.                 // Regex matching without querystring
  74.                 if (MatchRegex(url, root, ignoreDomain, disableQueryStringPassThrough))
  75.                     return true;
  76.             }
  77.             return false;
  78.         }
  79.  
  80.         bool MatchUrl(string url, int root, NameValueCollection querystring = null, bool ignoreDomain = false, bool disableQueryStringPassThrough = false)
  81.         {
  82.             // Url matching
  83.             int redirectId;
  84.             string urlWithTrailingSlash = url.EndsWith("/") ? string.Empty : string.Concat(url, "/");
  85.             string urlWithDomain = url.StartsWith("http") ? string.Empty : string.Concat(HttpContext.Current.Request.Url.Scheme, "://", HttpContext.Current.Request.Url.Host, url);
  86.             string urlWithDomainWithTrailingSlash = url.EndsWith("/") ? string.Empty : string.Concat(HttpContext.Current.Request.Url.Scheme, "://", HttpContext.Current.Request.Url.Host, url, "/");
  87.             string query = "SELECT NodeId, Message FROM infocaster301 WHERE (OldUrl = @url OR OldUrl = @urlWithDomain OR OldUrl = @urlWithTrailingSlash OR OldUrl = @urlWithDomainWithTrailingSlash) AND IsRegex = 0";
  88.             if (querystring != null)
  89.                 query = "SELECT NodeId, OldUrl, Message FROM infocaster301 WHERE (OldUrl LIKE @url + '%' OR OldUrl LIKE @urlWithDomain + '%') AND IsRegex = 0";
  90.             using (IRecordsReader reader = _sqlHelper.ExecuteReader(query, _sqlHelper.CreateParameter("url", url), _sqlHelper.CreateParameter("urlWithDomain", urlWithDomain), _sqlHelper.CreateParameter("urlWithTrailingSlash", urlWithTrailingSlash), _sqlHelper.CreateParameter("urlWithDomainWithTrailingSlash", urlWithDomainWithTrailingSlash)))
  91.             {
  92.                 while (reader.Read())
  93.                 {
  94.                     if (!reader.IsNull("NodeId"))
  95.                     {
  96.                         redirectId = reader.GetInt("NodeId");
  97.                         string message = reader.IsNull("Message") ? string.Empty : reader.GetString("Message");
  98.                         if (message == "--- Node removed ---")
  99.                         {
  100.                             HttpContext.Current.Response.Status = "410 Gone";
  101.                             HttpContext.Current.Response.End();
  102.                             return true;
  103.                         }
  104.                         else
  105.                         {
  106.                             Node n = new Node(redirectId);
  107.                             if (n != null && n.Name != null && n.Id > 0)
  108.                             {
  109.                                 Node rootNode = n.FindRoot();
  110.                                 if (rootNode.Id == root || root == -1 || ignoreDomain)
  111.                                 {
  112.                                     bool okay = true;
  113.                                     if (querystring != null)
  114.                                     {
  115.                                         string oldUrl = reader.GetString("OldUrl");
  116.                                         foreach (string key in querystring)
  117.                                         {
  118.                                             if (!oldUrl.Contains(string.Format("{0}={1}", key, querystring[key])))
  119.                                                 okay = false;
  120.                                         }
  121.                                     }
  122.                                     if (okay)
  123.                                     {
  124.  
  125.                                         // if querystring param = null - we're not matching on query string
  126.                                         // then check is query should be passed through
  127.  
  128.                                         string redirectUrl = n.NiceUrl;
  129.                                         if (!disableQueryStringPassThrough)
  130.                                         {
  131.                                             redirectUrl += HttpContext.Current.Request.Url.Query;
  132.                                         }                                        
  133.  
  134.                                         _redirectID = redirectId;
  135.                                         HttpContext.Current.Response.Clear();
  136.                                         HttpContext.Current.Response.Status = "301 Moved Permanently";
  137.                                         HttpContext.Current.Response.AddHeader("Location", redirectUrl);
  138.                                         HttpContext.Current.Response.End();
  139.                                         return true;
  140.                                     }
  141.                                 }
  142.                             }
  143.                         }
  144.                     }
  145.                 }
  146.             }
  147.             return false;
  148.         }
  149.  
  150.         bool MatchRegex(string url, int root, bool ignoreDomain = false, bool disableQueryStringPassThrough = false)
  151.         {
  152.             // Regex matching
  153.             int redirectId;
  154.             string query = "SELECT NodeId, OldUrl FROM infocaster301 WHERE IsRegex = 1 ORDER BY Inserted ASC";
  155.             using (IRecordsReader reader = _sqlHelper.ExecuteReader(query))
  156.             {
  157.                 Regex regex;
  158.                 while (reader.Read())
  159.                 {
  160.                     regex = new Regex(reader.GetString("OldUrl"));
  161.                     if ((regex.IsMatch(url) || (!url.EndsWith("/") && regex.IsMatch(string.Concat(url, "/")))) && !reader.IsNull("NodeId"))
  162.                     {
  163.                         redirectId = reader.GetInt("NodeId");
  164.                         Node n = new Node(redirectId);
  165.                         if (n != null && n.Name != null && n.Id > 0)
  166.                         {
  167.                             Node rootNode = n.FindRoot();
  168.                             if (rootNode.Id == root || root == -1 || ignoreDomain)
  169.                             {
  170.                                 string redirectUrl = n.NiceUrl;
  171.                                 if (!disableQueryStringPassThrough)
  172.                                 {
  173.                                     redirectUrl += HttpContext.Current.Request.Url.Query;
  174.                                 }
  175.  
  176.                                 _redirectID = redirectId;
  177.                                 HttpContext.Current.Response.Clear();
  178.                                 HttpContext.Current.Response.Status = "301 Moved Permanently";
  179.                                 HttpContext.Current.Response.AddHeader("Location", redirectUrl);
  180.                                 HttpContext.Current.Response.End();
  181.                                 return true;
  182.                             }
  183.                         }
  184.                     }
  185.                 }
  186.             }
  187.             return false;
  188.         }
  189.  
  190.         #endregion
  191.     }
  192. }
Advertisement
Add Comment
Please, Sign In to add comment