HOWTO: Common URL Redirection Techniques for IIS, Summary

For the next several entries, I am focusing on this frequently asked topic:

How do I rewrite / redirect / forward / mask requests from one URL to another with IIS?

Common questions that fall into this topic include:

  • Redirect requests from https://server to https://server (i.e. SSL-only site, Exchange/OWA login)
  • Redirect requests from https://external to https://internal and back (i.e. expose internal server to outside)
  • Redirect requests from /app/username/bob to /app.asp?username=bob (i.e. courtesy/pretty URLs)
  • Do any of the above either transparently (client URL/location bar does not change) or explicitly

I see these and similar questions asked over, and... over, and... over, and then some, and I rewrite my explanation again and again... and the MS newsgroup reader periodically sweeps my replies away, over and over. Hmm... sense any frustrating pattern here? ;-)

Hey, it may be the first time you asked the question, but it is not the first time I have answered it... so pardon me for being a little terse; I get that way when I am tired. This is my attempt at giving you the full, cogent details, hopefully once and for all. :-)

My main goals are to:

  1. Establish a "redirection taxonomy" to help you recognize and classify the type of redirection you want to perform.
  2. Show how to implement (or give reasons why it is not possible) each type of redirection using either built-in IIS "core" feature, custom ISAPI Filter DLLs, custom ISAPI Extension DLLs, or custom ASP script pages (I consider ASP as an arbitrary ISAPI Extension DLL which allows script code to make underlying IIS function calls).
  3. Along the way, explain any random, related tidbits that have been asked before.

As expected, the more sophisticated types of redirection require custom code installed as add-ons to IIS, but we are all grown-ups here who can either purchase binaries or copy/paste/compile code, right? Good! Now, I plan to show you how to do all these things without purchasing any add-on modules, but through explanation you should also rapidly see WHY you would want to purchase an existing solution - anyone mention SUPPORTABILITY!?!

Basic Types of Redirection

In my taxonomy, the web server can perform three types of redirection to handle any given request from the client:

  1. Client-Side Redirection - The server sends a "302 Redirect" response with a Location: header containing the new URL, and the client makes another request to the new URL.
  2. Server-Side Redirection  - The server transparently rewrites the request URL to another URL which remains on the same website as the original.
  3. Server-Side Forwarding - The server transparently rewrites the request URL to another URL which does NOT remain on the same website as the original. Note the new website can be on another machine, but not necessarily.

Before reading any further, I advise you to take a good look at the above classification and determine which type your question falls under. In particular, Server-Side Redirection/Forward have been described by people using colorful phrases such as:

  • Courtesy/Pretty URL
  • URL shadowing
  • URL masking
  • Publishing/Exporting internal website to be accessible externally
  • Redirecting URL on one web server to be handled by another web server
  • One web server reverse-proxying another server
  • Force HTTP requests to HTTPS/SSL
  • Etc...

In any case, I believe they all fall into exactly one of the three buckets in my taxonomy. If your desired redirection does NOT fall under exactly one of the three buckets or does not fall under ANY of my three buckets... feel free to add a Comment or post a private Contact email to me. I am open to suggestions/change. Really. :-P

Some Subtle Points

Some people distinguish redirections by whether the URL location/address bar changes in the client. This classification is problematic because:

  • HTML Frames can give the illusion of a non-changing URL location/address bar because web browsers usually only display the parent frame's URL, but anyone can browse the HTML to determine where the content is really coming from. After all, the user must have download the HTML in plain text in order for the browser to display it. Thus, the non-changing URL location/address bar hides absolutely nothing and achieves no security.
  • Server-Side Redirection/Forwarding also change the response without changing the client's URL location/address bar, and both are very different things from HTML Frames.

Some people are surprised that POST requests do not have transparent Client-Side Redirection. Well, let us pretend we are the browser and look at things from its perspective, and you tell me whether Client-Side Redirection should be transparent or not:

  • I just sent this large 4GB entity body to the server and got this 302 Redirect back. Should I go ahead and automatically POST the the 4GB entity body to the new URL? What if I am on a dial-up?
  • I just sent my username/password with a form over SSL and got this 302 Redirect back. Should I send it again over UNENCRYPTED HTTP to the new URL?

Other Subtle Point

Now, another common user statement which frequently follows the question about how to rewrite URLs on IIS is that: "Apache has had these three types of redirection built in forever, so why is IIS so far behind?" Well, let us look at the situation objectively, apples-to-apples.

Actually, Apache "core" does NOT perform ANY sort of redirection. You need to install and configure add-on modules like mod_redirect to get Client-Side Redirection, mod_rewrite to get Server-Side Redirection, and mod_proxy to get Server-Side Forwarding. So, the ability to redirect is NOT built-in; the modules happen to be in common distros and configuration is baked into httpd.config and .htaccess, so it appears built-in when you are really talking about availability of add-on modules bundled with Apache core.

Now, IIS "core" performs Client-Side redirection, configurable via the HttpRedirect property... so IIS "core" is not really behind feature-wise. Also, you need to install add-on modules to get Server-Side Redirection and Server-Side Forwarding behavior, so IIS is not really behind Apache in extensibility, either.

Where things differ is availability. No one seems to provide modules to do Server-Side Redirection or Server-Side Forwarding on IIS for free. At least, I am not aware of any free/open-source add-on IIS modules which implement those Server-Side behaviors; I only know of for-fee modules like ISAPIRewrite.

So, before you come barging into IIS forums/newsgroups asking for free code and complaining about the lack of free modules - consider contributing to the common cause if you can - because only then can you help improve the availability of public modules for IIS. I know that many people have written their own versions to perferm Server-Side Redirection/Forwarding, but none have donated their code for public use. It is all locked up on internal servers owned by private companies.

HOWTO Implement Redirections, Index

Ok, that is enough preface for now. Here are all the redirection possibilities that I can think of right now, categorized by the type of redirection performed, technology used to perform the redirection, and amount of coding involved. Get ready for this index to be updated with links...

  • Client-Side Redirection using:
    • IIS "Core" (no code) - HttpRedirect
    • IIS "Core" (script code) - HttpErrors and ASP
    • ASP (script code) - Response.Redirect
    • ISAPI Filter (compiled code) - SF_REQ_SEND_RESPONSE_HEADER
    • ISAPI Extension (compiled code) - HSE_REQ_SEND_RESPONSE_HEADER, HSE_REQ_SEND_URL, HSE_REQ_SEND_URL_REDIRECT_RESP
  • Server-Side Redirection using:
    • IIS "Core" (no code involved) - IIsWebFile and ScriptMaps
    • ASP (some code involved) - Server.Transfer and Server.Execute (ASP only)
    • ISAPI Filter (compiled code) - SetHeader( "url" ) in SF_NOTIFY_PREPROC_HEADERS or SF_NOTIFY_AUTH_COMPLETE
    • ISAPI Extension (compiled code) - HSE_REQ_EXEC_URL and HSE_REQ_EXEC_UNICODE_URL and Wildcard Application Mapping
  • Server-Side Forwarding using:
    • ISAPI Filter (compilied code) - Using WinHttp
    • ISAPI Extension (compiled code) - Using WinHttp and Wildcard Application Mapping

//David