我在哪里捕获并处理 IIS7 中超过 maxAllowedContentLength 的情况?

发布于 2024-07-14 09:58:26 字数 1490 浏览 8 评论 0原文

我有一个 aspx 页面,允许用户上传文件,并且我希望将最大文件上传大小限制为 10MB。 IIS7、.NET 3.5。 我在 web.config 文件中进行了以下配置:

<location path="foo.aspx">
    <system.web>
        <!-- maxRequestLength: kbytes, executionTimeout:seconds -->
        <httpRuntime maxRequestLength="10240" executionTimeout="120" />
        <authorization>
            <allow roles="customRole"/>
            <!-- Deny everyone else -->
            <deny users="*"/>
        </authorization>
    </system.web>
    <system.webServer>
        <security>
            <requestFiltering>
                <!-- maxAllowedContentLength: bytes -->
                <requestLimits maxAllowedContentLength="10240000"/>
            </requestFiltering>
        </security>
        <handlers accessPolicy="Read, Script">
            <add name="foo" path="foo.aspx" verb="POST"
               type="System.Web.UI.PageHandlerFactory"
               preCondition="integratedMode" />
        </handlers>       
    </system.webServer>
</location>

我有一个实现 IHttpModule 的自定义错误处理模块。 我发现当超过 maxRequestLength 时,确实会引发 HttpApplication.Error 。 但是,当我使用 maxAllowedContentLength 时,不会引发 HttpApplication.Error 事件,用户会被重定向到 404.13 页面。 我已经附加了 Visual Studio,并打开了第一次机会异常,没有抛出任何异常。

我的第一个想法是检查早期事件中的标题内容长度 - 是否有关于我在哪里执行此操作的建议/最佳实践? 发布日志请求? 结束请求?

I have an aspx page where I’m allowing a user to upload a file and I want to cap the max file upload size to be 10MB. IIS7, .NET 3.5. I have the following configured in my web.config file:

<location path="foo.aspx">
    <system.web>
        <!-- maxRequestLength: kbytes, executionTimeout:seconds -->
        <httpRuntime maxRequestLength="10240" executionTimeout="120" />
        <authorization>
            <allow roles="customRole"/>
            <!-- Deny everyone else -->
            <deny users="*"/>
        </authorization>
    </system.web>
    <system.webServer>
        <security>
            <requestFiltering>
                <!-- maxAllowedContentLength: bytes -->
                <requestLimits maxAllowedContentLength="10240000"/>
            </requestFiltering>
        </security>
        <handlers accessPolicy="Read, Script">
            <add name="foo" path="foo.aspx" verb="POST"
               type="System.Web.UI.PageHandlerFactory"
               preCondition="integratedMode" />
        </handlers>       
    </system.webServer>
</location>

I have a custom error handling module that implements IHttpModule. I’ve found that when maxRequestLength is exceeded, HttpApplication.Error does indeed get raised. However when I play with maxAllowedContentLength, the HttpApplication.Error event isn’t being raised and the user gets redirected to a 404.13 page. I've attached with Visual Studio with first chance exceptions turned on nothing is being thrown.

My first thought is to check the header content length in an earlier event – are there recommendations/best practices of where I do this? PostLogRequest? EndRequest?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

七七 2024-07-21 09:58:27

最简单的方法是在页面本身的OnError方法中处理。

我认为这仅适用于 .NET 4.0,因为 WebEventCode 属性在 .NET 4.0 中被记录为 NEW。

protected override void OnError(EventArgs e)
{
    Exception err = Server.GetLastError();
    if (err is HttpException)
    {
        if ((err as HttpException).WebEventCode == 3004)
        {
            Context.Items["error"] = "File exceeded maximum allowed length.";
            Server.Transfer( Context.Request.Url.LocalPath );
            return;
        }
    }
    base.OnError(e);
}

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    if (!IsPostBack)
    {
        string error = Context.Items["error"] as string;
        if (!string.IsNullOrEmpty( error ))
            showErrorMessage( error );
    }
}

我所做的是:

  • 使用 Server.GetLastError 获取最后一个错误,
  • 检查它是否是“最大请求”超过长度。” 错误(WebEventCode == 3004)。
  • 向 Context.Items 集合添加一个值,以将请求标记为错误
  • 使用 Server.Transfer(Context.Request.Url.LocalPath) 将请求传输回页面本身
  • 页面的 OnLoad 方法检查错误标记,并在以下情况下显示一条消息这

确保错误完全在请求的页面上得到处理,并且该页面能够报告错误。

另请注意,虽然浏览器最终会收到正确的响应,但浏览器可能会花一些时间上传整个请求,然后才能处理服务器的响应并显示它。 此行为可能被定义为 HTTP 协议中服务器/浏览器交互的一部分,因此对此可能无能为力。

The simplest method is to handle it in the OnError method of page itself.

I think this works only in .NET 4.0, since the WebEventCode property is documented as NEW in .NET 4.0.

protected override void OnError(EventArgs e)
{
    Exception err = Server.GetLastError();
    if (err is HttpException)
    {
        if ((err as HttpException).WebEventCode == 3004)
        {
            Context.Items["error"] = "File exceeded maximum allowed length.";
            Server.Transfer( Context.Request.Url.LocalPath );
            return;
        }
    }
    base.OnError(e);
}

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    if (!IsPostBack)
    {
        string error = Context.Items["error"] as string;
        if (!string.IsNullOrEmpty( error ))
            showErrorMessage( error );
    }
}

What I did was:

  • get the last error with Server.GetLastError
  • check that it's a "Maximum request length exceeded." error (WebEventCode == 3004).
  • added a value to Context.Items collections to flag the request as an error
  • transfer the request back to the page itself with Server.Transfer(Context.Request.Url.LocalPath)
  • the page's OnLoad method checks for the error flag and displays a message if present

This ensures the error is handled entirely on the requested page, and the page is capable of reporting errors.

Also note that while the browser will eventually receive a proper response, the browser may take its time uploading the entire request before it handles the server's response and displays it. This behavior is probably defined as part of the server/browser interaction in the HTTP protocol, so probably not much can be done about that.

扶醉桌前 2024-07-21 09:58:26

查看 IIS 7.0 的 ASP.NET 应用程序生命周期概述并在进行我自己的实验时,我假设请求验证是在引发任何事件之前由 IIS 在内部完成的。

看起来只有 LogRequest、PostLogRequest、EndRequest、PreSendRequestContent 和 PreSendRequestHeaders 在内部验证后出现此错误。

我决定将一个事件处理程序附加到自定义错误处理程序中的 HttpApplication.EndRequest 事件,并检查 POST 上的 404.13 状态代码并根据需要进行处理,就我而言是重定向到调用页面,该页面将检查 Server.GetLastError() 并向最终用户显示友好错误。

private void application_EndRequest(object sender, EventArgs e)
{
    HttpRequest request = HttpContext.Current.Request;
    HttpResponse response = HttpContext.Current.Response;

    if ((request.HttpMethod == "POST") &&
        (response.StatusCode == 404 && response.SubStatusCode == 13))
    {
        // Clear the response header but do not clear errors and
        // transfer back to requesting page to handle error
        response.ClearHeaders();
        HttpContext.Current.Server.Transfer(
            request.AppRelativeCurrentExecutionFilePath);
    }
}

我欢迎对此方法和替代方案提供反馈。

After looking at the ASP.NET Application Life Cycle Overview for IIS 7.0 and doing my own experimentation, I'm assuming that the request validation is done internally by IIS before any of the events are raised.

It looks like only LogRequest, PostLogRequest, EndRequest, PreSendRequestContent, and PreSendRequestHeaders are raised after the internal validation with this error.

I've decided to attach an event handler to the HttpApplication.EndRequest event in my custom error handler and check for the 404.13 status code on POST and handle as I need it to be handled, which in my case is to redirect to the calling page which will check Server.GetLastError() and display a friendly error to the end user.

private void application_EndRequest(object sender, EventArgs e)
{
    HttpRequest request = HttpContext.Current.Request;
    HttpResponse response = HttpContext.Current.Response;

    if ((request.HttpMethod == "POST") &&
        (response.StatusCode == 404 && response.SubStatusCode == 13))
    {
        // Clear the response header but do not clear errors and
        // transfer back to requesting page to handle error
        response.ClearHeaders();
        HttpContext.Current.Server.Transfer(
            request.AppRelativeCurrentExecutionFilePath);
    }
}

I'd welcome feedback on this approach and alternatives.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文