Пример #1
0
        public void LoadView()
        {
            UrlTrackerDomain domain           = null;
            Node             redirectRootNode = new Node(UrlTrackerModel.RedirectRootNodeId);

            List <UrlTrackerDomain> domains = UmbracoHelper.GetDomains(false);

            domain = domains.FirstOrDefault(x => x.NodeId == redirectRootNode.Id);
            if (domain == null)
            {
                domain = new UrlTrackerDomain(-1, redirectRootNode.Id, HttpContext.Current.Request.Url.Host);
            }
            if (!domains.Any())
            {
                pnlRootNode.Visible = false;
            }
            else
            {
                lnkRootNode.Text        = UrlTrackerHelper.GetName(domain);
                lnkRootNode.ToolTip     = UrlTrackerResources.SyncTree;
                lnkRootNode.NavigateUrl = string.Format("javascript:parent.UmbClientMgr.mainTree().syncTree('{1}', false);", redirectRootNode.Id, redirectRootNode.Path);
            }

            Uri oldUri = new Uri(UrlTrackerModel.CalculatedOldUrlWithDomain);

            lnkOldUrl.Text        = string.Format("{0} <i class=\"icon-share\"></i>", oldUri.AbsolutePath.StartsWith("/") ? oldUri.AbsolutePath.Substring(1) : oldUri.AbsolutePath);
            lnkOldUrl.NavigateUrl = oldUri.ToString();
        }
Пример #2
0
        public static bool AddUrlMapping(IContent content, int rootNodeId, string url, AutoTrackingTypes type, bool isChild = false)
        {
            if (url != "#" && content.Template != null && content.Template.Id > 0)
            {
                string notes = isChild ? "An ancestor" : "This page";
                switch (type)
                {
                case AutoTrackingTypes.Moved:
                    notes += " was moved";
                    break;

                case AutoTrackingTypes.Renamed:
                    notes += " was renamed";
                    break;

                case AutoTrackingTypes.UrlOverwritten:
                    notes += "'s property 'umbracoUrlName' changed";
                    break;
                }

                url = UrlTrackerHelper.ResolveShortestUrl(url);

                if (UrlTrackerSettings.HasDomainOnChildNode)
                {
                    var rootNode     = new Node(rootNodeId);
                    var rootUri      = new Uri(rootNode.NiceUrl);
                    var shortRootUrl = UrlTrackerHelper.ResolveShortestUrl(rootUri.AbsolutePath);
                    if (url.StartsWith(shortRootUrl, StringComparison.OrdinalIgnoreCase))
                    {
                        url = UrlTrackerHelper.ResolveShortestUrl(url.Substring(shortRootUrl.Length));
                    }
                }

                if (!string.IsNullOrEmpty(url))
                {
                    string query  = "SELECT 1 FROM icUrlTracker WHERE RedirectNodeId = @nodeId AND OldUrl = @url";
                    int    exists = _sqlHelper.ExecuteScalar <int>(query, _sqlHelper.CreateParameter("nodeId", content.Id), _sqlHelper.CreateStringParameter("url", url));

                    if (exists != 1)
                    {
                        LoggingHelper.LogInformation("UrlTracker Repository | Adding mapping for node id: {0} and url: {1}", new string[] { content.Id.ToString(), url });

                        query = "INSERT INTO icUrlTracker (RedirectRootNodeId, RedirectNodeId, OldUrl, Notes) VALUES (@rootNodeId, @nodeId, @url, @notes)";
                        _sqlHelper.ExecuteNonQuery(query, _sqlHelper.CreateParameter("rootNodeId", rootNodeId), _sqlHelper.CreateParameter("nodeId", content.Id), _sqlHelper.CreateStringParameter("url", url), _sqlHelper.CreateStringParameter("notes", notes));

                        if (content.Children().Any())
                        {
                            foreach (IContent child in content.Children())
                            {
                                Node node = new Node(child.Id);
                                AddUrlMapping(child, rootNodeId, node.NiceUrl, type, true);
                            }
                        }

                        return(true);
                    }
                }
            }
            return(false);
        }
        public static void AddGoneEntryByNodeId(int nodeId)
        {
            string url = umbraco.library.NiceUrl(nodeId);

            if (url == "#")
            {
                return;
            }

            if (url.StartsWith("http://") || url.StartsWith("https://"))
            {
                Uri uri = new Uri(url);
                url = uri.AbsolutePath;
            }
            url = UrlTrackerHelper.ResolveShortestUrl(url);

            string query  = "SELECT 1 FROM icUrlTracker WHERE RedirectNodeId = @redirectNodeId AND OldUrl = @oldUrl AND RedirectHttpCode = 410";
            int    exists = _sqlHelper.ExecuteScalar <int>(query, _sqlHelper.CreateParameter("redirectNodeId", nodeId), _sqlHelper.CreateStringParameter("oldUrl", url));

            if (exists != 1)
            {
                LoggingHelper.LogInformation("UrlTracker Repository | Inserting 410 Gone mapping for node with id: {0}", nodeId);

                query = "INSERT INTO icUrlTracker (RedirectNodeId, OldUrl, RedirectHttpCode, Notes) VALUES (@redirectNodeId, @oldUrl, 410, @notes)";
                _sqlHelper.ExecuteNonQuery(query, _sqlHelper.CreateParameter("redirectNodeId", nodeId), _sqlHelper.CreateStringParameter("oldUrl", url), _sqlHelper.CreateStringParameter("notes", "Node removed"));
            }
            else
            {
                LoggingHelper.LogInformation("UrlTracker Repository | Skipping 410 Gone mapping for node with id: {0} (already exists)", nodeId);
            }
        }
Пример #4
0
        /// <summary>
        /// Loads the view.
        /// </summary>
        public void LoadView()
        {
            List <UrlTrackerDomain> domains = UmbracoHelper.GetDomains(false);

            if (ddlRootNode.Items.Count == 1 && domains.Count > 1 || (domains.Count == 1 && new Uri(domains[0].UrlWithDomain).AbsolutePath != "/"))
            {
                // if there is only one site, but it is not with a root domain (ie: www.site.com but instead www.site.com/corporate) then also show the dropdown
                var list = domains.Select(x => new ListItem(UrlTrackerHelper.GetName(x), x.NodeId.ToString())).ToList();
                list.Insert(0, new ListItem("/", "-1"));
                ddlRootNode.DataSource           = list;
                ddlRootNode.AppendDataBoundItems = false;
                ddlRootNode.DataBind();
            }
            else if (domains.Count <= 1)
            {
                pnlRootNode.Visible = false;
            }

            if (ddlRootNode.Items.Count > 1)
            {
                ddlRootNode.SelectedValue = UrlTrackerModel.RedirectRootNodeId.ToString();
            }
            if (!string.IsNullOrEmpty(UrlTrackerModel.OldRegex) && string.IsNullOrEmpty(UrlTrackerModel.OldUrl))
            {
                mvRedirectFrom.SetActiveView(vwRedirectFromRegex);
                tbOldRegex.Text = UrlTrackerModel.OldRegex;
            }
            else
            {
                mvRedirectFrom.SetActiveView(vwRedirectFromUrl);
                tbOldUrl.Text            = UrlTrackerModel.OldUrl;
                tbOldUrlQueryString.Text = UrlTrackerModel.OldUrlQueryString;
            }
            mvRedirect.SetActiveView(UrlTrackerModel.RedirectNodeId.HasValue ? vwRedirectNode : vwRedirectUrl);
            if (UrlTrackerModel.RedirectNodeId.HasValue)
            {
                cpRedirectNode.Value = UrlTrackerModel.RedirectNodeId.Value.ToString();
            }
            tbRedirectUrl.Text = UrlTrackerModel.RedirectUrl;
            if (UrlTrackerModel.RedirectHttpCode == 301)
            {
                rbPermanent.Checked = true;
            }
            else if (UrlTrackerModel.RedirectHttpCode == 302)
            {
                rbTemporary.Checked = true;
            }
            cbRedirectPassthroughQueryString.Checked = UrlTrackerModel.RedirectPassThroughQueryString;
            cbForceRedirect.Checked = UrlTrackerModel.ForceRedirect;
            tbNotes.Text            = UrlTrackerModel.Notes;
            pnlReferrer.Visible     = !string.IsNullOrEmpty(UrlTrackerModel.Referrer);
            lblReferrer.Text        = UrlTrackerModel.Referrer;
            lblInserted.Text        = UrlTrackerModel.Inserted.ToString();
        }
