开发者

Getting alternating HTTP Errors and IO Errors with Rails 3, Paperclip, and Uploadify

I'm getting some truly bizarre behavior. Essentially, when I go to batch upload files, each file will alternate, starting with an HTTP Error, then following with an IO error on the next file. Even more interesting is that this doesn't always happen in Chrome -- sometimes, the HTTP errors don't appear and each alternating file uploads successfully, (with every other getting an IO Error). But in firefox, we get the alternating errors no matter what. See the following screenshot:

http://i.imgur.com/0mHWS.png

There are no errors in my logs and everything seems as it should. Below are the relevant pieces of my code, as well as a snippet from my log file.

I know there's a lot below, but I'm pretty desperate for a solution and I'm at my wits end. Thanks to anyone who can offer any help!

app/middleware/flash_session_cookie_middleware.rb

require 'rack/utils'

class FlashSessionCookieMiddleware
  def initialize(app, session_key = '_session_id')
    @app = app
    @session_key = session_key
  end

  def call(env)
    if env['HTTP_USER_AGENT'] =~ /^(Adobe|Shockwave) Flash/
      req = Rack::Request.new(env)
      env['HTTP_COOKIE'] = [ @session_key,
                             req.params[@session_key] ].join('=').freeze unless req.params[@session_key].nil?
      env['HTTP_ACCEPT'] = "#{req.params['_http_accept']}".freeze unless req.params['_http_accept'].nil?
    end

    @app.call(env)
  end
end

session_store.rb

Mysite::Application.config.session_store :cookie_store, :key => '_mysite_session'

# Use the database for sessions instead of the cookie-based default,
# which shouldn't be used to store highly confidential information
# (create the session table with "rails generate session_migration")
# Mysite::Application.config.session_store :active_record_store
Rails.application.config.middleware.insert_before(
  ActionDispatch::Session::CookieStore,
  FlashSessionCookieMiddleware,
  Rails.application.config.session_options[:key]
)

photo.rb

require 'paperclip_processors/watermark'
require 'paperclip_processors/ao'

class Photo < ActiveRecord::Base
belongs_to :user
belongs_to :owner, :polymorphic => true
belongs_to :parentcat, :polymorphic => true
has_many :comments, :as => :owner, :dependent => :destroy

has_attached_file :image, 
                :styles => { :admin_thumb => {
                              :geometry => "48x48#",
                              :processors => [:ao]
                              },
                            :gallery_thumb => {
                              :geometry => "106x106#",
                              :processors => [:ao]
                              },
                            :hero => {  
                              :processors => [:watermark],
                              :geometry => "568",
                              :watermark_path => "#{Rails.root}/public/images/watermark_250.png", 
                              :position => 'SouthWest',
                              },
                            :listing => {  
                              :processors => [:ao],
                              :geometry => "150x150#"
                            }
                           },
               :storage => :s3,
               :s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
               :path => "/:style/:id/:filename"
end

batch_upload.html.erb

<% content_for :javascript do %>
    <%= javascript_include_tag "uploadify/swfobject.js" %>
    <%= javascript_include_tag "uploadify/jquery.uploadify.v2.1.4.min.js" %>
 <% end %>

<% content_for :stylesheets do %>
    <%= stylesheet_link_tag "uploadify.css" %>
 <% end %>


<script type="text/javascript">
<%- session_key = Rails.application.config.session_options[:key] -%>

  $(function() {  
    // Create an empty object to store our custom script data
    var uploadify_script_data = {};

    // Fetch the CSRF meta tag data
    var csrf_token = $('meta[name=csrf-token]').attr('content');
    var csrf_param = $('meta[name=csrf-param]').attr('content');

    // Now associate the data in the config, encoding the data safely
    uploadify_script_data[csrf_param] = encodeURI(csrf_token);

    // Associate the session information
    uploadify_script_data['<%= session_key %>'] = '<%= cookies[session_key] %>';    
    uploadify_script_data['gallery_id'] = <%= @gallery.id %>

     // Configure Uploadify
    $('#photo_image').uploadify ({
      'script'          : '<%= batch_create_gallery_path(@gallery) %>',
      'uploader'        : '/javascripts/uploadify/uploadify.swf',
      'multi'           : true,
      'auto'            : true,
      'scriptData'      : uploadify_script_data,
      'cancelImg'       : '/images/cancel.png'  //take care that the image is accessible
    });
  });
