Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't HttpPostedFile perform as advertised and buffer downloads to disk rather than memory?

Tags:

I am uploading large files to an ASP.NET server using a standard HTML <input> control posting multipart-form data. This is an ASP.NET MVC application.

According to MSDN, the HttpPostedFile class buffers to disk out of the box:

"Files are uploaded in MIME multipart/form-data format. By default, all requests, including form fields and uploaded files, larger than 256 KB are buffered to disk, rather than held in server memory."

I assume this means that when I access HttpPostedFileBase in my controller, that when I access the HttpPostedFileBase's InputStream property, I can write the file buffer somewhere without having to worry about the server running out of memory, which is obviously an unworkable solution.

Here's a bit of pseudocode for how I'm handling each of the incoming files from HttpPostedFileBase.

for(var i = 0; i< Request.Files.Count;i++)
{
    var fileBase = Request.Files[i];
    if (fileBase.ContentLength == 0)
    {
        continue;
    }

    // One thread per file
    ThreadPool.QueueUserWorkItem(state =>
    {
        // Read from fileBase.InputStream
    }, 
    null);
}

My web.config's httpRuntime block looks like this:

<httpRuntime
  executionTimeout="1200"
  requestLengthDiskThreshold="2097151"
  maxRequestLength="2097151"
  useFullyQualifiedRedirectUrl="false"
  minFreeThreads="8"
  minLocalRequestFreeThreads="4"
  appRequestQueueLimit="100" />

My implementation works, multiple files are uploaded as expected, except that the same amount of memory required to buffer the entire payload is consumed by the server. I have to assume that the InputStream is buffering everything. When I upload more files than I have memory, it predictably crashes with an OutOfMemoryException. Here's an image of the memory spike when uploading an 800mb file.

alt text

I know I could use a Flash/Silverlight widget or write a custom HttpModule to intercept uploads and handle them myself, but the current requirement would work flawlessly if HttpPostedFile did what MSDN says it does (or I'm doing it wrong).

like image 420
Daniel Crenna Avatar asked Jul 18 '09 16:07

Daniel Crenna


1 Answers

why do you set

requestLengthDiskThreshold="2097151"

in the configuration? Doesn't that force the server to keep all uploads in RAM rather than buffering to disk?

like image 82
chris166 Avatar answered Oct 18 '22 15:10

chris166