VS's Cassini (Web Server) + Fiddler = Remote testing

From time to time, I have a need to debug a web site from a browser not installed on my current machine.  Safari/Mac or phone browsers are the quintessential example.  Granted, if it happens server-side, it happens for all browsers, and if it happens client-side, debugging server-side may not help.  But there’s that one random time every now and again when this becomes quite important: debug server, client isn’t on localhost.  Perhaps it’s easier to replay the request from the browser where the problem happened rather than figure out how to simulate it locally.  Perhaps it’s a weird combination of race conditions that make it happen.  Perhaps it’s how the cookies built up that led to cruft not easily reproducible elsewhere.  Alas, being able to debug the server from a non-local client comes in mighty handy now-and-again.

As we all know, Visual Studio’s built in web server (originally based on Cassini) is hard-coded to only bind to loopback.  If I had my way that wouldn’t be the case, but here we are.  Traditionally, we’d need to install our site in IIS, attach to the w3svc service, and debug that way.  (Even if you’re not on a 64-bit box, you can empathize with how intense that is.)

Fiddler is an awesome tool for watching network traffic flow between browser and web server.  In the end, everything you send between server and browser is either HTML, CSS, or JavaScript (or binary content like images and plug-ins), so watching it happen is incredibly insiteful.  We’ll not use Fiddler for that here, but I highly recommend it for that work as well.  (There’s times when watching the traffic yields insights quite difficult to see any other way.)  Alas, today we’ll just mis-use it as a proxy server that can forward traffic back and forth from a LAN address to a loopback address.

Here’s the steps:

  1. Download and install Fiddler from http://www.fiddlertool.com on the same machine as Visual Studio.

  2. Tools menu -> Fiddler Options -> Connections tab: click on “Allow remote computers to connect”, and push ok.  (While I’m in here, I usually turn off IPv6 in the General tab as that’s another no-no in VS’s version of Cassini.)

  3. Rules menu -> Customize Rules.  For me, it opened up CustomRules.js in notepad.

  4. Scroll down to the function labeled OnBeforeRequest and add a line kinda like this:

    if (oSession.host.toLowerCase() == "192.168.1.5:8888") oSession.host = "localhost:45678";

    Replace the first IP with the address of your machine (ipconfig /all from a cmd will give you this), and replace the port at the end with what ever you set / VS assigned to your project.  (Inside Visual Studio, in the project properties window, in the web tab, I always set it to “Specific Port” so I don’t have to come in here and futz with it every time VS wants to “help”.)

    This line says “if the inbound request says it’s going to this ip and port (that fiddler is listening to), reroute it to this other ip and port (that Visual Studio’s web debugger is listening to).

  5. Scroll down a bit further in CustomRules.js to the OnBeforeResponse function and add a line kinda like this:

    oSession.utilReplaceInResponse("localhost:45678″,"192.168.1.5:8888");

    You’ll also need to change the IP and port here to match the changes above as well, but note they’re reversed.

    This line says “if the body of the outbound message includes text that routes to Visual Studio’s debugger, rewrite it to point to Fiddler.”

  6. Save this file, restart Fiddler, and try it out.

(You may also have to adjust firewall rules on your development machine to allow inbound TCP connections on port 8888.)

And that’s it!  Now you’re remote debugging your project from a non-local address.

One final note: ideally, we’d create another rule in OnBeforeResponse that would rewrite headers as well.  I haven’t been very successful in doing that, so I haven’t included all the ways that don’t work.  But if you’re sending back a redirect to a full url without this rule, your client will happily time out looking for content on itself.  Why itself?  Because you redirected to localhost.  :D

Rob