private void OnBeginRequest(object sender, EventArgs e) { if (IsUpgrade) { return; } // find incoming URL string incoming = ""; try { // in case of een upgrade, PortalSettings will be null, nothing to do in such a case: // if (PortalSettings.Current == null) return; var fake = new ControlCollection(new LiteralControl("")); Common.Logger.Debug($"Calling DoRedirect From HttpModule"); RedirectController.DoRedirect(fake, redirectWhenNo404Detected: true, onlyLogWhen404: true); } catch (Exception exception) { // we're not writing in the eventlog, since the amount of log records can really explode // we MUST catch every possible exception here, otherwise the website would be completely down in case of a bug } }
private void Context_EndRequest(object sender, EventArgs e) { if (IsUpgrade) { return; } try { var rsp = HttpContext.Current.Response; var ps = Common.CurrentPortalSettings; // this needs to be done on EndRequest, to be sure PortalSettings.ActiveTab is correct if (rsp.StatusCode == (int)HttpStatusCode.OK) { Force404Controller.DoForce404Check(); } string incoming = Common.IncomingUrl; if (ps.ActiveTab?.TabID != ps.ErrorPage404 && rsp.StatusCode == (int)HttpStatusCode.NotFound && !string.IsNullOrEmpty(incoming)) { Common.Logger.Debug($"Logging redirect from Context_EndRequest. incoming:[{incoming}]"); RedirectController.AddRedirectLog(ps.PortalId, incoming, ""); } } catch (Exception exception) { // we're not writing in the eventlog, since the amount of log records can really explode // we MUST catch every possible exception here, otherwise the website would be completely down in case of a bug } }
public static void DoForce404Check() { // no forced 404 for authenticated users if (HttpContext.Current.Request.IsAuthenticated) { return; } // als tabInfo.IsForce404() en de url is "dieper" dan de tab zelf: dan een 404 geven var activeTab = Common.CurrentPortalSettings.ActiveTab; if (activeTab.IsForce404() && !IsDnnControlUrl()) { Common.Logger.Debug($"Force404-check for tab {Common.CurrentPortalSettings.ActiveTab.TabID}"); var tabFullUrl = ""; // activeTab can be a tab when handlers are being called. // in those cases, FullUrl throws an exception // we're "handling" that here try { tabFullUrl = activeTab.FullUrl.ToLowerInvariant(); } catch (Exception e) { } if (string.IsNullOrEmpty(tabFullUrl)) { return; } var incoming = Common.IncomingUrl; var tabUrl = new Uri(tabFullUrl); var incUrl = new Uri(incoming); // requests for dependancyhandler.axd don't get recognised as a handler and need to be explicitly ignored if (incoming.Contains("dependencyhandler.axd")) { return; } if (incUrl.LocalPath.StartsWith(tabUrl.LocalPath) && incUrl.LocalPath.Length > tabUrl.LocalPath.Length) { RedirectController.AddRedirectLog(Common.CurrentPortalSettings.PortalId, incoming, ""); Common.Handle404Exception(HttpContext.Current.Response, Common.CurrentPortalSettings); } // also check TabUrls with httpstatus=200 foreach (var tabUrlInfo in activeTab.TabUrls.Where(tu => tu.HttpStatus == ((int)HttpStatusCode.OK).ToString())) { if (incUrl.LocalPath.StartsWith(tabUrlInfo.Url.ToLowerInvariant()) && incUrl.LocalPath.Length > tabUrlInfo.Url.Length) { RedirectController.AddRedirectLog(Common.CurrentPortalSettings.PortalId, incoming, ""); Common.Handle404Exception(HttpContext.Current.Response, Common.CurrentPortalSettings); } } } }
private void Context_EndRequest(object sender, EventArgs e) { try { var rsp = HttpContext.Current.Response; var ps = Common.CurrentPortalSettings; string incoming = (string)HttpContext.Current.Items["40F_SEO_IncomingUrl"]; if (rsp.StatusCode == (int)HttpStatusCode.NotFound && !string.IsNullOrEmpty(incoming)) { Common.Logger.Debug($"Logging redirect from Context_EndRequest. incoming:[{incoming}]"); RedirectController.AddRedirectLog(ps.PortalId, incoming, ""); } } catch (Exception exception) { // we're not writing in the eventlog, since the amount of log records can really explode // we MUST catch every possible exception here, otherwise the website would be completely down in case of a bug } }
public static void DoRedirect(ControlCollection logToControls, bool redirectWhenNo404Detected = false, bool onlyLogWhen404 = false) { // find incoming URL string incoming = ""; try { // nothing to do if it's already a redirect because of an error //if (!String.IsNullOrEmpty(Request.QueryString["aspxerrorpath"])) // return; bool is404 = false; // we're matching lowercased: case insensitive incoming = IncomingUrl(logToControls, ref is404).ToLower(); // enable logging when DNN detects a 404 later on (e.g. for extentionless urls) HttpContext.Current.Items["40F_SEO_IncomingUrl"] = incoming; // register whether or not a 404 was detected RedirectController.SetRequest404Detected(is404); // since generating a 404 inside a 404 page // (which is what we do in case of .aspx errors) // will cause an additional redirect to the error page, // we here check if the incoming url contains an aspx error path // if so: stop processing, we're already done. if (HasAspxError(incoming)) { SetStatus404(); return; } if (UserInfo.IsSuperUser) { logToControls.Add(new LiteralControl(String.Format("Incoming: {0}<br/>", incoming))); } // check if URL is in Sources of mappingtable string target = ""; var mappingsNoRegex = RedirectConfig.Instance.MappingsDictionary(false); if (UserInfo.IsSuperUser) { logToControls.Add(new LiteralControl(String.Format("Mappings (with regex): {0}<br/>", RedirectConfig.Instance.MappingsDictionary(true).Count))); } if (UserInfo.IsSuperUser) { logToControls.Add(new LiteralControl(String.Format("Mappings (no regex): {0}<br/>", mappingsNoRegex.Count))); } // if we're in a 404, let's try to find a mapping if (is404 || redirectWhenNo404Detected) { Common.Logger.Debug($"Try to find a mapping for [{incoming}]"); // first try non-regex mappings, as they're supposed to be faster if (mappingsNoRegex.ContainsKey(incoming)) { target = mappingsNoRegex[incoming]; Common.Logger.Debug($"Mapping without regex found, Target: [{target}]"); } else if (mappingsNoRegex.ContainsKey(ToRelativeUrl(incoming))) { target = mappingsNoRegex[ToRelativeUrl(incoming)]; Common.Logger.Debug($"Mapping without regex found, Target: [{target}]"); } else { // no match found without regexes, try the ones with regex var mappingsUsingRegex = RedirectConfig.Instance.MappingsDictionary(true); // now try and match each one foreach (var mapping in mappingsUsingRegex) { var mappingSource = ToFullUrl(mapping.Key); var mappingTarget = ToFullUrl(mapping.Value); if (Regex.IsMatch(incoming, mappingSource)) { // got a match! target = Regex.Replace(incoming, mappingSource, mappingTarget); Common.Logger.Debug($"Mapping with regex found, Target: [{target}]"); } } } } // Log this 404 var ps = Common.CurrentPortalSettings; if (is404 || (redirectWhenNo404Detected && !string.IsNullOrEmpty(target))) { Common.Logger.Debug($"Logging redirect: is404:{is404}, redirectWhenNo404Detected:{redirectWhenNo404Detected}, target:[{target}]"); AddRedirectLog(ps.PortalId, incoming, target); } else if (!onlyLogWhen404) { Common.Logger.Debug($"Logging redirect for !onlyLogWhen404 target:[{target}]"); AddRedirectLog(ps.PortalId, incoming, target); } if (UserInfo.IsSuperUser) { logToControls.Add(new LiteralControl(String.Format("Target: {0}<br/>", target))); } // if so: redirect if (!String.IsNullOrEmpty(target)) { try { Common.Logger.Debug($"Redirect to:[{target}]"); Response.Redirect(target, false); Response.StatusCode = 301; Response.End(); } catch (Exception) { // do nothing: threadabortexception is normal behaviour } } // we're only displaying the logging if it's a 404 if (!is404) { logToControls.Clear(); } //else if (is404) // only if it was a 404 incoming //{ // // tell the client that the page wasn't found // SetStatus404(); //} } catch (Exception exception) { Common.Logger.Error($"Exception in DoRedirect: {exception.Message}. Stacktrace: {exception.StackTrace}"); // we're not writing in the eventlog, since the amount of log records can really explode if (UserInfo.IsSuperUser) { logToControls.Add(new LiteralControl(String.Format("Error: {0}<br/>", exception.Message + "<br/>" + exception.StackTrace))); } } }