Пример #5
0
        public void CreateNew()
        {
            List <UrlTrackerDomain> domains = UmbracoHelper.GetDomains();

            UrlTrackerRepository.AddUrlTrackerEntry(new UrlTrackerModel(UrlTrackerHelper.ResolveShortestUrl(tbOldUrl.Text), tbOldUrlQueryString.Text, tbOldRegex.Text, domains.Count > 1 ? int.Parse(ddlRootNode.SelectedValue) : domains.Any() ? domains.Single().NodeId : new Node(-1).ChildrenAsList.First().Id, !string.IsNullOrEmpty(cpRedirectNode.Value) ? (int?)int.Parse(cpRedirectNode.Value) : null, tbRedirectUrl.Text, rbPermanent.Checked ? 301 : 302, cbRedirectPassthroughQueryString.Checked, cbForceRedirect.Checked, tbNotes.Text));

            if (ddlRootNode.SelectedIndex != -1)
            {
                ddlRootNode.SelectedIndex = 0;
            }
            tbOldUrl.Text       = tbOldUrlQueryString.Text = tbOldRegex.Text = cpRedirectNode.Value = tbRedirectUrl.Text = tbNotes.Text = string.Empty;
            rbPermanent.Checked = cbRedirectPassthroughQueryString.Checked = true;
            rbTemporary.Checked = false;
        }
        public static bool AddUrlMapping(Document doc, int rootNodeId, string url, AutoTrackingTypes type, bool isChild = false)
        {
            if (url != "#")
            {
                string notes = isChild ? "An ancestor" : "This page";
                switch (type)
                {
                case AutoTrackingTypes.Moved:
                    notes += " was moved";
                    break;

                case AutoTrackingTypes.Renamed:
                    notes += " was renamed";
                    break;

                case AutoTrackingTypes.UrlOverwritten:
                    notes += "'s property 'umbracoUrlName' changed";
                    break;
                }

                url = UrlTrackerHelper.ResolveShortestUrl(url);

                if (!string.IsNullOrEmpty(url))
                {
                    string query  = "SELECT 1 FROM icUrlTracker WHERE RedirectNodeId = @nodeId AND OldUrl = @url";
                    int    exists = _sqlHelper.ExecuteScalar <int>(query, _sqlHelper.CreateParameter("nodeId", doc.Id), _sqlHelper.CreateStringParameter("url", url));

                    if (exists != 1)
                    {
                        LoggingHelper.LogInformation("UrlTracker Repository | Adding mapping for node id: {0} and url: {1}", new string[] { doc.Id.ToString(), url });

                        query = "INSERT INTO icUrlTracker (RedirectRootNodeId, RedirectNodeId, OldUrl, Notes) VALUES (@rootNodeId, @nodeId, @url, @notes)";
                        _sqlHelper.ExecuteNonQuery(query, _sqlHelper.CreateParameter("rootNodeId", rootNodeId), _sqlHelper.CreateParameter("nodeId", doc.Id), _sqlHelper.CreateStringParameter("url", url), _sqlHelper.CreateStringParameter("notes", notes));

                        if (doc.HasChildren)
                        {
                            foreach (Document child in doc.Children)
                            {
                                Node node = new Node(child.Id);
                                AddUrlMapping(child, rootNodeId, node.NiceUrl, type, true);
                            }
                        }

                        return(true);
                    }
                }
            }
            return(false);
        }
Пример #7
0
        public void LoadView()
        {
            List <UrlTrackerDomain> domains = UmbracoHelper.GetDomains();

            if (ddlRootNode.Items.Count == 1 && domains.Count > 1)
            {
                ddlRootNode.DataSource = domains.Select(x => new ListItem(UrlTrackerHelper.GetName(x), x.NodeId.ToString()));
                ddlRootNode.DataBind();
            }
            else if (domains.Count <= 1)
            {
                pnlRootNode.Visible = false;
            }

            if (ddlRootNode.Items.Count > 1)
            {
                ddlRootNode.SelectedValue = UrlTrackerModel.RedirectRootNodeId.ToString();
            }

            if (!string.IsNullOrEmpty(UrlTrackerModel.OldRegex) && string.IsNullOrEmpty(UrlTrackerModel.OldUrl))
            {
                tbOldRegex.Text = UrlTrackerModel.OldRegex;
            }
            else
            {
                tbOldUrl.Text            = UrlTrackerModel.OldUrl;
                tbOldUrlQueryString.Text = UrlTrackerModel.OldUrlQueryString;
            }
            if (UrlTrackerModel.RedirectNodeId.HasValue)
            {
                cpRedirectNode.Value = UrlTrackerModel.RedirectNodeId.Value.ToString();
            }
            tbRedirectUrl.Text = UrlTrackerModel.RedirectUrl;
            if (UrlTrackerModel.RedirectHttpCode == 301)
            {
                rbPermanent.Checked = true;
            }
            else if (UrlTrackerModel.RedirectHttpCode == 302)
            {
                rbTemporary.Checked = true;
            }
            cbRedirectPassthroughQueryString.Checked = UrlTrackerModel.RedirectPassThroughQueryString;
            cbForceRedirect.Checked = UrlTrackerModel.ForceRedirect;
            tbNotes.Text            = UrlTrackerModel.Notes;
            pnlReferrer.Visible     = !string.IsNullOrEmpty(UrlTrackerModel.Referrer);
            lblReferrer.Text        = UrlTrackerModel.Referrer;
            lblInserted.Text        = UrlTrackerModel.Inserted.ToString();
        }
