The question asked specifically about timeouts but also implied setting maxRequestLength as well. I'm going to try and give a really comprehensive answer to both issues (now that I have spent most of a day working it out).
Lets say we have a single URL on our website that we want to process file uploads. We want to take in up to a Gigabyte of data on that URL and we will allow clients to be connected for, at most, 1 hour. All other URLs we want to only allow 90 seconds of connection time and a maximum of 4MB in the POST body.
Global Settings
First you have to globally raise the limits on time and size for the entire site. First you want to set the "Connection Timeout" for the entire site. This acts as an absolute upper bound and it cannot be set from within the web.config. The IIS7 website has good instructions here. You can also do it programatically with the Microsoft.Web.Administration
library that shipped with IIS7/7.5:
var serverManager = ServerManager.OpenRemote("\\web-server-name");
var site = serverManager.Sites["Your-Site-Name"];
site.Limits.ConnectionTimeout = new TimeSpan(1, 0, 0);
Next you need to set the max size request that the site will allow. This is in a totally different place, in the Request Fitlering module. This module may not be installed by default on IIS7. Again Microsoft has good instructions for how to set the maxAllowedContentLength
through the GUI. This is something you can set from within the Web.config:
<system.webServer>
<security>
<requestFiltering>
<!-- Allow 1GB uploads -->
<requestLimits maxAllowedContentLength="1073741824"></requestLimits>
</requestFiltering>
</security>
</system.webServer>
This setting is evaluated against the Content-Length
header and requests larger than this will immediately result in a 404.13. The setting is in bytes and what comes next is in Kilobytes, very consistent this IIS7.
ASP.NET Settings
Next we want to cap all of the ASP.NET requests at 90 seconds/4MB. This can be done in the web.config:
<location>
<system.web>
<httpRuntime executionTimeout="90" maxRequestLength="4096" />
</system.web>
</location>
To make the settings global the system.web
tag is wrapped in a location
tag that has no path
attribute. (In the original question I did not wrap the system.web tag in the location tag which was probably the source of my problem.) maxRequestLength
is in kilobytes this time.
Finally we want to allow our special upload URL to accept huge uploads. Setting these values higher than the ones you set globally wont work. The global values override these settings.
<location path="Uploads/PostFile.rails">
<system.web>
<httpRuntime executionTimeout="3600" maxRequestLength="1048576" />
</system.web>
</location>
If everything else is set up right, that should do it. As Peter Bromberg suggested, you can add as many of these blocks as needed to raise the limits for specific URLs.
One last note: in debug mode IIS does not enforce the Connection Timeout or executionTimeout settings, to allow you more time for debugging. So to test your setting on a developer machine you should do a release build and you should set the 'Enable Server-Side Debugging' setting to false
.