// HACK: we cache this in the first call assuming applicationPath never changes during the whole lifetime of the application // also don't worry about locking; the worst case this will be created more than once public Regex GetRuleRegex(string applicationPath) { return(this._matchRx ?? (this._matchRx = RegexUtils.GetCachedRegex( "^" + RewriterUtils.ResolveUrl(applicationPath, this.LookFor) + "$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant))); }
private void RewriteUrl(HttpApplication app, out string portalAlias) { HttpRequest request = app.Request; HttpResponse response = app.Response; string requestedPath = app.Request.Url.AbsoluteUri; portalAlias = string.Empty; // determine portal alias looking for longest possible match string myAlias = Globals.GetDomainName(app.Request, true); PortalAliasInfo objPortalAlias; do { objPortalAlias = PortalAliasController.Instance.GetPortalAlias(myAlias); if (objPortalAlias != null) { portalAlias = myAlias; break; } int slashIndex = myAlias.LastIndexOf('/'); myAlias = slashIndex > 1 ? myAlias.Substring(0, slashIndex) : string.Empty; }while (myAlias.Length > 0); app.Context.Items.Add("UrlRewrite:OriginalUrl", app.Request.Url.AbsoluteUri); // Friendly URLs are exposed externally using the following format // http://www.domain.com/tabid/###/mid/###/ctl/xxx/default.aspx // and processed internally using the following format // http://www.domain.com/default.aspx?tabid=###&mid=###&ctl=xxx // The system for accomplishing this is based on an extensible Regex rules definition stored in /SiteUrls.config string sendTo = string.Empty; // save and remove the querystring as it gets added back on later // path parameter specifications will take precedence over querystring parameters string strQueryString = string.Empty; if (!string.IsNullOrEmpty(app.Request.Url.Query)) { strQueryString = request.QueryString.ToString(); requestedPath = requestedPath.Replace(app.Request.Url.Query, string.Empty); } // get url rewriting rules RewriterRuleCollection rules = RewriterConfiguration.GetConfig().Rules; // iterate through list of rules int matchIndex = -1; for (int ruleIndex = 0; ruleIndex <= rules.Count - 1; ruleIndex++) { // check for the existence of the LookFor value string pattern = "^" + RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, rules[ruleIndex].LookFor) + "$"; Match objMatch = Regex.Match(requestedPath, pattern, RegexOptions.IgnoreCase); // if there is a match if (objMatch.Success) { // create a new URL using the SendTo regex value sendTo = RewriterUtils.ResolveUrl( app.Context.Request.ApplicationPath, Regex.Replace(requestedPath, pattern, rules[ruleIndex].SendTo, RegexOptions.IgnoreCase)); string parameters = objMatch.Groups[2].Value; // process the parameters if (parameters.Trim().Length > 0) { // split the value into an array based on "/" ( ie. /tabid/##/ ) parameters = parameters.Replace("\\", "/"); string[] splitParameters = parameters.Split('/'); // icreate a well formed querystring based on the array of parameters for (int parameterIndex = 0; parameterIndex < splitParameters.Length; parameterIndex++) { // ignore the page name if ( splitParameters[parameterIndex].IndexOf( ".aspx", StringComparison.InvariantCultureIgnoreCase) == -1) { // get parameter name string parameterName = splitParameters[parameterIndex].Trim(); if (parameterName.Length > 0) { // add parameter to SendTo if it does not exist already if ( sendTo.IndexOf( "?" + parameterName + "=", StringComparison.InvariantCultureIgnoreCase) == -1 && sendTo.IndexOf( "&" + parameterName + "=", StringComparison.InvariantCultureIgnoreCase) == -1) { // get parameter delimiter string parameterDelimiter = sendTo.IndexOf("?", StringComparison.Ordinal) != -1 ? "&" : "?"; sendTo = sendTo + parameterDelimiter + parameterName; // get parameter value string parameterValue = string.Empty; if (parameterIndex < splitParameters.Length - 1) { parameterIndex += 1; if (!string.IsNullOrEmpty(splitParameters[parameterIndex].Trim())) { parameterValue = splitParameters[parameterIndex].Trim(); } } // add the parameter value if (parameterValue.Length > 0) { sendTo = sendTo + "=" + parameterValue; } } } } } } matchIndex = ruleIndex; break; // exit as soon as it processes the first match } } if (!string.IsNullOrEmpty(strQueryString)) { // add querystring parameters back to SendTo string[] parameters = strQueryString.Split('&'); // iterate through the array of parameters for (int parameterIndex = 0; parameterIndex <= parameters.Length - 1; parameterIndex++) { // get parameter name string parameterName = parameters[parameterIndex]; if (parameterName.IndexOf("=", StringComparison.Ordinal) != -1) { parameterName = parameterName.Substring(0, parameterName.IndexOf("=", StringComparison.Ordinal)); } // check if parameter already exists if (sendTo.IndexOf("?" + parameterName + "=", StringComparison.InvariantCultureIgnoreCase) == -1 && sendTo.IndexOf("&" + parameterName + "=", StringComparison.InvariantCultureIgnoreCase) == -1) { // add parameter to SendTo value sendTo = sendTo.IndexOf("?", StringComparison.Ordinal) != -1 ? sendTo + "&" + parameters[parameterIndex] : sendTo + "?" + parameters[parameterIndex]; } } } // if a match was found to the urlrewrite rules if (matchIndex != -1) { if (rules[matchIndex].SendTo.StartsWith("~")) { // rewrite the URL for internal processing RewriterUtils.RewriteUrl(app.Context, sendTo); } else { // it is not possible to rewrite the domain portion of the URL so redirect to the new URL response.Redirect(sendTo, true); } } else { // Try to rewrite by TabPath string url; if (Globals.UsePortNumber() && ((app.Request.Url.Port != 80 && !app.Request.IsSecureConnection) || (app.Request.Url.Port != 443 && app.Request.IsSecureConnection))) { url = app.Request.Url.Host + ":" + app.Request.Url.Port + app.Request.Url.LocalPath; } else { url = app.Request.Url.Host + app.Request.Url.LocalPath; } if (!string.IsNullOrEmpty(myAlias)) { if (objPortalAlias != null) { int portalID = objPortalAlias.PortalID; // Identify Tab Name string tabPath = url; if (tabPath.StartsWith(myAlias)) { tabPath = url.Remove(0, myAlias.Length); } // Default Page has been Requested if (tabPath == "/" + Globals.glbDefaultPage.ToLowerInvariant()) { return; } // Start of patch string cultureCode = string.Empty; Dictionary <string, Locale> dicLocales = LocaleController.Instance.GetLocales(portalID); if (dicLocales.Count > 1) { string[] splitUrl = app.Request.Url.ToString().Split('/'); foreach (string culturePart in splitUrl) { if (culturePart.IndexOf("-", StringComparison.Ordinal) > -1) { foreach (KeyValuePair <string, Locale> key in dicLocales) { if (key.Key.ToLower().Equals(culturePart.ToLower())) { cultureCode = key.Value.Code; tabPath = tabPath.Replace("/" + culturePart, string.Empty); break; } } } } } // Check to see if the tab exists (if localization is enable, check for the specified culture) int tabID = TabController.GetTabByTabPath( portalID, tabPath.Replace("/", "//").Replace(".aspx", string.Empty), cultureCode); // Check to see if neutral culture tab exists if (tabID == Null.NullInteger && cultureCode.Length > 0) { tabID = TabController.GetTabByTabPath( portalID, tabPath.Replace("/", "//").Replace(".aspx", string.Empty), string.Empty); } // End of patch if (tabID != Null.NullInteger) { string sendToUrl = "~/" + Globals.glbDefaultPage + "?TabID=" + tabID; if (!cultureCode.Equals(string.Empty)) { sendToUrl = sendToUrl + "&language=" + cultureCode; } if (!string.IsNullOrEmpty(app.Request.Url.Query)) { sendToUrl = sendToUrl + "&" + app.Request.Url.Query.TrimStart('?'); } RewriterUtils.RewriteUrl(app.Context, sendToUrl); return; } tabPath = tabPath.ToLowerInvariant(); if (tabPath.IndexOf('?') != -1) { tabPath = tabPath.Substring(0, tabPath.IndexOf('?')); } // Get the Portal PortalInfo portal = PortalController.Instance.GetPortal(portalID); string requestQuery = app.Request.Url.Query; if (!string.IsNullOrEmpty(requestQuery)) { requestQuery = TabIdRegex.Replace(requestQuery, string.Empty); requestQuery = PortalIdRegex.Replace(requestQuery, string.Empty); requestQuery = requestQuery.TrimStart('?', '&'); } if (tabPath == "/login.aspx") { if (portal.LoginTabId > Null.NullInteger && Globals.ValidateLoginTabID(portal.LoginTabId)) { if (!string.IsNullOrEmpty(requestQuery)) { RewriterUtils.RewriteUrl( app.Context, "~/" + Globals.glbDefaultPage + "?TabID=" + portal.LoginTabId + "&" + requestQuery); } else { RewriterUtils.RewriteUrl( app.Context, "~/" + Globals.glbDefaultPage + "?TabID=" + portal.LoginTabId); } } else { if (!string.IsNullOrEmpty(requestQuery)) { RewriterUtils.RewriteUrl( app.Context, "~/" + Globals.glbDefaultPage + "?TabID=" + portal.HomeTabId + "&portalid=" + portalID + "&ctl=login&" + requestQuery); } else { RewriterUtils.RewriteUrl( app.Context, "~/" + Globals.glbDefaultPage + "?TabID=" + portal.HomeTabId + "&portalid=" + portalID + "&ctl=login"); } } return; } if (tabPath == "/register.aspx") { if (portal.RegisterTabId > Null.NullInteger) { if (!string.IsNullOrEmpty(requestQuery)) { RewriterUtils.RewriteUrl( app.Context, "~/" + Globals.glbDefaultPage + "?TabID=" + portal.RegisterTabId + "&portalid=" + portalID + "&" + requestQuery); } else { RewriterUtils.RewriteUrl( app.Context, "~/" + Globals.glbDefaultPage + "?TabID=" + portal.RegisterTabId + "&portalid=" + portalID); } } else { if (!string.IsNullOrEmpty(requestQuery)) { RewriterUtils.RewriteUrl( app.Context, "~/" + Globals.glbDefaultPage + "?TabID=" + portal.HomeTabId + "&portalid=" + portalID + "&ctl=Register&" + requestQuery); } else { RewriterUtils.RewriteUrl( app.Context, "~/" + Globals.glbDefaultPage + "?TabID=" + portal.HomeTabId + "&portalid=" + portalID + "&ctl=Register"); } } return; } if (tabPath == "/terms.aspx") { if (!string.IsNullOrEmpty(requestQuery)) { RewriterUtils.RewriteUrl( app.Context, "~/" + Globals.glbDefaultPage + "?TabID=" + portal.HomeTabId + "&portalid=" + portalID + "&ctl=Terms&" + requestQuery); } else { RewriterUtils.RewriteUrl( app.Context, "~/" + Globals.glbDefaultPage + "?TabID=" + portal.HomeTabId + "&portalid=" + portalID + "&ctl=Terms"); } return; } if (tabPath == "/privacy.aspx") { if (!string.IsNullOrEmpty(requestQuery)) { RewriterUtils.RewriteUrl( app.Context, "~/" + Globals.glbDefaultPage + "?TabID=" + portal.HomeTabId + "&portalid=" + portalID + "&ctl=Privacy&" + requestQuery); } else { RewriterUtils.RewriteUrl( app.Context, "~/" + Globals.glbDefaultPage + "?TabID=" + portal.HomeTabId + "&portalid=" + portalID + "&ctl=Privacy"); } return; } tabPath = tabPath.Replace("/", "//"); tabPath = tabPath.Replace(".aspx", string.Empty); TabCollection objTabs = TabController.Instance.GetTabsByPortal(tabPath.StartsWith("//host") ? Null.NullInteger : portalID); foreach (KeyValuePair <int, TabInfo> kvp in objTabs) { if (kvp.Value.IsDeleted == false && kvp.Value.TabPath.ToLowerInvariant() == tabPath) { if (!string.IsNullOrEmpty(app.Request.Url.Query)) { RewriterUtils.RewriteUrl( app.Context, "~/" + Globals.glbDefaultPage + "?TabID=" + kvp.Value.TabID + "&" + app.Request.Url.Query.TrimStart('?')); } else { RewriterUtils.RewriteUrl( app.Context, "~/" + Globals.glbDefaultPage + "?TabID=" + kvp.Value.TabID); } return; } } } } } }