Upload Progress / Xupload

HTTP upload progress bars are rather obfuscated- they typically involve a process running on the server keeping track of the size of the tempfile that the HTTP server is writing to, then on the client side an AJAX call is made every couple seconds to the server during the upload to ask for the progress of the upload.

This is pretty ridiculous. Making million of AJAX requests (which probably slow down your upload) just to poll the server on this trivial fact? Your browser knows how much data you've sent - the best solution would be to have this information stored in the DOM. As far as I can tell, this is not happening.

Xupload (Discontinued product) is a beautiful hack to do this without AJAX. When you start your download it streams an HTML back back to you slowly. The first part of the HTML is normal, with elements defining the progress bar, javascript, etc., this comes all at once. Then comes information about your upload in progress incrementally as javascript calls:

    <script>SP(4,0,0,0,0);</script>     <script>SP(8,0,0,0,0);</script>     <script>SP(8,1,8,0,2);</script>     <script>SP(12,1,12,0,1);</script>

These javascript calls update the progress bar defined above. (SP($size,$time,$speed,$files_uploaded,$time_left)) Basically: you're loading a single page and as it loads the progress bar moves.

Can we do this in Rails? I've been experimenting with both Sean Treadway's UploadProgress and mongrel_upload_progress but have had no luck yet.

Ry

I’m using SWFUpload (http://labb.dev.mammon.se/swfupload/) in one of the apps I’m developing. It uses a small Flash object to send the file and provide progress. It’s working fine once you change the hardcoded path in mmSWFUpload.js to “/javascripts/SWFUpload/upload.swf”.

However, there are some issues:

  1. It doesn’t honor the Rails session_id cookie for the moment and thus generates a new session. If you’re trying to use it in a private section (using acts_as_authenticated, acl2, …) of your site, you’ll have to exclude the upload method from your before_filter. This is a minor security issue.

  2. You can use GET parameters, but can’t add additional POST parameters to the upload script such as an article_id, company_id, … to the request. This is a trivial nuisance, but it means you won’t be able to test for request.post in your controller.

  3. This is the biggest problem actually (at least for me): the content_type of the Tempfile is always set to application/octet-stream (generic binary file). I’m using acts_as_attachment and it uses the MIME type to determine whether the file is an image or just a non-image file. This has some serious implications if you’re using SWFUpload and acts_as_attachment to handle images (resize them, generate thumbnails). These operations will just (silently) fail. I could hack into acts_as_attachment and determine the filetype by using the file extension, but I would like to avoid this.

I’ve just sent these remarks to the author of SWFUpload a few hours ago, I seriously hope these minor flaws can be fixed, because this is the most reliable and easiest “AJAX upload” method I’ve tried (the others require server-side configs that aren’t available on shared hosts).

Best regards

Peter De Berdt