Iis 7 IIS7应用程序请求路由(arr反向代理)结合受管模块-超时

Iis 7 IIS7应用程序请求路由(arr反向代理)结合受管模块-超时,iis-7,timeout,httpmodule,reverse-proxy,Iis 7,Timeout,Httpmodule,Reverse Proxy,我正在尝试构建一个代理,该代理将为内部站点的请求提供服务(隐藏源站),但同时检查数据包并异步后处理它们 例如,假设对的所有SOAP调用都将转到,同时存储在数据库中以进行后期分析。内部服务器是一个黑匣子,因此在其上更改某些内容超出了这个问题的范围 无论如何,我已经配置了ARR,使用反向代理,使用通配符制作了URL重写过滤器,所有的工作都完美无缺。然后,我尝试添加一个用C#编写的托管HttpModule,并连接到应用程序_BeginRequest和应用程序_EndRequest。我可以访问请求头、结

我正在尝试构建一个代理,该代理将为内部站点的请求提供服务(隐藏源站),但同时检查数据包并异步后处理它们

例如,假设对的所有SOAP调用都将转到,同时存储在数据库中以进行后期分析。内部服务器是一个黑匣子,因此在其上更改某些内容超出了这个问题的范围

无论如何,我已经配置了ARR,使用反向代理,使用通配符制作了URL重写过滤器,所有的工作都完美无缺。然后,我尝试添加一个用C#编写的托管HttpModule,并连接到应用程序_BeginRequest和应用程序_EndRequest。我可以访问请求头、结束请求时的响应头(应用程序池处于集成模式),甚至可以通过在response.filter上设置一个过滤器来从outputstream读取响应内容,该过滤器将所有写入缓存在附加内存流中

问题是,当我试图从请求中读取(在模块BeginRequest处理程序中)输入流时,ARR会停留一段时间并抛出

HTTP错误502.3-网关错误 操作超时处理程序 应用程序请求路由处理器 错误代码0x80072ee2

所以它超时了

查看失败的请求跟踪,我看到:

模块设置响应错误状态 警告 ModuleName=“ApplicationRequestRouting”, 通知=“执行请求处理程序”, HttpStatus=“502”,HttpReason=“坏 网关”,HttpSubStatus=“3”, ErrorCode=“2147954402”, ConfigExceptionInfo=“” 设置\u响应\u错误\u描述警告 ErrorDescription=“操作已超时 “出去”

现在,网络上任何类似的帖子都没有帮助,因为这不是超时错误(代理设置为120秒,页面应答时间不到100毫秒),而当我对试图读取表单数据或输入流数据的处理程序的代码进行注释时,一切都很好

即使我在读取inputstream后将其位置设置为0,我仍然会超时。 如果我在EndRequest上读取输入流,它将获得0字节,即使它是POST请求。(这显然是错误的)

ARR是否存在一个错误,即我在尝试重新路由输入流之前尝试读取输入流

使用的东西:WindowsServer2008R2 IIS 7.5 ARR v2.Net Framework 3.5 模块

想法? 谢谢
/Cosmin

我知道这是一个老问题,但我只是经历了同样的事情并找到了解决办法。所以,我把它贴在这里是为了其他任何遇到这个问题的人

在我的例子中,我只看到
POST
请求的超时问题

似乎2.0/2.1 ARR假设输入流将位于发布数据的开头。但是,以下代码(例如)将打破此假设:

    HttpContext context = HttpContext.Current;
    HttpRequest request = context.Request;

    string value = request.Params["Name"];
关键是如何描述参数

    Gets a combined collection of System.Web.HttpRequest.QueryString,
    System.Web.HttpRequest.Form, System.Web.HttpRequest.ServerVariables,
    and System.Web.HttpRequest.Cookies items."`
当请求是POST时,访问
Params
将从输入流读取POST数据,从而使ARR的假设无效。正如从输入流读取一样

我知道我需要的数据在查询字符串中,而不是发布的数据,所以我通过访问
QueryString
而不是
Params
来解决这个问题。这样可以避免读取发布的数据,对我来说效果很好

    string value = request.QueryString["Name"];
ARR 2.5中似乎解决了此问题


如果您需要在向ARR移交之前访问发布的数据,升级ARR似乎是唯一的解决方案。关键是让HttpRequest处理将数据获取到
参数中的问题。如果你直接读它,它将不起作用

我刚刚遇到了这个错误,你的经验帮助我确定了根本原因

我的主服务器是基于MVC的,它查看
应用程序\u BeginRequest
方法中的Request.Form值。如果访问表单值,ARR将无法转发HTTP POST请求的主体。GET请求可以正常工作,因为没有主体

我有
routes.IgnoreRoute(“Forum/{*pathInfo}”)
作为注册路由,但ARR作为HttpModule运行,直到稍后在管道中启动。这意味着我的基于MVC的应用程序有机会访问帖子正文的内容,这在某种程度上阻止了ARR访问正文本身并将其转发到代理服务器

以下是Cosmin在iis.net论坛上的相关帖子:

在我的应用程序中,我将所有myserver.com/Forum/*请求反向代理到另一台服务器上的单独应用程序。因此,在访问Request.Form值之前,我只需检查我的MVC应用程序的application_BeginRequest方法中的HttpContext.Current.Request.Url,以确保它不包含/Forum。有一次我做到了这一点,邮政机构顺利通过了ARR


更新:进一步测试后,似乎ARR as POST仍然存在问题,来自未经身份验证的用户的POST仍然失败。我创建了一个带有单个Default.html文档的虚拟IIS.NET4.0网站,而不是主网站MVC。但是我仍然遇到POST请求和ARR的问题。然后我将应用程序池切换到ASP.NET 2.0,您知道吗,它可以工作。此时,我必须假设.NET 4.0管道中的某些内容正在访问输入流,这会阻止ARR访问输入流本身以转发帖子正文。

如果您可以切换到.NET Framework 4,则有一个解决方案

在HttpModule事件处理程序中完成BeginRequest/EndRequest后,添加对HttpRequest.InsertEntityBody的调用

/*BeginRequest事件:在处理请求之前执行*/
私有void应用程序_BeginRequest(对象源,事件参数e)
{
HttpApplication=(HttpApplication)源;
HttpRequest请求=application.Context.request;
//按要求做某事
DoMyOwnRequestProcessing(请求);
//在你完成之后,