UPDATE @englandpost points out that newer versions of paperclip support the :s3_host_name option, see http://rubydoc.info/gems/paperclip/Paperclip/Storage/S3. Thanks @englandpost
So you have your European S3 bucket thinking how cool you can select buckets near where your customers live, you gem install paperclip aws_s3
and do the dances and the rails and the rituals and the cap production deploy
, and you get
The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint.
Not Fair!
The interblags reccomend you use gem install s3
instead, with appropriate monkeypatches for Paperclip::Storage::S3
, but you might end up with this:
The request signature we calculated does not match the signature you provided. Check your key and signing method.
I tried and I tried, honest, s3
just wouldn't play the signature game by amazon's rules ... couldn't get anything to work, until I stumbled on http://www.mail-archive.com/heroku@googlegroups.com/msg05407.html in which the great and goodly Dan Croak recommends you put this in config/environment.rb
:
AWS::S3::DEFAULT_HOST = "s3-eu-west-1.amazonaws.com"
Well lo and behold I was finally able to upload stuff, my pretty pictures are showing up in my AWS console.
But you're not done yet: you still need to generate the correct URL (my_model.my_attachment.url
) for your pictures and mp3s and videos and Large Objects and whatever your pushing up to the clouds there ... Paperclip::Storage::S3
kindly hard-codes "s3.amazonaws.com" for you, and it doesn't work.
Here's the fix:
# in config/initializers/something.rb
Paperclip.interpolates(:s3_eu_url) { |attachment, style|
"#{attachment.s3_protocol}://s3-eu-west-1.amazonaws.com/#{attachment.bucket_name}/#{attachment.path(style).gsub(%r{^/}, "")}"
}
# in your model
has_attached_file :image,
:storage => :s3,
:s3_credentials => "#{Rails.root}/config/s3.yml",
:path => "for/example/:id/:style.:extension",
:url => ":s3_eu_url"
This is a big song and dance to simply tell paperclip how to construct the s3 url. Left to itself, paperclip will replace your url setting with one of its own (":s3_path_url"
) if it doesn't match /^:s3.*url$/
. Hence, the interpolation above is called "s3_eu_url", you can write your own for singapore or whatever far-flung place you've dumped your bucket.
Dude are you serious???? You saved my day!! Thaaaaaanks!
ReplyDeleteGreat stuff. I've been looking for a solution for this all day.
ReplyDeleteThanks man! An answer difficult to find...
ReplyDeletewhat about singapure bukets
ReplyDeleteThanks a lot, was working around this for quite too long!
ReplyDeleteWhy it doesn't work with:
AWS::S3::Base.establish_connection!(
:access_key_id => '123',
:secret_access_key => 'XYZ',
:server => 's3-eu-west-1.amazonaws.com'
)
???
Their manual could be more explicit!
Thanks..
Thanks! You saved my day
ReplyDeleteMany thanks! Been banging my head to the wall for the last hour.
ReplyDeleteThanks! This tip helped a lot
ReplyDeleteThanks, worked beautifully!
ReplyDeleteOne small correction: I'm using Paperclip v2.4.0 and it requires "s3_protocol" being called with the "style" parameter.
Anyone got this working with paperclip 2.4.5?
ReplyDeleteAre you able to elaborate how to "s3_protocol" being called with the "style" parameter."
I have created storage module for Paperclip that uses official 'aws-sdk' gem. It supports all S3 locations from the box.
ReplyDeleteWorks well, using it in production projects myself.
https://github.com/igor-alexandrov/paperclip-aws
Gorgeous !! You made my day !!
ReplyDeletethaaaaank you!!!
ReplyDeleteThat worked for me, thanks!
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
Deletenow you need just specify s3_host_name *http://rubydoc.info/gems/paperclip/Paperclip/Storage/S3
ReplyDeletethankyou
ReplyDeletethank you.it is working very fine
ReplyDeleteUpdate, the latest version of paperclip handles most of this for you. All you need is to include:
ReplyDelete:url => ":s3_domain_url"
in your has_attached_file statement.
Thanks
ReplyDeleteIt was vey helpful :)