Supporting Large File Uploads

There are several server configuration settings that factor into supporting large file uploads, and of course there are external factors such as network reliability and available bandwidth. Other factors include server side resources such as available memory on the web server and how much traffic or load is being serviced.

The httpRuntime element in Web.config has 2 important settings, maxRequestLength, and executionTimeout. 

maxRequestLength is in KB, so you must set it to a high enough number of KB slightly larger than the maximum file size you would like to support. The example below of 1048576 KB translates to 1 GB
If you google for "kb to mb" google provides a handy calculator for converting Kilobytes to Megabytes, Gigabytes etc. Note that if we want to support file uploads up to 1 GB then we probably should set the KB slightly higher to accommodate the html form posted with the file that also is part of the Request payload.

executionTimeout is in seconds, it determines how much time IIS will allow to complete a web request. It can take a while to upload a large file especially if bandwidth is limited. If the configured number of seconds elapses before the file finishes uploading the request will end with a timeout error. The example below is 3600 seconds which is 60 minutes. 

<system.web >
    <httpRuntime requestValidationMode="2.0" maxRequestLength="1048576" executionTimeout="3600" maxUrlLength="560" maxQueryStringLength="2048" />
</system.web>

In IIS 7.x using an Integrated Application pool (as opposed to a "Classic" application pool). We also have requestFiltering settings in the <system.webServer> section that are needed to support large file uploads. We have an example in comments in the Web.config file that ships with mojoPortal, to use it you would have to un-comment it and adjust the setting to your requirements. Note that in some environments request filtering may be locked down at a higher level such as from machine.config. If you un-comment it in the web.config file in those cases it can cause an error.

<system.webServer>
<security>
  <requestFiltering>
    <requestLimits maxAllowedContentLength="1073741824"/>
  </requestFiltering>
</security>
</system.webServer>

Note that maxAllowedContentLength is in Bytes, not KB.

Troubleshooting File Upload Problems

file upload error
When a file upload fails due to exceeding the httpRuntime maxRequestLength, an error will be logged:
"System.Web.HttpException (0x80004005): Maximum request length exceeded"

Similarly, when a file upload fails due to exceeding the httpRuntime executionTimeout, an error will be logged:
"System.Web.HttpException (0x80004005): Request timed out"

When a file upload fails due to exceeding requestLimits maxAllowedContentLength, nothing will be logged in the mojoPortal system log. The reason is because as noted in the IIS documentation, in this case IIS returns a 404 page not found. In this case the request never reached mojoPortal code so nothing was logged by mojoPortal.

For problems uploading files from the File Manager or from the WYSIWYG editors (CKeditor, TinyMCE), see also the Storage Quotas section in the article Allowing Users To Upload and Browse Files. File uploads will be blocked in those features once the quotas have been reached.

A hosting environment with low memory available to the site may not handle large file uploads. If you see repeated application start and end events being logged when you try to upload large files, the application pool may be reaching the allowed or available memory when it tries to process the request. Recycling the application pool kills the process handling web requests and can cause failed uploads if it happens while uploading whether the file upload caused it due to the memory limit or whether the application pool is recycled for other reasons (manually for example).

For information about the mojoPortal log see Basic Troubleshooting

Note that in all cases the IIS web logs are useful when you want to know the result of specific web requests or troubleshoot uploading problems. Especially if you don't see any clues in the mojoPortal log about file upload related errors. You should check the status code of the file upload web requests in the IIS web logs, and keep in mind the 404.13 status that IIS will return if the file is larger than the maxAllowedContentLength

Note also that drag and drop and multi file selection is only supported in modern web browsers that support HTML 5, such as IE 10 or higher and recent versions of Firefox, Chrome, and Safari.

If for some reason you are supporting mostly users with older web browsers (ie Windows XP Users) you might want to hide the drop zone since it won't work and will only confuse those users. In that case you can put this in the theme.skin file found in your skin folder:

<portal:jQueryFileUpload runat="server"
    UseDropZone="false"
/>

Advanced Configuration

The settings shown above will get the job done as far as enabling large file uploads but maybe we don't want to apply those liberal settings to the whole site. Allowing those large limits on any url could make it easier for denial of service attacks. Therefore it can be desirable to keep lower settings there and make more specific settings that apply only to the urls where we are expecting file uploads. Before we go into how to configure specific urls it would help to know which urls exist in mojoPortal that support file uploads. The following urls are used to upload files in mojoPortal and features that plug into mojoPortal that we know of. Custom features that you make yourself or third party features may have their own urls that need to support file uploads.

/Services/FileService.ashx is the main url used for uploads in the file managers and when uploading files from the wysiwyg editors
/Blog/upload.ashx handles media attachment uploads for blog posts
/FolderGallery/upload.ashx handles uploads for the Folder Gallery feature
/ImageGallery/upload.ashx handles uploads for the Image Gallery feature
/SharedFiles/upload.ashx handles uploads for the Shared Files feature
/XmlXsl/uploader.ashx handles uploads for the Xml/Xsl feature
/WebStore/upload.ashx handles uploadin product files for the WebStore feature
/FormWizard/upload.ashx handles uploads for Form Wizard Pro

Note also that if you are supporting legacy browsers like IE 6, our javascript file uploader which normally posts to a service url degrades to the standard <asp:FileInput and in this case the file posts to whatever page the input is on, so it could be on any url where a feature exists that does uploads. For example if you have page with the url /ourfiles and it has an instance of Shared Files feature on it and you have a user that is in a role allowed to upload to the Shared Files instance on that page and he is using IE 6 to do so, then it will not use our javascript uploader but will postback the file to the /ourfiles url along with the rest of the page postback.
Therefore if you need to support user uploading from IE 6 or other legacy browsers then you probably should just use the general settings at top of this page instead of configuring specific urls.

