Sitecore Reverse Proxy (8.1 → 10.4) – Part 3: IIS Rules and Custom Pipeline Implementation
In the previous article, we installed the ARR module in IIS and discussed the mistakes I made during the initial implementation.
In this article, we'll look at the IIS rules and the pipeline code used to make the reverse proxy work correctly.
<!--Home page--> <rule name="ProxyHomepageContent" stopProcessing="true"> <match url="^/?$" negate="false" ignoreCase="true"/> <serverVariables> <set name="HTTP_HOST" value="ss104cd.dev.local" /> </serverVariables> <action type="Rewrite" url="https://ss104cd.dev.local/en" appendQueryString="true" /> </rule> <!--EN--> <rule name="languagecoderuleEN" stopProcessing="true"> <match url="^en/?$" /> <serverVariables> <set name="HTTP_HOST" value="ss104cd.dev.local" /> </serverVariables> <action type="Redirect" url="https://ss104cd.dev.local/en/" appendQueryString="true" /> </rule> <!--AR--> <rule name="languagecoderuleAR" stopProcessing="true"> <match url="^ar/?$" /> <serverVariables> <set name="HTTP_HOST" value="ss104cd.dev.local" /> </serverVariables> <action type="Redirect" url="https://ss104cd.dev.local/ar/" appendQueryString="true" /> </rule> <!--Media--> <rule name="mediaLibraryProxy" stopProcessing="true"> <match url="^-/media/(.*)" /> <serverVariables> <set name="HTTP_HOST" value="ss104cd.dev.local" /> </serverVariables> <action type="Rewrite" url="https://ss104cd.dev.local/-/media/{R:1}" appendQueryString="true" /> </rule>
Custom Item Resolver for the HomePage and Other Proxied Pages:
Next, let's look at the implementation of a custom ItemResolver for the homepage reverse proxy.
This resolver can also be used for other pages that need to be proxied from the old Sitecore instance to the new Sitecore instance, regardless of whether the page exists on the old site.
public class HomePageResolvers : HttpRequestProcessor
{
//Any other pages that should be proxied like Sitecore homepage can be added to this list.
private static readonly string[] ProxiedSections = { "about" };
public override void Process(HttpRequestArgs args)
{
try
{
HttpContext current = HttpContext.Current;
if (current == null) return;
string rawUrl = current.Request.RawUrl;
int queryIndex = rawUrl.IndexOf('?');
string path = queryIndex >= 0
? rawUrl.Substring(0, queryIndex)
: rawUrl;
string url = path.TrimEnd('/').ToLowerInvariant();
string scLang = current.Request.QueryString["sc_lang"];
bool shouldAbort = url == ""
|| url == "/"
|| url == "/ar"
|| url == "/en"
|| MatchesAnyProxiedSection(url)
|| !string.IsNullOrEmpty(scLang);
Sitecore.Diagnostics.Log.Info(
"HomePageResolver url: " + url +
" scLang: " + scLang +
" shouldAbort: " + shouldAbort, this);
if (shouldAbort)
args.AbortPipeline();
}
catch (Exception ex)
{
Sitecore.Diagnostics.Log.Error(
"HomePageResolver: " + ex.Message, this);
}
}
private static bool MatchesAnyProxiedSection(string url)
{
foreach (string section in ProxiedSections)
{
if (MatchesSection(url, section))
return true;
}
return false;
}
// Check for pages: matches "/about", "/about/...",
// "/en/section", "/en/about/...", "/ar/about", "/ar/about/..."
// Does NOT match "/about123" or similar unrelated paths.
private static bool MatchesSection(string url, string section)
{
return url == "/" + section
|| url.StartsWith("/" + section + "/")
|| url == "/en/" + section
|| url.StartsWith("/en/" + section + "/")
|| url == "/ar/" + section
|| url.StartsWith("/ar/" + section + "/");
}
}
Custom StripLanguage Pipeline for Reverse Proxy:
Now let's look at the implementation of a custom StripLanguage pipeline.
This is required for the homepage reverse proxy and for other pages that need to be proxied and contain a language code in the URL.
using System.Web;
using Sitecore.Pipelines.PreprocessRequest;
namespace POC_SC_MVC
{
public class CustomStripLanguage : StripLanguage
{
//Any other pages that should be proxied like Sitecore homepage can be added to this
//list like en/about.or ar/about
private static readonly string[] ProxiedSections = { "about" };
public override void Process(PreprocessRequestArgs args)
{
HttpContext current = HttpContext.Current;
if (current != null)
{
string url = current.Request.RawUrl
.Split('?')[0]
.TrimEnd('/')
.ToLower();
//Dont add url.Contains("/en") or url.Contains("/ar") as it
//will skip all the pages that have /en or /ar in the url.
//This will break the existing functionality of the old site. Only skip the
//homepage and the proxied sections.
bool shouldSkip = url == "/en"
|| url == "/ar"
|| MatchesAnyProxiedSection(url);
if (shouldSkip)
{
Sitecore.Diagnostics.Log.Info(
"CustomStripLanguage: Skipping for " +
current.Request.RawUrl, this);
return;
}
}
base.Process(args);
}
private static bool MatchesAnyProxiedSection(string url)
{
foreach (string section in ProxiedSections)
{
if (MatchesSection(url, section))
return true;
}
return false;
}
private static bool MatchesSection(string url, string section)
{
return url == "/" + section
|| url.StartsWith("/" + section + "/")
|| url == "/en/" + section
|| url.StartsWith("/en/" + section + "/")
|| url == "/ar/" + section
|| url.StartsWith("/ar/" + section + "/");
}
}
}
Media Settings to Ignore:
<setting name="IgnoreUrlPrefixes" value="/sitecore/default.aspx|/trace.axd|/webresource.axd|/sitecore/shell/Controls/Rich Text Editor/Telerik.Web.UI.DialogHandler.aspx|/sitecore/shell/applications/content manager/telerik.web.ui.dialoghandler.aspx|/sitecore/shell/Controls/Rich Text Editor/Telerik.Web.UI.SpellCheckHandler.axd|/Telerik.Web.UI.WebResource.axd|/sitecore/admin/upgrade/|/layouts/testing|/sitecore/service/xdb/disabled.aspx|/-/media/imagefolderOfNewSite/|/~/media/imagefolderOfNewSite/" />
Important Note
- Do not add the home page path (
/) directly to IgnoreUrlPrefixes without using an appropriate ItemResolver.
Doing so can cause all pages on the old website to stop working correctly, because Sitecore will ignore the request before the required processing occurs.
The home page and other proxied pages should therefore be handled through the appropriate resolver and pipeline logic rather than simply adding/to IgnoreUrlPrefixes.
- All IIS rule and code deployments should happen on the old Sitecore instance; no changes are required on the new Sitecore instance.
Part 2
Comments
Post a Comment