Common Redirect Exclusions

2

November 15, 2012 by Alistair Deneys

Recently my TDS (Team Development for Sitecore) install started acting funny. And the symptoms didn’t seem consistent between different solutions, so it looked like the issue was to do with those specific installs.

When I tried to perform any operation from my TDS project with Sitecore I would receive an error about the response content type, followed by an error to do with the version of the server components: “The content type text/html; charset=utf-8 of the response message does not match the content type of the binding (text/xml; charset=utf-8)”.

clip_image002

Clicking OK to dismiss this dialog showed the next error to do with the version: “Warning: The version of the sitecore connector is from an older version of TDS”

clip_image002[8]

I tried everything I could think of to fix this issue. I used the “Install Sitecore Connector” option in my project context menu, I compared versions of the ASMX and DLL installed by TDS into my Sitecore folder and copied an updated version from another working Sitecore instance, I also applied a patch which was specific to a revision of Sitecore 6.4.

Eventually I logged the issue with Hedgehog support and they worked through the issue with me.

Now, keep in mind that TDS communicates with your Sitecore solution using a custom web service. The ASMX file resides under a folder called _DEV. Also in this folder is a web.config file containing the access GUID. An assembly is also added to your bin folder which contains the type used by the ASMX file.

Now, the fact that TDS uses a standard web service which communicates over HTTP is what saved me here. Hedgehog support suggested using an HTTP debugging proxy like Fiddler to look at the HTTP request and response. Good idea! This allowed me to see what was going on:

TDS request redirect

As you can see from the screenshot above, the request for the ASMX was being redirected to a lowercase version of the URL. This redirect strips the SOAP action header so instead of trying to execute a web method, this request turned into a GET request. BTW, this was on TDS 3. When writing this blog post I was testing against TDS 4 and it appeared the SOAP action was not stripped by the redirect, though the result was the same.

Now, you may recall I recently blogged about redirect components that can be used with Sitecore? Yeah. Here’s the gotcha. Make sure your redirect rules aren’t overzealous and process system/service requests rather than just limiting themselves to requests for content. The “administrator” modules I wrote about previously are not integrated into Sitecore, so they have no concept of a content request versus a service request. Instead, you’ll have to update your redirect rules so they ignore any requests that aren’t for content. The CMS modules are run from inside the CMS application, so by the time they get a chance to process the request they have already been processed by the CMS and you can be pretty sure that what you’re dealing with is a content request and not a service request which would have aborted before now.

In the above scenario I was using the IIS URL Rewrite module and I had a rewrite rule to redirect any request which contained an uppercase character to a lowercase version of the URL. This is a common SEO technique to help with canonicalization of the URLs on your site to ensure search engines don’t accidentally split your page ranking between several URLs differing only by case. This may seem funny to many Windows developers where we have a file system that ignores case, but to the rest of the world, including that of HTTP, case matters in both files and URLs, so search engines see /My-Page as a different URL to /my-page.

To fix the above TDS issue, I could update my rules to ignore anything in the _DEV folder, but a better solution would be to ignore any request for a web service endpoint; ignore any request ending in .asmx.

When creating your redirect rules for administrator modules (those configured outside of Sitecore), keep in mind that all requests will be processed by the redirect module.

Here’s a list of common exclusions you will probably need to work into your redirect rules when using a redirect module with Sitecore:

  • Anything under the sitecore folder
  • Anything under the temp folder
  • Anything under the virtual ScriptResource folder
  • Anything under the virtual WebResource folder
  • Any URL ending in .axd
  • Any URL ending in .asmx
  • Any URL ending in .svc
  • Anything under the layouts/system folder
  • Any URL with sc_mode in the query string
  • Any static resources on disk such as the codeflood embedded test runner (test.aspx file)

 

The IIS URL Rewrite module allows exclusions to be included in any rule through conditions. For a rule to apply to a request all conditions of the rule must be met. Here’s a sample configuration for a redirect rule for the IIS URL Rewrite module which includes the above exclusions.

<rule name="Lower Case Rule">
  <match url="[A-Z]" ignoreCase="false" />
  <conditions>
    <add input="{URL}" pattern="^/sitecore" negate="true" />
    <add input="{URL}" pattern="^/temp" negate="true" />
    <add input="{URL}" pattern="^/ScriptResource" negate="true" />
    <add input="{URL}" pattern="^/WebResource" negate="true" />
    <add input="{URL}" pattern="\.axd" negate="true" />
    <add input="{URL}" pattern="\.asmx" negate="true" />
    <add input="{URL}" pattern="\.svc" negate="true" />
    <add input="{URL}" pattern="^/layouts/system" negate="true" />
    <add input="{HTTP_URL}" pattern="\?.*sc_mode" negate="true" />
  </conditions>
  <action type="Redirect" url="{ToLower:{URL}}" />
</rule>

The “variables” in the input attribute of the condition entries (the names in curly braces) are server variables. You can find a list of common IIS server variables here: http://msdn.microsoft.com/en-us/library/ms524602%28v=vs.90%29.aspx.

If you’re using the UrlRewriter.net module, exclusions can be implemented through an unless element in configuration. The unless element is a conditional so no rules inside the unless will be processed unless the conditions of the unless are met.

Below is sample configuration for UrlRewriter.net implementing the same exclusions as above.

<unless url="^/sitecore|^/temp|^/scriptresource|
  ^/webresource|\.axd|\.asmx|\.svc|^/layouts/system|\?.*sc_mode">
  <if url="(?-i)[A-Z]+">
    <redirect url="(.*)" to="http://${HOST}${lower($1)}" processing="stop"/>
  </if>
</unless>

Note here how we only have a single attribute to put the condition in, which is in regular expression format. We could have implemented the IIS URL Rewriter configuration into a single regex as well, but I think splitting it out makes it much easier to read.

One nice aspect of the UrlRewriter.net configuration over the IIS URL Rewriter configuration is that you can wrap all rules in a single unless element, helping reduce the repetition of adding the conditions to several rules.

So next time you’re adding redirect rules, keep in mind the global implications.

Advertisements

2 thoughts on “Common Redirect Exclusions

  1. Ben McCallum says:

    Champion. Exact same issue. Thanks for sharing.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

The views expressed on this blog are solely my own and do not necessarily reflect the views of my employer.
%d bloggers like this: