Sub domains on IIS express

In the beginning I didn’t expect this would be difficult. And perhaps it is easier to set up if you are on a domain. However, in this scenario I’m not, and I’m not sure how much easier it would be if I was.

Anyway, FiddlerCore to the rescue. The solution is not perfect. It would be perfect if IIS Express could handle this for me, but it can’t. So perfect or not, I needed three steps:

  1. Setup FiddlerCore to capture all trafic for the sub domain, e.g. traffic for test.ocase.com
  2. Setup my application to handle sub domains and handle special cases when sub domains are redirected from Fiddler Core
  3. Manipulate the hosts file on the pc to listen to the sub domain, e.g. test.ocase.com

1. Setup FiddlerCore to capture all traffic for the sub domain test.ocase.com

First, I created a new HTTP Module. In the Init section, I placed this code:


if (!Fiddler.FiddlerApplication.IsStarted())
{
Fiddler.FiddlerCoreStartupFlags oFCSF = Fiddler.FiddlerCoreStartupFlags.Default;
Fiddler.FiddlerApplication.BeforeRequest += new Fiddler.SessionStateHandler(FiddlerApplication_BeforeRequest);

Fiddler.FiddlerApplication.Startup(m_Proxy.ListenToHttpPort, oFCSF);
}

Also, I inherited from IDisposable, and in the Dispose() method, I shut down Fiddler:


Boolean disposed;

public void Dispose()
{
if (!disposed)
{
if (Fiddler.FiddlerApplication.IsStarted())
Fiddler.FiddlerApplication.Shutdown();
disposed = true;
}
}

Finally, in the FiddlerApplication_BeforeRequest method, I placed this:

void FiddlerApplication_BeforeRequest(Fiddler.Session oSession)
{
if (oSession.host.ToLower().Contains("test.ocase.com"))
{
oSession.oRequest.headers.Add("proxyhost", oSession.host);
oSession.host = "http://ocase.com:8080";
}
}

This is where the magic happens. Here, I add a new HTTP header to the request with the key “proxyhost”. Whenever my sub domain is requested (contained in the oSession.host property), I handle the request.

I have one small obstacle, however. The HTTP 1.1 protocol specifies that the HTTP request should have a host header. The host header will contain the url including the sub domain. This means that when my browser requests test.ocase.com, it specifies this both in the URL and in the host header. So when fiddler redirects my request to “http://ocase.com:8080” (by specifying this in the oSession.host property), it will specify the url “http://ocase.com:8080” AND the host header “http://ocase.com:8080”. So, basically my sub domain is lost in the redirection process! To prevent this, I create a new HTTP header “proxyhost”, and here I set the value of the original host: “http://test.ocase.com” which includes the sub domain. I need to handle this in my application.

2. Setup my application to handle sub domains including sub domains with proxyhost
Basically, when I check out the sub domain in my application, I will first check to see if proxyhost is available. If it is, then I will use the sub domain specified in proxyhost. This will be the case when the sub domain is redirected through FiddlerCore. If it isn’t, no proxy is being used, thus no proxyhost is availble in the HTTP headers, and I’ll use the sub domain from the URL.

3. Manipulate the hosts file
The hosts file can be found here: %systemroot%\system32\drivers\etc\hosts. For example it could look like this:


# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
# 102.54.94.97 rhino.acme.com # source server
# 38.25.63.10 x.acme.com # x client host

# localhost name resolution is handled within DNS itself.
# 127.0.0.1 localhost
# ::1 localhost

127.0.0.1 ocase.com
127.0.0.1 test.ocase.com
127.0.0.1 test1.ocase.com
127.0.0.1 test2.ocase.com
127.0.0.1 ocase.ocase.com
127.0.0.1 test.localhost

I have added some sub domains for testing purposes, and I redirect all of them to the ip address of my localhost. This ensures that they are ultimately handled by my app. If I only change the host file and start my app, IIS Express will return an HTTP 400 Bad Request. But with FiddlerCore, the requests are captured at a lower level, and I can parse them correctly.

As with any other HTTP Module I can enable and disbale it in the web.config of my application. The examples posted in this blog post are really simple, but I ended up making it more generic obviously, and I also added more functionality such as logging and url redirection which I needed at a later stage in the development.

One response to “Sub domains on IIS express

  1. Thanks for finally talking about >Sub domains on IIS express | Linguistic forms
    <Loved it!

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