Application Request Routing (ARR) is a reverse proxy plug-in for IIS7+ that does many things, including functioning as a load balancer. For this post, I’m assuming that you already have an understanding of ARR.
Today I wanted to find out how the mysterious link between ARR and URL Rewrite is maintained. Let me explain…
ARR is unique in that it doesn’t work by itself. It sits on top of IIS7 and uses URL Rewrite. As a result, ARR depends on URL Rewrite to ‘catch’ the traffic and redirect it to an ARR Server Farm.
As the last step of creating a new Server Farm, ARR will prompt you with the following:
If you accept the prompt, it will create a URL Rewrite rule for you. If you say ‘No’, then you’re on your own to create a URL Rewrite rule.
When you say ‘Yes’, the Server Farm’s checkbox for “Use URL Rewrite to inspect incoming requests” will be checked. See the following screenshot.
However, I’m not a fan of this auto-rule. The problem is that if I make any changes to the URL Rewrite rule, which I always do, and then make the wrong change in ARR, it will blow away my settings. So, I prefer to create my own rule and manage it myself.
Since I had some old rules that were managed by ARR, I wanted to update them so that they were no longer managed that way.
I took a look at a config in applicationHost.config to try to find out what property would bind the two together. I assumed that there would be a property on the ServerFarm called something like urlRewriteRuleName that would serve as the link between ARR and URL Rewrite. I found no such property.
After a bit of testing, I found that the name of the URL Rewrite rule is the only link between ARR and URL Rewrite. I wouldn’t have guessed. The URL Rewrite rule needs to be exactly ARR_{ServerFarm Name}_loadBalance, although it’s not case sensitive.
Consider the following auto-created URL Rewrite rule:
And, the link between ARR and URL Rewrite exists:
Now, as soon as I rename that to anything else, for example, site.com ARR Binding, the link between ARR and URL Rewrite is broken.
To be certain of the relationship, I renamed it back again and sure enough, the relationship was reestablished.
Why is this important? It’s only important if you want to decouple the relationship between ARR the URL Rewrite rule, but if you want to do so, the best way to do that is to rename the URL Rewrite rule. If you uncheck the “Use URL Rewrite to inspect incoming requests” checkbox, it will delete your rule for you without prompting.
Conclusion
The mysterious link between ARR and URL Rewrite only exists through the ARR Rule name. If you want to break the link, simply rename the URL Rewrite rule. It’s completely safe to do so, and, in my opinion, this is a rule that you should manage yourself anyway.
I ran into a 500.50 error yesterday, which wasn’t very descriptive initially, so I thought I would provide some details on what it could be.
First, off, if you hit the page remotely, it’s going to hide the real details. It will look something like this:
Server Error
500 - Internal server error.
There is a problem with the resource you are looking for, and it cannot be displayed.
Checking the IIS logs will show that it’s a 500.50 error in this case.
The first thing to do after running into a general error like this is to test it locally on the server. Now you get a lot more information (I’ve included just some of the error details below):
HTTP Error 500.50 - URL Rewrite Module Error.
The server variable "HTTP_HOST" is not allowed to be set. Add the server variable name to the allowed server variable list.
Now we can tell exactly what happened. I’m using URL Rewrite 2.0. Version 2 now allows updating Server Variables. I tried to update the HTTP_HOST server variable at the site level but forgot to add HTTP_HOST as an approved server variable.
To fix this issue, go to View Server Variables in the Actions pane of URL Rewrite. Note that you will only see these if you are an administrator on the server.
Now add the server variable that you want to change at the site level:
That resolved my situation. However, a 500.50 error can be used for a number of things, always URL Rewrite related.
Here’s the official description of a 500.50 error:
500.50 - A rewrite error occurred during RQ_BEGIN_REQUEST notification handling. A configuration or inbound rule execution error occurred.
500.51, 500.52 and 500.53 are also URL Rewrite Related: http://support.microsoft.com/kb/943891
Here are a couple other posts of 500.50 situations:
http://forums.iis.net/t/1164360.aspx
http://www.digitalpimple.com/tutorials/windows-tutorials/fix-550-rewrite-error/ (I believe the author meant 500.50)
Hope that helps someone, and happy URL Rewriting!
I often do development, testing or troubleshooting where I want to see all server variables available to a site. For example, when using a reverse proxy for load balancing, SERVER_ADDR, HTTP_HOST and other variables can change.
Whenever I run into that situation, I write out a simple script that displays all server variables. I thought I would share it here.
Create a file on your server called serversvariables.aspx, test.aspx or whatever you want to call it. Place the following in it:
<%
For Each var as String in Request.ServerVariables
Response.Write(var & " " & Request(var) & "<br>")
Next
%>
Or if you prefer C#, use the following:
<% @ Page Language="C#" %>
<%
foreach (string var in Request.ServerVariables)
{
Response.Write(var + " " + Request[var] + "<br>");
}
%>
Then simply call the page from a web browser and it will list all server variables.
The top two variables are worth noting. They are ALL_HTTP and ALL_RAW which contain all server variables and are repeated with the specific server variables. Since they contain everything, they can clutter up the page. You can wrap the Response.Write line in an ‘if’ condition to exclude ALL_HTTP and ALL_RAW if you want, but I find for a quick testing page, I don’t bother, and it gives me every server variable.
The output will look something like this:
{ALL_HTTP and ALL_RAW have been removed from this example.}
APPL_MD_PATH: /LM/W3SVC/2/ROOT
APPL_PHYSICAL_PATH: C:\domains\example.com\
AUTH_TYPE: Forms
AUTH_USER: Scott
AUTH_PASSWORD:
LOGON_USER: Scott
REMOTE_USER: Scott
CERT_COOKIE:
CERT_FLAGS:
CERT_ISSUER:
CERT_KEYSIZE:
CERT_SECRETKEYSIZE:
CERT_SERIALNUMBER:
CERT_SERVER_ISSUER:
CERT_SERVER_SUBJECT:
CERT_SUBJECT:
CONTENT_LENGTH: 0
CONTENT_TYPE:
GATEWAY_INTERFACE: CGI/1.1
HTTPS: off
HTTPS_KEYSIZE:
HTTPS_SECRETKEYSIZE:
HTTPS_SERVER_ISSUER:
HTTPS_SERVER_SUBJECT:
INSTANCE_ID: 2
INSTANCE_META_PATH: /LM/W3SVC/2
LOCAL_ADDR: 206.72.119.72
PATH_INFO: /ServerVariables.aspx
PATH_TRANSLATED: C:\domains\example.com\ServerVariables.aspx
QUERY_STRING:
REMOTE_ADDR: 192.168.168.29
REMOTE_HOST: 192.168.168.29
REMOTE_PORT: 60137
REQUEST_METHOD: GET
SCRIPT_NAME: /ServerVariables.aspx
SERVER_NAME: www.example.com
SERVER_PORT: 80
SERVER_PORT_SECURE: 0
SERVER_PROTOCOL: HTTP/1.1
SERVER_SOFTWARE: Microsoft-IIS/7.5
URL: /ServerVariables.aspx
HTTP_CACHE_CONTROL: max-age=0
HTTP_CONNECTION: Keep-Alive
HTTP_ACCEPT: application/xml,application/xhtml+xml,text/html;q=0.9...HTTP_ACCEPT_CHARSET: ISO-8859-1,utf-8;q=0.7,*;q=0.3
HTTP_ACCEPT_ENCODING: gzip,deflate,sdch
HTTP_ACCEPT_LANGUAGE: en-US,en;q=0.8
HTTP_COOKIE: {removed}
HTTP_HOST: www.example.com
HTTP_MAX_FORWARDS: 10
HTTP_USER_AGENT: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) ...HTTP_X_ORIGINAL_HOST: www.example.com
HTTP_X_ORIGINAL_SERVER_PORT: 80
HTTP_X_ORIGINAL_URL: /ServerVariables.aspx
HTTP_X_FORWARDED_FOR: 192.168.168.29:60137
HTTP_X_ARR_LOG_ID: 3dc509e5-5da8-4b6b-91ee-f084c308e2ce
HTTP_X_SITE_INSTANCE: 01
Hope you find this useful. Happy coding / troubleshooting!