Пример #8
0
        public static void AddGoneEntryByNodeId(int nodeId)
        {
            if (UmbracoContext.Current == null) // NiceUrl will throw an exception if UmbracoContext is null, and we'll be unable to retrieve the URL of the node
            {
                return;
            }

            var url = umbraco.library.NiceUrl(nodeId);

            if (url == "#")
            {
                return;
            }

            if (url.StartsWith("http://") || url.StartsWith("https://"))
            {
                var uri = new Uri(url);
                url = uri.AbsolutePath;
            }
            url = UrlTrackerHelper.ResolveShortestUrl(url);

            var database = ApplicationContext.Current.DatabaseContext.Database;

            var query = "SELECT 1 FROM icUrlTracker WHERE RedirectNodeId = @redirectNodeId AND OldUrl = @oldUrl AND RedirectHttpCode = 410";

            var exists = database.ExecuteScalar <int?>(query, new object[] { new { redirectNodeId = nodeId }, new { oldUrl = url } });

            if (exists != 1)
            {
                LoggingHelper.LogInformation("UrlTracker Repository | Inserting 410 Gone mapping for node with id: {0}", nodeId);
                database.Insert(
                    "icUrlTracker",
                    "Id",
                    true,
                    new { RedirectNodeId = nodeId, OldUrl = url, RedirectHttpCode = 410, Notes = "Node removed" });
            }
            else
            {
                LoggingHelper.LogInformation("UrlTracker Repository | Skipping 410 Gone mapping for node with id: {0} (already exists)", nodeId);
            }
        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            if (!_earlyErrorDetected)
            {
                IUrlTrackerView activeView = GetActiveView();
                if (activeView != null)
                {
                    activeView.UrlTrackerModel = icAdvancedView.UrlTrackerModel = UrlTrackerModel;
                }

                if (gvUrlTracker.PageSize != PageSize)
                {
                    gvUrlTracker.PageSize = PageSize;
                }
                if (gvNotFound.PageSize != PageSize)
                {
                    gvNotFound.PageSize = PageSize;
                }
            }

            List <UrlTrackerDomain> domains = UmbracoHelper.GetDomains();

            if (ddlRootNode.Items.Count == 1 && domains.Count > 1 || (domains.Count == 1 && new Uri(domains[0].UrlWithDomain).AbsolutePath != "/"))
            {
                if (ddlRootNode.Items.Count <= 1)
                {
                    // if there is only one site, but it is not with a root domain (ie: www.site.com but instead www.site.com/corporate) then also show the dropdown
                    var list = domains.Select(x => new ListItem(UrlTrackerHelper.GetName(x), x.NodeId.ToString())).ToList();
                    list.Insert(0, new ListItem("/", "-1"));
                    ddlRootNode.DataSource           = list;
                    ddlRootNode.AppendDataBoundItems = false;
                    ddlRootNode.DataBind();
                }
            }
            else if (domains.Count <= 1)
            {
                lblRootNode.Visible = false;
            }
        }
Пример #10
0
        public void Save()
        {
            List <UrlTrackerDomain> domains = UmbracoHelper.GetDomains();

            UrlTrackerModel.OldUrl             = UrlTrackerHelper.ResolveShortestUrl(tbOldUrl.Text);
            UrlTrackerModel.OldUrlQueryString  = tbOldUrlQueryString.Text;
            UrlTrackerModel.OldRegex           = tbOldRegex.Text;
            UrlTrackerModel.RedirectRootNodeId = domains.Count > 1 ? int.Parse(ddlRootNode.SelectedValue) : domains.Any() ? domains.Single().NodeId : new Node(-1).ChildrenAsList.First().Id;
            if (!string.IsNullOrEmpty(cpRedirectNode.Value))
            {
                UrlTrackerModel.RedirectNodeId = int.Parse(cpRedirectNode.Value);
            }
            else
            {
                UrlTrackerModel.RedirectNodeId = null;
            }
            UrlTrackerModel.RedirectUrl      = tbRedirectUrl.Text;
            UrlTrackerModel.RedirectHttpCode = rbPermanent.Checked ? 301 : 302;
            UrlTrackerModel.RedirectPassThroughQueryString = cbRedirectPassthroughQueryString.Checked;
            UrlTrackerModel.ForceRedirect = cbForceRedirect.Checked;
            UrlTrackerModel.Notes         = tbNotes.Text;
            UrlTrackerRepository.UpdateUrlTrackerEntry(UrlTrackerModel);
        }
Пример #11
0
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            List <UrlTrackerDomain> domains = UmbracoHelper.GetDomains();

            if (ddlRootNode.Items.Count == 1 && domains.Count > 1 || (domains.Count == 1 && new Uri(domains[0].UrlWithDomain).AbsolutePath != "/"))
            {
                if (ddlRootNode.Items.Count <= 1)
                {
                    // if there is only one site, but it is not with a root domain (ie: www.site.com but instead www.site.com/corporate) then also show the dropdown
                    var list = domains.Select(x => new ListItem(UrlTrackerHelper.GetName(x), x.NodeId.ToString())).ToList();
                    list.Insert(0, new ListItem("/", "-1"));
                    ddlRootNode.DataSource           = list;
                    ddlRootNode.AppendDataBoundItems = false;
                    ddlRootNode.DataBind();
                }
            }
            else if (domains.Count <= 1)
            {
                pnlRootNode.Visible = false;
            }
        }
Пример #12
0
        public static int MigrateData()
        {
            if (!GetUrlTrackerTableExists())
            {
                throw new Exception("Url Tracker table not found.");
            }
            if (!GetUrlTrackeOldTableExists())
            {
                throw new Exception("Old Url Tracker table not found.");
            }

            int newUrlTrackerEntriesCount = 0;
            List <OldUrlTrackerModel> oldUrlTrackerEntries = new List <OldUrlTrackerModel>();
            string         query         = string.Format("SELECT * FROM {0}", UrlTrackerSettings.OldTableName);
            IRecordsReader recordsReader = _sqlHelper.ExecuteReader(query);

            while (recordsReader.Read())
            {
                oldUrlTrackerEntries.Add(new OldUrlTrackerModel()
                {
                    NodeId   = recordsReader.GetInt("NodeID"),
                    OldUrl   = recordsReader.GetString("OldUrl"),
                    IsCustom = recordsReader.GetBoolean("IsCustom"),
                    Message  = recordsReader.GetString("Message"),
                    Inserted = recordsReader.GetDateTime("Inserted"),
                    IsRegex  = recordsReader.GetBoolean("IsRegex")
                });
            }

            foreach (OldUrlTrackerModel oldUrlTrackerEntry in oldUrlTrackerEntries)
            {
                Node node = new Node(oldUrlTrackerEntry.NodeId);
                if ((node.Id > 0 || true) && !string.IsNullOrEmpty(oldUrlTrackerEntry.OldUrl) && oldUrlTrackerEntry.OldUrl != "#")
                {
                    string oldUrl = oldUrlTrackerEntry.OldUrl;
                    Uri    oldUri = null;
                    if (!oldUrlTrackerEntry.IsRegex)
                    {
                        if (!oldUrl.StartsWith(Uri.UriSchemeHttp))
                        {
                            oldUri = new Uri(_baseUri, oldUrl);
                        }
                        else
                        {
                            oldUri = new Uri(oldUrl);
                        }
                        oldUrl = UrlTrackerHelper.ResolveShortestUrl(oldUri.AbsolutePath);
                    }
                    else
                    {
                        if (oldUrl.StartsWith("^/"))
                        {
                            oldUrl = string.Concat("^", oldUrl.Substring(2));
                        }
                        if (oldUrl.StartsWith("/"))
                        {
                            oldUrl = oldUrl.Substring(1);
                        }
                        if (oldUrl.EndsWith("/$"))
                        {
                            oldUrl = string.Concat(oldUrl.Substring(0, oldUrl.Length - 2), "$");
                        }
                        if (oldUrl.EndsWith("/"))
                        {
                            oldUrl = oldUrl.Substring(0, oldUrl.Length - 1);
                        }
                    }

                    UrlTrackerModel newUrlTrackerEntry = new UrlTrackerModel(
                        !oldUrlTrackerEntry.IsRegex ? oldUrl : string.Empty,
                        oldUri != null ? !string.IsNullOrEmpty(oldUri.Query) && oldUri.Query.StartsWith("?") ? oldUri.Query.Substring(1) : oldUri.Query : string.Empty,
                        oldUrlTrackerEntry.IsRegex ? oldUrl : string.Empty,
                        node.GetDomainRootNode().Id,
                        oldUrlTrackerEntry.NodeId,
                        string.Empty,
                        301,
                        true,
                        false,
                        oldUrlTrackerEntry.Message);
                    newUrlTrackerEntry.Inserted = oldUrlTrackerEntry.Inserted;

                    AddUrlTrackerEntry(newUrlTrackerEntry);

                    newUrlTrackerEntriesCount++;
                }
            }

            return(newUrlTrackerEntriesCount);
        }
