Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Collections.Specialized;
- using System.Configuration;
- using System.Linq;
- using System.Text.RegularExpressions;
- using System.Web;
- using umbraco.BusinessLogic;
- using umbraco.cms.businesslogic.web;
- using umbraco.DataLayer;
- using umbraco.interfaces;
- using umbraco.NodeFactory;
- namespace InfoCaster.Umbraco._301UrlTracker
- {
- public class Handler301URLTracker : INotFoundHandler
- {
- #region Members
- ISqlHelper _sqlHelper { get { return Application.SqlHelper; } }
- int _redirectID = -1;
- #endregion
- #region INotFoundHandler Members
- #region Properties
- public bool CacheUrl { get { return false; } }
- public int redirectID { get { return _redirectID; } }
- #endregion
- public bool Execute(string url)
- {
- bool disabled = false;
- if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["infocasterDisable301URLTracker"]))
- {
- bool config;
- if (bool.TryParse(ConfigurationManager.AppSettings["infocasterDisable301URLTracker"], out config))
- disabled = config;
- }
- if (!disabled)
- {
- if (!url.StartsWith("/"))
- url = string.Concat("/", url);
- bool queryStringExists = HttpContext.Current.Request.QueryString.HasKeys();
- bool ignoreDomain = false;
- string ignoreDomainString = ConfigurationManager.AppSettings["301:ignoreDomain"];
- if (!string.IsNullOrEmpty(ignoreDomainString) && ignoreDomainString.ToLower() == "true")
- ignoreDomain = true;
- bool disableQueryStringPassThrough = false;
- string disableQueryStringPassThroughString = ConfigurationManager.AppSettings["301:disableQueryStringPassThrough"];
- if (!string.IsNullOrEmpty(disableQueryStringPassThroughString) && disableQueryStringPassThroughString.ToLower() == "true")
- disableQueryStringPassThrough = true;
- int root = Domain.GetRootFromDomain(HttpContext.Current.Request.Url.DnsSafeHost);
- if (queryStringExists)
- {
- // Url matching with querystring
- if (MatchUrl(url, root, HttpContext.Current.Request.QueryString, ignoreDomain, disableQueryStringPassThrough: true))
- return true;
- }
- // Url matching without querystring
- if (MatchUrl(url, root, ignoreDomain: ignoreDomain, disableQueryStringPassThrough: disableQueryStringPassThrough))
- return true;
- if (queryStringExists)
- {
- // Regex matching with querystring
- if (MatchRegex(HttpContext.Current.Request.RawUrl, root, ignoreDomain, disableQueryStringPassThrough: true))
- return true;
- }
- // Regex matching without querystring
- if (MatchRegex(url, root, ignoreDomain, disableQueryStringPassThrough))
- return true;
- }
- return false;
- }
- bool MatchUrl(string url, int root, NameValueCollection querystring = null, bool ignoreDomain = false, bool disableQueryStringPassThrough = false)
- {
- // Url matching
- int redirectId;
- string urlWithTrailingSlash = url.EndsWith("/") ? string.Empty : string.Concat(url, "/");
- string urlWithDomain = url.StartsWith("http") ? string.Empty : string.Concat(HttpContext.Current.Request.Url.Scheme, "://", HttpContext.Current.Request.Url.Host, url);
- string urlWithDomainWithTrailingSlash = url.EndsWith("/") ? string.Empty : string.Concat(HttpContext.Current.Request.Url.Scheme, "://", HttpContext.Current.Request.Url.Host, url, "/");
- string query = "SELECT NodeId, Message FROM infocaster301 WHERE (OldUrl = @url OR OldUrl = @urlWithDomain OR OldUrl = @urlWithTrailingSlash OR OldUrl = @urlWithDomainWithTrailingSlash) AND IsRegex = 0";
- if (querystring != null)
- query = "SELECT NodeId, OldUrl, Message FROM infocaster301 WHERE (OldUrl LIKE @url + '%' OR OldUrl LIKE @urlWithDomain + '%') AND IsRegex = 0";
- using (IRecordsReader reader = _sqlHelper.ExecuteReader(query, _sqlHelper.CreateParameter("url", url), _sqlHelper.CreateParameter("urlWithDomain", urlWithDomain), _sqlHelper.CreateParameter("urlWithTrailingSlash", urlWithTrailingSlash), _sqlHelper.CreateParameter("urlWithDomainWithTrailingSlash", urlWithDomainWithTrailingSlash)))
- {
- while (reader.Read())
- {
- if (!reader.IsNull("NodeId"))
- {
- redirectId = reader.GetInt("NodeId");
- string message = reader.IsNull("Message") ? string.Empty : reader.GetString("Message");
- if (message == "--- Node removed ---")
- {
- HttpContext.Current.Response.Status = "410 Gone";
- HttpContext.Current.Response.End();
- return true;
- }
- else
- {
- Node n = new Node(redirectId);
- if (n != null && n.Name != null && n.Id > 0)
- {
- Node rootNode = n.FindRoot();
- if (rootNode.Id == root || root == -1 || ignoreDomain)
- {
- bool okay = true;
- if (querystring != null)
- {
- string oldUrl = reader.GetString("OldUrl");
- foreach (string key in querystring)
- {
- if (!oldUrl.Contains(string.Format("{0}={1}", key, querystring[key])))
- okay = false;
- }
- }
- if (okay)
- {
- // if querystring param = null - we're not matching on query string
- // then check is query should be passed through
- string redirectUrl = n.NiceUrl;
- if (!disableQueryStringPassThrough)
- {
- redirectUrl += HttpContext.Current.Request.Url.Query;
- }
- _redirectID = redirectId;
- HttpContext.Current.Response.Clear();
- HttpContext.Current.Response.Status = "301 Moved Permanently";
- HttpContext.Current.Response.AddHeader("Location", redirectUrl);
- HttpContext.Current.Response.End();
- return true;
- }
- }
- }
- }
- }
- }
- }
- return false;
- }
- bool MatchRegex(string url, int root, bool ignoreDomain = false, bool disableQueryStringPassThrough = false)
- {
- // Regex matching
- int redirectId;
- string query = "SELECT NodeId, OldUrl FROM infocaster301 WHERE IsRegex = 1 ORDER BY Inserted ASC";
- using (IRecordsReader reader = _sqlHelper.ExecuteReader(query))
- {
- Regex regex;
- while (reader.Read())
- {
- regex = new Regex(reader.GetString("OldUrl"));
- if ((regex.IsMatch(url) || (!url.EndsWith("/") && regex.IsMatch(string.Concat(url, "/")))) && !reader.IsNull("NodeId"))
- {
- redirectId = reader.GetInt("NodeId");
- Node n = new Node(redirectId);
- if (n != null && n.Name != null && n.Id > 0)
- {
- Node rootNode = n.FindRoot();
- if (rootNode.Id == root || root == -1 || ignoreDomain)
- {
- string redirectUrl = n.NiceUrl;
- if (!disableQueryStringPassThrough)
- {
- redirectUrl += HttpContext.Current.Request.Url.Query;
- }
- _redirectID = redirectId;
- HttpContext.Current.Response.Clear();
- HttpContext.Current.Response.Status = "301 Moved Permanently";
- HttpContext.Current.Response.AddHeader("Location", redirectUrl);
- HttpContext.Current.Response.End();
- return true;
- }
- }
- }
- }
- }
- return false;
- }
- #endregion
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment