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

前端 未结 4 633
遥遥无期
遥遥无期 2021-02-04 10:55

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.

相关标签:
4条回答
  • 2021-02-04 11:21

    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.

    0 讨论(0)
  • 2021-02-04 11:36

    按照正常来说,再iis网站界面会有一个application request

    routing cache 的 icon, 可以点击 设置timeout 但是这里没有显示

    找到了 官方说明可以用命令行解决这个问题

    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 set config -section:system.webServer/proxy /timeout:"00:00:45" /commit:apphost

    重启下网站服务 我写的原文地址 https://zhuanlan.zhihu.com/p/157557980

    0 讨论(0)
  • 2021-02-04 11:38

    I just ran into this bug and your experiences helped me determine the root cause.

    My main server is MVC based and it looks at the Request.Form values in the Application_BeginRequest method. If the form values are accessed ARR fails to forward the body of a HTTP POST request. GET requests will work fine since there is no body.

    I have routes.IgnoreRoute ("Forum/{*pathInfo}"); as a registered route but ARR runs as a HttpModule and doesn't kick-in until later in the pipeline. That means my MVC based application is given the opportunity to access the content of the POST body which somehow prevents ARR from accessing the body itself and forwarding it to the proxy'd server.

    Here is Cosmin's related post on the iis.net forums: ARR 2.0 BUG - combined with managed http module timeout on read inputstream

    In my application I have all myserver.com/Forum/* requests being reverse proxy'd to a separate application on another server. So I simply checked the HttpContext.Current.Request.Url in my MVC application's Application_BeginRequest method to make sure it does not contain /Forum before accessing the Request.Form values. Once I did that the POST bodies made it through ARR just fine.

    UPDATE: after further testing it appears that there are still problems with ARR as POST from non-authenticated users still fails. Instead of the main website being MVC I created a dummy IIS .NET 4.0 website with a single Default.html document. But I still ran into problems with POST requests and ARR. Then I switch the application pool to ASP.NET 2.0 and what do you know, it works. At this point I have to assume that something in the .NET 4.0 pipeline is accessing the input stream which prevents ARR from accessing the input stream itself in order to forward the POST body.

    0 讨论(0)
  • 2021-02-04 11:40

    I know this is a year old question, but I just went through the same thing and found a solution. So, I'm posting it here for anyone else that runs into this.

    In my case I only saw the timeout issue with POST requests.

    It appears that the 2.0/2.1 ARR assumes that the input stream will be at the start of the posted data. However, the following code (for example) will break this assumption:

        HttpContext context = HttpContext.Current;
        HttpRequest request = context.Request;
    
        string value = request.Params["Name"];
    

    The key is how Params is described

        Gets a combined collection of System.Web.HttpRequest.QueryString,
        System.Web.HttpRequest.Form, System.Web.HttpRequest.ServerVariables,
        and System.Web.HttpRequest.Cookies items."`
    

    When the request is a POST, accessing Params will read the posted data from the input stream, invalidating ARR's assumption. As will reading from the input stream.

    I knew the data I needed was in the query string, not the posted data, so I worked around this by accessing the QueryString instead of Params. This avoids reading the posted data and works fine for me.

        string value = request.QueryString["Name"];
    

    This issue appears to be fixed in ARR 2.5.

    Upgrading ARR appears to be the only solution if you need to access posted data before handing off to ARR. The key is to let HttpRequest handle acquiring the data into Params. If you read it directly it will not work.

    0 讨论(0)
提交回复
热议问题