iis-7web-confighttp-status-code-404httpapplication

Where do I catch and handle maxAllowedContentLength exceeded in IIS7?


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?


Solution

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