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
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.