Estaba implementando para SugarStats.com una funcionalidad que permitiera a los usuarios hacer upload de archivos con sus mediciones de glucosa (estos archivos son generados por los medidores de glucosa en formato csv).

Las cosas funcionaban bien en Firefox y Internet Explorer, pero con Safari tuve varios problemas, uno de ellos tuvo que ver con un bug de Safari que hace que de vez en cuando se "cuelgue" al hacer upload de un archivo.

Al parecer la solución tenía que ver con el hecho agregarle el header http "Connection: close" a la página que contenga el formulario para el upload del archivo.

Hurgando un poco más me conseguí con un post titulado "Note To Self: Prevent Uploads Hanging In Safari", donde explican como en Basecamp previenen la falla de Safari en los uploads.

Mi código quedó asi:

close_connection_controller.rb

RUBY:
  1. # A pretty little hack to make uploads not hang in Safari.
  2. # The index action is called (via Ajax)
  3. # immediately before the upload is submitted.
  4. # The index action just returns an empty document with the "Connection: close"
  5. # header, telling Safari to close the active connection. A hack, but
  6. # effective.
  7. class CloseConnectionController <ApplicationController
  8.   def index
  9.     headers['Connection'] = 'close'
  10.     render :nothing => true
  11.   end
  12. end

app/views/meter_uploads/new.rhtml (formulario usado para el upload del archivo)

PHP:
  1. ...
  2. <script>
  3. function closeKeepAlive() {
  4.   if (/AppleWebKit|MSIE/.test(navigator.userAgent)) {
  5.     new Ajax.Request("/close_connection/", { asynchronous:false });
  6.   }
  7. }
  8. </script>
  9. <% form_for :meter_upload, :url => meter_uploads_path(:user_id => @user.id), :html => { :multipart => true, :onsubmit => 'closeKeepAlive();' } do |f| -%>
  10. ...

Y como creemos en el behavior driven development :-) el spec del controller es
close_connection_controller_spec.rb

RUBY:
  1. require File.dirname(__FILE__) + '/../spec_helper'
  2.  
  3. describe CloseConnectionController, "index action" do
  4.  
  5.   it "should return a document with Connection: close header" do
  6.     get 'index'
  7.     response.headers['Connection'].should == 'close'   
  8.   end
  9.  
  10.   it "should return an empty document" do
  11.     # due a bug in safari a render :nothing => true,
  12.     # is not really empty instead is a space
  13.     get 'index'
  14.     response.body.should == ' '
  15.   end
  16. end


RSS feeds

Suscríbete a nuestros RSS Feeds