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
精彩评论