Search code examples
fiddler

Executing a script from Fiddler Autoresponder


I'm trying to test out a script locally using Fiddler Autoresponder rules and I have an endpoint that includes a hash of the request body in the response. I figured I could just trigger a script from the autoresponder and calculate the hash and construct the response but it's been incredibly difficult to figure out how to do so.

As far as I can tell, scripts are supported by the AutoResponder but there's little to no documentation on it. The only reference I can find is this post in the Fiddler forums (https://www.telerik.com/forums/script-in-autoresponder) but I have no idea where in the documentation that detail comes from.

I can get scripts to run, but it seems to run before the request is sent and I can't figure out how to have it execute the request as normal (or load the response from a file, or populate the response body from the script) and then execute my code to add the hash as a header.

I've messed around with the Session object a bit but can't find anything obvious. Is there any better documentation for Fiddler that's actually up to date?


Solution

  • Here is an example of a function that constructs a response which incorporates dynamic information from the request.

    public static function UrbanDictionaryBlocker(oS: Session)
    {   
        if (oS.HTTPMethodIs("GET")) // avoid HTTPS errors
        {
            oS.utilCreateResponseAndBypassServer();
            oS.ResponseBody = System.Text.Encoding.UTF8.GetBytes("stop browsing urban dictionary at work: " + oS.fullUrl);
        }
    }
    

    I wrote an associated rule which maps URLs containing "urbandictionary" to this function.

    How I figured this out:

    I figured this out by setting up Fiddler extension develoment in Visual Studio, which gives much better intellisense for the Fiddler API. Using go to definition, I was then able to conveniently view a list of all methods on the Session class.

    Example:

    ...
            [CodeDescription("Returns true if request URI contains the specified string. Case-insensitive.")]
            public bool uriContains(string sLookfor);
            [CodeDescription("Copy an existing Session's response to this Session, bypassing the server if not already contacted")]
            public void utilAssignResponse(Session oFromSession);
            [CodeDescription("Copy an existing response to this Session, bypassing the server if not already contacted")]
            public void utilAssignResponse(HTTPResponseHeaders oRH, byte[] arrBody);
            [CodeDescription("Use BZIP2 to compress the response body. Throws exceptions to caller.")]
            public bool utilBZIP2Response();
            [CodeDescription("Apply Transfer-Encoding: chunked to the response, if possible.")]
            public bool utilChunkResponse(int iSuggestedChunkCount);
            [CodeDescription("Call inside OnBeforeRequest to create a Response object and bypass the server.")]
            public void utilCreateResponseAndBypassServer();
            [CodeDescription("Removes chunking and HTTP Compression from the Request. Adds or updates Content-Length header.")]
            public bool utilDecodeRequest();
            public bool utilDecodeRequest(bool bSilent);
            [CodeDescription("Removes chunking and HTTP Compression from the response. Adds or updates Content-Length header.")]
            public bool utilDecodeResponse();
    ...
    

    And then I guessed that utilCreateResponseAndBypassServer was the tool for the job.