Maintain protocol in URL Rewrite Rules

The URL Rewrite 2.0 module for IIS7+ is a very powerful tool for manipulating requests to an IIS server. We use it quite heavily with Application Request Routing load balancers in our environment. The combination allows us to perform L7 load balancing of requests. One of the great features of ARR is the ability to perform SSL offloading, which effectively terminates the SSL connection at the ARR node. Accomplishing this is quite simple – you create your rule and use HTTP:// as the scheme to route to the appropriate server farm. However, there are times when you will want to pass through the protocol to the backend servers.

There are a few ways to accomplish this. First, you could create two rules with a condition tracking the HTTPS server variable and route appropriately. However, this doubles the number of rules to maintain. Second, you could use a condition on the CACHE_URL variable and a back reference in the rewritten URL. The problem there is that you then need to match all of the conditions which could be a problem if your rule depends on a logical “or” match for conditions. Lastly, my preference involves using a rewrite map on the HTTPS server variable.

The idea is that we create a rewrite map named MapProtocol that contains two key value pairs – ON = https and OFF = http (I also prefer to set the default value for the rewrite map to http in the off chance the HTTPS variable does not contain a value). Then, we use that rewrite map in the Action url against the HTTPS server variable. The rule will look something like this:

<rule name="ARR Maintain protcol" enabled="true" stopProcessing="true">
  <match url=".*" />
    <conditions>
      <add input="{LOCAL_ADDR}" pattern="10\.1\.1\.10" />
    </conditions>
  <action type="Rewrite" url="{MapProtocol:{HTTPS}}://Webfarm1/{R:0}" />
</rule>
 
<rewriteMap name="MapProtocol" defaultValue="http">
  <add key="ON" value="https" />
  <add key="OFF" value="http" />
</rewriteMap>