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> /// 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); } } }
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); }
internal static bool GetUrlFromExtensionUrlProviders( int portalId, TabInfo tab, FriendlyUrlSettings settings, string friendlyUrlPath, string cultureCode, ref string endingPageName, out string changedPath, out bool changeToSiteRoot, ref List <string> messages, Guid parentTraceId) { bool wasChanged = false; changedPath = friendlyUrlPath; changeToSiteRoot = false; ExtensionUrlProvider activeProvider = null; if (messages == null) { messages = new List <string>(); } try { List <ExtensionUrlProvider> providersToCall = GetProvidersToCall(tab.TabID, portalId, settings, parentTraceId); FriendlyUrlOptions options = UrlRewriterUtils.GetOptionsFromSettings(settings); foreach (ExtensionUrlProvider provider in providersToCall) { activeProvider = provider; // keep for exception purposes bool useDnnPagePath; // go through and call each provider to generate the friendly urls for the module string customPath = provider.ChangeFriendlyUrl( tab, friendlyUrlPath, options, cultureCode, ref endingPageName, out useDnnPagePath, ref messages); if (string.IsNullOrEmpty(endingPageName)) { endingPageName = Globals.glbDefaultPage; // set back to default.aspx if provider cleared it } // now check to see if a change was made or not. Don't trust the provider. if (!string.IsNullOrEmpty(customPath)) { // was customPath any different to friendlyUrlPath? if (string.CompareOrdinal(customPath, friendlyUrlPath) != 0) { wasChanged = true; changedPath = customPath.Trim(); changeToSiteRoot = !useDnnPagePath; // useDNNpagePath means no change to site root. const string format = "Path returned from {0} -> path:{1}, ending Page:{2}, use Page Path:{3}"; messages.Add(string.Format(format, provider.ProviderConfig.ProviderName, customPath, endingPageName, useDnnPagePath)); break; // first module provider to change the Url is the only one used } } } } catch (Exception ex) { LogModuleProviderExceptionInRequest(ex, "500 Internal Server Error", activeProvider, null, messages); // reset all values to defaults wasChanged = false; changedPath = friendlyUrlPath; changeToSiteRoot = false; } return(wasChanged); }
/// <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); } } }