Пример #13
0
        static void UrlTrackerDo(string callingEventName, bool ignoreHttpStatusCode = false)
        {
            HttpContext  context  = HttpContext.Current;
            HttpRequest  request  = context.Request;
            HttpResponse response = context.Response;

            if (!string.IsNullOrEmpty(request.QueryString[UrlTrackerSettings.HttpModuleCheck]))
            {
                response.Clear();
                response.Write(UrlTrackerSettings.HttpModuleCheck);
                response.StatusCode = 200;
                response.End();
                return;
            }

            LoggingHelper.LogInformation("UrlTracker HttpModule | {0} start", callingEventName);

            if (UrlTrackerSettings.IsDisabled)
            {
                LoggingHelper.LogInformation("UrlTracker HttpModule | UrlTracker is disabled by config");
                return;
            }

            string url = request.RawUrl;

            if (url.StartsWith("/") && url != "/")
            {
                url = url.Substring(1);
            }

            LoggingHelper.LogInformation("UrlTracker HttpModule | Incoming URL is: {0}", url);

            if (_urlTrackerInstalled && (response.StatusCode == (int)HttpStatusCode.NotFound || ignoreHttpStatusCode))
            {
                if (response.StatusCode == (int)HttpStatusCode.NotFound)
                {
                    LoggingHelper.LogInformation("UrlTracker HttpModule | Response statusCode is 404, continue URL matching");
                }
                else
                {
                    LoggingHelper.LogInformation("UrlTracker HttpModule | Checking for forced redirects (AcquireRequestState), continue URL matching");
                }

                string urlWithoutQueryString = url;
                if (InfoCaster.Umbraco.UrlTracker.Helpers.UmbracoHelper.IsReservedPathOrUrl(url))
                {
                    LoggingHelper.LogInformation("UrlTracker HttpModule | URL is an umbraco reserved path or url, ignore request");
                    return;
                }

                //bool urlHasQueryString = request.QueryString.HasKeys() && url.Contains('?');
                bool urlHasQueryString = url.Contains('?'); // invalid querystring (?xxx) without = sign must also be stripped...

                if (urlHasQueryString)
                {
                    urlWithoutQueryString = url.Substring(0, url.IndexOf('?'));
                }

                string shortestUrl = UrlTrackerHelper.ResolveShortestUrl(urlWithoutQueryString);

                int rootNodeId = -1;
                List <UrlTrackerDomain> domains = UmbracoHelper.GetDomains();
                if (domains.Any())
                {
                    string fullRawUrl;
                    string previousFullRawUrlTest;
                    string fullRawUrlTest;
                    fullRawUrl = previousFullRawUrlTest = fullRawUrlTest = string.Format("{0}{1}{2}{3}", request.Url.Scheme, Uri.SchemeDelimiter, request.Url.Host, request.RawUrl);

                    UrlTrackerDomain urlTrackerDomain;
                    do
                    {
                        if (previousFullRawUrlTest.EndsWith("/"))
                        {
                            urlTrackerDomain = domains.FirstOrDefault(x => (x.UrlWithDomain == fullRawUrlTest) || (x.UrlWithDomain == fullRawUrlTest + "/"));
                            if (urlTrackerDomain != null)
                            {
                                rootNodeId            = urlTrackerDomain.NodeId;
                                urlWithoutQueryString = fullRawUrl.Replace(fullRawUrlTest, string.Empty);
                                if (urlWithoutQueryString.StartsWith("/"))
                                {
                                    urlWithoutQueryString = urlWithoutQueryString.Substring(1);
                                }
                                if (urlWithoutQueryString.EndsWith("/"))
                                {
                                    urlWithoutQueryString = urlWithoutQueryString.Substring(0, urlWithoutQueryString.Length - 1);
                                }

                                break;
                            }
                        }
                        previousFullRawUrlTest = fullRawUrlTest;
                        fullRawUrlTest         = fullRawUrlTest.Substring(0, fullRawUrlTest.Length - 1);
                    }while (fullRawUrlTest.Length > 0);
                }
                if (rootNodeId == -1)
                {
                    List <INode> children = new Node(rootNodeId).ChildrenAsList;
                    if (children != null && children.Any())
                    {
                        rootNodeId = children.First().Id;
                    }
                }
                else
                {
                    var rootUrl = "/";
                    try
                    {
                        rootUrl = new Node(rootNodeId).Url;
                    }
                    catch (ArgumentNullException)
                    {
                        // could not get full url for path, so we keep / as the root... (no other way to check, happens for favicon.ico for example)
                    }
                    var rootFolder = rootUrl != @"/" ? new Uri(HttpContext.Current.Request.Url, rootUrl).AbsolutePath.TrimStart('/') : string.Empty;
                    if (shortestUrl.StartsWith(rootFolder, StringComparison.OrdinalIgnoreCase))
                    {
                        shortestUrl = shortestUrl.Substring(rootFolder.Length);
                    }
                }
                LoggingHelper.LogInformation("UrlTracker HttpModule | Current request's rootNodeId: {0}", rootNodeId);

                string redirectUrl      = null;
                int?   redirectHttpCode = null;
                bool   redirectPassThroughQueryString = true;

                if (!ignoreHttpStatusCode)
                {
                    // Normal matching (database)
                    LoadUrlTrackerMatchesFromDatabase(request, urlWithoutQueryString, urlHasQueryString, shortestUrl, rootNodeId, ref redirectUrl, ref redirectHttpCode, ref redirectPassThroughQueryString);
                }
                else
                {
                    // Forced matching (cache)
                    LoadUrlTrackerMatchesFromCache(request, urlWithoutQueryString, urlHasQueryString, shortestUrl, rootNodeId, ref redirectUrl, ref redirectHttpCode, ref redirectPassThroughQueryString);
                }

                string query;
                if (!redirectHttpCode.HasValue)
                {
                    if (!ignoreHttpStatusCode)
                    {
                        // Normal matching (database)
                        // Regex matching
                        query = "SELECT * FROM icUrlTracker WHERE Is404 = 0 AND ForceRedirect = @forceRedirect AND (RedirectRootNodeId = @redirectRootNodeId OR RedirectRootNodeId = -1) AND OldRegex IS NOT NULL ORDER BY Inserted DESC";
                        using (IRecordsReader reader = _sqlHelper.ExecuteReader(query, _sqlHelper.CreateParameter("forceRedirect", ignoreHttpStatusCode ? 1 : 0), _sqlHelper.CreateParameter("redirectRootNodeId", rootNodeId)))
                        {
                            Regex regex;
                            while (reader.Read())
                            {
                                regex = new Regex(reader.GetString("OldRegex"));
                                if (regex.IsMatch(url))
                                {
                                    LoggingHelper.LogInformation("UrlTracker HttpModule | Regex match found");
                                    if (!reader.IsNull("RedirectNodeId"))
                                    {
                                        int redirectNodeId = reader.GetInt("RedirectNodeId");
                                        LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect node id: {0}", redirectNodeId);
                                        Node n = new Node(redirectNodeId);
                                        if (n != null && n.Name != null && n.Id > 0)
                                        {
                                            redirectUrl = UmbracoHelper.GetUrl(redirectNodeId);
                                            LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect url set to: {0}", redirectUrl);
                                        }
                                        else
                                        {
                                            LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect node is invalid; node is null, name is null or id <= 0");
                                        }
                                    }
                                    else if (!reader.IsNull("RedirectUrl"))
                                    {
                                        redirectUrl = reader.GetString("RedirectUrl");
                                        LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect url set to: {0}", redirectUrl);

                                        if (_capturingGroupsRegex.IsMatch(redirectUrl))
                                        {
                                            LoggingHelper.LogInformation("UrlTracker HttpModule | Found regex capturing groups in the redirect url");
                                            redirectUrl = regex.Replace(url, redirectUrl);

                                            LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect url changed to: {0} (because of regex capturing groups)", redirectUrl);
                                        }
                                    }

                                    redirectPassThroughQueryString = reader.GetBoolean("RedirectPassThroughQueryString");
                                    LoggingHelper.LogInformation("UrlTracker HttpModule | PassThroughQueryString is enabled");

                                    redirectHttpCode = reader.GetInt("RedirectHttpCode");
                                    LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect http code set to: {0}", redirectHttpCode);
                                }
                            }
                        }
                    }
                    else
                    {
                        // Forced matching (cache)
                        List <UrlTrackerModel> forcedRedirects = UrlTrackerRepository.GetForcedRedirects().Where(x => !string.IsNullOrEmpty(x.OldRegex)).ToList();
                        if (forcedRedirects == null || !forcedRedirects.Any())
                        {
                            return;
                        }

                        foreach (var match in forcedRedirects.Select(x => new { UrlTrackerModel = x, Regex = new Regex(x.OldRegex) }).Where(x => x.Regex.IsMatch(url)))
                        {
                            LoggingHelper.LogInformation("UrlTracker HttpModule | Regex match found");
                            if (match.UrlTrackerModel.RedirectNodeId.HasValue)
                            {
                                LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect node id: {0}", match.UrlTrackerModel.RedirectNodeId.Value);
                                Node n = new Node(match.UrlTrackerModel.RedirectNodeId.Value);
                                if (n != null && n.Name != null && n.Id > 0)
                                {
                                    redirectUrl = UmbracoHelper.GetUrl(match.UrlTrackerModel.RedirectNodeId.Value);
                                    LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect url set to: {0}", redirectUrl);
                                }
                                else
                                {
                                    LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect node is invalid; node is null, name is null or id <= 0");
                                }
                            }
                            else if (!string.IsNullOrEmpty(match.UrlTrackerModel.RedirectUrl))
                            {
                                redirectUrl = match.UrlTrackerModel.RedirectUrl;
                                LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect url set to: {0}", redirectUrl);

                                if (_capturingGroupsRegex.IsMatch(redirectUrl))
                                {
                                    LoggingHelper.LogInformation("UrlTracker HttpModule | Found regex capturing groups in the redirect url");
                                    redirectUrl = match.Regex.Replace(url, redirectUrl);

                                    LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect url changed to: {0} (because of regex capturing groups)", redirectUrl);
                                }
                            }

                            redirectPassThroughQueryString = match.UrlTrackerModel.RedirectPassThroughQueryString;
                            LoggingHelper.LogInformation("UrlTracker HttpModule | PassThroughQueryString is enabled");

                            redirectHttpCode = match.UrlTrackerModel.RedirectHttpCode;
                            LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect http code set to: {0}", redirectHttpCode);
                        }
                    }
                }

                if (redirectHttpCode.HasValue)
                {
                    string redirectLocation = string.Empty;

                    if (!string.IsNullOrEmpty(redirectUrl))
                    {
                        if (redirectUrl == "/")
                        {
                            redirectUrl = string.Empty;
                        }
                        Uri redirectUri = new Uri(redirectUrl.StartsWith(Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase) ? redirectUrl : string.Format("{0}{1}{2}{3}/{4}", request.Url.Scheme, Uri.SchemeDelimiter, request.Url.Host, request.Url.Port != 80 && UrlTrackerSettings.AppendPortNumber ? string.Concat(":", request.Url.Port) : string.Empty, redirectUrl.StartsWith("/") ? redirectUrl.Substring(1) : redirectUrl));
                        if (redirectPassThroughQueryString)
                        {
                            NameValueCollection redirectQueryString = HttpUtility.ParseQueryString(redirectUri.Query);
                            NameValueCollection newQueryString      = HttpUtility.ParseQueryString(request.Url.Query);
                            if (redirectQueryString.HasKeys())
                            {
                                newQueryString = newQueryString.Merge(redirectQueryString);
                            }
                            string pathAndQuery = Uri.UnescapeDataString(redirectUri.PathAndQuery) + redirectUri.Fragment;
                            redirectUri = new Uri(string.Format("{0}{1}{2}{3}/{4}{5}", redirectUri.Scheme, Uri.SchemeDelimiter, redirectUri.Host, redirectUri.Port != 80 && UrlTrackerSettings.AppendPortNumber ? string.Concat(":", redirectUri.Port) : string.Empty, pathAndQuery.Contains('?') ? pathAndQuery.Substring(0, pathAndQuery.IndexOf('?')) : pathAndQuery.StartsWith("/") ? pathAndQuery.Substring(1) : pathAndQuery, newQueryString.HasKeys() ? string.Concat("?", newQueryString.ToQueryString()) : string.Empty));
                        }

                        if (redirectUri == new Uri(string.Format("{0}{1}{2}{3}/{4}", request.Url.Scheme, Uri.SchemeDelimiter, request.Url.Host, request.Url.Port != 80 && UrlTrackerSettings.AppendPortNumber ? string.Concat(":", request.Url.Port) : string.Empty, request.RawUrl.StartsWith("/") ? request.RawUrl.Substring(1) : request.RawUrl)))
                        {
                            LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect URL is the same as Request.RawUrl; don't redirect");
                            return;
                        }
                        if (request.Url.Host.Equals(redirectUri.Host, StringComparison.OrdinalIgnoreCase))
                        {
                            redirectLocation = redirectUri.PathAndQuery + redirectUri.Fragment;
                        }
                        else
                        {
                            redirectLocation = redirectUri.AbsoluteUri;
                        }
                        LoggingHelper.LogInformation("UrlTracker HttpModule | Response redirectlocation set to: {0}", redirectLocation);
                    }

                    response.Clear();
                    response.StatusCode = redirectHttpCode.Value;
                    LoggingHelper.LogInformation("UrlTracker HttpModule | Response statuscode set to: {0}", response.StatusCode);

                    if (!string.IsNullOrEmpty(redirectLocation))
                    {
                        response.RedirectLocation = redirectLocation;
                    }

                    response.End();
                }
                else if (!ignoreHttpStatusCode)
                {
                    // Log 404
                    if (!UrlTrackerSettings.IsNotFoundTrackingDisabled && !UrlTrackerSettings.NotFoundUrlsToIgnore.Contains(urlWithoutQueryString) && !UmbracoHelper.IsReservedPathOrUrl(urlWithoutQueryString) && request.Headers["X-UrlTracker-Ignore404"] != "1")
                    {
                        bool ignoreNotFoundBasedOnRegexPatterns = false;
                        foreach (Regex regexNotFoundUrlToIgnore in UrlTrackerSettings.RegexNotFoundUrlsToIgnore)
                        {
                            if (regexNotFoundUrlToIgnore.IsMatch(urlWithoutQueryString))
                            {
                                ignoreNotFoundBasedOnRegexPatterns = true;
                                break;
                            }
                        }

                        if (!ignoreNotFoundBasedOnRegexPatterns)
                        {
                            LoggingHelper.LogInformation("UrlTracker HttpModule | No match found, logging as 404 not found");
                            query = "INSERT INTO icUrlTracker (OldUrl, RedirectRootNodeId, ";
                            if (urlHasQueryString)
                            {
                                query += "OldUrlQueryString, ";
                            }
                            query += "Is404, Referrer) VALUES (@oldUrl, @redirectRootNodeId, ";
                            if (urlHasQueryString)
                            {
                                query += "@oldUrlQueryString, ";
                            }
                            query += "1, @referrer)";
                            _sqlHelper.ExecuteNonQuery(query, _sqlHelper.CreateParameter("oldUrl", urlWithoutQueryString), _sqlHelper.CreateParameter("redirectRootNodeId", rootNodeId), _sqlHelper.CreateParameter("oldUrlQueryString", request.QueryString.ToString()), _sqlHelper.CreateParameter("referrer", request.UrlReferrer != null && !request.UrlReferrer.ToString().Contains(UrlTrackerSettings.ReferrerToIgnore) ? (object)request.UrlReferrer.ToString() : DBNull.Value));
                        }
                    }
                    if (UrlTrackerSettings.IsNotFoundTrackingDisabled)
                    {
                        LoggingHelper.LogInformation("UrlTracker HttpModule | No match found and not found (404) tracking is disabled");
                    }
                    if (UrlTrackerSettings.NotFoundUrlsToIgnore.Contains(urlWithoutQueryString))
                    {
                        LoggingHelper.LogInformation("UrlTracker HttpModule | No match found, url is configured to be ignored: {0}", urlWithoutQueryString);
                    }
                    else if (UmbracoHelper.IsReservedPathOrUrl(urlWithoutQueryString))
                    {
                        LoggingHelper.LogInformation("UrlTracker HttpModule | No match found, url is ignored because it's an umbraco reserved URL or path: {0}", urlWithoutQueryString);
                    }
                    else if (request.Headers["X-UrlTracker-Ignore404"] == "1")
                    {
                        LoggingHelper.LogInformation("UrlTracker HttpModule | No match found, url is ignored because the 'X-UrlTracker-Ignore404' header was set to '1'. URL: {0}", urlWithoutQueryString);
                    }
                }
                else
                {
                    LoggingHelper.LogInformation("UrlTracker HttpModule | No match found in {0}", callingEventName);
                }
            }
            else
            {
                LoggingHelper.LogInformation("UrlTracker HttpModule | Response statuscode is not 404, UrlTracker won't do anything");
            }

            LoggingHelper.LogInformation("UrlTracker HttpModule | {0} end", callingEventName);
        }
