IIS7 Application Request Routing (arr reverse proxy) combined with managed module - time out

user682385 picture user682385 · Mar 29, 2011 · Viewed 12.2k times · Source

I am trying to build a proxy that would serve requests to an internal site (hiding the origin) but at the same time inspect the packets and asynchronously post-process them.

E.g. let's say all SOAP calls to http://www.foo.com will go to http://192.168.1.1, and at the same time be stored in a DB for post analysis. The internal server is a black box, so changing something on it is out of this question scope.

Anyway, I have configured ARR, with reverse proxy, made URL rewrite filter with wildcards, all works flawless. Then, I tried to add an managed HttpModule written in C#, and hooked to Application_BeginRequest and Application_EndRequest. I am able to access request headers, response headers on end request (app pool being in integrated mode) and even able to read response content from the outputstream by setting a filter on Response.Filter, that caches all writes in an additional memory stream.

The problem is that the moment I try to read (inside the module BeginRequest handler) the input stream from the request, ARR stays a while and throws a

HTTP Error 502.3 - Bad Gateway The operation timed out Handler ApplicationRequestRoutingHandler Error Code 0x80072ee2

So it times out.

Looking with Failed Request Tracing I see:

MODULE_SET_RESPONSE_ERROR_STATUS Warning ModuleName="ApplicationRequestRouting", Notification="EXECUTE_REQUEST_HANDLER", HttpStatus="502", HttpReason="Bad Gateway", HttpSubStatus="3", ErrorCode="2147954402", ConfigExceptionInfo="" SET_RESPONSE_ERROR_DESCRIPTION Warning ErrorDescription="The operation timed out"

Now any similar posts on the net didn't helped as this isn't a timeout error (proxy has 120 seconds setting, page answers in under 100 ms), and the moment I comment the code of the handler that tries to read FORM data or InputStream data, everything works as a charm.

Even if I set the position of the inputstream to 0 after reading it, I still get timeouts. If I read the input stream on EndRequest, it gets 0 bytes, even if it was a POST request. (which is clearly wrong)

Does ARR has a bug in the fact that I try to read an input stream before it tries to re-route it?

Things used: Windows Server 2008 R2 IIS 7.5 ARR v2 .Net Framework 3.5 module

Ideas? Thanks /Cosmin

Answer

Andrés Robinet picture Andrés Robinet · Mar 17, 2012

If you can switch to .Net Framework 4, there is a solution for this.

After you are done with your BeginRequest/EndRequest in your HttpModule event handler, add a call to HttpRequest.InsertEntityBody.

    /* BeginRequest event: Executes before request is processed */
    private void Application_BeginRequest(Object source, EventArgs e)
    {
        HttpApplication application = (HttpApplication)source;
        HttpRequest request = application.Context.Request;

        // Do something with request
        DoMyOwnRequestProcessing(request);

        // After you finish, make sure IIS gets the entity body
        // For example, Application Request Routing needs this
        request.InsertEntityBody();
    }

Take a look at this on MSDN: HttpRequest.InsertEntityBody.