From d21e056faa3b20061422d5520443360c9747bc48 Mon Sep 17 00:00:00 2001 From: Gregory Man Date: Thu, 14 Aug 2008 11:50:45 +0300 Subject: [PATCH] Implemented S3 url foramt switcher. Include host/path switch and http/https switch [#19 state:resolved] --- lib/paperclip/storage.rb | 26 +++++++++++++++++++++++++- test/storage_test.rb | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/lib/paperclip/storage.rb b/lib/paperclip/storage.rb index 9c8095c..8d8b446 100644 --- a/lib/paperclip/storage.rb +++ b/lib/paperclip/storage.rb @@ -92,18 +92,34 @@ module Paperclip # to interpolate. Keys should be unique, like filenames, and despite the fact that # S3 (strictly speaking) does not support directories, you can still use a / to # separate parts of your file name. + # * +url_format+: [:path | :host] (dafult: ':path') This is way how paperclip will generate + # paths to accsses your's files. S3 support to kinds of paths: + # path: http://s3.amazonaws.com/yours_bucket_name" + # host: http://yours_bucket_name.amazonaws.com + # Reead more here: http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?VirtualHosting.html + # * +use_https+ [:true | :false] (default: ':true') This determine if you want to use https + # to accsses yours files. module S3 def self.extended base require 'right_aws' base.instance_eval do @bucket = @options[:bucket] + @url_format = @options[:url_format] || :path + @use_https = @options[:use_https] || :true @s3_credentials = parse_credentials(@options[:s3_credentials]) @s3_options = @options[:s3_options] || {} @s3_permissions = @options[:s3_permissions] || 'public-read' @url = ":s3_url" end + base.class.interpolations[:s3_url] = lambda do |attachment, style| - "https://s3.amazonaws.com/#{attachment.bucket_name}/#{attachment.path(style).gsub(%r{^/}, "")}" + prefix = attachment.use_https? ? 'https' : 'http' + if attachment.use_subdomain_url_format? + url = "#{prefix}://#{attachment.bucket_name}.amazonaws.com" + else + url = "#{prefix}://s3.amazonaws.com/#{attachment.bucket_name}" + end + url += "/#{attachment.path(style).gsub(%r{^/}, "")}" end ActiveRecord::Base.logger.info("[paperclip] S3 Storage Initalized.") end @@ -121,6 +137,14 @@ module Paperclip def bucket_name @bucket end + + def use_subdomain_url_format? + @url_format == :host + end + + def use_https? + @use_https != :false + end def parse_credentials creds creds = find_credentials(creds).stringify_keys diff --git a/test/storage_test.rb b/test/storage_test.rb index e5ae2e7..1ecac6f 100644 --- a/test/storage_test.rb +++ b/test/storage_test.rb @@ -60,7 +60,29 @@ class StorageTest < Test::Unit::TestCase should "not be extended by the Filesystem module" do assert ! Dummy.new.avatar.is_a?(Paperclip::Storage::Filesystem) end - + + context "when assigned will generate right paths" do + should "generate path based url by default" do + rebuild_model_for_paths_testing + assert_match %r{^https://s3\.amazonaws\.com/testing/avatars/original/5k\.png}, @dummy.avatar.url + end + + should "generate path based url by default if use_http set to :false" do + rebuild_model_for_paths_testing(:use_https => :false) + assert_match %r{^http://s3\.amazonaws\.com/testing/avatars/original/5k\.png}, @dummy.avatar.url + end + + should "generate host based url using https if :url_format set to :host" do + rebuild_model_for_paths_testing(:url_format => :host) + assert_match %r{^https://testing\.amazonaws\.com/avatars/original/5k\.png}, @dummy.avatar.url + end + + should "generate host based url using http if :url_format set to :host and use_http set to :false" do + rebuild_model_for_paths_testing(:url_format => :host, :use_https => :false) + assert_match %r{^http://testing\.amazonaws\.com/avatars/original/5k\.png}, @dummy.avatar.url + end + end + context "when assigned" do setup do @file = File.new(File.join(File.dirname(__FILE__), 'fixtures', '5k.png')) @@ -150,4 +172,18 @@ class StorageTest < Test::Unit::TestCase end end end + private + def rebuild_model_for_paths_testing(options={}) + params = {:storage => :s3, + :bucket => "testing", + :path => ":attachment/:style/:basename.:extension", + :s3_credentials => { + 'access_key_id' => "12345", + 'secret_access_key' => "54321" + }}.merge(options) + rebuild_model(params) + @file = File.new(File.join(File.dirname(__FILE__), 'fixtures', '5k.png')) + @dummy = Dummy.new + @dummy.avatar = @file + end end -- 1.5.4.3