Created
February 17, 2012 06:02
-
-
Save elvuel/1851088 to your computer and use it in GitHub Desktop.
Paperclip + valums’s file-uploader problem on Heroku
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FIXED: See the next file for a working RawFileUpload class. | |
UPDATE: Heroku uses thin server and I use webrick. When I tried thin on my local machine, it didn't work. | |
So, the conclusion is there is some difference between webrick and thin that's causing the problem. | |
This file is related to this blog post: | |
http://mooooooooooo.wordpress.com/2010/12/03/paperclip-valums%E2%80%99s-file-uploader-and-middleware-continued/ | |
The code in the blog post works fine on my local machine but not on Heroku. | |
# In my photos_controller.rb: | |
def create | |
# print params to log | |
puts "photo create params: " + params.inspect | |
if @photo.save | |
#... | |
end | |
end | |
The output for the params line in my local machine: | |
photo create params: {"photo"=>{"image"=>#<ActionDispatch::Http::UploadedFile:0x00000003fb1910 @original_filename="Desert.jpg", @content_type=image/jpeg, @headers=nil, @tempfile=#<File:/tmp/raw-upload.20110711-3169-yigmmi>>}, "authenticity_token"=>"0yvXnzV8fnsP24eAxJFH4aViG4nBMydB6O+dZ7HdY+4=", "qqfile"=>"Desert.jpg", "action"=>"create", "controller"=>"photos", "venue_id"=>"test"} | |
And same thing on Heroku: | |
photo create params: {"authenticity_token"=>"2WiyKzNC10V8op6ryCRA24zdqjvWPF7HQgsv9L95zL0=", "qqfile"=>"Desert.jpg", "action"=>"create", "controller"=>"photos", "venue_id"=>"foo"} | |
Clearly something is wrong there. | |
Here's my 'rake middleware' output on local machine: | |
use ActionDispatch::Static | |
use ActionDispatch::Static | |
use Rack::Lock | |
use ActiveSupport::Cache::Strategy::LocalCache | |
use Rack::Runtime | |
use Rails::Rack::Logger | |
use ActionDispatch::ShowExceptions | |
use ActionDispatch::RemoteIp | |
use Rack::Sendfile | |
use ActionDispatch::Callbacks | |
use ActiveRecord::ConnectionAdapters::ConnectionManagement | |
use ActiveRecord::QueryCache | |
use ActionDispatch::Cookies | |
use ActionDispatch::Session::CookieStore | |
use ActionDispatch::Flash | |
use ActionDispatch::ParamsParser | |
use Rack::MethodOverride | |
use ActionDispatch::Head | |
use ActionDispatch::BestStandardsSupport | |
use Warden::Manager | |
use RawFileUpload | |
use OmniAuth::Strategies::Facebook | |
run MyApp::Application.routes | |
And same thing on Heroku: | |
use ActionDispatch::Static | |
use ActionDispatch::Static | |
use Rack::Lock | |
use Rack::Runtime | |
use Rails::Rack::Logger | |
use ActionDispatch::ShowExceptions | |
use ActionDispatch::RemoteIp | |
use Rack::Sendfile | |
use ActionDispatch::Callbacks | |
use ActiveRecord::ConnectionAdapters::ConnectionManagement | |
use ActiveRecord::QueryCache | |
use ActionDispatch::Cookies | |
use ActionDispatch::Session::CookieStore | |
use ActionDispatch::Flash | |
use ActionDispatch::ParamsParser | |
use Rack::MethodOverride | |
use ActionDispatch::Head | |
use ActionDispatch::BestStandardsSupport | |
use Warden::Manager | |
use RawFileUpload | |
use OmniAuth::Strategies::Facebook | |
run MyApp::Application.routes | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'mime/types' | |
class RawFileUpload | |
def initialize(app) | |
@app = app | |
end | |
def call(env) | |
if raw_file_post?(env) | |
convert_and_call(env) | |
else | |
@app.call(env) | |
end | |
end | |
private | |
def raw_file_post?(env) | |
env['HTTP_X_FILE_NAME'] && | |
env['CONTENT_TYPE'] == 'application/octet-stream' && | |
env['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' | |
end | |
def convert_and_call(env) | |
# sometimes env['rack.input'] is Tempfile, sometimes StringIO => make it always StringIO | |
input = env['rack.input'] | |
if input.is_a? Tempfile | |
input = StringIO.new(input.read) | |
end | |
env['rack.input'] = input | |
# convert to UTF8 | |
tempfile = Tempfile.new('raw-upload.') | |
input.each do |chunk| | |
tempfile << chunk.force_encoding('UTF-8') | |
end | |
tempfile.flush | |
tempfile.rewind | |
multipart_hash = { | |
:image => { | |
:filename => env['HTTP_X_FILE_NAME'], | |
:type => MIME::Types.type_for(env['HTTP_X_FILE_NAME']).first, | |
:tempfile => tempfile | |
} | |
} | |
env['rack.request.form_input'] = env['rack.input'] | |
env['rack.request.form_hash'] ||= {} | |
env['rack.request.query_hash'] ||= {} | |
env['rack.request.form_hash']['photo'] = multipart_hash | |
env['rack.request.query_hash']['photo'] = multipart_hash | |
@app.call(env) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment