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 (http://www.sibsoft.net/xupload.html) 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