Пример #14
0
        private static void UrlTrackerDo(bool ignoreHttpStatusCode = false)
        {
            HttpContext  context  = HttpContext.Current;
            HttpRequest  request  = context.Request;
            HttpResponse response = context.Response;

            if (!string.IsNullOrEmpty(request.QueryString[UrlTrackerSettings.HttpModuleCheck]))
            {
                response.Clear();
                response.Write(UrlTrackerSettings.HttpModuleCheck);
                response.StatusCode = 200;
                response.End();
                return;
            }

            LoggingHelper.LogInformation("UrlTracker HttpModule | PostReleaseRequestState start");

            if (UrlTrackerSettings.IsDisabled)
            {
                LoggingHelper.LogInformation("UrlTracker HttpModule | UrlTracker is disabled by config");
                return;
            }

            string url = request.RawUrl;

            if (url.StartsWith("/"))
            {
                url = url.Substring(1);
            }

            LoggingHelper.LogInformation("UrlTracker HttpModule | Incoming URL is: {0}", url);

            if (_urlTrackerInstalled && (response.StatusCode == (int)HttpStatusCode.NotFound || ignoreHttpStatusCode))
            {
                if (response.StatusCode == (int)HttpStatusCode.NotFound)
                {
                    LoggingHelper.LogInformation("UrlTracker HttpModule | Response statusCode is 404, continue URL matching");
                }
                else
                {
                    LoggingHelper.LogInformation("UrlTracker HttpModule | Checking for forced redirects (AcquireRequestState), continue URL matching");
                }

                string urlWithoutQueryString = url;
                if (InfoCaster.Umbraco.UrlTracker.Helpers.UmbracoHelper.IsReservedPathOrUrl(url))
                {
                    LoggingHelper.LogInformation("UrlTracker HttpModule | URL is an umbraco reserved path or url, ignore request");
                    return;
                }

                bool urlHasQueryString = request.QueryString.HasKeys() && url.Contains('?');
                if (urlHasQueryString)
                {
                    urlWithoutQueryString = url.Substring(0, url.IndexOf('?'));
                }

                string shortestUrl = UrlTrackerHelper.ResolveShortestUrl(urlWithoutQueryString);

                int rootNodeId = -1;
                List <UrlTrackerDomain> domains = UmbracoHelper.GetDomains();
                if (domains.Any())
                {
                    string fullRawUrl;
                    string previousFullRawUrlTest;
                    string fullRawUrlTest;
                    fullRawUrl = previousFullRawUrlTest = fullRawUrlTest = string.Format("{0}://{1}{2}", request.Url.Scheme, request.Url.Host, request.RawUrl);

                    UrlTrackerDomain urlTrackerDomain;
                    do
                    {
                        if (previousFullRawUrlTest.EndsWith("/"))
                        {
                            urlTrackerDomain = domains.FirstOrDefault(x => x.UrlWithDomain == fullRawUrlTest);
                            if (urlTrackerDomain != null)
                            {
                                rootNodeId            = urlTrackerDomain.NodeId;
                                urlWithoutQueryString = fullRawUrl.Replace(fullRawUrlTest, string.Empty);
                                if (urlWithoutQueryString.StartsWith("/"))
                                {
                                    urlWithoutQueryString = urlWithoutQueryString.Substring(1);
                                }
                                break;
                            }
                        }
                        previousFullRawUrlTest = fullRawUrlTest;
                        fullRawUrlTest         = fullRawUrlTest.Substring(0, fullRawUrlTest.Length - 1);
                    }while (fullRawUrlTest.Length > 0);
                }
                if (rootNodeId == -1)
                {
                    rootNodeId = -1;
                    List <INode> children = new Node(rootNodeId).ChildrenAsList;
                    if (children != null && children.Any())
                    {
                        rootNodeId = children.First().Id;
                    }
                }
                LoggingHelper.LogInformation("UrlTracker HttpModule | Current request's rootNodeId: {0}", rootNodeId);

                string redirectUrl      = null;
                int?   redirectHttpCode = null;
                bool   redirectPassThroughQueryString = true;

                // Normal matching
                string query = "SELECT * FROM icUrlTracker WHERE Is404 = 0 AND ForceRedirect = @forceRedirect AND (RedirectRootNodeId = @redirectRootNodeId OR RedirectRootNodeId IS NULL) AND (OldUrl = @url OR OldUrl = @shortestUrl) ORDER BY OldUrlQueryString DESC";
                using (IRecordsReader reader = _sqlHelper.ExecuteReader(query, _sqlHelper.CreateParameter("forceRedirect", ignoreHttpStatusCode ? "1" : "0"), _sqlHelper.CreateParameter("redirectRootNodeId", rootNodeId), _sqlHelper.CreateParameter("url", urlWithoutQueryString), _sqlHelper.CreateParameter("shortestUrl", shortestUrl)))
                {
                    while (reader.Read())
                    {
                        LoggingHelper.LogInformation("UrlTracker HttpModule | URL match found");
                        if (!reader.IsNull("RedirectNodeId"))
                        {
                            int redirectNodeId = reader.GetInt("RedirectNodeId");
                            LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect node id: {0}", redirectNodeId);
                            Node n = new Node(redirectNodeId);
                            if (n != null && n.Name != null && n.Id > 0)
                            {
                                string tempUrl = UmbracoHelper.GetUrl(redirectNodeId);
                                redirectUrl = tempUrl.StartsWith("http") ? tempUrl : string.Format("{0}://{1}{2}{3}", HttpContext.Current.Request.Url.Scheme, HttpContext.Current.Request.Url.Host, HttpContext.Current.Request.Url.Port != 80 ? string.Concat(":", HttpContext.Current.Request.Url.Port) : string.Empty, tempUrl);
                                if (redirectUrl.StartsWith("http"))
                                {
                                    Uri    redirectUri  = new Uri(redirectUrl);
                                    string pathAndQuery = Uri.UnescapeDataString(redirectUri.PathAndQuery);
                                    redirectUrl = pathAndQuery.StartsWith("/") && pathAndQuery != "/" ? pathAndQuery.Substring(1) : pathAndQuery;
                                }
                                LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect url set to: {0}", redirectUrl);
                            }
                            else
                            {
                                LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect node is invalid; node is null, name is null or id <= 0");
                                continue;
                            }
                        }
                        else if (!reader.IsNull("RedirectUrl"))
                        {
                            redirectUrl = reader.GetString("RedirectUrl");
                            LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect url set to: {0}", redirectUrl);
                        }

                        redirectPassThroughQueryString = reader.GetBoolean("RedirectPassThroughQueryString");
                        LoggingHelper.LogInformation("UrlTracker HttpModule | PassThroughQueryString is {0}", redirectPassThroughQueryString ? "enabled" : "disabled");

                        NameValueCollection oldUrlQueryString = null;
                        if (!reader.IsNull("OldUrlQueryString"))
                        {
                            oldUrlQueryString = HttpUtility.ParseQueryString(reader.GetString("OldUrlQueryString"));
                            LoggingHelper.LogInformation("UrlTracker HttpModule | Old URL query string set to: {0}", oldUrlQueryString.ToQueryString());
                        }

                        if ((urlHasQueryString || oldUrlQueryString != null) && (oldUrlQueryString != null && !request.QueryString.CollectionEquals(oldUrlQueryString)))
                        {
                            LoggingHelper.LogInformation("UrlTracker HttpModule | Aborting; query strings don't match");
                            continue;
                        }

                        redirectHttpCode = reader.GetInt("RedirectHttpCode");
                        LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect http code set to: {0}", redirectHttpCode);

                        break;
                    }
                }

                if (!redirectHttpCode.HasValue)
                {
                    // Regex matching
                    query = "SELECT * FROM icUrlTracker WHERE Is404 = 0 AND ForceRedirect = @forceRedirect AND RedirectRootNodeId = @redirectRootNodeId AND OldRegex IS NOT NULL ORDER BY Inserted DESC";
                    using (IRecordsReader reader = _sqlHelper.ExecuteReader(query, _sqlHelper.CreateParameter("forceRedirect", ignoreHttpStatusCode ? "1" : "0"), _sqlHelper.CreateParameter("redirectRootNodeId", rootNodeId)))
                    {
                        Regex regex;
                        while (reader.Read())
                        {
                            regex = new Regex(reader.GetString("OldRegex"));
                            if (regex.IsMatch(url))
                            {
                                LoggingHelper.LogInformation("UrlTracker HttpModule | Regex match found");
                                if (!reader.IsNull("RedirectNodeId"))
                                {
                                    int redirectNodeId = reader.GetInt("RedirectNodeId");
                                    LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect node id: {0}", redirectNodeId);
                                    Node n = new Node(redirectNodeId);
                                    if (n != null && n.Name != null && n.Id > 0)
                                    {
                                        redirectUrl = UmbracoHelper.GetUrl(redirectNodeId);
                                        LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect url set to: {0}", redirectUrl);
                                    }
                                    else
                                    {
                                        LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect node is invalid; node is null, name is null or id <= 0");
                                    }
                                }
                                else if (!reader.IsNull("RedirectUrl"))
                                {
                                    redirectUrl = reader.GetString("RedirectUrl");
                                    LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect url set to: {0}", redirectUrl);

                                    if (_capturingGroupsRegex.IsMatch(redirectUrl))
                                    {
                                        LoggingHelper.LogInformation("UrlTracker HttpModule | Found regex capturing groups in the redirect url");
                                        redirectUrl = regex.Replace(url, redirectUrl);

                                        LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect url changed to: {0} (because of regex capturing groups)", redirectUrl);
                                    }
                                }

                                redirectPassThroughQueryString = reader.GetBoolean("RedirectPassThroughQueryString");
                                LoggingHelper.LogInformation("UrlTracker HttpModule | PassThroughQueryString is enabled");

                                redirectHttpCode = reader.GetInt("RedirectHttpCode");
                                LoggingHelper.LogInformation("UrlTracker HttpModule | Redirect http code set to: {0}", redirectHttpCode);
                            }
                        }
                    }
                }

                if (redirectHttpCode.HasValue)
                {
                    response.Clear();
                    response.StatusCode = redirectHttpCode.Value;
                    LoggingHelper.LogInformation("UrlTracker HttpModule | Response statuscode set to: {0}", response.StatusCode);
                    if (!string.IsNullOrEmpty(redirectUrl))
                    {
                        if (redirectUrl == "/")
                        {
                            redirectUrl = string.Empty;
                        }
                        Uri redirectUri = new Uri(redirectUrl.StartsWith("http") ? redirectUrl : string.Format("{0}://{1}{2}/{3}", request.Url.Scheme, request.Url.Host, request.Url.Port != 80 ? string.Concat(":", request.Url.Port) : string.Empty, redirectUrl));
                        if (redirectPassThroughQueryString)
                        {
                            NameValueCollection redirectQueryString = HttpUtility.ParseQueryString(redirectUri.Query);
                            NameValueCollection newQueryString      = HttpUtility.ParseQueryString(request.Url.Query);
                            if (redirectQueryString.HasKeys())
                            {
                                newQueryString = newQueryString.Merge(redirectQueryString);
                            }
                            string pathAndQuery = Uri.UnescapeDataString(redirectUri.PathAndQuery);
                            redirectUri = new Uri(string.Format("{0}://{1}{2}/{3}{4}", redirectUri.Scheme, redirectUri.Host, redirectUri.Port != 80 ? string.Concat(":", redirectUri.Port) : string.Empty, pathAndQuery.Contains('?') ? pathAndQuery.Substring(0, pathAndQuery.IndexOf('?')) : pathAndQuery.StartsWith("/") ? pathAndQuery.Substring(1) : pathAndQuery, newQueryString.HasKeys() ? string.Concat("?", newQueryString.ToQueryString()) : string.Empty));
                        }
                        response.RedirectLocation = redirectUri.ToString();
                        LoggingHelper.LogInformation("UrlTracker HttpModule | Response redirectlocation set to: {0}", response.RedirectLocation);
                    }
                    response.End();
                }
                else if (!ignoreHttpStatusCode)
                {
                    // Log 404
                    if (!UrlTrackerSettings.IsNotFoundTrackingDisabled && !UrlTrackerSettings.NotFoundUrlsToIgnore.Contains(urlWithoutQueryString) && !UmbracoHelper.IsReservedPathOrUrl(urlWithoutQueryString) && request.Headers["X-UrlTracker-Ignore404"] != "1")
                    {
                        bool ignoreNotFoundBasedOnRegexPatterns = false;
                        foreach (Regex regexNotFoundUrlToIgnore in UrlTrackerSettings.RegexNotFoundUrlsToIgnore)
                        {
                            if (regexNotFoundUrlToIgnore.IsMatch(urlWithoutQueryString))
                            {
                                ignoreNotFoundBasedOnRegexPatterns = true;
                                break;
                            }
                        }

                        if (!ignoreNotFoundBasedOnRegexPatterns)
                        {
                            LoggingHelper.LogInformation("UrlTracker HttpModule | No match found, logging as 404 not found");
                            query = "INSERT INTO icUrlTracker (OldUrl, RedirectRootNodeId, ";
                            if (urlHasQueryString)
                            {
                                query += "OldUrlQueryString, ";
                            }
                            query += "Is404, Referrer) VALUES (@oldUrl, @redirectRootNodeId, ";
                            if (urlHasQueryString)
                            {
                                query += "@oldUrlQueryString, ";
                            }
                            query += "1, @referrer)";
                            _sqlHelper.ExecuteNonQuery(query, _sqlHelper.CreateParameter("oldUrl", urlWithoutQueryString), _sqlHelper.CreateParameter("redirectRootNodeId", rootNodeId), _sqlHelper.CreateParameter("oldUrlQueryString", request.QueryString.ToString()), _sqlHelper.CreateParameter("referrer", request.UrlReferrer != null && !request.UrlReferrer.ToString().Contains(UrlTrackerSettings.ReferrerToIgnore) ? (object)request.UrlReferrer.ToString() : DBNull.Value));
                        }
                    }
                    if (UrlTrackerSettings.IsNotFoundTrackingDisabled)
                    {
                        LoggingHelper.LogInformation("UrlTracker HttpModule | No match found and not found (404) tracking is disabled");
                    }
                    if (UrlTrackerSettings.NotFoundUrlsToIgnore.Contains(urlWithoutQueryString))
                    {
                        LoggingHelper.LogInformation("UrlTracker HttpModule | No match found, url is configured to be ignored: {0}", urlWithoutQueryString);
                    }
                    else if (UmbracoHelper.IsReservedPathOrUrl(urlWithoutQueryString))
                    {
                        LoggingHelper.LogInformation("UrlTracker HttpModule | No match found, url is ignored because it's an umbraco reserved URL or path: {0}", urlWithoutQueryString);
                    }
                    else if (request.Headers["X-UrlTracker-Ignore404"] == "1")
                    {
                        LoggingHelper.LogInformation("UrlTracker HttpModule | No match found, url is ignored because the 'X-UrlTracker-Ignore404' header was set to '1'. URL: {0}", urlWithoutQueryString);
                    }
                }
            }
            else
            {
                LoggingHelper.LogInformation("UrlTracker HttpModule | Response statuscode is not 404, UrlTracker won't do anything");
            }

            LoggingHelper.LogInformation("UrlTracker HttpModule | PostReleaseRequestState end");
        }
