URL Rewrite with the AutoResponder

1,730 views
Skip to first unread message

Marc J. Cawood

unread,
Aug 20, 2010, 11:17:25 PM8/20/10
to Fiddler
Hi Eric,

I know one could do this with a filter but it seems to me a simple
enhancement to the standard AutoResponder to do dynamic URL rewriting.
At the moment each AutoResponder entry has two parts:
REGEX -> FILEPATH

For Example:
regex:(?insx).*\.css$ -> C:\temp\style.css

At the moment the FILEPATH part is static. But with Regex you can
replace variables. For example:
regex:(?insx).*/(.*)\.css -> C:\temp\$1.css

Heck one could even do:
regex:(?insx)http://myliveserver.com/(.*)\.css -> http://mytestserver.com/$1.css

In this way one could maintain a local cache without having to make a
rule for each file.

Cheers

Marc
PS: If you have a filter handy which does this, don't hesitate posting
it ;-)

Marc J. Cawood

unread,
Aug 21, 2010, 12:27:43 AM8/21/10
to Fiddler
By "filter" I meant custom rule. Unfortunately it seems you can't do
what I need with custom rules because the x-replywith file does not
support subfolders.

I have tried:
oSession["x-replywithfile"] ="C:\temp\default.css";
and also
oSession["x-replywithfile"] =".\subfolder\default.css";

The only thing which works is to stay in the same folder:
oSession["x-replywithfile"] ="default.css";

Which means I'd need all my cached files in the same "Fiddler2\Captures
\Responses\" folder. Not good.

I also can't modify the URL since I am switching protocol from http to
file.

Is writing a plugin DLL the only way out?

EricLaw

unread,
Aug 21, 2010, 12:43:12 AM8/21/10
to Fiddler
You can specify any file path. The trick is that you have to escape
backslashes in JavaScript.

e.g.

oSession["x-replywithfile"] ="C:\\temp\\default.css";



Marc J. Cawood

unread,
Aug 21, 2010, 1:46:53 AM8/21/10
to Fiddler
Wonderful thanks Eric!

I now have a way of forcing the browser to use the local cache.

if (oSession.HostnameIs("www.mysite.com")) {
var s:String = oSession.host + oSession.PathAndQuery;
s = s.Replace("/", "\\");
if (System.IO.File.Exists("C:\\Users\\xxx\\Documents\\Fiddler2\
\Captures\\Responses\\" + s)) {
oSession["x-replywithfile"] = s;
}
}

Marc J. Cawood

unread,
Aug 21, 2010, 1:52:45 AM8/21/10
to Fiddler
Is there any way via scripting to tell Fiddler to store responses so
that the cache I am working with is automatically filled?

Something like:

if (cacheHit)
replyWithCache
else
waitForResponse
cacheResponse

EricLaw

unread,
Aug 21, 2010, 12:16:23 PM8/21/10
to Fiddler
You can write script that does this, yes, but it's a non-trivial
script to write.

Assorted methods on the Session object allow you to store the Response
(including headers) to disk.

Marc J. Cawood

unread,
Aug 23, 2010, 10:45:40 AM8/23/10
to Fiddler
It's surprisingly easy actually - I'm really impressed with Fiddler!!

static function OnBeforeRequest(oSession: Session)
{
// Cache Onyx Scripts and Static Resources
if (oSession.host.match(/crm.lgs-net.com/) &&
oSession.HTTPMethodIs("GET") &&
oSession.url.match(/\.(js$)|(gif$)|(jpe?g$)|(css$)/))
{
var s:String = oSession.host + oSession.PathAndQuery;
s = s.Replace("/", "\\");
s = s.Replace(":", "+");
s = "C:\\temp\\" + s;
if (System.IO.File.Exists(s)) {
oSession["x-replywithfile"] = s;
oSession["ui-comments"] = "hit";
} else {
oSession.SaveResponseBody(s);
oSession["ui-comments"] = "miss";
}
}
}


I just have one small issue to solve. Very occasionally Fiddler seems
to save a file of 0 bytes which is unusable. I need to therefore check
more than just if the file exists but verify its size. When I do this,
Fiddler cannot parse the script though it appears to me to be
valid .NET code:

MessageBox.Show(System.IO.FileInfo("C:\temp\test.htm").Length);

I've also tried:

var l:long = System.IO.FileInfo("C:\temp\test.htm").Length;

Same error: Type mismatch

EricLaw

unread,
Aug 23, 2010, 11:01:18 AM8/23/10
to Fiddler
Hi, Marc!

The example code you provided below isn't using double-backslashes in
the filepath, which is one problem.

>Very occasionally Fiddler seems to save a file of 0 bytes which is unusable

That's because you're using oSession.SaveResponseBody(s), which is
going to store no bytes if there's no body, e.g. a 304. You want to
save the response in such a way that the headers are preserved, and
you probably only want to save HTTP/200 responses.

if (oSession.responseCode == 200){
var oFS = new FileStream("C:\\whatever\\1.dat");
oSession.WriteResponseToStream(oFS, false);
oFS.Dispose();
}

The bigger problem is that you're calling SaveResponseBody inside
OnBeforeREQUEST which is never going to work. You need to do that
inside OnBeforeResponse.

Your path-character replacement code needs some work to be robust in
general; it doesn't account for a bunch of characters that are not
legal for path characters, including * and ? (although obviously it
may work fine for your restricted scenario).

-Eric

Marc J. Cawood

unread,
Aug 23, 2010, 11:31:08 AM8/23/10
to Fiddler
Hi Eric,

I am using double backslashes (I replace / with \\) but the problem
seems to have been either that I was saving empty bodies (304s) or I
was in the wrong method. Either way it's working nicely now.

However that code you gave doesn't get accepted (I guess because it's
C# and I need this JScript stuff you use in CustomRules.js).
But actually SaveResponseBody and oSession["x-replywithfile"] is
working just fine for me!

Thanks a million!

Marc

EricLaw

unread,
Aug 23, 2010, 11:44:03 AM8/23/10
to Fiddler
Using SaveResponseBody isn't going to result in the same behavior as
saving the headers.

The code I show is JScript.NET. You may need to use e.g.
System.IO.FileStream instead of just "FileStream"

If you give me more to go on than "doesn't get accepted" we can fix
whatever trivial typos there were.

Marc J. Cawood

unread,
Aug 24, 2010, 1:14:16 AM8/24/10
to Fiddler
> The code I show is JScript.NET. You may need to use e.g.
> System.IO.FileStream instead of just "FileStream"

OK, I've just added the import System.IO; to my file - thanks.

While we're on the subject of syntax errors - do you have any idea why
this doesn't get accepted?

MessageBox(FileInfo("C:\temp\test.htm").Length);

Fiddler says "Type mismatch".

EricLaw

unread,
Aug 24, 2010, 9:55:17 AM8/24/10
to Fiddler
Length is a number. MessageBox takes a string. Add .ToString() on the
end.
Reply all
Reply to author
Forward
0 new messages