/// <summary> /// The main method for the processor. It simply overrides the Process method. /// </summary> public override void Process(HttpRequestArgs args) { // This processer is added to the pipeline after the Sitecore Item Resolver. We want to skip everything if the item resolved successfully. // Also, skip processing for the visitor identification items related to DMS. Assert.ArgumentNotNull(args, "args"); var allowExternalHost = AllowExternalHost(HttpContext.Current.Request.Url.Host); if ((allowExternalHost || Context.Item == null || AllowRedirectsOnFoundItem(Context.Database)) && args.LocalPath != Constants.Paths.VisitorIdentification && Context.Database != null) { // Grab the actual requested path for use in both the item and pattern match sections. var requestedUrl = HttpContext.Current.Request.Url.ToString().TrimEnd('/'); var requestedPath = HttpContext.Current.Request.Url.AbsolutePath; var requestedPathAndQuery = HttpContext.Current.Request.Url.PathAndQuery; var currentIpAddress = GetClientIPAddress(); var db = Context.Database; // First, we check for exact matches because those take priority over pattern matches. if (Sitecore.Configuration.Settings.GetBoolSetting(Constants.Settings.RedirExactMatch, true)) { // Loop through the exact match entries to look for a match. foreach (Item possibleRedirect in GetRedirects(db, Constants.Templates.RedirectUrl, Constants.Templates.VersionedRedirectUrl, Sitecore.Configuration.Settings.GetSetting(Constants.Settings.QueryExactMatch))) { var trimmedItemRequestedUrl = possibleRedirect[Constants.Fields.RequestedUrl].TrimEnd('/'); if (requestedUrl.Equals(trimmedItemRequestedUrl, StringComparison.OrdinalIgnoreCase) || requestedPath.Equals(trimmedItemRequestedUrl, StringComparison.OrdinalIgnoreCase)) { var redirectToItemId = possibleRedirect.Fields[Constants.Fields.RedirectToItem]; var redirectToUrl = possibleRedirect.Fields[Constants.Fields.RedirectToUrl]; var redirectFromCode = possibleRedirect.Fields[Constants.Fields.RedirectCode]; var maxMind = Sitecore.Configuration.Settings.GetSetting(Constants.Settings.MaxMindType); if (redirectToItemId.HasValue && !string.IsNullOrEmpty(redirectToItemId.ToString())) { var redirectToItem = db.GetItem(ID.Parse(redirectToItemId)); if (redirectToItem != null) { var responseStatus = GetResponseStatus(possibleRedirect); switch (maxMind) { case "0": { SendResponse(redirectToItem, HttpContext.Current.Request.Url.Query, responseStatus, args); break; } case "1": { if (!redirectFromCode.HasValue || string.IsNullOrEmpty(redirectFromCode.ToString())) { goto case "0"; } if (redirectFromCode.HasValue && !string.IsNullOrEmpty(redirectFromCode.ToString()) && HaveCodeMatch(redirectFromCode.Value, DatabaseHelper.GetCodeFromIP(currentIpAddress))) { goto case "0"; } break; } case "2": { if (!redirectFromCode.HasValue || string.IsNullOrEmpty(redirectFromCode.ToString())) { goto case "0"; } if (redirectFromCode.HasValue && !string.IsNullOrEmpty(redirectFromCode.ToString()) && HaveCodeMatch(redirectFromCode.Value, WebServiceHelper.GetCodeFromIP(currentIpAddress))) { goto case "0"; } break; } default: { goto case "0"; } } } } else if (redirectToUrl.HasValue && !string.IsNullOrEmpty(redirectToUrl.ToString())) { var responseStatus = GetResponseStatus(possibleRedirect); switch (maxMind) { case "0": { SendResponse(redirectToUrl.Value, HttpContext.Current.Request.Url.Query, responseStatus, args); break; } case "1": { if (!redirectFromCode.HasValue || string.IsNullOrEmpty(redirectFromCode.ToString())) { goto case "0"; } if (redirectFromCode.HasValue && !string.IsNullOrEmpty(redirectFromCode.ToString()) && HaveCodeMatch(redirectFromCode.Value, DatabaseHelper.GetCodeFromIP(currentIpAddress))) { goto case "0"; } break; } case "2": { if (!redirectFromCode.HasValue || string.IsNullOrEmpty(redirectFromCode.ToString())) { goto case "0"; } if (redirectFromCode.HasValue && !string.IsNullOrEmpty(redirectFromCode.ToString()) && HaveCodeMatch(redirectFromCode.Value, DatabaseHelper.GetCodeFromIP(currentIpAddress))) { goto case "0"; } break; } default: { goto case "0"; } } } } } } // Finally, we check for pattern matches because we didn't hit on an exact match. if (Sitecore.Configuration.Settings.GetBoolSetting(Constants.Settings.RedirPatternMatch, true)) { // Loop through the pattern match items to find a match foreach (Item possibleRedirectPattern in GetRedirects(db, Constants.Templates.RedirectPattern, Constants.Templates.VersionedRedirectPattern, Sitecore.Configuration.Settings.GetSetting(Constants.Settings.QueryExactMatch))) { var redirectPath = string.Empty; var relativePathMatch = false; if (Regex.IsMatch(requestedUrl, possibleRedirectPattern[Constants.Fields.RequestedExpression], RegexOptions.IgnoreCase)) { redirectPath = Regex.Replace(requestedUrl, possibleRedirectPattern[Constants.Fields.RequestedExpression], possibleRedirectPattern[Constants.Fields.SourceItem], RegexOptions.IgnoreCase); } else if (Regex.IsMatch(requestedPathAndQuery, possibleRedirectPattern[Constants.Fields.RequestedExpression], RegexOptions.IgnoreCase)) { if (!string.IsNullOrEmpty(possibleRedirectPattern[Constants.Fields.SourceItem])) { redirectPath = Regex.Replace(requestedPathAndQuery, possibleRedirectPattern[Constants.Fields.RequestedExpression], possibleRedirectPattern[Constants.Fields.SourceItem], RegexOptions.IgnoreCase); } else if ( !string.IsNullOrEmpty( possibleRedirectPattern[Constants.Fields.RelativeDestinationPath])) { redirectPath = Regex.Replace(requestedPathAndQuery, possibleRedirectPattern[Constants.Fields.RequestedExpression], possibleRedirectPattern[Constants.Fields.RelativeDestinationPath], RegexOptions.IgnoreCase); relativePathMatch = true; } } if (string.IsNullOrEmpty(redirectPath)) { continue; } // Query portion gets in the way of getting the sitecore item. var pathAndQuery = redirectPath.Split('?'); var path = pathAndQuery[0]; if (LinkManager.Provider != null && LinkManager.Provider.GetDefaultUrlOptions() != null && LinkManager.Provider.GetDefaultUrlOptions().EncodeNames) { path = MainUtil.DecodeName(path); } var redirectToItem = db.GetItem(path); var responseStatus = GetResponseStatus(redirectToItem); if (redirectToItem != null) { var query = pathAndQuery.Length > 1 ? "?" + pathAndQuery[1] : ""; SendResponse(redirectToItem, query, responseStatus, args); } else if (relativePathMatch) { var query = pathAndQuery.Length > 1 ? "?" + pathAndQuery[1] : ""; SendResponse(redirectPath, query, responseStatus, args); } } } if (!allowExternalHost) { return; } //Couldn't find a mapping based on settings. For non-Sitecore hostnames var notFoundUrl = Sitecore.Configuration.Settings.GetSetting(Constants.Settings.ExternalHostsNotFoundUrl); SendTempResponse(notFoundUrl, HttpContext.Current.Request.Url.Query, args); } }