Esempio n. 1
0
        /// <summary>
        /// Logs the 404 error to a table for later checking 
        /// </summary>
        /// <param name="request"></param>
        /// <param name="settings"></param>
        /// <param name="result"></param>
        public static void Log404(HttpRequest request, FriendlyUrlSettings settings, UrlAction result)
        {
            var controller = new LogController();
            var log = new LogInfo
                {
                    LogTypeKey = EventLogController.EventLogType.PAGE_NOT_FOUND_404.ToString(),
                    LogPortalID = (result.PortalAlias != null) ? result.PortalId : -1
                };
            log.LogProperties.Add(new LogDetailInfo("TabId", (result.TabId > 0) ? result.TabId.ToString() : String.Empty));
            log.LogProperties.Add(new LogDetailInfo("PortalAlias",  (result.PortalAlias != null) ? result.PortalAlias.HTTPAlias : String.Empty));
            log.LogProperties.Add(new LogDetailInfo("OriginalUrl",  result.RawUrl));

            if (request != null)
            {
                if (request.UrlReferrer != null)
                {
                    log.LogProperties.Add(new LogDetailInfo("Referer", request.UrlReferrer.AbsoluteUri));
                }
                log.LogProperties.Add(new LogDetailInfo("Url", request.Url.AbsoluteUri));
                log.LogProperties.Add(new LogDetailInfo("UserAgent", request.UserAgent));
                log.LogProperties.Add(new LogDetailInfo("HostAddress", request.UserHostAddress));
                log.LogProperties.Add(new LogDetailInfo("HostName", request.UserHostName));
            }

            controller.AddLog(log);
        }
Esempio n. 2
0
        /// <summary>
        /// Checks for a redirect based on a module friendly url provider rule
        /// </summary>
        /// <param name="requestUri"></param>
        /// <param name="result"></param>
        /// <param name="queryStringCol"></param>
        /// <param name="settings"></param>
        /// <param name="parentTraceId"></param>
        /// <returns></returns>
        internal static bool CheckForModuleProviderRedirect(Uri requestUri,
                                                            ref UrlAction result,
                                                            NameValueCollection queryStringCol,
                                                            FriendlyUrlSettings settings,
                                                            Guid parentTraceId)
        {
            var    messages = new List <string>();
            string location;
            bool   redirected = ExtensionUrlProviderController.CheckForRedirect(requestUri,
                                                                                result,
                                                                                queryStringCol,
                                                                                settings,
                                                                                out location,
                                                                                ref messages,
                                                                                parentTraceId);

            if (messages != null)
            {
                result.DebugMessages.AddRange(messages);
            }
            if (redirected)
            {
                result.FinalUrl = location;
                result.Action   = ActionType.Redirect301;
                result.Reason   = RedirectReason.Custom_Redirect;
            }
            return(redirected);
        }
Esempio n. 3
0
        /// <summary>
        /// Cancels a redirect.
        /// </summary>
        /// <param name="result"></param>
        /// <param name="context"></param>
        /// <param name="settings"></param>
        /// <param name="message"></param>
        internal static void CancelRedirect(ref UrlAction result, HttpContext context, FriendlyUrlSettings settings, string message)
        {
            result.Action   = ActionType.Continue;
            result.Reason   = RedirectReason.Not_Redirected;
            result.FinalUrl = null;

            // clean the path for the rewrite
            NameValueCollection queryString = null;

            if (context != null)
            {
                queryString = context.Request.QueryString;
            }

            result.RewritePath = RedirectTokens.RemoveAnyRedirectTokens(result.RewritePath, queryString);

            // redo the rewrite to fix up the problem.  The user has ticked 'permanent redirect' but hasn't supplied a forwarding Url
            if (context != null)

            // if no context supplied, means no rewrite was required because querystring didn't contain do301 action
            {
                // RewriterUtils.RewriteUrl(context, result.RewritePath, settings.RebaseClientPath);
                RewriterUtils.RewriteUrl(context, result.RewritePath);
            }

            result.DebugMessages.Add(message);
        }
 /// <summary>
 /// Checks for a redirect based on a module friendly url provider rule
 /// </summary>
 /// <param name="requestUri"></param>
 /// <param name="result"></param>
 /// <param name="queryStringCol"></param>
 /// <param name="settings"></param>
 /// <param name="parentTraceId"></param>
 /// <returns></returns>
 internal static bool CheckForModuleProviderRedirect(Uri requestUri, 
                                                         ref UrlAction result,
                                                         NameValueCollection queryStringCol,
                                                         FriendlyUrlSettings settings, 
                                                         Guid parentTraceId)
 {
     var messages = new List<string>();
     string location;
     bool redirected = ExtensionUrlProviderController.CheckForRedirect(requestUri, 
                                                                         result, 
                                                                         queryStringCol, 
                                                                         settings,
                                                                         out location, 
                                                                         ref messages, 
                                                                         parentTraceId);
     if (messages != null)
     {
         result.DebugMessages.AddRange(messages);
     }
     if (redirected)
     {
         result.FinalUrl = location;
         result.Action = ActionType.Redirect301;
         result.Reason = RedirectReason.Custom_Redirect;
     }
     return redirected;
 }
        /// <summary>
        /// Logs the 404 error to a table for later checking.
        /// </summary>
        /// <param name="request"></param>
        /// <param name="settings"></param>
        /// <param name="result"></param>
        public static void Log404(HttpRequest request, FriendlyUrlSettings settings, UrlAction result)
        {
            var log = new LogInfo
            {
                LogTypeKey  = EventLogController.EventLogType.PAGE_NOT_FOUND_404.ToString(),
                LogPortalID = (result.PortalAlias != null) ? result.PortalId : -1,
            };

            log.LogProperties.Add(new LogDetailInfo("TabId", (result.TabId > 0) ? result.TabId.ToString() : string.Empty));
            log.LogProperties.Add(new LogDetailInfo("PortalAlias", (result.PortalAlias != null) ? result.PortalAlias.HTTPAlias : string.Empty));
            log.LogProperties.Add(new LogDetailInfo("OriginalUrl", result.RawUrl));

            if (request != null)
            {
                try
                {
                    if (request.UrlReferrer != null)
                    {
                        log.LogProperties.Add(new LogDetailInfo("Referer", request.UrlReferrer.AbsoluteUri));
                    }
                }
                catch (UriFormatException)
                {
                    log.LogProperties.Add(new LogDetailInfo("Referer", request.Headers["Referer"]));
                }

                log.LogProperties.Add(new LogDetailInfo("Url", request.Url.AbsoluteUri));
                log.LogProperties.Add(new LogDetailInfo("UserAgent", request.UserAgent));
                log.LogProperties.Add(new LogDetailInfo("HostAddress", request.UserHostAddress));
                log.LogProperties.Add(new LogDetailInfo("HostName", request.UserHostName));
            }

            LogController.Instance.AddLog(log);
        }
