我正在尝试构建一个代理,为内部站点提供请求(隐藏原点),但同时检查数据包并异步后处理它们。
E.g。假设所有对http://www.foo.com的SOAP调用都将转到http://192.168.1.1,同时存储在数据库中进行后期分析。内部服务器是一个黑盒子,所以更改它的内容超出了这个问题的范围。
无论如何,我已经配置了ARR,使用反向代理,使用通配符进行URL重写过滤,所有工作都完美无瑕。然后,我尝试添加一个用C#编写的托管HttpModule,并挂钩到Application_BeginRequest和Application_EndRequest。我能够在最终请求(应用程序池处于集成模式)中访问请求标头,响应标头,甚至能够通过在Response.Filter上设置过滤器来读取输出流中的响应内容,该过滤器将所有写入缓存在附加内存流中。
问题是,当我尝试读取(在模块BeginRequest处理程序内)来自请求的输入流时,ARR会停留一段时间并抛出一个
HTTP错误502.3 - 糟糕的网关 操作超时处理程序 ApplicationRequestRoutingHandler 错误代码0x80072ee2
所以它超时了。
查看失败的请求跟踪我看到:
MODULE_SET_RESPONSE_ERROR_STATUS 警告 模块名= “ApplicationRequestRouting”, 通知= “EXECUTE_REQUEST_HANDLER”, HttpStatus =“502”,HttpReason =“不好 Gateway“,HttpSubStatus =”3“, 错误码= “2147954402”, ConfigExceptionInfo = “” SET_RESPONSE_ERROR_DESCRIPTION警告 ErrorDescription =“操作定时 出“
现在网上的任何类似帖子都没有帮助,因为这不是超时错误(代理设置为120秒,页面答案不到100毫秒),以及我评论试图处理程序的代码的那一刻读取FORM数据或InputStream数据,一切都可以作为魅力。
即使我在读取后将输入流的位置设置为0,我仍然会超时。 如果我在EndRequest上读取输入流,它将获得0个字节,即使它是POST请求。 (这显然是错误的)
ARR是否有一个错误,我尝试在尝试重新路由之前尝试读取输入流?
使用的东西:Windows Server 2008 R2 IIS 7.5 ARR v2 .Net Framework 3.5 模块
想法? 谢谢 /科斯明
答案 0 :(得分:6)
如果您可以切换到.Net Framework 4,那么就有一个解决方案。
在HttpModule事件处理程序中完成BeginRequest / EndRequest后,添加对 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();
}
在MSDN上查看此内容:HttpRequest.InsertEntityBody。
答案 1 :(得分:4)
我知道这是一个一年前的问题,但我只是经历了同样的事情并找到了解决方案。所以,我在这里发布它是为了遇到这个问题的其他人。
就我而言,我只看到了POST
次请求的超时问题。
似乎2.0 / 2.1 ARR 假定输入流将位于发布数据的开头。但是,以下代码(例如)将打破这一假设:
HttpContext context = HttpContext.Current;
HttpRequest request = context.Request;
string value = request.Params["Name"];
关键是如何描述Params
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
将从输入流中读取发布的数据,从而使ARR的假设无效。从输入流中读取。
我知道我需要的数据是在查询字符串中,而不是发布的数据,所以我通过访问QueryString
而不是Params
解决了这个问题。这样可以避免阅读发布的数据并且对我有用。
string value = request.QueryString["Name"];
此问题似乎已在ARR 2.5中修复。
如果您需要在转交到ARR之前访问发布的数据,升级ARR似乎是唯一的解决方案。关键是让HttpRequest处理将数据收集到Params
。如果你直接阅读它将无法正常工作。
答案 2 :(得分:2)
我刚遇到这个错误,你的经历帮助我确定了根本原因。
我的主服务器是基于MVC的,它查看Application_BeginRequest
方法中的Request.Form值。如果访问表单值,则ARR无法转发HTTP POST请求的正文。由于没有正文,GET请求将正常工作。
我有routes.IgnoreRoute ("Forum/{*pathInfo}");
作为注册路线,但ARR作为HttpModule运行,并且直到管道中的后期才开始运行。这意味着我的基于MVC的应用程序有机会访问POST主体的内容,以某种方式阻止ARR访问主体本身并将其转发到代理服务器。
这是Cosmin在iis.net论坛上的相关帖子:ARR 2.0 BUG - combined with managed http module timeout on read inputstream
在我的应用程序中,我将所有 myserver.com/Forum / * 请求反向代理到另一台服务器上的单独应用程序。所以我只是检查了我的MVC应用程序的 Application_BeginRequest 方法中的HttpContext.Current.Request.Url,以确保它在访问Request.Form值之前不包含/ Forum。一旦我这样做,POST机构通过ARR就可以了。
更新:在进一步测试后,似乎ARR仍然存在问题,因为来自未经身份验证的用户的POST仍然失败。而不是主网站是MVC我创建了一个虚拟的IIS .NET 4.0网站,其中包含一个Default.html文档。但我仍遇到POST请求和ARR的问题。然后我将应用程序池切换到ASP.NET 2.0,你知道什么,它的工作原理。在这一点上,我必须假设.NET 4.0管道中的某些东西正在访问输入流,这阻止了ARR访问输入流本身以转发POST主体。
答案 3 :(得分:0)
按照正常来说,再iis网站界面会有一个应用程序请求
routing cache的图标,可以单击设置超时,但是这里没有显示
找到了官方说明可以用命令行解决这个问题
https://blogs.iis.net/richma/502-3-bad-gateway-the-operation-timed-out-with-iis-application-request-routing-arr blogs.iis.net
执行以下命令,然后重启下网站服务
进入到C:\ Windows \ System32 \ inetsrv:管理员命令行工具执行以下命令
appcmd.exe设置配置-section:system.webServer / proxy / timeout:“ 00:00:45” / commit:apphost
重启下网站服务 我写的财经报地址 https://zhuanlan.zhihu.com/p/157557980