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:
- Setup FiddlerCore to capture all trafic for the sub domain, e.g. traffic for test.ocase.com
- Setup my application to handle sub domains and handle special cases when sub domains are redirected from Fiddler Core
- 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:
Fiddler.FiddlerCoreStartupFlags oFCSF = Fiddler.FiddlerCoreStartupFlags.Default;
Fiddler.FiddlerApplication.BeforeRequest += new Fiddler.SessionStateHandler(FiddlerApplication_BeforeRequest);
Also, I inherited from
IDisposable, and in the
Dispose() method, I shut down Fiddler:
public void Dispose()
disposed = true;
Finally, in the FiddlerApplication_BeforeRequest method, I placed this:
void FiddlerApplication_BeforeRequest(Fiddler.Session oSession)
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
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
# For example:
# 126.96.36.199 rhino.acme.com # source server
# 188.8.131.52 x.acme.com # x client host
# localhost name resolution is handled within DNS itself.
# 127.0.0.1 localhost
# ::1 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.