</script>

<h2><%= @page_title = "Batch Upload for #{@gallery.title}" %></h2>

<h3>Upload a Photo</h3>
<% form_for Photo.new(:owner_id => @gallery.id), :html => {:multipart => true} do |f| %>
    <div class="field imagefield">
        <%= f.label :image, 'Image upload' %>
        <%= f.file_field :image %>
    </div>
  <div class="actions">
    <%= f.submit "Batch Upload" %>
  </div>
<% end %>

gallery_controller.rb

 def batch_create
     @gallery = Gallery.find(params[:gallery_id])
     params[:Filedata].content_type = MIME::Types.type_for(params[:Filedata].original_filename).to_s

     @photo = @gallery.photos.build
     @photo.title = params[:Filename]
     @photo.image = params[:Filedata]

     if @photo.save!
       render :json => { 'status' => 'success'  }
     else
       render :json => { 'status' => 'error'  }
     end
 end

a log snippet of one of the batch upload creations

Started POST "/galleries/199/batch_create" for 127.0.0.1 at Thu Aug 04 02:58:33 -0400 2011
  Processing by GalleriesController#batch_create as HTML
  Parameters: {"Filename"=>"1967_MercBenz_250SL_31.jpg", "_mysite_session"=>"BAh7CSIQX2NzcmZfdG9rZW4iMWtRSm1iOWFuZHFZbXNjcmZaTWVRdUowU3hjVGZDc0dBai9CKzF1MStWaVk9Ig9zZXNzaW9uX2lkIiUwMDc2NTVjY2IwNDE5ZmY4YzQ4OTA3Mzk4ODQzM2FhYyIZd2FyZGVuLnVzZXIudXNlci5rZXlbCCIJVXNlclsGaQciIiQyYSQxMCR6V0V4NXNDMGRNbkRhb3l4Z01oOE5PIgpmbGFzaElDOiVBY3Rpb25EaXNwYXRjaDo6Rmxhc2g6OkZsYXNoSGFzaHsGOgtub3RpY2UiR0dhbGxlcnkgd2FzIHN1Y2Nlc3NmdWxseSBjcmVhdGVkLiBZb3UgbWF5IG5vdyBiYXRjaCB1cGxvYWQgcGhvdG9zLgY6CkB1c2VkbzoIU2V0BjoKQGhhc2h7AA==--e1fea6f4d32b97a12368146c4b0502c6df1b67dc", "folder"=>"/galleries/199/", "authenticity_token"=>"kQJmb9andqYmscrfZMeQuJ0SxcTfCsGAj/B 1u1 ViY=", "Upload"=>"Submit Query", "id"=>"199", "Filedata"=>#<ActionDispatch::Http::UploadedFile:0x104440340 @tempfile=#<File:/var/folders/gr/px9hb0ns3w13t4k487k8cgzc0000gn/T/RackMultipart20110804-71738-bzeny5-0>, @content_type="application/octet-stream", @original_filename="1967_MercBenz_250SL_31.jpg", @headers="Content-Disposition: form-data; name=\"开发者_如何学PythonFiledata\"; filename=\"1967_MercBenz_250SL_31.jpg\"\r\nContent-Type: application/octet-stream\r\n">, "gallery_id"=>"199"}
  SQL (0.1ms)  BEGIN
[paperclip] Saving attachments.
  SQL (0.1ms)  COMMIT
Geokit is using the domain: localhost
  SQL (7.7ms)  SHOW TABLES
  Gallery Load (0.2ms)  SELECT `galleries`.* FROM `galleries` WHERE `galleries`.`id` = 199 LIMIT 1
  SQL (0.4ms)  SHOW TABLES
  SQL (0.6ms)  SHOW TABLES
Completed   in 370ms
Redirected to http://localhost:3000/


Have you tried to eliminate S3 as the source of the problem? The consistency of this issue makes me feel like the uploadify script isn't the actual source of the problem. Also, try :s3_credentials => "#{Rails.root}/config/s3.yml" instead.


I ended up scrapping this solution entirely and using Ryan Bates' jQuery file uploader: http://railscasts.com/episodes/381-jquery-file-upload

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