Пример #15
0
        public static int MigrateData()
        {
            if (!GetUrlTrackerTableExists())
            {
                throw new Exception("Url Tracker table not found.");
            }
            if (!GetUrlTrackeOldTableExists())
            {
                throw new Exception("Old Url Tracker table not found.");
            }

            var newUrlTrackerEntriesCount = 0;

            var query = string.Format("SELECT * FROM {0}", UrlTrackerSettings.OldTableName);

            var oldUrlTrackerEntries = ApplicationContext.Current.DatabaseContext.Database.Query <OldUrlTrackerModel>(query).ToList();

            foreach (var oldUrlTrackerEntry in oldUrlTrackerEntries)
            {
                var node = new Node(oldUrlTrackerEntry.NodeId);
                if ((node.Id > 0 || true) && !string.IsNullOrEmpty(oldUrlTrackerEntry.OldUrl) && oldUrlTrackerEntry.OldUrl != "#")
                {
                    var oldUrl = oldUrlTrackerEntry.OldUrl;
                    Uri oldUri = null;
                    if (!oldUrlTrackerEntry.IsRegex)
                    {
                        if (!oldUrl.StartsWith(Uri.UriSchemeHttp))
                        {
                            oldUri = new Uri(_baseUri, oldUrl);
                        }
                        else
                        {
                            oldUri = new Uri(oldUrl);
                        }
                        oldUrl = UrlTrackerHelper.ResolveShortestUrl(oldUri.AbsolutePath);
                    }
                    else
                    {
                        if (oldUrl.StartsWith("^/"))
                        {
                            oldUrl = string.Concat("^", oldUrl.Substring(2));
                        }
                        if (oldUrl.StartsWith("/"))
                        {
                            oldUrl = oldUrl.Substring(1);
                        }
                        if (oldUrl.EndsWith("/$"))
                        {
                            oldUrl = string.Concat(oldUrl.Substring(0, oldUrl.Length - 2), "$");
                        }
                        if (oldUrl.EndsWith("/"))
                        {
                            oldUrl = oldUrl.Substring(0, oldUrl.Length - 1);
                        }
                    }

                    var newUrlTrackerEntry = new UrlTrackerModel(
                        !oldUrlTrackerEntry.IsRegex ? oldUrl : string.Empty,
                        oldUri != null ? !string.IsNullOrEmpty(oldUri.Query) && oldUri.Query.StartsWith("?") ? oldUri.Query.Substring(1) : oldUri.Query : string.Empty,
                        oldUrlTrackerEntry.IsRegex ? oldUrl : string.Empty,
                        node.GetDomainRootNode().Id,
                        oldUrlTrackerEntry.NodeId,
                        string.Empty,
                        301,
                        true,
                        false,
                        oldUrlTrackerEntry.Message);
                    newUrlTrackerEntry.Inserted = oldUrlTrackerEntry.Inserted;

                    AddUrlTrackerEntry(newUrlTrackerEntry);

                    newUrlTrackerEntriesCount++;
                }
            }

            return(newUrlTrackerEntriesCount);
        }
