tldr: Browsers need better ways of handling large HTTP requests – possibly with an "upload monitor" (Scroll to the last paragraph for a little more)
I think that we’ve all come across this before: you go to a website, select a file to upload, hit “Submit” and then wait forever and hope that the file you’ve selected has actually made it to the server on the other side. Recently, while building an ASP.NET MVC application for a client, I decided that I wanted a better experience for my end users, especially since this application is to be externally hosted from the client, who is the primary user. As such, I didn’t want the client to be waiting and hoping that the documents and images that they are uploading are actually reaching the other side.
With a quick bit of searching, I found SWFUpload – which appeared to have all the features that I wanted: a nice interface, multiple file uploads and very customisable. Having implemented SWFUpload into my application, I hit a major bug. As it turns out, SWFUpload was built using Flash, and Flash (being the wonderful Adobe application it is) only sends cookies from Internet Explorer, if at all. This meant that the uploading component would not use the same session as Firefox, and so would be redirected to the "log in" page instead of uploading the file. The suggested fix from SWFUpload didn’t work (apart from the various security exploits it introduced) and implementing my own SessionIDManager (to permit session id’s in the query string) failed due to ASP.NET’s SQL Membership Provider storing additional Authentication data in a separate cookie.
Luckily enough, Silverlight supports sending the cookies from the browser it is hosted in. Hoping for a simple, drop-in solution I was (again) severely disappointed. The Silverlight component I had chosen (Silverlight Multi File Uploader), as well as many others, send the file in the body of the HTTP request (instead of putting it in a mulitpart/form-data encoded POST header) and chunked the upload. This was greatly frustrating as I wanted to put the uploaded file straight into the database, without placing it temporarily on the file system. After some hacking of the Silverlight component, I was able to strip out the chunking code, but attempting to have the request use mulitpart/form-data failed due to Silverlight’s unusual (but rather logical) way of doing HTTP Requests. Silverlight relies on the browser sending the request and completing its headers (such as Content-Length). However, the Content-Length header is put before the Content-Type and this causes IIS (and, most likely, every other webserver) to ignore the POST variables. In short, I couldn’t have the file uploaded properly (ie appearing in the Request.Files array), but I could live with put it in the HTTP Request body (and access it via the Request.InputStream stream).