Esempio n. 6
0
        internal static bool CheckForRedirect(
            Uri requestUri,
            UrlAction result,
            NameValueCollection queryStringCol,
            FriendlyUrlSettings settings,
            out string location,
            ref List <string> messages,
            Guid parentTraceId)
        {
            bool redirected = false;

            location = string.Empty;
            ExtensionUrlProvider activeProvider = null;

            try
            {
                List <ExtensionUrlProvider> providersToCall = GetProvidersToCall(result.TabId, result.PortalId, settings,
                                                                                 parentTraceId);
                if (providersToCall != null && providersToCall.Count > 0)
                {
                    FriendlyUrlOptions options = UrlRewriterUtils.GetOptionsFromSettings(settings);
                    foreach (ExtensionUrlProvider provider in providersToCall)
                    {
                        activeProvider = provider; // for error handling
                        redirected     = provider.CheckForRedirect(result.TabId, result.PortalId, result.HttpAlias,
                                                                   requestUri, queryStringCol, options, out location,
                                                                   ref messages);
                        if (redirected)
                        {
                            result.FinalUrl = location;
                            result.Reason   = RedirectReason.Module_Provider_Redirect;
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                // log module provider exception
                LogModuleProviderExceptionInRequest(ex, "500 Internal Server Error", activeProvider, result, messages);

                // return defaults
                redirected = false;
                location   = string.Empty;
                string providerName = "Unknown";
                if (activeProvider != null)
                {
                    providerName = activeProvider.ProviderConfig.ProviderName;
                }

                if (result != null)
                {
                    result.DebugMessages.Add("Exception in provider [" + providerName + "] :" + ex.Message);
                }
            }

            return(redirected);
        }
        /// <summary>
        /// Returns a ChosenPortalAlias object where the portalId, culture code and isMobile matches
        /// </summary>
        /// <param name="aliases"></param>
        /// <param name="portalId"></param>
        /// <param name="result"></param>
        /// <param name="cultureCode"></param>
        /// <param name="browserType"></param>
        /// <returns>A ChosenPOrtalAlias</returns>
        /// <remarks>Note will return a best-match by portal if no specific culture Code match found</remarks>
        public static PortalAliasInfo GetAliasByPortalIdAndSettings(this IEnumerable<PortalAliasInfo> aliases, int portalId, UrlAction result, string cultureCode, BrowserTypes browserType)
        {
            var aliasList = aliases.ToList();

            var defaultAlias = aliasList.ToList().Where(a => a.PortalID == portalId)
                                        .OrderByDescending(a => a.IsPrimary)
                                        .FirstOrDefault();

            //27138 : Redirect loop caused by duplicate primary aliases.  Changed to only check by browserType/Culture code which makes a primary alias
            var foundAlias = aliasList.Where(a => a.BrowserType == browserType
                                            && (String.Compare(a.CultureCode, cultureCode, StringComparison.OrdinalIgnoreCase) == 0 || String.IsNullOrEmpty(a.CultureCode))
                                            && a.PortalID == portalId)
                        .OrderByDescending(a => a.IsPrimary)
                        .ThenByDescending(a => a.CultureCode)
                        .FirstOrDefault();

			//JIRA DNN-4882 : DevPCI fix bug with url Mobile -> Search alias with culture code
			// START DNN-4882
            if (foundAlias == null)
            {
                foundAlias = aliasList.Where(a => (String.Compare(a.CultureCode, cultureCode, StringComparison.OrdinalIgnoreCase) == 0 || String.IsNullOrEmpty(a.CultureCode))
                                           && a.PortalID == portalId)
					   .OrderByDescending(a => a.IsPrimary)
					   .ThenByDescending(a => a.CultureCode)
					   .FirstOrDefault();
            }
            // END DNN-4882
		
            if (foundAlias != null)
            {
                if(result !=null && result.PortalAlias != null)
                {
                    if (foundAlias.BrowserType != result.PortalAlias.BrowserType)
                    {
                        result.Reason = foundAlias.CultureCode != result.PortalAlias.CultureCode 
                            ? RedirectReason.Wrong_Portal_Alias_For_Culture_And_Browser 
                            : RedirectReason.Wrong_Portal_Alias_For_Browser_Type;
                    }
                    else
                    {
                        if (foundAlias.CultureCode != result.PortalAlias.CultureCode)
                        {
                            result.Reason = RedirectReason.Wrong_Portal_Alias_For_Culture;
                        }
                    }
                }
            }
            else
            {
                foundAlias = defaultAlias;
            }

            //if we didn't find a specific match, return the default, which is the closest match
            return foundAlias;
        }
 /// <summary>
 /// Returns the chosen portal alias for a specific portal Id and culture Code
 /// </summary>
 /// <param name="aliases"></param>
 /// <param name="portalId"></param>
 /// <param name="cultureCode"></param>
 /// <remarks>Detects the current browser type if possible.  If can't be deteced 'normal' is used. If a specific browser type is required, use overload with browser type.</remarks>
 /// <returns></returns>
 public static PortalAliasInfo GetAliasByPortalIdAndSettings(this IEnumerable<PortalAliasInfo> aliases, int portalId, UrlAction result, string cultureCode, FriendlyUrlSettings settings)
 {
     var browserType = BrowserTypes.Normal;
     //if required, and possible, detect browser type
     if (HttpContext.Current != null && settings != null)
     {
         HttpRequest request = HttpContext.Current.Request;
         HttpResponse response = HttpContext.Current.Response;
         browserType = FriendlyUrlController.GetBrowserType(request, response, settings);
     }
     return GetAliasByPortalIdAndSettings(aliases, portalId, result, cultureCode, browserType);
 }
Esempio n. 9
0
        /// <summary>
        /// Sets the Action and Reason values in the UrlAction parameter.
        /// </summary>
        /// <param name="result"></param>
        /// <param name="settings"></param>
        internal static void SetRedirectReasonAndAction(ref UrlAction result, FriendlyUrlSettings settings)
        {
            RedirectReason reason;
            ActionType     action;
            string         newUrl;

            DetermineRedirectReasonAndAction(result.RewritePath, result, true, settings, out newUrl, out reason,
                                             out action);
            result.Action      = action;
            result.Reason      = reason;
            result.RewritePath = newUrl;
        }
Esempio n. 10
0
        /// <summary>
        /// Gets a redirect Url for when the tab has a specified external Url that is of type 'TabType.Tab'.  This covers both
        /// 'PermanentRedirect' and 'ExternalUrl' scenarios, where the settings are to redirect the value.
        /// </summary>
        /// <param name="tab"></param>
        /// <param name="settings"></param>
        /// <param name="cleanPath"></param>
        /// <param name="result"></param>
        /// <param name="permRedirect"></param>
        /// <param name="parentTraceId"></param>
        /// <returns></returns>
        /// <remarks>823 : Moved from CheckForRedirects to allow call earlier in pipeline.</remarks>
        internal static string GetTabRedirectUrl(
            TabInfo tab,
            FriendlyUrlSettings settings,
            string cleanPath,
            UrlAction result,
            out bool permRedirect,
            Guid parentTraceId)
        {
            string bestFriendlyUrl = null;

            // 592 : check for permanent redirect
            permRedirect = tab.PermanentRedirect;
            int redirectTabId;

            if (int.TryParse(tab.Url, out redirectTabId))
            {
                // ok, redirecting to a new tab, specified by the tabid in the Url field
                TabInfo redirectTab = TabController.Instance.GetTab(redirectTabId, tab.PortalID, false);
                if (redirectTab != null)
                {
                    // now get the friendly url for that tab
                    bestFriendlyUrl = AdvancedFriendlyUrlProvider.ImprovedFriendlyUrl(
                        redirectTab,
                        cleanPath,
                        Globals.glbDefaultPage,
                        result.HttpAlias,
                        false,
                        settings,
                        parentTraceId);
                }
            }
            else
            {
                // use the url, as specified in the dnn tab url property
                // 776 : when no url, don't redirect
                if (tab.Url != string.Empty)
                {
                    bestFriendlyUrl = tab.Url;
                }
                else
                {
                    // 776: no actual Url for the 'perm redirect'.
                    // this is a mistake on the part of the person who created the perm redirect
                    // but don't create a redirect or there will be a terminal loop
                    permRedirect = false;
                }
            }

            return(bestFriendlyUrl);
        }
 /// <summary>
 /// Cancels a redirect
 /// </summary>
 /// <param name="result"></param>
 /// <param name="context"></param>
 /// <param name="settings"></param>
 /// <param name="message"></param>
 internal static void CancelRedirect(ref UrlAction result, HttpContext context, FriendlyUrlSettings settings, string message)
 {
     result.Action = ActionType.Continue;
     result.Reason = RedirectReason.Not_Redirected;
     result.FinalUrl = null;
     //clean the path for the rewrite 
     NameValueCollection queryString = null;
     if (context != null)
     {
         queryString = context.Request.QueryString;
     }
     result.RewritePath = RedirectTokens.RemoveAnyRedirectTokens(result.RewritePath, queryString);
     //redo the rewrite to fix up the problem.  The user has ticked 'permanent redirect' but hasn't supplied a forwarding Url
     if (context != null)
     //if no context supplied, means no rewrite was required because querystring didn't contain do301 action
     {
         //RewriterUtils.RewriteUrl(context, result.RewritePath, settings.RebaseClientPath);
         RewriterUtils.RewriteUrl(context, result.RewritePath);
     }
     result.DebugMessages.Add(message);
 }
 private static bool IgnoreRequest(UrlAction result, string requestedPath, string ignoreRegex, HttpRequest request)
 {
     bool retVal = false;
     //check if we are upgrading/installing 
     //829 : use result physical path instead of requset physical path
     //875 : cater for the upgradewizard.aspx Url that is new to DNN 6.1
     if (request != null && (IgnoreRequestForInstall(request) || IgnoreRequestForWebServer(requestedPath)))
     {
         //ignore all install requests
         retVal = true;
     }
     else if (request != null && (request.Path.EndsWith("SetGettingStartedPageAsShown") || request.Path.ToLower().EndsWith("ImageChallenge.captcha.aspx".ToLower())))
     {
         //ignore request to the Getting Started Web Method
         retVal = true;
     }
     else
     {
         try
         {
             if ((ignoreRegex.Length > 0))
             {
                 if (Regex.IsMatch(requestedPath, ignoreRegex, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
                 {
                     retVal = true;
                 }
             }
         }
         catch (Exception ex)
         {
             UrlRewriterUtils.LogExceptionInRequest(ex, "Not Set", result);
             result.Ex = ex;
         }
     }
     return retVal;
 }
 internal static void RewriteAsChildAliasRoot(HttpContext context, 
                                                 UrlAction result, 
                                                 string aliasQueryString,
                                                 FriendlyUrlSettings settings)
 {
     string culture = null;
     //look for specific alias to rewrite language parameter
     var primaryAliases = PortalAliasController.Instance.GetPortalAliasesByPortalId(result.PortalId).ToList();
     if (result.PortalId > -1 && result.HttpAlias != null)
     {
         culture = primaryAliases.GetCultureByPortalIdAndAlias(result.PortalId, result.HttpAlias);
     }
     if (string.IsNullOrEmpty(culture))
         //732 : when no culture returned can be "" as well as null : no culture causes no rewrite, which results in redirect to parent alias
     {
         //set the default culture code here
         //735 : switch to custom method for getting portal
         PortalInfo pi = CacheController.GetPortal(result.PortalId, false);
         if (pi != null)
         {
             culture = pi.DefaultLanguage;
         }
     }
     if (!string.IsNullOrEmpty(culture)) //a culture was identified for the alias root
     {
         if (RewriteController.AddLanguageCodeToRewritePath(ref aliasQueryString, culture))
         {
             result.CultureCode = culture;
         }
         result.DoRewrite = true;
         result.RewritePath = "~/" + Globals.glbDefaultPage + aliasQueryString;
         //the expected /default.aspx path (defaultPageUrl) matches the requested Url (/default.aspx)
         if (context != null)
         {
             //only do if not testing
             RewriterUtils.RewriteUrl(context, result.RewritePath);
         }
     }
 }
 /// <summary>
 /// Configures the result object to set the correct Alias redirect
 /// parameters and destination URL
 /// </summary>
 /// <param name="result"></param>
 /// <param name="wrongAlias"></param>
 /// <param name="rightAlias"></param>
 /// <param name="ignoreCustomAliasTabs"></param>
 /// <param name="redirectReason"></param>
 /// <param name="internalAliases"></param>
 /// <param name="settings"></param>
 /// <returns></returns>
 private static bool ConfigurePortalAliasRedirect(ref UrlAction result, 
                                                     string wrongAlias, 
                                                     string rightAlias,
                                                     bool ignoreCustomAliasTabs, 
                                                     RedirectReason redirectReason,
                                                     List<InternalAlias> internalAliases,
                                                     FriendlyUrlSettings settings)
 {
     //wrong alias for the portal
     //check to see if the wrong portal alias could be a custom alias for a tab
     bool doRedirect;
     if (ignoreCustomAliasTabs == false) //check out custom alias tabs collection
     {
         //if an alias is a custom tab alias for a specific tab, then don't redirect
         if (CheckIfAliasIsCustomTabAlias(ref result, wrongAlias, settings)) 
             doRedirect = false;
         else
         {
             doRedirect = true;
         }
     }
     else
     {
         doRedirect = true; //do redirect, ignore custom alias entries for tabs
     }
     //check to see if it is an internal alias.  These are used to block redirects
     //to allow for reverse proxy requests, which must change the rewritten alias
     //while leaving the requested alias
     bool internalAliasFound = false;
     if (doRedirect && internalAliases != null && internalAliases.Count > 0)
     {
         if (internalAliases.Any(ia => String.Compare(ia.HttpAlias, wrongAlias, StringComparison.OrdinalIgnoreCase) == 0))
         {
             internalAliasFound = true;
             doRedirect = false;
         }
     }
     //if still need to do redirect, then set the settings that will cause the redirect (redirect not done here)
     if (doRedirect)
     {
         result.Action = ActionType.Redirect301;
         result.Reason = redirectReason;
         string destUrl = result.OriginalPath.Replace(wrongAlias, rightAlias);
         if (redirectReason == RedirectReason.Wrong_Portal_Alias_For_Culture ||
             redirectReason == RedirectReason.Wrong_Portal_Alias_For_Culture_And_Browser)
         {
             destUrl = destUrl.Replace("/language/" + result.CultureCode, "");
         }
         destUrl = CheckForSiteRootRedirect(rightAlias, destUrl);
         result.FinalUrl = destUrl;
     }
     else
     {
         //838 : don't overwrite the reason if already have checkfor301
         // and don't do a check on the basis that an internal alias was found
         if (result.Action != ActionType.CheckFor301 && internalAliasFound == false)
         {
             //set status to 'check for redirect'
             result.Action = ActionType.CheckFor301;
             result.Reason = RedirectReason.Custom_Tab_Alias;
         }
     }
     return doRedirect;
 }
        private void ProcessRequest(HttpContext context,
                                Uri requestUri,
                                bool useFriendlyUrls,
                                UrlAction result,
                                FriendlyUrlSettings settings,
                                bool allowSettingsChange,
                                Guid parentTraceId)
        {
            bool finished = false;
            bool showDebug = false;
            bool postRequest = false;

            HttpRequest request = context.Request;
            HttpResponse response = context.Response;
            string requestType = request.RequestType;
            NameValueCollection queryStringCol = request.QueryString;

            try
            {

                string fullUrl, querystring;
                //699: get the full url based on the request and the quersytring, rather than the requestUri.ToString()
                //there is a difference in encoding, which can corrupt results when an encoded value is in the querystring
                RewriteController.GetUrlWithQuerystring(request, requestUri, out fullUrl, out querystring);

                showDebug = CheckForDebug(request, queryStringCol, settings.AllowDebugCode);
                string ignoreRegex = settings.IgnoreRegex;
                bool ignoreRequest = IgnoreRequest(result, fullUrl, ignoreRegex, request);
                bool redirectAlias = false;
                if (!ignoreRequest)
                {
                    //set original path
                    context.Items["UrlRewrite:OriginalUrl"] = requestUri.AbsoluteUri;

                    //set the path of the result object, and determine if a redirect is allowed on this request
                    result.SetOriginalPath(requestUri.ToString(), settings);
                    //737 : set the mobile browser 
                    result.SetBrowserType(request, response, settings);
                    //add to context
                    context.Items["UrlRewrite:BrowserType"] = result.BrowserType.ToString();

                    //839 : split out this check
                    result.SetRedirectAllowed(result.OriginalPath, settings);

                    //find the portal alias first
                    string wrongAlias;
                    bool isPrimaryAlias;
                    var requestedAlias = GetPortalAlias(settings, fullUrl, out redirectAlias, out isPrimaryAlias, out wrongAlias);
                    
                    if (requestedAlias != null)
                    {
                        //827 : now get the correct settings for this portal (if not a test request)
                        //839 : separate out redirect check as well and move above first redirect test (ConfigurePortalAliasRedirect)
                        if (allowSettingsChange)
                        {
                            settings = new FriendlyUrlSettings(requestedAlias.PortalID);
                            result.SetRedirectAllowed(result.OriginalPath, settings);
                        }
                        result.PortalAlias = requestedAlias;
                        result.PrimaryAlias = requestedAlias;//this is the primary alias
                        result.PortalId = requestedAlias.PortalID;
                        result.CultureCode = requestedAlias.CultureCode;
                        //get the portal alias mapping for this portal
                        result.PortalAliasMapping = PortalSettings.GetPortalAliasMappingMode(requestedAlias.PortalID);

                        //if requested alias wasn't the primary, we have a replacement, redirects are allowed and the portal alias mapping mode is redirect
                        //then do a redirect based on the wrong portal
                        if ((redirectAlias && wrongAlias != null) && result.RedirectAllowed && result.PortalAliasMapping != PortalSettings.PortalAliasMapping.Redirect)
                        {
                            //this is the alias, we are going to enforce it as the primary alias
                            result.PortalAlias = requestedAlias;
                            result.PrimaryAlias = requestedAlias;
                            //going to redirect this alias because it is incorrect
                            //or do we just want to mark as 'check for 301??'
                            redirectAlias = ConfigurePortalAliasRedirect(ref result,
                                                                            wrongAlias,
                                                                            requestedAlias.HTTPAlias,
                                                                            false,
                                                                            settings.InternalAliasList,
                                                                            settings);
                        }
                        else
                        {
                            //do not redirect the wrong alias, but set the primary alias value
                            if (wrongAlias != null)
                            {
                                //get the portal alias info for the requested alias (which is the wrong one)
                                //and set that as the alias, but also set the found alias as the primary
                                PortalAliasInfo wrongAliasInfo = PortalAliasController.Instance.GetPortalAlias(wrongAlias);
                                if (wrongAliasInfo != null)
                                {
                                    result.PortalAlias = wrongAliasInfo;
                                    result.PrimaryAlias = requestedAlias;
                                }
                                
                            }
                        }
                    }
                }
                ignoreRegex = settings.IgnoreRegex;
                ignoreRequest = IgnoreRequest(result, fullUrl, ignoreRegex, request);
                if (!ignoreRequest) 
                {
                    //check to see if a post request
                    if (request.RequestType == "POST")
                    {
                        postRequest = true;
                    }

                    //check the portal alias again.  This time, in more depth now that the portal Id is known 
                    //this check handles browser types/language specific aliases & mobile aliases
                    string primaryHttpAlias;
                    if (!redirectAlias && IsPortalAliasIncorrect(context, request, requestUri, result, queryStringCol, settings, parentTraceId, out primaryHttpAlias))
                    {
                        //it was an incorrect alias
                        PortalAliasInfo primaryAlias = PortalAliasController.Instance.GetPortalAlias(primaryHttpAlias);
                        if (primaryAlias != null) result.PrimaryAlias = primaryAlias;
                        //try and redirect the alias if the settings allow it
                        redirectAlias = RedirectPortalAlias(primaryHttpAlias, ref result, settings);
                    }

                    if (redirectAlias)
                    {
                        //not correct alias for portal : will be redirected
                        //perform a 301 redirect if one has already been found
                        response.Status = "301 Moved Permanently";
                        response.AppendHeader("X-Redirect-Reason", result.Reason.ToString().Replace("_", " ") + " Requested");
                        response.AddHeader("Location", result.FinalUrl);
                        finished = true;
                        response.End();
                    }
                    if (!finished)
                    {
                        //Check to see if this to be rewritten into default.aspx?tabId=nn format
                        //this call is the main rewriting matching call.  It makes the decision on whether it is a 
                        //physical file, whether it is toe be rewritten or redirected by way of a stored rule

                        //Check if we have a standard url
                        var uri = new Uri(fullUrl);
                        if (uri.PathAndQuery.ToLowerInvariant().StartsWith("/" + Globals.glbDefaultPage.ToLowerInvariant()))
                        {
                            result.DoRewrite = true;
                            result.Action = ActionType.CheckFor301;
                            result.RewritePath = Globals.glbDefaultPage + uri.Query;
                        }
                        else
                        {
                            bool isPhysicalResource;
                            CheckForRewrite(fullUrl, querystring, result, useFriendlyUrls, queryStringCol, settings, out isPhysicalResource, parentTraceId);
                        }

                        //return 404 if there is no portal alias for a rewritten request
                        if (result.DoRewrite && result.PortalAlias == null)
                        {
                            //882 : move this logic in from where it was before to here
                            //so that non-rewritten requests don't trip over it
                            //no portal alias found for the request : that's a 404 error
                            result.Action = ActionType.Output404;
                            result.Reason = RedirectReason.No_Portal_Alias;

                            Handle404OrException(settings, context, null, result, false, showDebug);
                            finished = true; //cannot fulfil request unless correct portal alias specified
                        }
                    }

                    if (!finished && result.DoRewrite)
                    {
                        //check the identified portal alias details for any extra rewrite information required
                        //this includes the culture and the skin, which can be placed into the rewrite path
                        //This logic is here because it will catch any Urls which are excluded from rewriting
                        var primaryAliases = PortalAliasController.Instance.GetPortalAliasesByPortalId(result.PortalId).ToList();

                        if (result.PortalId > -1 && result.HttpAlias != null)
                        {
                            string culture;
                            string skin;
                            BrowserTypes browserType;
                            primaryAliases.GetSettingsByPortalIdAndAlias(result.PortalId, result.HttpAlias,
                                                                                            out culture, 
                                                                                            out browserType,
                                                                                            out skin);
                            //add language code to path if it exists (not null) and if it's not already there
                            string rewritePath = result.RewritePath;
                            if (RewriteController.AddLanguageCodeToRewritePath(ref rewritePath, culture))
                            {
                                result.CultureCode = culture;
                            }

                            //852: add skinSrc to path if it exists and if it's not already there
                            string debugMessage;
                            RewriteController.AddSkinToRewritePath(result.TabId, result.PortalId, ref rewritePath, skin, out debugMessage);
                            result.RewritePath = rewritePath; //reset back from ref temp var
                            if (debugMessage != null)
                            {
                                result.DebugMessages.Add(debugMessage);
                            }
                        }
                    }

                    if (!finished && result.DoRewrite)
                    {
                        //if so, do the rewrite
                        if (result.RewritePath.StartsWith(result.Scheme) || result.RewritePath.StartsWith(Globals.glbDefaultPage) == false)
                        {
                            if (result.RewritePath.Contains(Globals.glbDefaultPage) == false)
                            {
                                RewriterUtils.RewriteUrl(context, "~/" + result.RewritePath);
                            }
                            else
                            {
                                //if there is no TabId and we have the domain
                                if (!result.RewritePath.ToLowerInvariant().Contains("tabId="))
                                {
                                    RewriterUtils.RewriteUrl(context, "~/" + result.RewritePath);
                                }
                                else
                                {
                                    RewriterUtils.RewriteUrl(context, result.RewritePath);
                                }
                            }
                        }
                        else
                        {
                            RewriterUtils.RewriteUrl(context, "~/" + result.RewritePath);
                        }
                    }

                    //confirm which portal the request is for 
                    if (!finished)
                    {
                        IdentifyPortalAlias(context, request, requestUri, result, queryStringCol, settings, parentTraceId);
                        if (result.Action == ActionType.Redirect302Now)
                        {
                            //performs a 302 redirect if requested
                            response.AppendHeader("X-Redirect-Reason", result.Reason.ToString().Replace("_", " ") + " Requested");
                            response.Redirect(result.FinalUrl, false);
                            finished = true;
                        }
                        else
                        {
                            if (result.Action == ActionType.Redirect301 && !string.IsNullOrEmpty(result.FinalUrl))
                            {
                                finished = true;
                                //perform a 301 redirect if one has already been found
                                response.Status = "301 Moved Permanently";
                                response.AppendHeader("X-Redirect-Reason", result.Reason.ToString().Replace("_", " ") + " Requested");
                                response.AddHeader("Location", result.FinalUrl);
                                response.End();
                            }
                        }
                    }
                    
                    if (!finished)
                    {
                        //check to see if this tab has an external url that should be forwared or not
                        finished = CheckForTabExternalForwardOrRedirect(context, ref result, response, settings, parentTraceId);
                    }

                    //check for a parameter redirect (we had to do all the previous processing to know we are on the right portal and identify the tabid)
                    //if the CustomParmRewrite flag is set, it means we already rewrote these parameters, so they have to be correct, and aren't subject to 
                    //redirection.  The only reason to do a custom parm rewrite is to interpret already-friendly parameters
                    if (!finished
                        && !postRequest /* either request is null, or it's not a post - 551 */
                        && result.HttpAlias != null /* must have a http alias */
                        && !result.CustomParmRewrite && /* not custom rewritten parms */
                        ((settings.EnableCustomProviders &&
                          RedirectController.CheckForModuleProviderRedirect(requestUri, ref result, queryStringCol, settings, parentTraceId))
                        //894 : allow disable of all custom providers
                         ||
                         RedirectController.CheckForParameterRedirect(requestUri, ref result, queryStringCol, settings)))
                    {
                        //301 redirect to new location based on parameter match
                        if (response != null)
                        {
                            switch (result.Action)
                            {
                                case ActionType.Redirect301:
                                    response.Status = "301 Moved Permanently";
                                    response.AppendHeader("X-Redirect-Reason", result.Reason.ToString().Replace("_", " ") + " Requested");
                                    response.AddHeader("Location", result.FinalUrl);
                                    response.End();
                                    break;
                                case ActionType.Redirect302:
                                    response.AppendHeader("X-Redirect-Reason", result.Reason.ToString().Replace("_", " ") + " Requested");
                                    response.Redirect(result.FinalUrl);
                                    break;
                                case ActionType.Output404:
                                    response.AppendHeader("X-Result-Reason", result.Reason.ToString().Replace("_", " "));
                                    Handle404OrException(settings, context, null, result, true, showDebug);
                                    break;
                            }
                        }
                        finished = true;
                    }

                    //shifted until after the 301 redirect code to allow redirects to be checked for pages which have no rewrite value
                    //look for a 404 result from the rewrite, because of a deleted page or rule
                    if (!finished && result.Action == ActionType.Output404)
                    {
                        if (result.OriginalPath == result.HttpAlias && result.PortalAlias != null
                                && result.Reason != RedirectReason.Deleted_Page && result.Reason != RedirectReason.Disabled_Page)
                        {
                            //Request for domain with no page identified (and no home page set in Site Settings)
                            result.Action = ActionType.Continue;
                        }
                        else
                        {
                            finished = true;
                            response.AppendHeader("X-Result-Reason", result.Reason.ToString().Replace("_", " "));

                            if (showDebug)
                            {
                                ShowDebugData(context, requestUri.AbsoluteUri, result, null);
                            }
                            //show the 404 page if configured
                            result.Reason = RedirectReason.Requested_404;
                            Handle404OrException(settings, context, null, result, true, showDebug);
                        }
                    }

                    if (!finished)
                    {
                        //add the portal settings to the app context if the portal alias has been found and is correct
                        if (result.PortalId != -1 && result.PortalAlias != null)
                        {
                            Globals.SetApplicationName(result.PortalId);
                            // load the PortalSettings into current context 
                            var portalSettings = new PortalSettings(result.TabId, result.PortalAlias);
                            //set the primary alias if one was specified
                            if (result.PrimaryAlias != null) portalSettings.PrimaryAlias = result.PrimaryAlias;

                            if (result.CultureCode != null && fullUrl.Contains(result.CultureCode) &&
                                portalSettings.DefaultLanguage == result.CultureCode)
                            {
                                //when the request culture code is the same as the portal default, check for a 301 redirect, because we try and remove the language from the url where possible
                                result.Action = ActionType.CheckFor301;
                            }

                            int portalHomeTabId = portalSettings.HomeTabId;
                            if (context != null && portalSettings != null && !context.Items.Contains("PortalSettings"))
                            {
                                context.Items.Add("PortalSettings", portalSettings);
                            }
                            //check if a secure redirection is needed
                            //this would be done earlier in the piece, but need to know the portal settings, tabid etc before processing it
                            bool redirectSecure = CheckForSecureRedirect(portalSettings, requestUri, result, queryStringCol, settings);
                            if (redirectSecure)
                            {
                                if (response != null)
                                {
                                    //702 : don't check final url until checked for null reference first
                                    if (result.FinalUrl != null)
                                    {
                                        if (result.FinalUrl.StartsWith("https://"))
                                        {
                                            if (showDebug)
                                            {
                                                /*
                                                string debugMsg = "{0}, {1}, {2}, {3}, {4}";
                                                string productVer = System.Reflection.Assembly.GetExecutingAssembly().GetName(false).Version.ToString();
                                                response.AppendHeader("X-" + prodName + "-Debug", string.Format(debugMsg, requestUri.AbsoluteUri, result.FinalUrl, result.RewritePath, result.Action, productVer));
                                                 */
                                                ShowDebugData(context, fullUrl, result, null);
                                            }
                                            response.AppendHeader("X-Redirect-Reason", result.Reason.ToString().Replace("_", " ") + " Requested");
                                            response.Redirect(result.FinalUrl, false);
                                            finished = true;
                                        }
                                        else
                                        {
                                            if (settings.SSLClientRedirect)
                                            {
                                                //redirect back to http version, use client redirect
                                                response.Clear();
                                                // add a refresh header to the response 
                                                response.AddHeader("Refresh", "0;URL=" + result.FinalUrl);
                                                // add the clientside javascript redirection script
                                                response.Write("<html><head><title></title>");
                                                response.Write(@"<!-- <script language=""javascript"">window.location.replace(""" + result.FinalUrl + @""")</script> -->");
                                                response.Write("</head><body><div><a href='" + result.FinalUrl + "'>" + result.FinalUrl + "</a></div></body></html>");
                                                if (showDebug)
                                                {
                                                    /*
                                                    string debugMsg = "{0}, {1}, {2}, {3}, {4}";
                                                    string productVer = System.Reflection.Assembly.GetExecutingAssembly().GetName(false).Version.ToString();
                                                    response.AppendHeader("X-" + prodName + "-Debug", string.Format(debugMsg, requestUri.AbsoluteUri, result.FinalUrl, result.RewritePath, result.Action, productVer));
                                                     */
                                                    ShowDebugData(context, fullUrl, result, null);
                                                }
                                                // send the response
                                                //891 : reinstate the response.end to stop the entire page loading
                                                response.End();
                                                finished = true;
                                            }
                                            else
                                            {
                                                response.AppendHeader("X-Redirect-Reason", result.Reason.ToString().Replace("_", " ") + " Requested");
                                                response.Redirect(result.FinalUrl, false);
                                                finished = true;
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                //check for, and do a 301 redirect if required 
                                if (CheckForRedirects(requestUri, fullUrl, queryStringCol, result, requestType, settings, portalHomeTabId))
                                {
                                    if (response != null)
                                    {
                                        if (result.Action == ActionType.Redirect301)
                                        {
                                            response.Status = "301 Moved Permanently";
                                            response.AppendHeader("X-Redirect-Reason", result.Reason.ToString().Replace("_", " ") + " Requested");
                                            response.AddHeader("Location", result.FinalUrl);
                                            finished = true;
                                            response.End();
                                        }
                                        else if (result.Action == ActionType.Redirect302)
                                        {
                                            response.AppendHeader("X-Redirect-Reason", result.Reason.ToString().Replace("_", " ") + " Requested");
                                            response.Redirect(result.FinalUrl, false);
                                            finished = true;
                                        }
                                    }
                                }
                                else
                                {
                                    //612 : Don't clear out a 302 redirect if set
                                    if (result.Action != ActionType.Redirect302 &&
                                        result.Action != ActionType.Redirect302Now)
                                    {
                                        result.Reason = RedirectReason.Not_Redirected;
                                        result.FinalUrl = null;
                                    }
                                }
                            }
                        }
                        else
                        {
                            // alias does not exist in database 
                            // and all attempts to find another have failed 
                            //this should only happen if the HostPortal does not have any aliases 
                            result.Action = ActionType.Output404;
                            if (response != null)
                            {
                                if (showDebug)
                                {
                                    ShowDebugData(context, fullUrl, result, null);
                                }
                                result.Reason = RedirectReason.Requested_404;
                                //912 : change 404 type to transfer to allow transfer to main portal in single-portal installs
                                Handle404OrException(settings, context, null, result, true, showDebug);
                                finished = true;
                            }
                        }
                    }

                    //404 page ??
                    if (settings.TabId404 > 0 && settings.TabId404 == result.TabId)
                    {
                        string status = queryStringCol["status"];
                        if (status == "404")
                        {
                            //respond with a 404 error
                            result.Action = ActionType.Output404;
                            result.Reason = RedirectReason.Requested_404_In_Url;
                            Handle404OrException(settings, context, null, result, true, showDebug);
                        }
                    }
                    else
                    {
                        if (result.DoRewrite == false && result.CanRewrite != StateBoolean.False && !finished &&
                            result.Action == ActionType.Continue)
                        {
                            //739 : catch no-extension 404 errors
                            string pathWithNoQs = result.OriginalPath;
                            if (pathWithNoQs.Contains("?"))
                            {
                                pathWithNoQs = pathWithNoQs.Substring(0, pathWithNoQs.IndexOf("?", StringComparison.Ordinal));
                            }
                            if (!pathWithNoQs.Substring(pathWithNoQs.Length - 5, 5).Contains("."))
                            {
                                //no page extension, output a 404 if the Url is not found
                                //766 : check for physical path before passing off as a 404 error
                                //829 : change to use action physical path
                                //893 : filter by regex pattern to exclude urls which are valid, but show up as extensionless
                                if ((request != null && Directory.Exists(result.PhysicalPath))
                                    ||
                                    Regex.IsMatch(pathWithNoQs, settings.ValidExtensionlessUrlsRegex, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
                                {
                                    //do nothing : it's a request for a valid physical path, maybe including a default document
                                    result.VirtualPath = StateBoolean.False;
                                }
                                else
                                {
                                    if (!ServiceApi.IsMatch(context.Request.RawUrl))
                                    {
                                        //no physical path, intercept the request and hand out a 404 error
                                        result.Action = ActionType.Output404;
                                        result.Reason = RedirectReason.Page_404;
                                        result.VirtualPath = StateBoolean.True;
                                        //add in a message to explain this 404, becaue it can be cryptic
                                        result.DebugMessages.Add("404 Reason : Not found and no extension");
                                        Handle404OrException(settings, context, null, result, true, showDebug);
                                    }
                                }
                            }
                        }
                    }

                    //  show debug messages after extensionless-url special 404 handling
                    if (showDebug)
                    {
                        ShowDebugData(context, fullUrl, result, null);
                    }
                }
            }
            catch (ThreadAbortException)
            {
                //do nothing, a threadAbortException will have occured from using a server.transfer or response.redirect within the code block.  This is the highest
                //level try/catch block, so we handle it here.
            }
            catch (Exception ex)
            {
                if (showDebug)
                {
                    Services.Exceptions.Exceptions.LogException(ex);
                }
                if (response != null)
                {
                    if (showDebug)
                    {
                        ShowDebugData(context, requestUri.AbsoluteUri, result, ex);
                    }
                    if (result != null)
                    {
                        result.Ex = ex;
                        result.Reason = RedirectReason.Exception;
                    }
                    Handle404OrException(settings, context, ex, result, false, showDebug);
                }
                else
                {
                    if (result != null && result.DebugMessages != null)
                    {
                        result.DebugMessages.Add("Exception: " + ex.Message);
                        result.DebugMessages.Add("Stack Trace: " + ex.StackTrace);
                    }
                    throw;
                }
            }
            finally
            {
                //809 : add in new code copied from urlRewrite class in standard Url Rewrite module
                if (context != null && context.Items["FirstRequest"] != null)
                {
                    context.Items.Remove("FirstRequest");
                    //process any messages in the eventQueue for the Application_Start_FIrstRequest event
                    EventQueueController.ProcessMessages("Application_Start_FirstRequest");
                }
            }
        }
        /// <summary>
        /// Redirects an alias if that is allowed by the settings
        /// </summary>
        /// <param name="httpAlias"></param>
        /// <param name="result"></param>
        /// <param name="settings"></param>
        /// <returns></returns>

        private static bool RedirectPortalAlias(string httpAlias, ref UrlAction result, FriendlyUrlSettings settings)
        {
            bool redirected = false;
            //redirect to primary alias
            if (result.PortalAliasMapping == PortalSettings.PortalAliasMapping.Redirect && result.RedirectAllowed)
            {
                if (result.Reason == RedirectReason.Wrong_Portal_Alias_For_Browser_Type || result.Reason == RedirectReason.Wrong_Portal_Alias_For_Culture ||
                    result.Reason == RedirectReason.Wrong_Portal_Alias_For_Culture_And_Browser)
                {
                    redirected = ConfigurePortalAliasRedirect(ref result, result.HttpAlias, httpAlias, false, result.Reason, settings.InternalAliasList, settings);
                }
                else
                {
                    redirected = ConfigurePortalAliasRedirect(ref result, result.HttpAlias, httpAlias, false, settings.InternalAliasList, settings);
                }
            }

            return redirected;
        }
        private bool CheckForSecureRedirect(PortalSettings portalSettings, 
                                                Uri requestUri, 
                                                UrlAction result, 
                                                NameValueCollection queryStringCol,
                                                FriendlyUrlSettings settings)
        {
            bool redirectSecure = false;
            string url = requestUri.ToString();
            //889 : don't run secure redirect code for physical resources or requests that aren't a rewritten Url
            if (result.IsPhysicalResource == false && result.TabId >= 0)
                // no secure redirection for physical resources, only tab-specific requests can be redirected for ssl connections
            {
                if (portalSettings.ActiveTab != null)
                {
                    result.DebugMessages.Add("ActiveTab: " + portalSettings.ActiveTab.TabID.ToString() + "/" +
                                             portalSettings.ActiveTab.TabName + " IsSecure: " +
                                             portalSettings.ActiveTab.IsSecure.ToString());

                    //check ssl enabled
                    if (portalSettings.SSLEnabled)
                    {
                        //717 : check page is secure, connection is not secure
                        //952 : support SSl Offloading in DNN 6.2+
                        if (portalSettings.ActiveTab.IsSecure && !result.IsSecureConnection && !result.IsSSLOffloaded)
                        {
                            redirectSecure = true;
                            string stdUrl = portalSettings.STDURL;
                            string sslUrl = portalSettings.SSLURL;
                            if (string.IsNullOrEmpty(result.HttpAlias) == false)
                            {
                                stdUrl = result.HttpAlias;
                            }
                            url = url.Replace("http://", "https://");
                            url = ReplaceDomainName(url, stdUrl, sslUrl);
                        }
                    }
                    //check ssl enforced
                    if (portalSettings.SSLEnforced)
                    {
                        //check page is not secure, connection is secure
                        if (!portalSettings.ActiveTab.IsSecure && result.IsSecureConnection)
                        {
                            //has connection already been forced to secure?
                            if (queryStringCol["ssl"] == null)
                            {
                                //no? well this page shouldn't be secure
                                string stdUrl = portalSettings.STDURL;
                                string sslUrl = portalSettings.SSLURL;
                                url = url.Replace("https://", "http://");
                                url = ReplaceDomainName(url, sslUrl, stdUrl);
                                redirectSecure = true;
                            }
                        }
                    }
                }


                if (redirectSecure)
                {
                    //now check to see if excluded.  Why now? because less requests are made to redirect secure,
                    //so we don't have to check the exclusion as often.
                    bool exclude = false;
                    string doNotRedirectSecureRegex = settings.DoNotRedirectSecureRegex;
                    if (!string.IsNullOrEmpty(doNotRedirectSecureRegex))
                    {
                        //match the raw url
                        exclude = (Regex.IsMatch(result.RawUrl, doNotRedirectSecureRegex, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant));
                    }
                    if (!exclude)
                    {
                        result.Action = ActionType.Redirect302Now;
                        result.Reason = RedirectReason.Secure_Page_Requested;
                        //760 : get the culture specific home page tabid for a redirect comparison
                        int homePageTabId = portalSettings.HomeTabId;
                        homePageTabId = TabPathHelper.GetHomePageTabIdForCulture(portalSettings.DefaultLanguage,
                                                                                 portalSettings.PortalId,
                                                                                 result.CultureCode, homePageTabId);
                        if (result.TabId == homePageTabId)
                        {
                            //replace the /default.aspx in the Url if it was found
                            url = Regex.Replace(url, @"(?<!(\?.+))/default.aspx", "/", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
                        }
                        result.FinalUrl = url;
                    }
                    else
                    {
                        //702 : change return value if exclusion has occured
                        redirectSecure = false;
                    }
                }
            }
            return redirectSecure;
        }
Esempio n. 18
0
 /// <summary>
 /// Sets the Action and Reason values in the UrlAction parameter
 /// </summary>
 /// <param name="result"></param>
 /// <param name="settings"></param>
 internal static void SetRedirectReasonAndAction(ref UrlAction result, FriendlyUrlSettings settings)
 {
     RedirectReason reason;
     ActionType action;
     string newUrl;
     DetermineRedirectReasonAndAction(result.RewritePath, result, true, settings, out newUrl, out reason,
                                      out action);
     result.Action = action;
     result.Reason = reason;
     result.RewritePath = newUrl;
 }
Esempio n. 19
0
        internal static bool CheckForParameterRedirect(Uri requestUri,
                                                       ref UrlAction result,
                                                       NameValueCollection queryStringCol,
                                                       FriendlyUrlSettings settings)
        {
            //check for parameter replaced works by inspecting the parameters on a rewritten request, comparing
            //them agains the list of regex expressions on the friendlyurls.config file, and redirecting to the same page
            //but with new parameters, if there was a match
            bool redirect = false;
            //get the redirect actions for this portal
            var messages = new List <string>();
            Dictionary <int, List <ParameterRedirectAction> > redirectActions = CacheController.GetParameterRedirects(settings, result.PortalId, ref messages);

            if (redirectActions != null && redirectActions.Count > 0)
            {
                try
                {
                    #region trycatch block

                    string rewrittenUrl = result.RewritePath ?? result.RawUrl;

                    List <ParameterRedirectAction> parmRedirects = null;
                    //find the matching redirects for the tabid
                    int tabId = result.TabId;
                    if (tabId > -1)
                    {
                        if (redirectActions.ContainsKey(tabId))
                        {
                            //find the right set of replaced actions for this tab
                            parmRedirects = redirectActions[tabId];
                        }
                    }
                    //check for 'all tabs' redirections
                    if (redirectActions.ContainsKey(-1)) //-1 means 'all tabs' - rewriting across all tabs
                    {
                        //initialise to empty collection if there are no specific tab redirects
                        if (parmRedirects == null)
                        {
                            parmRedirects = new List <ParameterRedirectAction>();
                        }
                        //add in the all redirects
                        List <ParameterRedirectAction> allRedirects = redirectActions[-1];
                        parmRedirects.AddRange(allRedirects); //add the 'all' range to the tab range
                        tabId = result.TabId;
                    }
                    if (redirectActions.ContainsKey(-2) && result.OriginalPath.ToLowerInvariant().Contains("default.aspx"))
                    {
                        //for the default.aspx page
                        if (parmRedirects == null)
                        {
                            parmRedirects = new List <ParameterRedirectAction>();
                        }
                        List <ParameterRedirectAction> defaultRedirects = redirectActions[-2];
                        parmRedirects.AddRange(defaultRedirects); //add the default.aspx redirects to the list
                        tabId = result.TabId;
                    }
                    //726 : allow for site-root redirects, ie redirects where no page match
                    if (redirectActions.ContainsKey(-3))
                    {
                        //request is for site root
                        if (parmRedirects == null)
                        {
                            parmRedirects = new List <ParameterRedirectAction>();
                        }
                        List <ParameterRedirectAction> siteRootRedirects = redirectActions[-3];
                        parmRedirects.AddRange(siteRootRedirects); //add the site root redirects to the collection
                    }
                    //OK what we have now is a list of redirects for the currently requested tab (either because it was specified by tab id,
                    // or because there is a replaced for 'all tabs'

                    if (parmRedirects != null && parmRedirects.Count > 0 && rewrittenUrl != null)
                    {
                        foreach (ParameterRedirectAction parmRedirect in parmRedirects)
                        {
                            //regex test each replaced to see if there is a match between the parameter string
                            //and the parmRedirect
                            string compareWith   = rewrittenUrl;
                            var    redirectRegex = RegexUtils.GetCachedRegex(parmRedirect.LookFor,
                                                                             RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
                            Match regexMatch    = redirectRegex.Match(compareWith);
                            bool  success       = regexMatch.Success;
                            bool  siteRootTried = false;
                            //if no match, but there is a site root redirect to try
                            if (!success && parmRedirect.TabId == -3)
                            {
                                siteRootTried = true;
                                compareWith   = result.OriginalPathNoAlias;
                                regexMatch    = redirectRegex.Match(compareWith);
                                success       = regexMatch.Success;
                            }
                            if (!success)
                            {
                                result.DebugMessages.Add(parmRedirect.Name + " redirect not matched (" + rewrittenUrl +
                                                         ")");
                                if (siteRootTried)
                                {
                                    result.DebugMessages.Add(parmRedirect.Name + " redirect not matched [site root] (" +
                                                             result.OriginalPathNoAlias + ")");
                                }
                            }
                            else
                            {
                                //success! there was a match in the parameters
                                string parms = redirectRegex.Replace(compareWith, parmRedirect.RedirectTo);
                                if (siteRootTried)
                                {
                                    result.DebugMessages.Add(parmRedirect.Name + " redirect matched [site root] with (" +
                                                             result.OriginalPathNoAlias + "), replaced with " + parms);
                                }
                                else
                                {
                                    result.DebugMessages.Add(parmRedirect.Name + " redirect matched with (" +
                                                             compareWith + "), replaced with " + parms);
                                }
                                string finalUrl = "";
                                //now we need to generate the friendly Url

                                //first check to see if the parameter replacement string has a destination tabid specified
                                if (parms.ToLowerInvariant().Contains("tabid/"))
                                {
                                    //if so, using a feature whereby the dest tabid can be changed within the parameters, which will
                                    //redirect the page as well as redirecting the parameter values
                                    string[] parmParts = parms.Split('/');
                                    bool     tabIdNext = false;
                                    foreach (string parmPart in parmParts)
                                    {
                                        if (tabIdNext)
                                        {
                                            //changes the tabid of page, effects a page redirect along with a parameter redirect
                                            Int32.TryParse(parmPart, out tabId);
                                            parms = parms.Replace("tabid/" + tabId.ToString(), "");
                                            //remove the tabid/xx from the path
                                            break; //that's it, we're finished
                                        }
                                        if (parmPart.Equals("tabid", StringComparison.InvariantCultureIgnoreCase))
                                        {
                                            tabIdNext = true;
                                        }
                                    }
                                }
                                else if (tabId == -1)
                                {
                                    //find the home tabid for this portal
                                    //735 : switch to custom method for getting portal
                                    PortalInfo portal = CacheController.GetPortal(result.PortalId, true);
                                    tabId = portal.HomeTabId;
                                }
                                if (parmRedirect.ChangeToSiteRoot)
                                {
                                    //when change to siteroot requested, new path goes directly off the portal alias
                                    //so set the finalUrl as the poratl alias
                                    finalUrl = result.Scheme + result.HttpAlias + "/";
                                }
                                else
                                {
                                    //if the tabid has been supplied, do a friendly url provider lookup to get the correct format for the tab url
                                    if (tabId > -1)
                                    {
                                        TabInfo tab = TabController.Instance.GetTab(tabId, result.PortalId, false);
                                        if (tab != null)
                                        {
                                            string path = Globals.glbDefaultPage + TabIndexController.CreateRewritePath(tab.TabID, "");
                                            string friendlyUrlNoParms = AdvancedFriendlyUrlProvider.ImprovedFriendlyUrl(tab,
                                                                                                                        path,
                                                                                                                        Globals.glbDefaultPage,
                                                                                                                        result.HttpAlias,
                                                                                                                        false,
                                                                                                                        settings,
                                                                                                                        Guid.Empty);
                                            if (friendlyUrlNoParms.EndsWith("/") == false)
                                            {
                                                friendlyUrlNoParms += "/";
                                            }
                                            finalUrl = friendlyUrlNoParms;
                                        }
                                        if (tab == null)
                                        {
                                            result.DebugMessages.Add(parmRedirect.Name +
                                                                     " tabId in redirect rule (tabId:" +
                                                                     tabId.ToString() + ", portalId:" +
                                                                     result.PortalId.ToString() +
                                                                     " ), tab was not found");
                                        }
                                        else
                                        {
                                            result.DebugMessages.Add(parmRedirect.Name +
                                                                     " tabId in redirect rule (tabId:" +
                                                                     tabId.ToString() + ", portalId:" +
                                                                     result.PortalId.ToString() + " ), tab found : " +
                                                                     tab.TabName);
                                        }
                                    }
                                }
                                if (parms.StartsWith("//"))
                                {
                                    parms = parms.Substring(2);
                                }
                                if (parms.StartsWith("/"))
                                {
                                    parms = parms.Substring(1);
                                }

                                if (settings.PageExtensionUsageType != PageExtensionUsageType.Never)
                                {
                                    if (parms.EndsWith("/"))
                                    {
                                        parms = parms.TrimEnd('/');
                                    }
                                    if (parms.Length > 0)
                                    {
                                        //we are adding more parms onto the end, so remove the page extension
                                        //from the parameter list
                                        //946 : exception when settings.PageExtension value is empty
                                        parms += settings.PageExtension;
                                        //816: if page extension is /, then don't do this
                                        if (settings.PageExtension != "/" &&
                                            string.IsNullOrEmpty(settings.PageExtension) == false)
                                        {
                                            finalUrl = finalUrl.Replace(settings.PageExtension, "");
                                        }
                                    }
                                    else
                                    {
                                        //we are removing all the parms altogether, so
                                        //the url needs to end in the page extension only
                                        //816: if page extension is /, then don't do this
                                        if (settings.PageExtension != "/" &&
                                            string.IsNullOrEmpty(settings.PageExtension) == false)
                                        {
                                            finalUrl = finalUrl.Replace(settings.PageExtension + "/",
                                                                        settings.PageExtension);
                                        }
                                    }
                                }
                                //put the replaced parms back on the end
                                finalUrl += parms;

                                //set the final url
                                result.FinalUrl = finalUrl;
                                result.Reason   = RedirectReason.Custom_Redirect;
                                switch (parmRedirect.Action)
                                {
                                case "301":
                                    result.Action = ActionType.Redirect301;
                                    break;

                                case "302":
                                    result.Action = ActionType.Redirect302;
                                    break;

                                case "404":
                                    result.Action = ActionType.Output404;
                                    break;
                                }
                                redirect = true;
                                break;
                            }
                        }
                    }

                    #endregion
                }
                catch (Exception ex)
                {
                    Services.Exceptions.Exceptions.LogException(ex);
                    messages.Add("Exception: " + ex.Message + "\n" + ex.StackTrace);
                }
                finally
                {
                    if (messages.Count > 0)
                    {
                        result.DebugMessages.AddRange(messages);
                    }
                }
            }
            return(redirect);
        }
Esempio n. 20
0
        /// <summary>
        /// logs an exception related to a module provider once per cache-lifetime.
        /// </summary>
        /// <param name="ex"></param>
        /// <param name="status"></param>
        /// <param name="result"></param>
        /// <param name="messages"></param>
        /// <param name="provider"></param>
        public static void LogModuleProviderExceptionInRequest(Exception ex, string status,
                                                               ExtensionUrlProvider provider,
                                                               UrlAction result,
                                                               List <string> messages)
        {
            if (ex != null)
            {
                string moduleProviderName    = "Unknown Provider";
                string moduleProviderVersion = "Unknown Version";
                if (provider != null)
                {
                    moduleProviderName    = provider.ProviderConfig.ProviderName;
                    moduleProviderVersion = provider.GetType().Assembly.GetName(false).Version.ToString();
                }

                // this logic prevents a site logging an exception for every request made.  Instead
                // the exception will be logged once for the life of the cache / application restart or 1 hour, whichever is shorter.
                // create a cache key for this exception type
                string cacheKey = ex.GetType().ToString();

                // see if there is an existing object logged for this exception type
                object existingEx = DataCache.GetCache(cacheKey);
                if (existingEx == null)
                {
                    // if there was no existing object logged for this exception type, this is a new exception
                    DateTime expire = DateTime.Now.AddHours(1);
                    DataCache.SetCache(cacheKey, cacheKey, expire);

                    // just store the cache key - it doesn't really matter
                    // create a log event
                    string productVer = DotNetNukeContext.Current.Application.Version.ToString();
                    var    log        = new LogInfo {
                        LogTypeKey = "GENERAL_EXCEPTION"
                    };
                    log.AddProperty(
                        "Url Rewriting Extension Url Provider Exception",
                        "Exception in Url Rewriting Process");
                    log.AddProperty("Provider Name", moduleProviderName);
                    log.AddProperty("Provider Version", moduleProviderVersion);
                    log.AddProperty("Http Status", status);
                    log.AddProperty("Product Version", productVer);
                    if (result != null)
                    {
                        log.AddProperty("Original Path", result.OriginalPath ?? "null");
                        log.AddProperty("Raw Url", result.RawUrl ?? "null");
                        log.AddProperty("Final Url", result.FinalUrl ?? "null");

                        log.AddProperty("Rewrite Result", !string.IsNullOrEmpty(result.RewritePath)
                                                                     ? result.RewritePath
                                                                     : "[no rewrite]");
                        log.AddProperty("Redirect Location", string.IsNullOrEmpty(result.FinalUrl)
                                                                    ? "[no redirect]"
                                                                    : result.FinalUrl);
                        log.AddProperty("Action", result.Action.ToString());
                        log.AddProperty("Reason", result.Reason.ToString());
                        log.AddProperty("Portal Id", result.PortalId.ToString());
                        log.AddProperty("Tab Id", result.TabId.ToString());
                        log.AddProperty("Http Alias", result.PortalAlias != null ? result.PortalAlias.HTTPAlias : "Null");

                        if (result.DebugMessages != null)
                        {
                            int i = 1;
                            foreach (string debugMessage in result.DebugMessages)
                            {
                                string msg = debugMessage;
                                if (debugMessage == null)
                                {
                                    msg = "[message was null]";
                                }

                                log.AddProperty("Debug Message[result] " + i.ToString(), msg);
                                i++;
                            }
                        }
                    }
                    else
                    {
                        log.AddProperty("Result", "Result value null");
                    }

                    if (messages != null)
                    {
                        int i = 1;
                        foreach (string msg in messages)
                        {
                            log.AddProperty("Debug Message[raw] " + i.ToString(), msg);
                            i++;
                        }
                    }

                    log.AddProperty("Exception Type", ex.GetType().ToString());
                    log.AddProperty("Message", ex.Message);
                    log.AddProperty("Stack Trace", ex.StackTrace);
                    if (ex.InnerException != null)
                    {
                        log.AddProperty("Inner Exception Message", ex.InnerException.Message);
                        log.AddProperty("Inner Exception Stacktrace", ex.InnerException.StackTrace);
                    }

                    log.BypassBuffering = true;
                    LogController.Instance.AddLog(log);
                }
            }
        }
Esempio n. 21
0
        internal static bool TransformFriendlyUrlPath(
            string newUrl,
            string tabKeyVal,
            string[] urlParms,
            bool isSiteRootMatch,
            ref UrlAction result,
            FriendlyUrlSettings settings,
            out string rewrittenUrl,
            out bool newAction,
            ref List <string> messages,
            Guid parentTraceId)
        {
            bool rewriteDone = false;

            rewrittenUrl = newUrl;
            newAction    = false;
            ExtensionUrlProvider activeProvider = null;

            try
            {
                int tabId = result.TabId;
                if (isSiteRootMatch)
                {
                    tabId = RewriteController.SiteRootRewrite;
                }

                List <ExtensionUrlProvider> providersToCall = GetProvidersToCall(
                    tabId,
                    result.PortalId,
                    settings,
                    parentTraceId);
                if (providersToCall != null && providersToCall.Count > 0)
                {
                    // now check for providers by calling the providers
                    int upperBound = urlParms.GetUpperBound(0);

                    // clean extension off parameters array
                    var parms = new string[upperBound + 1];
                    Array.ConstrainedCopy(urlParms, 0, parms, 0, upperBound + 1);
                    if (upperBound >= 0)
                    {
                        bool replaced;
                        parms[upperBound] = RewriteController.CleanExtension(parms[upperBound], settings, out replaced);
                    }

                    // get options from current settings
                    FriendlyUrlOptions options = UrlRewriterUtils.GetOptionsFromSettings(settings);
                    foreach (ExtensionUrlProvider provider in providersToCall)
                    {
                        // set active provider for exception handling
                        activeProvider = provider;

                        // call down to specific providers and see if we get a rewrite
                        string location;
                        int    status;
                        string queryString = provider.TransformFriendlyUrlToQueryString(
                            parms,
                            result.TabId,
                            result.PortalId,
                            options,
                            result.CultureCode,
                            result.PortalAlias,
                            ref messages,
                            out status,
                            out location);
                        if (status == 0 || status == 200) // either not set, or set to '200 OK'.
                        {
                            if (!string.IsNullOrEmpty(queryString) && queryString != newUrl)
                            {
                                rewriteDone = true;

                                // check for duplicate tabIds.
                                string qsRemainder = null;
                                if (Regex.IsMatch(queryString, @"tabid=\d+", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
                                {
                                    // 930 : look for other querystring information in the rewritten Url, or invalid rewritten urls can be created
                                    // pattern to determine which tab matches
                                    // look for any other querystirng information in the already rewritten Url (ie language parameters)
                                    Match rewrittenUrlMatch = RewrittenUrlRegex.Match(rewrittenUrl);
                                    if (rewrittenUrlMatch.Groups["qs"].Success)
                                    {
                                        // keep any other querystring remainders
                                        qsRemainder = rewrittenUrlMatch.Groups["qs"].Captures.Cast <Capture>().Aggregate(string.Empty, (current, qsCapture) => current + qsCapture.Value); // initialise
                                    }

                                    // supplied value overwrites existing value, so remove from the rewritten url
                                    rewrittenUrl = RewrittenUrlRegex.Replace(rewrittenUrl, string.Empty);
                                }

                                if (rewrittenUrl.Contains("?") == false)
                                {
                                    // use a leading ?, not a leading &
                                    queryString = FriendlyUrlController.EnsureNotLeadingChar("&", queryString);
                                    queryString = FriendlyUrlController.EnsureLeadingChar("?", queryString);
                                }
                                else
                                {
                                    // use a leading &, not a leading ?
                                    queryString = FriendlyUrlController.EnsureNotLeadingChar("?", queryString);
                                    queryString = FriendlyUrlController.EnsureLeadingChar("&", queryString);
                                }

                                // add querystring onto rewritten Url
                                rewrittenUrl += queryString;
                                if (qsRemainder != null)
                                {
                                    rewrittenUrl += qsRemainder;
                                }

                                break;
                            }
                        }
                        else
                        {
                            switch (status)
                            {
                            case 301:
                                result.Action   = ActionType.Redirect301;
                                result.Reason   = RedirectReason.Module_Provider_Rewrite_Redirect;
                                result.FinalUrl = location;
                                break;

                            case 302:
                                result.Action   = ActionType.Redirect302;
                                result.Reason   = RedirectReason.Module_Provider_Rewrite_Redirect;
                                result.FinalUrl = location;
                                break;

                            case 404:
                                result.Action = ActionType.Output404;
                                break;

                            case 500:
                                result.Action = ActionType.Output500;
                                break;
                            }

                            newAction = true; // not doing a 200 status
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                // log module provider exception
                LogModuleProviderExceptionInRequest(ex, "500 Internal Server Error", activeProvider, result, messages);

                // reset values to initial
                rewriteDone  = false;
                rewrittenUrl = newUrl;
                newAction    = false;
                string providerName = "Unknown";
                if (activeProvider != null)
                {
                    providerName = activeProvider.ProviderConfig.ProviderName;
                }

                if (result != null)
                {
                    result.DebugMessages.Add("Exception in provider [" + providerName + "] :" + ex.Message);
                }
            }

            return(rewriteDone);
        }
        /// <summary>
        /// logs an exception once per cache-lifetime.
        /// </summary>
        /// <param name="ex"></param>
        /// <param name="status"></param>
        /// <param name="result"></param>
        public static void LogExceptionInRequest(Exception ex, string status, UrlAction result)
        {
            if (ex != null)
            {
                // 831 : improve exception logging by logging custom properties instead of just the raw exception
                // this logic prevents a site logging an exception for every request made.  Instead
                // the exception will be logged once for the life of the cache / application restart or 1 hour, whichever is shorter.
                // create a cache key for this exception type
                string cacheKey = ex.GetType().ToString();

                // see if there is an existing object logged for this exception type
                object existingEx = DataCache.GetCache(cacheKey);
                if (existingEx == null)
                {
                    // if there was no existing object logged for this exception type, this is a new exception
                    DateTime expire = DateTime.Now.AddHours(1);
                    DataCache.SetCache(cacheKey, cacheKey, expire);

                    // just store the cache key - it doesn't really matter
                    // create a log event
                    var log = new LogInfo {
                        LogTypeKey = "GENERAL_EXCEPTION"
                    };
                    log.AddProperty("Url Processing Exception", "Exception in Url Rewriting Process");
                    log.AddProperty("Http Status", status);
                    if (result != null)
                    {
                        log.AddProperty("Original Path", result.OriginalPath ?? "null");
                        log.AddProperty("Raw Url", result.RawUrl ?? "null");
                        log.AddProperty("Final Url", result.FinalUrl ?? "null");

                        log.AddProperty("Rewrite Result", !string.IsNullOrEmpty(result.RewritePath)
                                                                     ? result.RewritePath
                                                                     : "[no rewrite]");
                        log.AddProperty("Redirect Location", string.IsNullOrEmpty(result.FinalUrl)
                                                                    ? "[no redirect]"
                                                                    : result.FinalUrl);
                        log.AddProperty("Action", result.Action.ToString());
                        log.AddProperty("Reason", result.Reason.ToString());
                        log.AddProperty("Portal Id", result.PortalId.ToString());
                        log.AddProperty("Tab Id", result.TabId.ToString());
                        log.AddProperty("Http Alias", result.PortalAlias != null
                                                                ? result.PortalAlias.HTTPAlias
                                                                : "Null");

                        if (result.DebugMessages != null)
                        {
                            int i = 1;
                            foreach (string msg in result.DebugMessages)
                            {
                                log.AddProperty("Debug Message " + i.ToString(), msg);
                                i++;
                            }
                        }
                    }
                    else
                    {
                        log.AddProperty("Result", "Result value null");
                    }

                    log.AddProperty("Exception Type", ex.GetType().ToString());
                    log.AddProperty("Message", ex.Message);
                    log.AddProperty("Stack Trace", ex.StackTrace);
                    if (ex.InnerException != null)
                    {
                        log.AddProperty("Inner Exception Message", ex.InnerException.Message);
                        log.AddProperty("Inner Exception Stacktrace", ex.InnerException.StackTrace);
                    }

                    log.BypassBuffering = true;
                    LogController.Instance.AddLog(log);

                    // Log this error in lig4net
                    Logger.Error(ex);
                }
            }
        }
 public void ProcessTestRequestWithContext(HttpContext context, 
                                             Uri requestUri,
                                             bool useFriendlyUrls, 
                                             UrlAction result, 
                                             FriendlyUrlSettings settings)
 {
     Guid parentTraceId = Guid.Empty;
     _settings = settings;
     ProcessRequest(context, 
                         requestUri,
                         useFriendlyUrls, 
                         result,
                         settings, 
                         false, 
                         parentTraceId);
 }
        private static bool CheckForTabExternalForwardOrRedirect(HttpContext context, 
                                                                    ref UrlAction result,
                                                                    HttpResponse response, 
                                                                    FriendlyUrlSettings settings,
                                                                    Guid parentTraceId)
        {
            bool finished = false;
            HttpRequest request = null;
            if (context != null)
            {
                request = context.Request;
            }

            try
            {
                            //check for external forwarding or a permanent redirect request
            //592 : check for permanent redirect (823 : moved location from 'checkForRedirects')
            if (result.TabId > -1 && result.PortalId > -1 &&
                (settings.ForwardExternalUrlsType != DNNPageForwardType.NoForward ||
                 result.Reason == RedirectReason.Tab_Permanent_Redirect))
            {
                bool allowRedirect = !(result.RewritePath != null && result.RewritePath.ToLower().Contains("&ctl=tab"));
                //594 : do not redirect settings pages for external urls
                if (allowRedirect)
                {
                    TabInfo tab;
                    allowRedirect = CheckFor301RedirectExclusion(result.TabId, result.PortalId, false, out tab, settings);
                    if (allowRedirect)
                    {
                        //772 : not redirecting file type Urls when requested.
                        bool permanentRedirect = false;
                        string redirectUrl = null;
                        string cleanPath = null;
                        bool doRedirect = false;
                        switch (tab.TabType)
                        {
                            case TabType.File:
                                //have to fudge in a portal settings object for this to work - shortcoming of LinkClick URl generation
                                var portalSettings = new PortalSettings(result.TabId, result.PortalAlias);
                                if (context != null)
                                {
                                    context.Items.Add("PortalSettings", portalSettings);
                                    result.Reason = RedirectReason.File_Url;
                                    string fileUrl = Globals.LinkClick(tab.Url, tab.TabID, -1);
                                    context.Items.Remove("PortalSettings");
                                    //take back out again, because it will be done further downstream
                                    //do a check to make sure we're not repeating the Url again, because the tabid is set but we don't want to touch
                                    //a linkclick url
                                    if (!result.OriginalPathNoAlias.EndsWith(HttpUtility.UrlDecode(fileUrl), true, CultureInfo.InvariantCulture))
                                    {
                                        redirectUrl = fileUrl;
                                    }
                                }
                                if (redirectUrl != null)
                                {
                                    doRedirect = true;
                                }
                                break;
                            case TabType.Url:
                                result.Reason = RedirectReason.Tab_External_Url;
                                redirectUrl = tab.Url;
                                if (redirectUrl != null)
                                {
                                    doRedirect = true;
                                    if (settings.ForwardExternalUrlsType == DNNPageForwardType.Redirect301)
                                    {
                                        result.Action = ActionType.Redirect301;
                                        result.Reason = RedirectReason.Tab_External_Url;
                                    }
                                    else if (settings.ForwardExternalUrlsType == DNNPageForwardType.Redirect302)
                                    {
                                        result.Action = ActionType.Redirect302;
                                        result.Reason = RedirectReason.Tab_External_Url;
                                    }
                                }
                                break;
                            case TabType.Tab:
                                // if a tabType.tab is specified, it's either an external url or a permanent redirect

                                //get the redirect path of the specific tab, as long as we have a valid request to work from
                                if (request != null)
                                {
                                    //get the rewrite or requested path in a clean format, suitable for input to the friendly url provider
                                    cleanPath = RewriteController.GetRewriteOrRequestedPath(result, request.Url);
                                    //727 prevent redirectLoop with do301 in querystring
                                    if (result.Action == ActionType.Redirect301 ||
                                        result.Action == ActionType.Redirect302)
                                    {
                                        cleanPath = RedirectTokens.RemoveAnyRedirectTokens(cleanPath,
                                                                                           request.QueryString);
                                    }
                                    //get the redirect Url from the friendly url provider using the tab, path and settings
                                    redirectUrl = RedirectController.GetTabRedirectUrl(tab, settings, cleanPath, result,
                                                                                       out permanentRedirect,
                                                                                       parentTraceId);
                                }
                                //check to make sure there isn't a blank redirect Url
                                if (redirectUrl == null)
                                {
                                    //problem : no redirect Url to redirect to
                                    //solution : cancel the redirect
                                    string message = "Permanent Redirect chosen for Tab " +
                                                     tab.TabPath.Replace("//", "/") +
                                                     " but forwarding Url was not valid";
                                    RedirectController.CancelRedirect(ref result, context, settings, message);
                                }
                                else
                                {
                                    //if there was a redirect Url, set the redirect action and set the type of redirect going to use
                                    doRedirect = true;
                                    if (permanentRedirect)
                                    {
                                        result.Action = ActionType.Redirect301;
                                        result.Reason = RedirectReason.Tab_Permanent_Redirect;
                                        //should be already set, anyway
                                        result.RewritePath = cleanPath;
                                    }
                                    else
                                    {
                                        //not a permanent redirect, check if the page forwarding is set
                                        if (settings.ForwardExternalUrlsType == DNNPageForwardType.Redirect301)
                                        {
                                            result.Action = ActionType.Redirect301;
                                            result.Reason = RedirectReason.Tab_External_Url;
                                        }
                                        else if (settings.ForwardExternalUrlsType == DNNPageForwardType.Redirect302)
                                        {
                                            result.Action = ActionType.Redirect302;
                                            result.Reason = RedirectReason.Tab_External_Url;
                                        }
                                    }
                                }
                                break;
                            default:
                                //only concern here is if permanent redirect is requested, but there is no external url specified
                                if (result.Reason == RedirectReason.Tab_Permanent_Redirect)
                                {
                                    bool permRedirect = tab.PermanentRedirect;
                                    if (permRedirect)
                                    {
                                        //problem : permanent redirect marked, but no forwarding url supplied
                                        //solution : cancel redirect
                                        string message = "Permanent Redirect chosen for Tab " +
                                                         tab.TabPath.Replace("//", "/") +
                                                         " but no forwarding Url Supplied";
                                        RedirectController.CancelRedirect(ref result, context, settings, message);
                                    }
                                }
                                break;
                        }

                        //do the redirect we have specified
                        if (doRedirect &&
                            (result.Action == ActionType.Redirect301 || result.Action == ActionType.Redirect302))
                        {
                            result.FinalUrl = redirectUrl;
                            if (result.Action == ActionType.Redirect301)
                            {
                                if (response != null)
                                {
                                    //perform a 301 redirect to the external url of the tab
                                    response.Status = "301 Moved Permanently";
                                    response.AppendHeader("X-Redirect-Reason",
                                                          result.Reason.ToString().Replace("_", " ") + " Requested");
                                    response.AddHeader("Location", result.FinalUrl);
                                    response.End();
                                }
                            }
                            else
                            {
                                if (result.Action == ActionType.Redirect302)
                                {
                                    if (response != null)
                                    {
                                        //perform a 301 redirect to the external url of the tab
                                        response.AppendHeader("X-Redirect-Reason",
                                                              result.Reason.ToString().Replace("_", " ") + " Requested");
                                        response.Redirect(result.FinalUrl);
                                    }
                                }
                            }
                            finished = true;
                        }
                    }
                }
            }

            }
            catch (ThreadAbortException)
            {
                //do nothing, a threadAbortException will have occured from using a server.transfer or response.redirect within the code block.  This is the highest
                //level try/catch block, so we handle it here.
            }
            return finished;
        }
Esempio n. 25
0
        private static void ShowDebugData(HttpContext context, string requestUri, UrlAction result, Exception ex)
        {
            if (context != null)
            {
                HttpResponse response = context.Response;

                //handle null responses wherever they might be found - this routine must be tolerant to all kinds of invalid inputs
                if (requestUri == null)
                {
                    requestUri = "null Uri";
                }
                string finalUrl = "null final Url";
                string rewritePath = "null rewrite path";
                string action = "null action";
                if (result != null)
                {
                    finalUrl = result.FinalUrl;
                    action = result.Action.ToString();
                    rewritePath = result.RewritePath;
                }
                //format up the error message to show
                const string debugMsg = "{0}, {1}, {2}, {3}, {4}, {5}, {6}";
                string productVer = Assembly.GetExecutingAssembly().GetName(false).Version.ToString();
                string portalSettings = "";
                string browser = "Unknown";
                //949 : don't rely on 'result' being non-null
                if (result != null)
                {
                    browser = result.BrowserType.ToString();
                }
                if (context.Items.Contains("PortalSettings"))
                {
                    var ps = (PortalSettings) context.Items["PortalSettings"];
                    if (ps != null)
                    {
                        portalSettings = ps.PortalId.ToString();
                        if (ps.PortalAlias != null)
                        {
                            portalSettings += ":" + ps.PortalAlias.HTTPAlias;
                        }
                    }
                }
                response.AppendHeader("X-" + _productName + "-Debug",
                                      string.Format(debugMsg, requestUri, finalUrl, rewritePath, action, productVer,
                                                    portalSettings, browser));
#if (DEBUG)
                var rawOutput = new StringWriter();
                rawOutput.WriteLine("<div style='background-color:black;color:white;'>");
                rawOutput.WriteLine("<p>Advanced Url Rewriting Debug Output</p>");
                rawOutput.WriteLine("<p>" +
                                    string.Format(debugMsg, requestUri, finalUrl, rewritePath, action, productVer,
                                                  portalSettings, browser) + "</p>");
#endif
                int msgNum = 1;
                if (result != null)
                {
                    foreach (string msg in result.DebugMessages)
                    {
#if (DEBUG)
                        rawOutput.WriteLine("<div>Debug Message " + msgNum.ToString("00") + ": " + msg + "</div>");
#endif
                        response.AppendHeader("X-" + _productName + "-Debug-" + msgNum.ToString("00"), msg);
                        msgNum++;
                    }
                }
                if (ex != null)
                {
                    response.AppendHeader("X-" + _productName + "-Ex", ex.Message);
                }
#if (DEBUG)
                if (ex != null)
                {
                    rawOutput.WriteLine("Exception : " + ex.Message);
                }
                else
                {
                    rawOutput.WriteLine("No Exception");
                }

                rawOutput.WriteLine("</div>");
                response.Write(rawOutput.ToString());
#endif
            }
        }
        protected bool IsPortalAliasIncorrect(HttpContext context, 
                                                    HttpRequest request, 
                                                    Uri requestUri,
                                                    UrlAction result, 
                                                    NameValueCollection queryStringCol,
                                                    FriendlyUrlSettings settings, 
                                                    Guid parentTraceId,
                                                    out string httpAlias)
        {
            //now check to make sure it's the primary portal alias for this portal/language/browser
            bool incorrectAlias = false;
            httpAlias = null;
            //if (result.RedirectAllowed && result.PortalId > -1)
            if (result.PortalId > -1) //portal has been identified
            {
                var portalAliases = PortalAliasController.Instance.GetPortalAliasesByPortalId(result.PortalId).ToList();

                if (queryStringCol != null && queryStringCol["forceAlias"] != "true")
                {
                    if (portalAliases.Count > 0)
                    {
                        string checkAlias = result.HttpAlias;
                        bool continueLoop = true;
                        bool triedWWW = false;
                        while (httpAlias == null && continueLoop)
                        {
                            if (portalAliases.ContainsAlias(result.PortalId, checkAlias))
                            {
                                if (portalAliases.Count > 0)
                                {
                                    //var cpa = portalAliases.GetAliasByPortalIdAndSettings(result);
                                    string url = requestUri.ToString();
                                    RewriteController.CheckLanguageMatch(ref url, result);
                                    var cpa = portalAliases.GetAliasByPortalIdAndSettings(result.PortalId, result, result.CultureCode, result.BrowserType);

                                    if (cpa != null)
                                    {
                                        httpAlias = cpa.HTTPAlias;
                                        continueLoop = false;
                                    }
                                    if (String.IsNullOrEmpty(result.CultureCode) && cpa == null)
                                    {
                                        //if there is a specific culture for this portal alias, then check that
                                        string culture = portalAliases.GetCultureByPortalIdAndAlias(result.PortalId, result.HttpAlias);
                                        //if this matches the alias of the request, then we know we have the correct alias because it is a specific culture
                                        if (!string.IsNullOrEmpty(culture))
                                        {
                                            continueLoop = false;
                                        }
                                    }
                                }
                            }
                            //check whether to still go on or not
                            if (continueLoop)
                            {
                                //this alias doesn't exist in the list
                                //check if it has a www on it - if not, try adding, if it does, try removing
                                if (!triedWWW)
                                {
                                    triedWWW = true; //now tried adding/removing www
                                    if (checkAlias.ToLower().StartsWith("www."))
                                    {
                                        checkAlias = checkAlias.Substring(4);
                                    }
                                    else
                                    {
                                        checkAlias = "www." + checkAlias;
                                    }
                                }
                                else
                                {
                                    //last thing to try, get the default language and see if there is a portal alias for that
                                    //thus, any aliases not identified as belonging to a language are redirected back to the 
                                    //alias named for the default language
                                    continueLoop = false;
                                    //735 : switch to custom method for getting portal
                                    PortalInfo pi = CacheController.GetPortal(result.PortalId, false);
                                    if (pi != null)
                                    {
                                        string cultureCode = pi.DefaultLanguage;
                                        if (!string.IsNullOrEmpty(cultureCode))
                                        {
                                            var primaryPortalAlias = portalAliases.GetAliasByPortalIdAndSettings(result.PortalId, result,cultureCode,settings);
                                            if (primaryPortalAlias != null)
                                            {
                                                httpAlias = primaryPortalAlias.HTTPAlias;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    
                    //check to see if it is a custom tab alais - in that case, it is allowed to be requested for the tab
                    if (CheckIfAliasIsCustomTabAlias(ref result, httpAlias, settings))
                    {
                        //change the primary alias to the custom tab alias that has been requested.
                        result.PrimaryAlias = result.PortalAlias;
                    }
                    else
                        if (httpAlias != null && String.Compare(httpAlias, result.HttpAlias, StringComparison.OrdinalIgnoreCase) != 0)
                        {
                            incorrectAlias = true;
                        }
                }
            }
            return incorrectAlias;
        }
 private bool IsRedirectAllowed(string url, HttpApplication app, PortalSettings portalSettings)
 {
     var urlAction = new UrlAction(app.Request);
     urlAction.SetRedirectAllowed(url, new FriendlyUrlSettings(portalSettings.PortalId));
     return urlAction.RedirectAllowed;
 }
 private static bool ConfigurePortalAliasRedirect(ref UrlAction result, 
                                                     string wrongAlias, 
                                                     string rightAlias,
                                                     bool ignoreCustomAliasTabs, 
                                                     List<InternalAlias> internalAliases,
                                                     FriendlyUrlSettings settings)
 {
     return ConfigurePortalAliasRedirect(ref result, 
                                             wrongAlias, 
                                             rightAlias, 
                                             ignoreCustomAliasTabs,
                                             RedirectReason.Wrong_Portal_Alias, 
                                             internalAliases, 
                                             settings);
 }
        private static bool CheckForRedirects(Uri requestUri, 
                                                string fullUrl, 
                                                NameValueCollection queryStringCol,
                                                UrlAction result, 
                                                string requestType, 
                                                FriendlyUrlSettings settings,
                                                int portalHomeTabId)
        {
            bool redirected = false;
            if (queryStringCol["error"] == null && queryStringCol["message"] == null && requestType != "POST")
            {
                //if the / is missing from an extension-less request, then check for a 301 redirect
                if (settings.PageExtensionUsageType == PageExtensionUsageType.Never)
                {
                    //575 check on absolutePath instead of absoluteUri : this ignores query strings and fragments like #
                    //610 don't always end with '/' - reverses previous setting
                    //687 don't double-check 301 redirects.  'CheckFor301' is less concise than 'Redirect301'
                    // DNN-21906: if the redirect is for splash page, then we should continue the 302 redirect.
                    if (requestUri.AbsolutePath.EndsWith("/") && result.Action != ActionType.Redirect301 && result.Reason != RedirectReason.Requested_SplashPage)
                    {
                        result.Action = ActionType.CheckFor301;
                    }
                }
                if (settings.RedirectWrongCase && result.Action == ActionType.Continue)
                {
                    result.Action = ActionType.CheckFor301;
                }
                string scheme = requestUri.Scheme + Uri.SchemeDelimiter;
                bool queryStringHas301Parm = (queryStringCol["do301"] != null);
                //727 : keep a bool value if there is a do301 request in the querystring
                //check for a 301 request in the query string, or an explicit 301 or 302 request
                //2.0 - check for explicit do301=true instead of just do301 key
                string do301Val = queryStringCol["do301"];
                if (result.TabId > -1 //valid tab
                    && (result.Action == ActionType.Redirect301 //specific 301 redirect
                        || (do301Val != null && do301Val == "true") //or rewrite hint for specific 301 redirect 
                        || result.Action == ActionType.Redirect302)) //or specific 302 redirect
                {
                    //we have ordered a 301 redirect earlier in the code
                    //get the url for redirection by re-submitting the path into the Friendly Url Provider
                    string pathOnly = RewriteController.GetRewriteOrRequestedPath(result, requestUri);
                    //727 prevent redirectLoop with do301 in querystring
                    if (result.Action == ActionType.Redirect301 || queryStringHas301Parm || result.Action == ActionType.Redirect302)
                    {
                        pathOnly = RedirectTokens.RemoveAnyRedirectTokens(pathOnly, queryStringCol);
                    }

                    //check for exclusion by regex for this url
                    if (result.RedirectAllowed)
                    {
                        //get the tab so we know where to go
                        TabInfo tab;
                        bool checkRedirect = CheckFor301RedirectExclusion(result.TabId, result.PortalId, true, out tab, settings);

                        if (checkRedirect)
                        {
                            if ((result.Reason == RedirectReason.Deleted_Page || result.Reason == RedirectReason.Disabled_Page)
                                && portalHomeTabId > 0
                                && settings.DeletedTabHandlingType == DeletedTabHandlingType.Do301RedirectToPortalHome)
                            {
                                //redirecting to home page  
                                TabInfo homeTab = TabController.Instance.GetTab(portalHomeTabId, result.PortalId, false);
                                if (homeTab != null)
                                {
                                    string homePageUrl = AdvancedFriendlyUrlProvider.ImprovedFriendlyUrl(homeTab, 
                                                                                                         pathOnly,
                                                                                                         Globals.glbDefaultPage,
                                                                                                         result.HttpAlias,
                                                                                                         false, 
                                                                                                         settings,
                                                                                                         Guid.Empty);
                                    result.Action = ActionType.Redirect301;
                                    result.FinalUrl = homePageUrl;
                                    result.RewritePath = pathOnly;
                                    redirected = true;
                                }
                            }
                            else
                            {
                                //get the rewrite or requested path in a clean format, suitable for input to the friendly url provider
                                string cleanPath = RewriteController.GetRewriteOrRequestedPath(result, requestUri);

                                //727 prevent redirectLoop with do301 in querystring
                                //also check for existing in path of do301 token
                                if (result.Action == ActionType.Redirect301 || do301Val != null || result.Action == ActionType.Redirect302)
                                {
                                    cleanPath = RedirectTokens.RemoveAnyRedirectTokens(cleanPath, queryStringCol);
                                }

                                //get best friendly url from friendly url provider
                                string bestFriendlyUrl = AdvancedFriendlyUrlProvider.ImprovedFriendlyUrl(tab, 
                                                                                                         cleanPath,
                                                                                                         Globals.glbDefaultPage,
                                                                                                         result.HttpAlias,
                                                                                                         false, 
                                                                                                         settings,
                                                                                                         Guid.Empty);

                                //get what the friendly Url for this tab should be and stick it in as the redirect
                                //727 : using boolean because we wanted to get rid of the do301 before calculating the correct url
                                if (queryStringHas301Parm)
                                {
                                    result.Action = ActionType.Redirect301;
                                    if (result.Reason == RedirectReason.Not_Redirected)
                                    {
                                        result.Reason = RedirectReason.Unfriendly_Url_1;
                                    }
                                }
                                result.FinalUrl = bestFriendlyUrl;
                                result.RewritePath = pathOnly;
                                redirected = true; //mark as redirected
                            }
                        }
                        else
                        {
                            //redirect disallowed 
                            //618: dont' clear if 302 redirect selected
                            if (result.Action != ActionType.Redirect302Now || result.Action != ActionType.Redirect302)
                            {
                                RedirectController.CancelRedirect(ref result, null, settings, "Redirect requested but cancelled because disallowed");
                            }
                        }
                    }
                }
                else if (result.TabId > -1 && result.RedirectAllowed && result.Action == ActionType.CheckFor301)
                {
                    //301 check was requested in earlier processing
                    //get the tab controller and retrieve the tab the request is for 
                    //don't redirect unless allowed, the tab is valid, and it's not an admin or super tab 
                    if (settings.RedirectUnfriendly)
                    {
                        TabInfo tab;
                        bool allowRedirect = CheckFor301RedirectExclusion(result.TabId, result.PortalId, true, out tab, settings);
                        if (allowRedirect && tab != null)
                        {
                            //remove the http alias from the url. Do this by putting the url back together from the request and removing the alias 
                            string rewritePathOnly;
                            if (result.DoRewrite)
                            {
                                rewritePathOnly = result.RewritePath;
                                var pos = rewritePathOnly.IndexOf("default.aspx", StringComparison.OrdinalIgnoreCase);
                                if (pos > Null.NullInteger)
                                {
                                    rewritePathOnly = rewritePathOnly.Substring(pos);
                                }
                            }
                            else
                            {
                                rewritePathOnly = requestUri.Host + requestUri.PathAndQuery;
                            }

                            //remove the http alias from the path 
                            var pathAliasEnd = rewritePathOnly.IndexOf(result.PortalAlias.HTTPAlias, StringComparison.InvariantCultureIgnoreCase);
                            var queryStringIndex = rewritePathOnly.IndexOf("?", StringComparison.InvariantCultureIgnoreCase);
                            if (pathAliasEnd > Null.NullInteger && (queryStringIndex == Null.NullInteger || pathAliasEnd < queryStringIndex))
                            {
                                rewritePathOnly = rewritePathOnly.Substring(pathAliasEnd + result.PortalAlias.HTTPAlias.Length);
                            }
                            
                            rewritePathOnly = HttpUtility.UrlDecode(rewritePathOnly, Encoding.UTF8);
                            //now check to see if need to remove /default.aspx from the end of the requested Url
                            string requestedUrl = fullUrl;
                            int requestedUrlAliasEnd = requestedUrl.IndexOf(result.PortalAlias.HTTPAlias, StringComparison.InvariantCultureIgnoreCase) 
                                                        + (result.PortalAlias.HTTPAlias + "/").Length;
                            if (requestedUrlAliasEnd > Null.NullInteger)
                            {
                                //818 : when a site root is used for a custom page Url, then check for max length within bounds
                                if ((requestedUrl.Length - requestedUrlAliasEnd) >= 12 && requestedUrl.Substring(requestedUrlAliasEnd).ToLower() == "default.aspx")
                                {
                                    requestedUrl = requestedUrl.Substring(0, requestedUrl.Length - 12);
                                    //12 = default.aspx length
                                }
                            }

                            //what happens here is that the request is reverse-engineered to see if it matches what the friendly Url shoudl have been 
                            //get what the friendly Url for this tab should be 
                            string bestFriendlyUrl;
                            //819 : leaving /do301/check in Url because not using cleanPath to remove from

                            string cleanPath = RedirectTokens.RemoveAnyRedirectTokensAndReasons(rewritePathOnly);
                            //string cleanPath = rewritePathOnly.Replace("&do301=check","");//remove check parameter if it exists
                            //cleanPath = cleanPath.Replace("&do301=true", "");//don't pass through internal redirect check parameter
                            cleanPath = cleanPath.Replace("&_aumdebug=true", ""); //remove debug parameter if it exists

                            Match match = Regex.Match(rewritePathOnly, "(?:&(?<parm>.[^&]+)=$)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
                            if (match.Success)
                            {
                                //when the pathOnly value ends with '=' it means there is a query string pair with a key and no value
                                //make the assumption that this was passed in as a page name OTHER than default page
                                string pageName = match.Groups["parm"].Value; //get the last parameter in the list

                                cleanPath = cleanPath.Replace(match.Value, "");
                                //remove the last parameter from the path

                                //generate teh friendly URl name with the last parameter as the page name, not a query string parameter
                                bestFriendlyUrl = AdvancedFriendlyUrlProvider.ImprovedFriendlyUrl(tab, 
                                                                                                    cleanPath,
                                                                                                    pageName + settings.PageExtension,
                                                                                                    result.HttpAlias,
                                                                                                    false, 
                                                                                                    settings,
                                                                                                    Guid.Empty);
                            }
                            else
                            {
                                bestFriendlyUrl = AdvancedFriendlyUrlProvider.ImprovedFriendlyUrl(tab, 
                                                                                                    cleanPath,
                                                                                                    Globals.glbDefaultPage,
                                                                                                    result.HttpAlias,
                                                                                                    false, 
                                                                                                    settings,
                                                                                                    Guid.Empty);
                            }

                            //if the incomign request doesn't match the 'most friendly' url, a 301 Moved Permanently status is returned, along with the friendly url 
                            //check the bestFriendlyUrl against either the url, or rawUrl (with and without host) 
                            //in each case, the aumdebug parameter will be searched for and replaced
                            var urlDecode = HttpUtility.UrlDecode(requestedUrl);
                            if (urlDecode != null)
                            {
                                string rawUrlWithHost = StripDebugParameter(urlDecode.ToLower());
                                //string rawUrlWithHost = StripDebugParameter(System.Web.HttpUtility.UrlDecode(scheme + requestUri.Host + requestUri.PathAndQuery).ToLower());
                                string rawUrlWithHostNoScheme = StripDebugParameter(rawUrlWithHost.Replace(scheme, ""));
                                string bestFriendlyNoScheme = StripDebugParameter(bestFriendlyUrl.ToLower().Replace(scheme, ""));
                                string requestedPathNoScheme = StripDebugParameter(requestUri.AbsoluteUri.Replace(scheme, "").ToLower());
                                string rawUrlLowerCase = StripDebugParameter(requestUri.AbsoluteUri.ToLower());

                                //check to see if just an alias redirect of an internal alias
                                var primaryAliases = PortalAliasController.Instance.GetPortalAliasesByPortalId(result.PortalId).ToList();

                                if (settings.InternalAliasList != null && settings.InternalAliasList.Count > 0 && primaryAliases.Count > 0)
                                {
                                    var cpa = primaryAliases.GetAliasByPortalIdAndSettings(result);
                                    if (cpa != null)
                                    {
                                        string chosenAlias = cpa.HTTPAlias.ToLower();
                                        foreach (InternalAlias ia in settings.InternalAliasList)
                                        {
                                            string internalAlias = ia.HttpAlias.ToLower();
                                            if (requestedPathNoScheme.Contains(internalAlias))
                                            {
                                                //an internal alias has been used.
                                                //replace this in the comparison charts to do a 'fair' comparison
                                                requestedPathNoScheme = requestedPathNoScheme.Replace(internalAlias,chosenAlias);
                                                rawUrlWithHost = rawUrlWithHost.Replace(scheme + internalAlias,scheme + chosenAlias);
                                                rawUrlWithHostNoScheme = rawUrlWithHostNoScheme.Replace(internalAlias,chosenAlias);
                                                rawUrlLowerCase = rawUrlLowerCase.Replace(internalAlias, chosenAlias);
                                                break;
                                            }
                                        }
                                    }
                                }
                                if (!(bestFriendlyNoScheme == requestedPathNoScheme
                                      || bestFriendlyNoScheme == rawUrlWithHost
                                      || bestFriendlyNoScheme == rawUrlWithHostNoScheme
                                      || bestFriendlyNoScheme == HttpUtility.UrlDecode(requestedPathNoScheme)
                                      || bestFriendlyNoScheme == rawUrlLowerCase))
                                {
                                    redirected = true;
                                    result.Action = ActionType.Redirect301;
                                    result.FinalUrl = bestFriendlyUrl;
                                    if (result.Reason != RedirectReason.Custom_Tab_Alias &&
                                        result.Reason != RedirectReason.Deleted_Page &&
                                        result.Reason != RedirectReason.Disabled_Page)
                                    {
                                        result.Reason = RedirectReason.Unfriendly_Url_2;
                                    }
                                    result.DebugMessages.Add("Compared :" + bestFriendlyNoScheme + " [generated] -> " + requestedPathNoScheme + " [requested with no scheme]");
                                    result.DebugMessages.Add("Compared :" + bestFriendlyNoScheme + " [generated] -> " + rawUrlWithHost + " [requested with host and scheme]");
                                    result.DebugMessages.Add("Compared :" + bestFriendlyNoScheme + " [generated] -> " + rawUrlWithHostNoScheme + " [requested with host, no scheme]");
                                    result.DebugMessages.Add("Compared :" + bestFriendlyNoScheme + " [generated] -> " + HttpUtility.UrlDecode(requestedPathNoScheme) + " [requested and decoded]");
                                    result.DebugMessages.Add("Compared :" + bestFriendlyNoScheme + " [generated] -> " + rawUrlLowerCase + " [requested raw Url]");
                                }
                            }
                        }
                    }
                }

                if (result.RedirectAllowed && settings.RedirectWrongCase)
                {
                    //check for redirects where a redirectToSubDomain is specified, 
                    //redirect for Wrong case is specified, and there is a valid tab and it's not already redirected somewhere else
                    bool doRedirect = false;
                    string redirectPath = redirected ? result.FinalUrl : requestUri.AbsoluteUri;
                    string redirectPathOnly = redirectPath;
                    if (redirectPathOnly.Contains("?"))
                    {
                        redirectPathOnly = redirectPathOnly.Substring(0, redirectPathOnly.IndexOf("?", StringComparison.Ordinal));
                    }
                    // Thanks Etienne for the fix for Diacritic Characters Terminal Loop!
                    // if the url contains url encoded characters, they appear here uppercase -> %C3%83%C2
                    // decode the url to get back the original character and do proper casing comparison
                    string urlDecodedRedirectPath = HttpUtility.UrlDecode(redirectPathOnly);

                    //check for wrong case redirection
                    if (urlDecodedRedirectPath != null && (settings.RedirectWrongCase && String.CompareOrdinal(urlDecodedRedirectPath, urlDecodedRedirectPath.ToLower()) != 0))
                    {
                        TabInfo tab;
                        bool allowRedirect = CheckFor301RedirectExclusion(result.TabId, result.PortalId, true, out tab, settings);

                        if (allowRedirect && !string.IsNullOrEmpty(settings.ForceLowerCaseRegex))
                        {
                            //don't allow redirect if excluded from redirecting in the force lower case regex pattern (606)
                            allowRedirect = !Regex.IsMatch(redirectPath, settings.ForceLowerCaseRegex, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
                        }

                        if (allowRedirect)
                        {
                            //special case : when IIS automatically places /default.aspx on the end of the string,
                            //then don't try and redirect to the lower case /default.aspx, just let it through.
                            //we don't know whether IIS appended /Default.aspx on the end, however, we can guess
                            //if the redirectDefault.aspx is turned on (511)
                            if (settings.RedirectDefaultPage == false && redirectPathOnly.EndsWith(Globals.glbDefaultPage, StringComparison.InvariantCultureIgnoreCase))
                            {
                                //ignore this, because it's just a redirect of the /Default.aspx to /default.aspx
                            }
                            else
                            {
                                redirectPath = redirectPath.Replace(redirectPathOnly, redirectPathOnly.ToLower());
                                doRedirect = true;
                                result.Reason = RedirectReason.Not_Lower_Case;
                            }
                        }
                    }
                    if (doRedirect)
                    {
                        result.Action = ActionType.Redirect301;
                        result.FinalUrl = CheckForSiteRootRedirect(result.PortalAlias.HTTPAlias, redirectPath);
                        redirected = true;
                    }
                }
            }
            return redirected;
        }
 /// <summary>
 /// Checks to see whether the specified alias is a customTabAlias
 /// </summary>
 /// <param name="result"></param>
 /// <param name="httpAlias"></param>
 /// <param name="settings"></param>
 /// <returns></returns>
 private static bool CheckIfAliasIsCustomTabAlias(ref UrlAction result, string httpAlias, FriendlyUrlSettings settings)
 {
     List<string> customAliasesForTabs = TabIndexController.GetCustomPortalAliases(settings);
     bool isACustomTabAlias = false;
     if (customAliasesForTabs != null && customAliasesForTabs.Count > 0)
     {
         //remove any customAliases that are also primary aliases.
         foreach (var cpa in PortalAliasController.Instance.GetPortalAliasesByPortalId(result.PortalId))
         {
             if (cpa.IsPrimary == true && customAliasesForTabs.Contains(cpa.HTTPAlias))
             {
                 customAliasesForTabs.Remove(cpa.HTTPAlias);
             }
         }
         isACustomTabAlias = customAliasesForTabs.Contains(httpAlias.ToLower());
     }
     return isACustomTabAlias;
 }
        private static void ShowDebugData(HttpContext context, string requestUri, UrlAction result, Exception ex)
        {
            if (context != null)
            {
                HttpResponse response = context.Response;

                //handle null responses wherever they might be found - this routine must be tolerant to all kinds of invalid inputs
                if (requestUri == null)
                {
                    requestUri = "null Uri";
                }
                string finalUrl = "null final Url";
                string rewritePath = "null rewrite path";
                string action = "null action";
                if (result != null)
                {
                    finalUrl = result.FinalUrl;
                    action = result.Action.ToString();
                    rewritePath = result.RewritePath;
                }
                //format up the error message to show
                const string debugMsg = "{0}, {1}, {2}, {3}, {4}, {5}, {6}";
                string productVer = DotNetNukeContext.Current.Application.Version.ToString();
                string portalSettings = "";
                string browser = "Unknown";
                //949 : don't rely on 'result' being non-null
                if (result != null)
                {
                    browser = result.BrowserType.ToString();
                }
                if (context.Items.Contains("PortalSettings"))
                {
                    var ps = (PortalSettings) context.Items["PortalSettings"];
                    if (ps != null)
                    {
                        portalSettings = ps.PortalId.ToString();
                        if (ps.PortalAlias != null)
                        {
                            portalSettings += ":" + ps.PortalAlias.HTTPAlias;
                        }
                    }
                }
                response.AppendHeader("X-" + _productName + "-Debug",
                                      string.Format(debugMsg, requestUri, finalUrl, rewritePath, action, productVer,
                                                    portalSettings, browser));
                int msgNum = 1;
                if (result != null)
                {
                    foreach (string msg in result.DebugMessages)
                    {
                        response.AppendHeader("X-" + _productName + "-Debug-" + msgNum.ToString("00"), msg);
                        msgNum++;
                    }
                }
                if (ex != null)
                {
                    response.AppendHeader("X-" + _productName + "-Ex", ex.Message);
                }
            }
        }
        private void IdentifyPortalAlias(HttpContext context, 
                                            HttpRequest request, 
                                            Uri requestUri, UrlAction result,
                                            NameValueCollection queryStringCol, 
                                            FriendlyUrlSettings settings,
                                            Guid parentTraceId)
        {
            //get the domain name of the request, if it isn't already supplied
            if (request != null && string.IsNullOrEmpty(result.DomainName))
            {
                result.DomainName = Globals.GetDomainName(request); //parse the domain name out of the request
            }

            // get tabId from querystring ( this is mandatory for maintaining portal context for child portals ) 
            if (queryStringCol["tabid"] != null)
            {
                string raw = queryStringCol["tabid"];
                int tabId;
                if (Int32.TryParse(raw, out tabId))
                {
                    result.TabId = tabId;
                }
                else
                {
                    //couldn't parse tab id
                    //split in two?
                    string[] tabids = raw.Split(',');
                    if (tabids.GetUpperBound(0) > 0)
                    {
                        //hmm more than one tabid
                        if (Int32.TryParse(tabids[0], out tabId))
                        {
                            result.TabId = tabId;
                            //but we want to warn against this!
                            var ex =
                                new Exception(
                                    "Illegal request exception : Two TabId parameters provided in a single request: " +
                                    requestUri);
                            UrlRewriterUtils.LogExceptionInRequest(ex, "Not Set", result);

                            result.Ex = ex;
                        }
                        else
                        {
                            //yeah, nothing, divert to 404 
                            result.Action = ActionType.Output404;
                            var ex =
                                new Exception(
                                    "Illegal request exception : TabId parameters in query string, but invalid TabId requested : " +
                                    requestUri);
                            UrlRewriterUtils.LogExceptionInRequest(ex, "Not Set", result);
                            result.Ex = ex;
                        }
                    }
                }
            }
            // get PortalId from querystring ( this is used for host menu options as well as child portal navigation ) 
            if (queryStringCol["portalid"] != null)
            {
                string raw = queryStringCol["portalid"];
                int portalId;
                if (Int32.TryParse(raw, out portalId))
                {
                    //848 : if portal already found is different to portal id in querystring, then load up different alias
                    //this is so the portal settings will be loaded correctly.
                    if (result.PortalId != portalId)
                    {
                        //portal id different to what we expected
                        result.PortalId = portalId;
                        //check the loaded portal alias, because it might be wrong
                        if (result.PortalAlias != null && result.PortalAlias.PortalID != portalId)
                        {
                            //yes, the identified portal alias is wrong.  Find the correct alias for this portal
                            PortalAliasInfo pa = TabIndexController.GetPortalAliasByPortal(portalId, result.DomainName);
                            if (pa != null)
                            {
                                //note: sets portal id and portal alias
                                result.PortalAlias = pa;
                            }
                        }
                    }
                }
            }
            else
            {
                //check for a portal alias if there's no portal Id in the query string
                //check for absence of captcha value, because the captcha string re-uses the alias querystring value
                if (queryStringCol["alias"] != null && queryStringCol["captcha"] == null)
                {
                    string alias = queryStringCol["alias"];
                    PortalAliasInfo portalAlias = PortalAliasController.Instance.GetPortalAlias(alias);
                    if (portalAlias != null)
                    {
                        //ok the portal alias was found by the alias name
                        // check if the alias contains the domain name
                        if (alias.Contains(result.DomainName) == false)
                        {
                            // replaced to the domain defined in the alias 
                            if (request != null)
                            {
                                string redirectDomain = Globals.GetPortalDomainName(alias, request, true);
                                //retVal.Url = redirectDomain;
                                result.FinalUrl = redirectDomain;
                                result.Action = ActionType.Redirect302Now;
                                result.Reason = RedirectReason.Alias_In_Url;
                            }
                        }
                        else
                        {
                            // the alias is the same as the current domain 
                            result.HttpAlias = portalAlias.HTTPAlias;
                            result.PortalAlias = portalAlias;
                            result.PortalId = portalAlias.PortalID;
                            //don't use this crap though - we don't want ?alias=portalAlias in our Url
                            if (result.RedirectAllowed)
                            {
                                string redirect = requestUri.Scheme + Uri.SchemeDelimiter + result.PortalAlias.HTTPAlias +
                                                  "/";
                                result.Action = ActionType.Redirect301;
                                result.FinalUrl = redirect;
                                result.Reason = RedirectReason.Unfriendly_Url_Child_Portal;
                            }
                        }
                    }
                }
            }
            //first try and identify the portal using the tabId, but only if we identified this tab by looking up the tabid
            //from the original url
            //668 : error in child portal redirects to child portal home page because of mismatch in tab/domain name
            if (result.TabId != -1 && result.FriendlyRewrite == false)
            {
                // get the alias from the tabid, but only if it is for a tab in that domain 
                // 2.0 : change to compare retrieved alias to the already-set httpAlias
                string httpAliasFromTab = PortalAliasController.GetPortalAliasByTab(result.TabId, result.DomainName);
                if (httpAliasFromTab != null)
                {
                    //882 : account for situation when portalAlias is null.
                    if (result.PortalAlias != null && String.Compare(result.PortalAlias.HTTPAlias, httpAliasFromTab, StringComparison.OrdinalIgnoreCase) != 0
                        || result.PortalAlias == null)
                    {
                        //691 : change logic to force change in portal alias context rather than force back.
                        //This is because the tabid in the query string should take precedence over the portal alias
                        //to handle parent.com/default.aspx?tabid=xx where xx lives in parent.com/child/ 
                        var tab = TabController.Instance.GetTab(result.TabId, Null.NullInteger, false);
                        //when result alias is null or result alias is different from tab-identified portalAlias
                        if (tab != null && (result.PortalAlias == null || tab.PortalID != result.PortalAlias.PortalID))
                        {
                            //the tabid is different to the identified portalid from the original alias identified
                            //so get a new alias 
                            PortalAliasInfo tabPortalAlias = PortalAliasController.Instance.GetPortalAlias(httpAliasFromTab, tab.PortalID);
                            if (tabPortalAlias != null)
                            {
                                result.PortalId = tabPortalAlias.PortalID;
                                result.PortalAlias = tabPortalAlias;
                                result.Action = ActionType.CheckFor301;
                                result.Reason = RedirectReason.Wrong_Portal;
                            }
                        }
                    }
                }
            }
            //if no alias, try and set by using the identified http alias or domain name
            if (result.PortalAlias == null)
            {
                if (!string.IsNullOrEmpty(result.HttpAlias))
                {
                    result.PortalAlias = PortalAliasController.Instance.GetPortalAlias(result.HttpAlias);
                }
                else
                {
                    result.PortalAlias = PortalAliasController.Instance.GetPortalAlias(result.DomainName);
                    if (result.PortalAlias == null && result.DomainName.EndsWith("/"))
                    {
                        result.DomainName = result.DomainName.TrimEnd('/');
                        result.PortalAlias = PortalAliasController.Instance.GetPortalAlias(result.DomainName);
                    }
                }
            }

            if (result.PortalId == -1)
            {
                if (!requestUri.LocalPath.ToLower().EndsWith(Globals.glbDefaultPage.ToLower()))
                {
                    // allows requests for aspx pages in custom folder locations to be processed 
                    return;
                }
                //the domain name was not found so try using the host portal's first alias
                if (Host.Host.HostPortalID != -1)
                {
                    result.PortalId = Host.Host.HostPortalID;
                    // use the host portal, but replaced to the host portal home page
                    var aliases = PortalAliasController.Instance.GetPortalAliasesByPortalId(result.PortalId).ToList();
                    if (aliases.Count > 0)
                    {
                        string alias = null;

                        //get the alias as the chosen portal alias for the host portal based on the result culture code
                        var cpa = aliases.GetAliasByPortalIdAndSettings(result.PortalId, result, result.CultureCode, settings);
                        if (cpa != null)
                        {
                            alias = cpa.HTTPAlias;
                        }

                        if (alias != null)
                        {
                            result.Action = ActionType.Redirect301;
                            result.Reason = RedirectReason.Host_Portal_Used;
                            string destUrl = MakeUrlWithAlias(requestUri, alias);
                            destUrl = CheckForSiteRootRedirect(alias, destUrl);
                            result.FinalUrl = destUrl;
                        }
                        else
                        {
                            //Get the first Alias for the host portal
                            result.PortalAlias = aliases[result.PortalId];
                            string url = MakeUrlWithAlias(requestUri, result.PortalAlias);
                            if (result.TabId != -1)
                            {
                                url += requestUri.Query;
                            }
                            result.FinalUrl = url;
                            result.Reason = RedirectReason.Host_Portal_Used;
                            result.Action = ActionType.Redirect302Now;
                        }
                    }
                }
            }

            //double check to make sure we still have the correct alias now that all other information is known (ie tab, portal, culture)
            //770 : redirect alias based on tab id when custom alias used
            if (result.TabId == -1 && result.Action == ActionType.CheckFor301 &&
                result.Reason == RedirectReason.Custom_Tab_Alias)
            {
                //here because the portal alias matched, but no tab was found, and because there are custom tab aliases used for this portal
                //need to redirect back to the chosen portal alias and keep the current path.
                string wrongAlias = result.HttpAlias; //it's a valid alias, but only for certain tabs
                var primaryAliases = PortalAliasController.Instance.GetPortalAliasesByPortalId(result.PortalId).ToList();
                if (primaryAliases != null && result.PortalId > -1)
                {
                    //going to look for the correct alias based on the culture of the request
                    string requestCultureCode = result.CultureCode;
                    //if that didn't work use the default language of the portal
                    if (requestCultureCode == null)
                    {
                        //this might end up in a double redirect if the path of the Url is for a specific language as opposed
                        //to a path belonging to the default language domain
                        PortalInfo portal = PortalController.Instance.GetPortal(result.PortalId);
                        if (portal != null)
                        {
                            requestCultureCode = portal.DefaultLanguage;
                        }
                    }
                    //now that the culture code is known, look up the correct portal alias for this portalid/culture code
                    var cpa = primaryAliases.GetAliasByPortalIdAndSettings(result.PortalId, result, requestCultureCode, settings);
                    if (cpa != null)
                    {
                        //if an alias was found that matches the request and the culture code, then run with that
                        string rightAlias = cpa.HTTPAlias;
                        //will cause a redirect to the primary portal alias - we know now that there was no custom alias tab
                        //found, so it's just a plain wrong alias
                        ConfigurePortalAliasRedirect(ref result, wrongAlias, rightAlias, true,
                                                     settings.InternalAliasList, settings);
                    }
                }
            }
            else
            {
                //then check to make sure it's the chosen portal alias for this portal
                //627 : don't do it if we're redirecting to the host portal 
                if (result.RedirectAllowed && result.Reason != RedirectReason.Host_Portal_Used)
                {
                    string primaryAlias;
                    //checking again in case the rewriting operation changed the values for the valid portal alias
                    bool incorrectAlias = IsPortalAliasIncorrect(context, request, requestUri, result, queryStringCol, settings, parentTraceId, out primaryAlias);
                    if (incorrectAlias) RedirectPortalAlias(primaryAlias, ref result, settings);
                }
            }

            //check to see if we have to avoid the core 302 redirect for the portal alias that is in the /defualt.aspx
            //for child portals
            //exception to that is when a custom alias is used but no rewrite has taken place
            if (result.DoRewrite == false && (result.Action == ActionType.Continue
                                              ||
                                              (result.Action == ActionType.CheckFor301 &&
                                               result.Reason == RedirectReason.Custom_Tab_Alias)))
            {
                string aliasQuerystring;
                bool isChildAliasRootUrl = CheckForChildPortalRootUrl(requestUri.AbsoluteUri, result, out aliasQuerystring);
                if (isChildAliasRootUrl)
                {
                    RewriteAsChildAliasRoot(context, result, aliasQuerystring, settings);
                }
            }
        }
        internal static bool TransformFriendlyUrlPath(string newUrl, 
                                                        string tabKeyVal, 
                                                        string[] urlParms,
                                                        bool isSiteRootMatch, 
                                                        ref UrlAction result,
                                                        FriendlyUrlSettings settings, 
                                                        out string rewrittenUrl,
                                                        out bool newAction, 
                                                        ref List<string> messages,  
                                                        Guid parentTraceId)
        {
            bool rewriteDone = false;
            rewrittenUrl = newUrl;
            newAction = false;
            ExtensionUrlProvider activeProvider = null;
            try
            {
                int tabId = result.TabId;
                if (isSiteRootMatch)
                {
                    tabId = RewriteController.SiteRootRewrite;
                }
                List<ExtensionUrlProvider> providersToCall = GetProvidersToCall(tabId, 
                                                                                result.PortalId, 
                                                                                settings,
                                                                                parentTraceId);
                if (providersToCall != null && providersToCall.Count > 0)
                {
                    //now check for providers by calling the providers
                    int upperBound = urlParms.GetUpperBound(0);
                    //clean extension off parameters array
                    var parms = new string[upperBound + 1];
                    Array.ConstrainedCopy(urlParms, 0, parms, 0, upperBound + 1);
                    if (upperBound >= 0)
                    {
                        bool replaced;
                        parms[upperBound] = RewriteController.CleanExtension(parms[upperBound], settings, out replaced);
                    }
                    //get options from current settings
                    FriendlyUrlOptions options = UrlRewriterUtils.GetOptionsFromSettings(settings);
                    foreach (ExtensionUrlProvider provider in providersToCall)
                    {
                        //set active provider for exception handling
                        activeProvider = provider;
                        //call down to specific providers and see if we get a rewrite
                        string location;
                        int status;
                        string queryString = provider.TransformFriendlyUrlToQueryString(parms, 
                                                                                        result.TabId,
                                                                                        result.PortalId, 
                                                                                        options,
                                                                                        result.CultureCode,
                                                                                        result.PortalAlias, 
                                                                                        ref messages,
                                                                                        out status, 
                                                                                        out location);
                        if (status == 0 || status == 200) //either not set, or set to '200 OK'.
                        {
                            if (!string.IsNullOrEmpty(queryString) && queryString != newUrl)
                            {
                                rewriteDone = true;
                                //check for duplicate tabIds.
                                string qsRemainder = null;
                                if (Regex.IsMatch(queryString, @"tabid=\d+", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
                                {
                                    //930 : look for other querystring information in the rewritten Url, or invalid rewritten urls can be created
                                    //pattern to determine which tab matches
                                    const string rewrittenUrlPattern = @"(?<tabid>(?:\?|&)tabid=\d+)(?<qs>&[^=]+=[^&]*)*";
                                    //look for any other querystirng information in the already rewritten Url (ie language parameters)
                                    Match rewrittenUrlMatch = Regex.Match(rewrittenUrl, rewrittenUrlPattern,
                                                                          RegexOptions.IgnoreCase |
                                                                          RegexOptions.CultureInvariant);
                                    if (rewrittenUrlMatch.Groups["qs"].Success)
                                    {
                                        //keep any other querystring remainders
                                        qsRemainder = rewrittenUrlMatch.Groups["qs"].Captures.Cast<Capture>().Aggregate("", (current, qsCapture) => current + qsCapture.Value); //initialise
                                    }
                                    //supplied value overwrites existing value, so remove from the rewritten url
                                    rewrittenUrl = Regex.Replace(rewrittenUrl, rewrittenUrlPattern, "", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
                                }
                                if (rewrittenUrl.Contains("?") == false)
                                {
                                    //use a leading ?, not a leading &
                                    queryString = FriendlyUrlController.EnsureNotLeadingChar("&", queryString);
                                    queryString = FriendlyUrlController.EnsureLeadingChar("?", queryString);
                                }
                                else
                                {
                                    //use a leading &, not a leading ?
                                    queryString = FriendlyUrlController.EnsureNotLeadingChar("?", queryString);
                                    queryString = FriendlyUrlController.EnsureLeadingChar("&", queryString);
                                }

                                //add querystring onto rewritten Url
                                rewrittenUrl += queryString;
                                if (qsRemainder != null)
                                {
                                    rewrittenUrl += qsRemainder;
                                }
                                break;
                            }
                        }
                        else
                        {
                            switch (status)
                            {
                                case 301:
                                    result.Action = ActionType.Redirect301;
                                    result.Reason = RedirectReason.Module_Provider_Rewrite_Redirect;
                                    result.FinalUrl = location;
                                    break;
                                case 302:
                                    result.Action = ActionType.Redirect302;
                                    result.Reason = RedirectReason.Module_Provider_Rewrite_Redirect;
                                    result.FinalUrl = location;
                                    break;
                                case 404:
                                    result.Action = ActionType.Output404;
                                    break;
                                case 500:
                                    result.Action = ActionType.Output500;
                                    break;
                            }
                            newAction = true; //not doing a 200 status
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //log module provider exception
                LogModuleProviderExceptionInRequest(ex, "500 Internal Server Error", activeProvider, result, messages);
                //reset values to initial
                rewriteDone = false;
                rewrittenUrl = newUrl;
                newAction = false;
                string providerName = "Unknown";
                if (activeProvider != null)
                {
                    providerName = activeProvider.ProviderConfig.ProviderName;
                }
                if (result != null)
                {
                    result.DebugMessages.Add("Exception in provider [" + providerName + "] :" + ex.Message);
                }
            }
            return rewriteDone;
        }
 internal static bool CheckForChildPortalRootUrl(string requestUrl, UrlAction result, out string aliasQueryString)
 {
     bool isChildPortalRootUrl = false;
     //what we are going to test for here is that if this is a child portal request, for the /default.aspx of the child portal
     //then we are going to avoid the core 302 redirect to ?alias=portalALias by rewriting to the /default.aspx of the site root
     //684 : don't convert querystring items to lower case
     //do the check by constructing what a child alias url would look like and compare it with the requested urls
     //912 : when requested without a valid portal alias, portalALias is null.  Refuse and return false.
     aliasQueryString = null;
     if (result.PortalAlias != null && result.PortalAlias.HTTPAlias != null)
     {
         string defaultPageUrl = result.Scheme + result.PortalAlias.HTTPAlias + "/" +
                                 Globals.glbDefaultPage.ToLower(); //child alias Url with /default.aspx
         //660 : look for a querystring on the site root for a child portal, and handle it if so
         if (String.CompareOrdinal(requestUrl.ToLower(), defaultPageUrl) == 0)
         {
             //exact match : that's the alias root
             isChildPortalRootUrl = true;
             aliasQueryString = "";
         }
         if (!isChildPortalRootUrl && requestUrl.Contains("?"))
         {
             //is we didn't get an exact match but there is a querystring, then investigate
             string[] requestUrlParts = requestUrl.Split('?');
             if (requestUrlParts.GetUpperBound(0) > 0)
             {
                 string rootPart = requestUrlParts[0];
                 string queryString = requestUrlParts[1];
                 if (String.Compare(rootPart, defaultPageUrl, StringComparison.OrdinalIgnoreCase) == 0)
                 {
                     //rewrite, but put in the querystring on the rewrite path
                     isChildPortalRootUrl = true;
                     aliasQueryString = "?" + queryString;
                     //674: check for 301 if this value is a tabid/xx - otherwise the url will just evaluate as is
                     if (queryString.ToLower().StartsWith("tabid="))
                     {
                         result.Action = ActionType.CheckFor301;
                     }
                 }
             }
         }
     }
     return isChildPortalRootUrl;
 }
        /// <summary>
        /// logs an exception related to a module provider once per cache-lifetime
        /// </summary>
        /// <param name="ex"></param>
        /// <param name="status"></param>
        /// <param name="result"></param>
        /// <param name="messages"></param>
        /// <param name="provider"></param>
        public static void LogModuleProviderExceptionInRequest(Exception ex, string status,
                                                                ExtensionUrlProvider provider, 
                                                                UrlAction result,
                                                                List<string> messages)
        {
            if (ex != null)
            {
                string moduleProviderName = "Unknown Provider";
                string moduleProviderVersion = "Unknown Version";
                if (provider != null)
                {
                    moduleProviderName = provider.ProviderConfig.ProviderName;
                    moduleProviderVersion = provider.GetType().Assembly.GetName(false).Version.ToString();
                }
                //this logic prevents a site logging an exception for every request made.  Instead 
                //the exception will be logged once for the life of the cache / application restart or 1 hour, whichever is shorter.
                //create a cache key for this exception type
                string cacheKey = ex.GetType().ToString();
                //see if there is an existing object logged for this exception type
                object existingEx = DataCache.GetCache(cacheKey);
                if (existingEx == null)
                {
                    //if there was no existing object logged for this exception type, this is a new exception
                    DateTime expire = DateTime.Now.AddHours(1);
                    DataCache.SetCache(cacheKey, cacheKey, expire);
                    //just store the cache key - it doesn't really matter
                    //create a log event
                    string productVer = Assembly.GetExecutingAssembly().GetName(false).Version.ToString();
                    var elc = new EventLogController();
                    var logEntry = new LogInfo {LogTypeKey = "GENERAL_EXCEPTION"};
                    logEntry.AddProperty("Url Rewriting Extension Url Provider Exception",
                                         "Exception in Url Rewriting Process");
                    logEntry.AddProperty("Provider Name", moduleProviderName);
                    logEntry.AddProperty("Provider Version", moduleProviderVersion);
                    logEntry.AddProperty("Http Status", status);
                    logEntry.AddProperty("Product Version", productVer);
                    if (result != null)
                    {
                        logEntry.AddProperty("Original Path", result.OriginalPath ?? "null");
                        logEntry.AddProperty("Raw Url", result.RawUrl ?? "null");
                        logEntry.AddProperty("Final Url", result.FinalUrl ?? "null");

                        logEntry.AddProperty("Rewrite Result", !string.IsNullOrEmpty(result.RewritePath)
                                                                     ? result.RewritePath
                                                                     : "[no rewrite]");
                        logEntry.AddProperty("Redirect Location", string.IsNullOrEmpty(result.FinalUrl) 
                                                                    ? "[no redirect]" 
                                                                    : result.FinalUrl);
                        logEntry.AddProperty("Action", result.Action.ToString());
                        logEntry.AddProperty("Reason", result.Reason.ToString());
                        logEntry.AddProperty("Portal Id", result.PortalId.ToString());
                        logEntry.AddProperty("Tab Id", result.TabId.ToString());
                        logEntry.AddProperty("Http Alias", result.PortalAlias != null ? result.PortalAlias.HTTPAlias : "Null");

                        if (result.DebugMessages != null)
                        {
                            int i = 1;
                            foreach (string debugMessage in result.DebugMessages)
                            {
                                string msg = debugMessage;
                                if (debugMessage == null)
                                {
                                    msg = "[message was null]";
                                }
                                logEntry.AddProperty("Debug Message[result] " + i.ToString(), msg);
                                i++;
                            }
                        }
                    }
                    else
                    {
                        logEntry.AddProperty("Result", "Result value null");
                    }
                    if (messages != null)
                    {
                        int i = 1;
                        foreach (string msg in messages)
                        {
                            logEntry.AddProperty("Debug Message[raw] " + i.ToString(), msg);
                            i++;
                        }
                    }
                    logEntry.AddProperty("Exception Type", ex.GetType().ToString());
                    logEntry.AddProperty("Message", ex.Message);
                    logEntry.AddProperty("Stack Trace", ex.StackTrace);
                    if (ex.InnerException != null)
                    {
                        logEntry.AddProperty("Inner Exception Message", ex.InnerException.Message);
                        logEntry.AddProperty("Inner Exception Stacktrace", ex.InnerException.StackTrace);
                    }
                    logEntry.BypassBuffering = true;
                    elc.AddLog(logEntry);
                }
            }
        }
        private static void CheckForRewrite(string fullUrl, 
                                                string querystring, 
                                                UrlAction result, 
                                                bool useFriendlyUrls,
                                                NameValueCollection queryStringCol, 
                                                FriendlyUrlSettings settings,
                                                out bool isPhysicalResource, 
                                                Guid parentTraceId)
        {
            bool checkForRewrites;
            //just check to make sure it isn't a physical resource on the server
            RewriteController.IdentifyByPhysicalResource(result.PhysicalPath, 
                                                            fullUrl, 
                                                            queryStringCol, 
                                                            ref result,
                                                            useFriendlyUrls, 
                                                            settings, 
                                                            out isPhysicalResource,
                                                            out checkForRewrites, 
                                                            parentTraceId);

            if (checkForRewrites && RewriteController.CanRewriteRequest(result, fullUrl, settings))
            {
                bool doSiteUrlProcessing = false;
                //728 new regex expression to pass values straight onto the siteurls.config file
                if (!string.IsNullOrEmpty(settings.UseSiteUrlsRegex))
                {
                    doSiteUrlProcessing = Regex.IsMatch(fullUrl, settings.UseSiteUrlsRegex, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
                }

                if (!doSiteUrlProcessing)
                    //if a virtual request, and not starting with the siteUrls.config file, go on to find the rewritten path
                {
                    //looks up the page index to find the correct Url
                    bool doRewrite = RewriteController.IdentifyByTabPathEx(fullUrl, querystring, result, queryStringCol, settings, parentTraceId);
                    if (!doRewrite)
                    {
                        doSiteUrlProcessing = true;
                    }
                }
                if (doSiteUrlProcessing)
                {
                    //728 : compare requests against the siteurls.config file, either if no other match was found, or if we want to skip the rest of the processing
                    // the standard DNN way of rewriting, using expressions found in the siteurls.config file
                    RewriteController.IdentifyByRegEx(fullUrl, querystring, result.ApplicationPath, ref result, settings, parentTraceId);
                }
            }
        }
Esempio n. 37
0
        /// <summary>
        /// DetermineRedirectReasonAndAction extracts the redirect value from the rewrite url and
        /// returns the new rewritten url, and the reason for the redirection, and an action value for the type of redirect.
        /// </summary>
        /// <param name="rewrittenUrl">Rewritten url as found in page dictionary.</param>
        /// <param name="result">The current rewrite result.</param>
        /// <param name="wasParms">true if there are parameters in the path, false if not.</param>
        /// <param name="settings">current FriendlyUrlSettings object.</param>
        /// <param name="action">New action value for UrlAction object.</param>
        /// <param name="reason">New redirect reason value for UrlAction object.</param>
        /// <param name="newUrl">Url to used for rewrite process.</param>
        internal static void DetermineRedirectReasonAndAction(
            string rewrittenUrl,
            UrlAction result,
            bool wasParms,
            FriendlyUrlSettings settings,
            out string newUrl,
            out RedirectReason reason,
            out ActionType action)
        {
            // init parms
            newUrl = rewrittenUrl;
            action = result.Action;
            reason = result.Reason;

            // get the action type from the rewrite path
            ActionType foundAction;
            bool       actionInPath = GetActionFromRewritePath(rewrittenUrl, out foundAction);

            // only overrwrite action if it was found in the rewrite path
            if (actionInPath)
            {
                action = foundAction;
            }

            // get the list of redirect reason tokens from the url
            List <string> redirectReasons = GetRedirectReasonTokensFromRewritePath(rewrittenUrl);

            // when redirect action in path, and redirect reasons are empty, add custom redirect
            if (redirectReasons.Count == 0 && action != ActionType.Continue)
            {
                redirectReasons.Add("cr");
            }

            bool clearActionToken = false;

            foreach (string rrTkn in redirectReasons)
            {
                switch (rrTkn)
                {
                case "up":
                    // user profile redirect
                    clearActionToken = true;
                    if (wasParms)
                    {
                        if (reason == RedirectReason.Not_Redirected)
                        {
                            if (settings.RedirectOldProfileUrl)
                            {
                                reason = RedirectReason.User_Profile_Url;
                                action = ActionType.CheckFor301;
                            }
                            else
                            {
                                action = ActionType.Continue;
                            }
                        }
                    }
                    else
                    {
                        // if no parms, then we're not doing a userprofileaction redirect
                        reason = RedirectReason.Custom_Redirect;

                        // then check for a 301 redirect
                        action = ActionType.CheckFor301;
                    }

                    break;

                case "dl":
                case "db":
                    // deleted tab dl
                    // disabled tab db
                    clearActionToken = true;

                    // 626 Deleted tab hanlding not working properyly - override
                    if (settings.DeletedTabHandlingType == DeletedTabHandlingType.Do404Error)
                    {
                        action = ActionType.Output404;     // output a 404 as per settings
                    }

                    // 838 : handle disabled pages separately
                    reason = rrTkn == "dl" ? RedirectReason.Deleted_Page : RedirectReason.Disabled_Page;
                    break;

                case "pr":
                    // pr = permanent redirect
                    reason           = RedirectReason.Tab_Permanent_Redirect;
                    clearActionToken = true;
                    break;

                case "sr":
                    // sr = spaces replaced in url
                    clearActionToken = true;
                    reason           = RedirectReason.Spaces_Replaced;
                    break;

                case "hp":
                    // hp = home page redirect
                    if (wasParms)
                    {
                        // cancel the home page replaced if there were parameters added and page extensions
                        // are in use - otherwise a 404 will occur for the relative path
                        reason           = RedirectReason.Not_Redirected;
                        action           = ActionType.Continue;
                        clearActionToken = true;
                    }
                    else
                    {
                        reason           = RedirectReason.Site_Root_Home;
                        clearActionToken = true;
                    }

                    break;

                default:
                    // any other redirect with no reason is a custom redirect
                    if (reason == RedirectReason.Not_Redirected)
                    {
                        reason = RedirectReason.Custom_Redirect;
                    }

                    clearActionToken = true;
                    break;
                }
            }

            if (clearActionToken)
            {
                // clear both action and reason
                newUrl = RemoveAnyRedirectTokensAndReasons(newUrl);
            }
            else
            {
                // clear just reason
                newUrl = RemoveAnyRedirectReasons(newUrl);
            }
        }
        internal override void RewriteUrl(object sender, EventArgs e)
        {
            Guid parentTraceId = Guid.Empty;
            const bool debug = true;
            bool failedInitialization = false;
            bool ignoreForInstall = false;
            var app = (HttpApplication) sender;
            try
            {
                //875 : completely ignore install/upgrade requests immediately
                ignoreForInstall = IgnoreRequestForInstall(app.Request);

                if (ignoreForInstall == false)
                {
                    _settings = new FriendlyUrlSettings(-1);

                    SecurityCheck(app);
                }
                
            }
            catch (Exception ex)
            {
                //exception handling for advanced Url Rewriting requests
                failedInitialization = true;
                DotNetNuke.Services.Exceptions.Exceptions.LogException(ex);
                if (app.Context != null)
                {
                    ShowDebugData(app.Context, app.Request.Url.AbsoluteUri, null, ex);
                    Handle404OrException(_settings, app.Context, ex, null, false, debug);
                }
                else
                {
                    throw;
                }
            }
            if (!failedInitialization && !ignoreForInstall)
            {
                //if made it through there and not installing, go to next call.  Not in exception catch because it implements it's own top-level exception handling
                var request = app.Context.Request;

                //829 : change constructor to stop using physical path
                var result = new UrlAction(request)
                                        {
                                            IsSecureConnection = request.IsSecureConnection,
                                            IsSSLOffloaded = IsSSLOffloadEnabled(request),
                                            RawUrl = request.RawUrl
                                        };
                ProcessRequest(app.Context,
                                    app.Context.Request.Url,
                                     Host.Host.UseFriendlyUrls,
                                     result,
                                     _settings,
                                     true,
                                     parentTraceId);
            }
        }
Esempio n. 39
0
 public static PortalAliasInfo GetAliasByPortalIdAndSettings(this IEnumerable<PortalAliasInfo> aliases, UrlAction result)
 {
     return GetAliasByPortalIdAndSettings(aliases, result.PortalId, result, result.CultureCode, result.BrowserType);
 }
        private static void Handle404OrException(FriendlyUrlSettings settings, HttpContext context, Exception ex, UrlAction result, bool transfer, bool showDebug)
        {
            //handle Auto-Add Alias
            if (result.Action == ActionType.Output404 && CanAutoAddPortalAlias())
            {
                //Need to determine if this is a real 404 or a possible new alias.
                var portalId = Host.Host.HostPortalID;
                if (portalId > Null.NullInteger)
                {
                    if (string.IsNullOrEmpty(result.DomainName))
                    {
                        result.DomainName = Globals.GetDomainName(context.Request); //parse the domain name out of the request
                    }

                    //Get all the existing aliases
                    var aliases = PortalAliasController.Instance.GetPortalAliasesByPortalId(portalId).ToList();

                    bool autoaddAlias;
                    bool isPrimary = false;
                    if (!aliases.Any())
                    {
                        autoaddAlias = true;
                        isPrimary = true;
                    }
                    else
                    {
                        autoaddAlias = true;
                        foreach (var alias in aliases)
                        {
                            if (result.DomainName.ToLowerInvariant().IndexOf(alias.HTTPAlias, StringComparison.Ordinal) == 0
                                    && result.DomainName.Length >= alias.HTTPAlias.Length)
                            {
                                autoaddAlias = false;
                                break;
                            }
                        }
                    }

                    if (autoaddAlias)
                    {
                        var portalAliasInfo = new PortalAliasInfo
                                                  {
                                                      PortalID = portalId, 
                                                      HTTPAlias = result.DomainName,
                                                      IsPrimary = isPrimary
                                                  };
                        PortalAliasController.Instance.AddPortalAlias(portalAliasInfo);

                        context.Response.Redirect(context.Request.Url.ToString(), true);
                    }
                }
            }


            if (context != null)
            {
                HttpRequest request = context.Request;
                HttpResponse response = context.Response;
                HttpServerUtility server = context.Server;

                const string errorPageHtmlHeader = @"<html><head><title>{0}</title></head><body>";
                const string errorPageHtmlFooter = @"</body></html>";
                var errorPageHtml = new StringWriter();
                CustomErrorsSection ceSection = null;
                //876 : security catch for custom error reading
                try
                {
                    ceSection = (CustomErrorsSection) WebConfigurationManager.GetSection("system.web/customErrors");
                }
// ReSharper disable EmptyGeneralCatchClause
                catch (Exception)
// ReSharper restore EmptyGeneralCatchClause
                {
                    //on some medium trust environments, this will throw an exception for trying to read the custom Errors
                    //do nothing
                }

                /* 454 new 404/500 error handling routine */
                bool useDNNTab = false;
                int errTabId = -1;
                string errUrl = null;
                string status = "";
                bool isPostback = false;
                if (settings != null)
                {
                    if (request.RequestType == "POST")
                    {
                        isPostback = true;
                    }
                    if (result != null && ex != null)
                    {
                        result.DebugMessages.Add("Exception: " + ex.Message);
                        result.DebugMessages.Add("Stack Trace: " + ex.StackTrace);
                        if (ex.InnerException != null)
                        {
                            result.DebugMessages.Add("Inner Ex : " + ex.InnerException.Message);
                            result.DebugMessages.Add("Stack Trace: " + ex.InnerException.StackTrace);
                        }
                        else
                        {
                            result.DebugMessages.Add("Inner Ex : null");
                        }
                    }
                    string errRH;
                    string errRV;
                    int statusCode;
                    if (result != null && result.Action != ActionType.Output404)
                    {
                        //output everything but 404 (usually 500)
                        if (settings.TabId500 > -1) //tabid specified for 500 error page, use that
                        {
                            useDNNTab = true;
                            errTabId = settings.TabId500;
                        }
                        errUrl = settings.Url500;
                        errRH = "X-UrlRewriter-500";
                        errRV = "500 Rewritten to {0} : {1}";
                        statusCode = 500;
                        status = "500 Internal Server Error";
                    }
                    else //output 404 error 
                    {
                        if (settings.TabId404 > -1) //if the tabid is specified for a 404 page, then use that
                        {
                            useDNNTab = true;
                            errTabId = settings.TabId404;
                        }
                        if (!String.IsNullOrEmpty(settings.Regex404))
                            //with 404 errors, there's an option to catch certain urls and use an external url for extra processing.
                        {
                            try
                            {
                                //944 : check the original Url in case the requested Url has been rewritten before discovering it's a 404 error
                                string requestedUrl = request.Url.ToString();
                                if (result != null && string.IsNullOrEmpty(result.OriginalPath) == false)
                                {
                                    requestedUrl = result.OriginalPath;
                                }
                                if (Regex.IsMatch(requestedUrl, settings.Regex404, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))
                                {
                                    useDNNTab = false;
                                        //if we have a match in the 404 regex value, then don't use the tabid
                                }
                            }
                            catch (Exception regexEx)
                            {
                                //.some type of exception : output in response header, and go back to using the tabid 
                                response.AppendHeader("X-UrlRewriter-404Exception", regexEx.Message);
                            }
                        }
                        errUrl = settings.Url404;
                        errRH = "X-UrlRewriter-404";
                        errRV = "404 Rewritten to {0} : {1} : Reason {2}";
                        status = "404 Not Found";
                        statusCode = 404;
                    }

                    // check for 404 logging
                    if ((result == null || result.Action == ActionType.Output404))
                    {
                        //Log 404 errors to Event Log
                        UrlRewriterUtils.Log404(request, settings, result);
                    }
                    //912 : use unhandled 404 switch
                    string reason404 = null;
                    bool unhandled404 = true;
                    if (useDNNTab && errTabId > -1)
                    {
                        unhandled404 = false; //we're handling it here
                        TabInfo errTab = TabController.Instance.GetTab(errTabId, result.PortalId, true);
                        if (errTab != null)
                        {
                            bool redirect = false;
                            //ok, valid tabid.  what we're going to do is to load up this tab via a rewrite of the url, and then change the output status
                            string reason = "Not Found";
                            if (result != null)
                            {
                                reason = result.Reason.ToString();
                            }
                            response.AppendHeader(errRH, string.Format(errRV, "DNN Tab",
                                                                errTab.TabName + "(Tabid:" + errTabId.ToString() + ")",
                                                                reason));
                            //show debug messages even if in debug mode
                            if (context != null && response != null && result != null && showDebug)
                            {
                                ShowDebugData(context, result.OriginalPath, result, null);
                            }
                            if (!isPostback)
                            {
                                response.ClearContent();
                                response.StatusCode = statusCode;
                                response.Status = status;
                            }
                            else
                            {
                                redirect = true;
                                    //redirect postbacks as you can't postback successfully to a server.transfer
                            }
                            errUrl = Globals.glbDefaultPage + TabIndexController.CreateRewritePath(errTab.TabID, "");
                            //have to update the portal settings with the new tabid
                            PortalSettings ps = null;
                            if (context != null && context.Items != null)
                            {
                                if (context.Items.Contains("PortalSettings"))
                                {
                                    ps = (PortalSettings) context.Items["PortalSettings"];
                                    context.Items.Remove("PortalSettings"); //nix it from the context
                                }
                            }
                            if (ps != null && ps.PortalAlias != null)
                            {
                                ps = new PortalSettings(errTabId, ps.PortalAlias);
                            }
                            else
                            {
                                if (result.HttpAlias != null && result.PortalId > -1)
                                {
                                    PortalAliasInfo pa = PortalAliasController.Instance.GetPortalAlias(result.HttpAlias, result.PortalId);
                                    ps = new PortalSettings(errTabId, pa);
                                }
                                else
                                {
                                    //912 : handle 404 when no valid portal can be identified
                                    //results when iis is configured to handle portal alias, but 
                                    //DNN isn't.  This always returns 404 because a multi-portal site
                                    //can't just show the 404 page of the host site.
                                    ArrayList portals = PortalController.Instance.GetPortals();
                                    if (portals != null && portals.Count == 1)
                                    {
                                        //single portal install, load up portal settings for this portal
                                        var singlePortal = (PortalInfo) portals[0];
                                        //list of aliases from database
                                        var aliases = PortalAliasController.Instance.GetPortalAliasesByPortalId(singlePortal.PortalID).ToList();
                                        //list of aliases from Advanced Url settings
                                        List<string> chosen = aliases.GetAliasesForPortalId(singlePortal.PortalID);
                                        PortalAliasInfo useFor404 = null;
                                        //go through all aliases and either get the first valid one, or the first 
                                        //as chosen in the advanced url management settings
                                        foreach (var pa in aliases)
                                        {
                                            if (useFor404 == null)
                                            {
                                                useFor404 = pa; //first one by default
                                            }

                                            //matching?
                                            if (chosen != null && chosen.Count > 0)
                                            {
                                                if (chosen.Contains(pa.HTTPAlias))
                                                {
                                                    useFor404 = pa;
                                                }
                                            }
                                            else
                                            {
                                                break; //no further checking
                                            }
                                        }
                                        //now configure that as the portal settings
                                        if (useFor404 != null)
                                        {
                                            //create portal settings context for identified portal alias in single portal install
                                            ps = new PortalSettings(errTabId, useFor404);
                                        }
                                    }
                                    else
                                    {
                                        reason404 = "Requested domain name is not configured as valid website";
                                        unhandled404 = true;
                                    }
                                }
                            }
                            if (ps != null)
                            {
                                //re-add the context items portal settings back in
                                context.Items.Add("PortalSettings", ps);
                            }
                            if (redirect)
                            {
                                errUrl = TestableGlobals.Instance.NavigateURL();
                                response.Redirect(errUrl, true); //redirect and end response.  
                                //It will mean the user will have to postback again, but it will work the second time
                            }
                            else
                            {
                                if (transfer)
                                {
                                    //execute a server transfer to the default.aspx?tabid=xx url
                                    //767 : object not set error on extensionless 404 errors
                                    if (context.User == null)
                                    {
                                        context.User = Thread.CurrentPrincipal;
                                    }
                                    response.TrySkipIisCustomErrors = true;
                                    //881 : spoof the basePage object so that the client dependency framework
                                    //is satisfied it's working with a page-based handler
                                    IHttpHandler spoofPage = new CDefault();
                                    context.Handler = spoofPage;
                                    server.Transfer("~/" + errUrl, true);
                                }
                                else
                                {
                                    context.RewritePath("~/Default.aspx", false);
                                    response.TrySkipIisCustomErrors = true;
                                    response.Status = "404 Not Found";
                                    response.StatusCode = 404;
                                }
                            }
                        }
                    }
                    //912 : change to new if statement to handle cases where the TabId404 couldn't be handled correctly
                    if (unhandled404)
                    {
                        //proces the error on the external Url by rewriting to the external url
                        if (!String.IsNullOrEmpty(errUrl))
                        {
                            response.ClearContent();
                            response.TrySkipIisCustomErrors = true;
                            string reason = "Not Found";
                            if (result != null)
                            {
                                reason = result.Reason.ToString();
                            }
                            response.AppendHeader(errRH, string.Format(errRV, "Url", errUrl, reason));
                            if (reason404 != null)
                            {
                                response.AppendHeader("X-Url-Master-404-Data", reason404);
                            }
                            response.StatusCode = statusCode;
                            response.Status = status;
                            server.Transfer("~/" + errUrl, true);
                        }
                        else
                        {
                            errorPageHtml.Write(status + "<br>The requested Url does not return any valid content.");
                            if (reason404 != null)
                            {
                                errorPageHtml.Write(status + "<br>" + reason404);
                            }
                            errorPageHtml.Write("<div style='font-weight:bolder'>Administrators</div>");
                            errorPageHtml.Write("<div>Change this message by configuring a specific 404 Error Page or Url for this website.</div>");

                            //output a reason for the 404
                            string reason = "";
                            if (result != null)
                            {
                                reason = result.Reason.ToString();
                            }
                            if (!string.IsNullOrEmpty(errRH) && !string.IsNullOrEmpty(reason))
                            {
                                response.AppendHeader(errRH, reason);
                            }
                            response.StatusCode = statusCode;
                            response.Status = status;
                        }
                    }
                }
                else
                {
                    //fallback output if not valid settings
                    if (result != null && result.Action == ActionType.Output404)
                    {
                        //don't restate the requested Url to prevent cross site scripting
                        errorPageHtml.Write("404 Not Found<br>The requested Url does not return any valid content.");
                        response.StatusCode = 404;
                        response.Status = "404 Not Found";
                    }
                    else
                    {
                        //error, especially if invalid result object

                        errorPageHtml.Write("500 Server Error<br><div style='font-weight:bolder'>An error occured during processing : if possible, check the event log of the server</div>");
                        response.StatusCode = 500;
                        response.Status = "500 Internal Server Error";
                        if (result != null)
                        {
                            result.Action = ActionType.Output500;
                        }
                    }
                }

                if (ex != null)
                {
                    if (context != null)
                    {
                        if (context.Items.Contains("UrlRewrite:Exception") == false)
                        {
                            context.Items.Add("UrlRewrite:Exception", ex.Message);
                            context.Items.Add("UrlRewrite:StackTrace", ex.StackTrace);
                        }
                    }

                    if (ceSection != null && ceSection.Mode == CustomErrorsMode.Off)
                    {
                        errorPageHtml.Write(errorPageHtmlHeader);
                        errorPageHtml.Write("<div style='font-weight:bolder'>Exception:</div><div>" + ex.Message + "</div>");
                        errorPageHtml.Write("<div style='font-weight:bolder'>Stack Trace:</div><div>" + ex.StackTrace + "</div>");
                        errorPageHtml.Write("<div style='font-weight:bolder'>Administrators</div>");
                        errorPageHtml.Write("<div>You can see this exception because the customErrors attribute in the web.config is set to 'off'.  Change this value to 'on' or 'RemoteOnly' to show Error Handling</div>");
                        try
                        {
                            if (errUrl != null && errUrl.StartsWith("~"))
                            {
                                errUrl = VirtualPathUtility.ToAbsolute(errUrl);
                            }
                        }
                        finally
                        {
                            if (errUrl != null)
                            {
                                errorPageHtml.Write("<div>The error handling would have shown this page : <a href='" + errUrl + "'>" + errUrl + "</a></div>");
                            }
                            else
                            {
                                errorPageHtml.Write("<div>The error handling could not determine the correct page to show.</div>");
                            }
                        }
                    }
                }

                string errorPageHtmlBody = errorPageHtml.ToString();
                if (errorPageHtmlBody.Length > 0)
                {
                    response.Write(errorPageHtmlHeader);
                    response.Write(errorPageHtmlBody);
                    response.Write(errorPageHtmlFooter);
                }
                if (ex != null)
                {
                    UrlRewriterUtils.LogExceptionInRequest(ex, status, result);
                }
            }
        }
 internal static bool CheckForRedirect(Uri requestUri, 
                                         UrlAction result, 
                                         NameValueCollection queryStringCol,
                                         FriendlyUrlSettings settings, 
                                         out string location,
                                         ref List<string> messages, 
                                         Guid parentTraceId)
 {
     bool redirected = false;
     location = "";
     ExtensionUrlProvider activeProvider = null;
     try
     {
         List<ExtensionUrlProvider> providersToCall = GetProvidersToCall(result.TabId, result.PortalId, settings,
                                                                      parentTraceId);
         if (providersToCall != null && providersToCall.Count > 0)
         {
             FriendlyUrlOptions options = UrlRewriterUtils.GetOptionsFromSettings(settings);
             foreach (ExtensionUrlProvider provider in providersToCall)
             {
                 activeProvider = provider; //for error handling
                 redirected = provider.CheckForRedirect(result.TabId, result.PortalId, result.HttpAlias,
                                                        requestUri, queryStringCol, options, out location,
                                                        ref messages);
                 if (redirected)
                 {
                     result.FinalUrl = location;
                     result.Reason = RedirectReason.Module_Provider_Redirect;
                     break;
                 }
             }
         }
     }
     catch (Exception ex)
     {
         //log module provider exception
         LogModuleProviderExceptionInRequest(ex, "500 Internal Server Error", activeProvider, result, messages);
         //return defaults
         redirected = false;
         location = "";
         string providerName = "Unknown";
         if (activeProvider != null)
         {
             providerName = activeProvider.ProviderConfig.ProviderName;
         }
         if (result != null)
         {
             result.DebugMessages.Add("Exception in provider [" + providerName + "] :" + ex.Message);
         }
     }
     return redirected;
 }