Пример #16
0
        public static bool AddUrlMapping(IContent content, int rootNodeId, string url, AutoTrackingTypes type, bool isChild = false)
        {
            if (url != "#" && content.Template != null && content.Template.Id > 0)
            {
                var notes = isChild ? "An ancestor" : "This page";
                switch (type)
                {
                case AutoTrackingTypes.Moved:
                    notes += " was moved";
                    break;

                case AutoTrackingTypes.Renamed:
                    notes += " was renamed";
                    break;

                case AutoTrackingTypes.UrlOverwritten:
                    notes += "'s property 'umbracoUrlName' changed";
                    break;

                case AutoTrackingTypes.UrlOverwrittenSEOMetadata:
                    notes += string.Format("'s property '{0}' changed", UrlTrackerSettings.SEOMetadataPropertyName);
                    break;
                }

                url = UrlTrackerHelper.ResolveShortestUrl(url);

                if (UrlTrackerSettings.HasDomainOnChildNode)
                {
                    var rootNode = new Node(rootNodeId);
                    var rootUrl  = !rootNode.Url.StartsWith("/")
                        ? rootNode.NiceUrl
                        : string.Format("{0}{1}{2}", Uri.UriSchemeHttp, Uri.SchemeDelimiter, HttpContext.Current.Request.Url.Host) + rootNode.NiceUrl;

                    var rootUri      = new Uri(rootUrl);
                    var shortRootUrl = UrlTrackerHelper.ResolveShortestUrl(rootUri.AbsolutePath);
                    if (url.StartsWith(shortRootUrl, StringComparison.OrdinalIgnoreCase))
                    {
                        url = UrlTrackerHelper.ResolveShortestUrl(url.Substring(shortRootUrl.Length));
                    }
                }

                var database = ApplicationContext.Current.DatabaseContext.Database;

                if (!string.IsNullOrEmpty(url))
                {
                    var query = "SELECT 1 FROM icUrlTracker WHERE RedirectNodeId = @nodeId AND OldUrl = @url";

                    var exists = database.ExecuteScalar <int?>(query, new object[] { new { nodeId = content.Id }, new { url = url } });

                    if (exists != 1)
                    {
                        LoggingHelper.LogInformation("UrlTracker Repository | Adding mapping for node id: {0} and url: {1}", new string[] { content.Id.ToString(), url });

                        database.Insert(
                            "icUrlTracker",
                            "Id",
                            true,
                            new { RedirectRootNodeId = rootNodeId, RedirectNodeId = content.Id, OldUrl = url, Notes = notes });
                        if (content.Children().Any())
                        {
                            foreach (var child in content.Children())
                            {
                                var node = new Node(child.Id);
                                AddUrlMapping(child, rootNodeId, node.NiceUrl, type, true);
                            }
                        }

                        return(true);
                    }
                }
            }
            return(false);
        }