There are 2 ways that you can configure the needed settings for specific urls. The first way is to add the settings within the main Web.config file within the existing <configuration> element you would add location elements something like this to configure the Shared Files feature:

<location path ="SharedFiles/upload.ashx">
    <system.web >
      <httpRuntime requestValidationMode="2.0" maxRequestLength="1048576" executionTimeout="3600" maxUrlLength="560" maxQueryStringLength="2048" />
    </system.web>
    <system.webServer>
    <security>
      <requestFiltering>
        <requestLimits maxAllowedContentLength="1073741824"/>
      </requestFiltering>
    </security>
    </system.webServer>
  </location>
  
The other way is to make a new web.config file and put it in the /SharedFiles folder. The content of the new web.config would be like this:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<location path ="upload.ashx">
<system.web >
  <httpRuntime requestValidationMode="2.0" maxRequestLength="1048576" executionTimeout="3600" maxUrlLength="560" maxQueryStringLength="2048" />
</system.web>
<system.webServer>
<security>
  <requestFiltering>
    <requestLimits maxAllowedContentLength="1073741824"/>
  </requestFiltering>
</security>
</system.webServer>
</location>
</configuration>

Note that the location path changed from SharedFiles/upload.ashx in the main Web.config to just upload.ashx in the new web.config file that is in the SharedFiles folder. The path is relative to the location of the web.config.

This second approach of using extra Web.config files in the folders where you want to support upload requests has the advantage of less work when you upgrade to a new version of mojoPortal because you should always use the new Web.config file that ships with mojoPortal, so if you out extra settings there you would need to restore those customizations to the new Web.config file. We don't ship any web.config files in other folders of mojoPortal or its features so there is no risk of them being overwritten during upgrades.

Legacy Information for versions of mojoPortal Older than 2.3.9.7

In version 2.3.9.7 we removed all use of NeatUpload from mojoPortal. The information below applies only to versions of mojoPortal older than that.

There are a number of features in mojoPortal content management system which allow for uploading files, however the maximum file size that can be uploaded depends upon configuration. In addition to the information on this page, file uploads can be limited by available disk space. Some hosting providers give you a certain amount of disk space but you must allocate it to your sites in order for it to be available. So in addition to settings mentioned on this page you may need to look around in your hosting control panel for information about available space and allocation of that space to your site(s).

Overview

When running in Full Trust (and using the Web.config file configured for full trust), mojoPortal uses NeatUpload and the file size limits are controlled by the NeatUpload section in Web.config.

Note that we ship 2 versions of Web.config, one is configured for Medium Trust and has NeatUpload disabled, the other is for Full Trust hosting and has NeatUpload enabled. The only difference between the files is whether NeatUpload is enabled. NeatUpload provides a nice progress bar during uploads but it only works in Full Trust hosting. If you see a progress bar when uploading then you are using NeatUpload if you don't then you are not.

<neatUpload xmlns="http://www.brettle.com/neatupload/config/2008"

useHttpModule="true"

maxNormalRequestLength="4096"

maxRequestLength="2097151"

multiRequestUploadHandlerUrl="~/NeatUpload/MultiRequestUploadHandler.ashx"

maxUploadRate="300"

></neatUpload>

Whereas, when running in Medium Trust NeatUpload is disabled and file upload limits are controlled by the httpRuntime settings like this:

<httpRuntime maxRequestLength="2097151" executionTimeout="3600"  />

Note that executionTimeout is relevant even when you are using NeatUpload

http://msdn.microsoft.com/en-us/library/e1f13641.aspx

IIS 7

If you use IIS7 you also have to do the following (see discussion at http://forums.iis.net/p/1108662/1702390.aspx):

at an elevated (run as admin) command prompt enter:

%windir%\system32\inetsrv\appcmd set config "MySite/MyApp" -section:requestFiltering -requestLimits.maxAllowedContentLength:104857600 -commitpath:apphost

you can verify that the setting was inserted OK by doing and checking out the output:

%windir%\system32\inetsrv\appcmd list config "MySite/MyApp" -section:requestFiltering

the command is changing the maxAllowedContentLength request limit that IIS7 requestFiltering (the replacement for urlscan) has introduced

NeatUpload documentation also mentions the following alternative regarding the IIS7 issue:

(Optional) To allow larger uploads than the 30MB default used by IIS7, add the following to your Web.config under the configuration/system.webServer/security/requestFiltering section:

 <requestLimits maxAllowedContentLength="size_in_bytes"></requestLimits>

Example:

<system.webServer>
        <security>
            <requestFiltering><requestLimits maxAllowedContentLength="262144000" /></requestFiltering>

<!-- maxAllowedContentLength is in bytes. Defaults to 30,000,000 -->
        </security>
    </system.webServer>

Note that for such a change to be allowed, you or your hosting provider might need to change the machine's %SystemRoot%/system32/inetserv/config/applicationHost.config file such that the overrideModeDefault attribute for the requestFiltering section is Allow instead of Deny.

Additional Resources:

http://msdn.microsoft.com/en-us/library/aa479405.aspx

http://aspnetresources.com/articles/dark_side_of_file_uploads.aspx

Created by Joe Audette on Nov 27, 2009
Last Modified by Joe Audette on Jan 23, 2014