{"id":127,"date":"2007-05-27T22:13:45","date_gmt":"2007-05-27T10:13:45","guid":{"rendered":"http:\/\/craig.dubculture.co.nz\/blog\/2007\/05\/27\/ways-to-get-an-upload-progress-bar-in-a-ruby-on-rails-application\/"},"modified":"2007-09-10T10:58:00","modified_gmt":"2007-09-09T22:58:00","slug":"ways-to-get-an-upload-progress-bar-in-a-ruby-on-rails-application","status":"publish","type":"post","link":"http:\/\/craig.dubculture.co.nz\/blog\/2007\/05\/27\/ways-to-get-an-upload-progress-bar-in-a-ruby-on-rails-application\/","title":{"rendered":"Ways to get an upload progress bar in a Ruby on Rails application"},"content":{"rendered":"<p>Ready?<\/p>\n<ul>\n<li>The \"<a href=\"http:\/\/sean.treadway.info\/demo\/upload\/\">Sean Treadway method<\/a>\"  Requires fcgid and Apache.  Pretty much superseded by...<\/li>\n<li><a href=\"http:\/\/mongrel.rubyforge.org\/docs\/upload_progress.html\">Mongrel's upload progress<\/a> extension.  Your upload form launches an AJAX updater that says \"How far thru' the file am I, foo'?\" every N seconds.  However, because your upstream bandwidth is hosed (especially on 128Kbps DSL), it tends to take N+15 seconds to get a response.  Can be notoriously hard to make go.  (Hint, try sudo gem cleanup, and not running your code as root, or not being on a VPN to the server.  Any combination of these might have helped.)\n<ul>\n<li>Mongrel tends to be run behind a load balancing proxy.  These <a href=\"http:\/\/rubyforge.org\/pipermail\/mongrel-users\/2006-November\/002132.html\">sometimes buffer requests<\/a> so you end up sending 100% of the file before the server knows a file is coming.  A solution appears to be to run another Mongrel instance on another port to accept uploads.  This is a solution that lots of people suggest but no-one actually says \"I do this, here's how\".<\/li>\n<li>Apache users might need to use <a href=\"http:\/\/httpd.apache.org\/docs\/2.0\/mod\/mod_proxy_http.html\">mod_proxy_html<\/a> to rewrite your links, if your JS doesn't have URLs generated with Rails' url_to helpers.  This may or may not exist for Apache 2.2.<\/li>\n<li>I have everything working up to this point, but the progress doesn't actually display for me using Apache 2.2 as my load balancer.<\/li>\n<\/ul>\n<\/li>\n<li>There is a <a href=\"http:\/\/four.livejournal.com\/747302.html\">Mongrel Upload Progress with Streaming<\/a> extention, based on <a href=\"http:\/\/www.sibsoft.net\/xupload.html\">XUpload<\/a>. The <a href=\"http:\/\/four.livejournal.com\/680111.html\">author<\/a> sounds like he's been working on making it use JSON rather than Javascript, but there's not been a release since.  May or may not work with Safari.<\/li>\n<li>Use <a href=\"http:\/\/upload.lighttpd.net\/upload.html\">lighttpd and it's upload progress engine<\/a>.  I presume you'd just use it to proxy Mongrel.  (Not really for me, as I'm somewhat tied to Apache on my SSL port.)<\/li>\n<li><a href=\"http:\/\/brainspl.at\/articles\/2006\/10\/18\/merb-is-useable-and-a-gem\">Merb<\/a>, which seems to be Ruby off Rails.  Again, it is used as a secondary server that just accepts uploads, but I have no idea how you'd run a merb and hand uploads to <a href=\"http:\/\/boxroom.rubyforge.org\">your Rails application<\/a>.  Comments to this welcome.<\/li>\n<li><strike>Shockwave<\/strike> <strike>Macromedia<\/strike> Adobe Flash, which does all the upload progress client-side. There's a nice degrades-to-Javascript engine called <a href=\"http:\/\/swfupload.mammon.se\/\">SWFUpload<\/a> to try here.<\/li>\n<\/ul>\n<p>Confused yet?<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ready? The \"Sean Treadway method\" Requires fcgid and Apache. Pretty much superseded by... Mongrel's upload progress extension. Your upload form launches an AJAX updater that says \"How far thru' the file am I, foo'?\" every N seconds. However, because your upstream bandwidth is hosed (especially on 128Kbps DSL), it tends to take N+15 seconds to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[66,68],"tags":[55,54,48],"_links":{"self":[{"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/posts\/127"}],"collection":[{"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/comments?post=127"}],"version-history":[{"count":0,"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/posts\/127\/revisions"}],"wp:attachment":[{"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/media?parent=127"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/categories?post=127"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/craig.dubculture.co.nz\/blog\/wp-json\/wp\/v2\/tags?post=127"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}