Commit 75f413da by Prem Sichanugrist

Use AWS::SDK instead of AWS::S3

The original commit came from @amazonwebservices and @trevorrowe in #579.
I had to revise the commit and make sure all the test cases are passing.
All credits still goes to those guys, thanks a lot!
parent 5f3b88d1
PATH
remote: .
specs:
paperclip (2.4.5)
activerecord (>= 2.3.0)
activesupport (>= 2.3.2)
cocaine (>= 0.0.2)
mime-types
GEM GEM
remote: http://rubygems.org/ remote: http://rubygems.org/
specs: specs:
activemodel (3.1.0) activemodel (3.1.2)
activesupport (= 3.1.0) activesupport (= 3.1.2)
bcrypt-ruby (~> 3.0.0)
builder (~> 3.0.0) builder (~> 3.0.0)
i18n (~> 0.6) i18n (~> 0.6)
activerecord (3.1.0) activerecord (3.1.2)
activemodel (= 3.1.0) activemodel (= 3.1.2)
activesupport (= 3.1.0) activesupport (= 3.1.2)
arel (~> 2.2.1) arel (~> 2.2.1)
tzinfo (~> 0.3.29) tzinfo (~> 0.3.29)
activesupport (3.1.0) activesupport (3.1.2)
multi_json (~> 1.0) multi_json (~> 1.0)
appraisal (0.3.8) appraisal (0.4.0)
bundler bundler
rake rake
arel (2.2.1) arel (2.2.1)
...@@ -23,13 +31,13 @@ GEM ...@@ -23,13 +31,13 @@ GEM
cucumber (>= 1.0.2) cucumber (>= 1.0.2)
rdiscount (>= 1.6.8) rdiscount (>= 1.6.8)
rspec (>= 2.6.0) rspec (>= 2.6.0)
aws-s3 (0.6.2) aws-sdk (1.2.1)
builder httparty (~> 0.7)
mime-types json (~> 1.4)
xml-simple nokogiri (>= 1.4.4)
uuidtools (~> 2.1)
bcat (0.6.2) bcat (0.6.2)
rack (~> 1.0) rack (~> 1.0)
bcrypt-ruby (3.0.1)
builder (3.0.0) builder (3.0.0)
capybara (1.1.1) capybara (1.1.1)
mime-types (>= 1.16) mime-types (>= 1.16)
...@@ -41,7 +49,6 @@ GEM ...@@ -41,7 +49,6 @@ GEM
childprocess (0.2.2) childprocess (0.2.2)
ffi (~> 1.0.6) ffi (~> 1.0.6)
cocaine (0.2.0) cocaine (0.2.0)
coderay (1.0.0)
cucumber (1.0.6) cucumber (1.0.6)
builder (>= 2.1.2) builder (>= 2.1.2)
diff-lcs (>= 1.1.2) diff-lcs (>= 1.1.2)
...@@ -65,31 +72,27 @@ GEM ...@@ -65,31 +72,27 @@ GEM
formatador (0.2.1) formatador (0.2.1)
gherkin (2.4.21) gherkin (2.4.21)
json (>= 1.4.6) json (>= 1.4.6)
httparty (0.8.1)
multi_json
multi_xml
i18n (0.6.0) i18n (0.6.0)
json (1.6.1) json (1.6.1)
json_pure (1.6.1) json_pure (1.6.1)
metaclass (0.0.1) metaclass (0.0.1)
method_source (0.6.5)
ruby_parser (>= 2.0.5)
mime-types (1.16) mime-types (1.16)
mocha (0.10.0) mocha (0.10.0)
metaclass (~> 0.0.1) metaclass (~> 0.0.1)
multi_json (1.0.3) multi_json (1.0.3)
multi_xml (0.4.1)
net-scp (1.0.4) net-scp (1.0.4)
net-ssh (>= 1.99.1) net-ssh (>= 1.99.1)
net-ssh (2.1.4) net-ssh (2.1.4)
nokogiri (1.5.0) nokogiri (1.5.0)
pry (0.9.6)
coderay (>= 0.9.8)
method_source (>= 0.6.5)
ruby_parser (>= 2.0.5)
slop (~> 2.1.0)
rack (1.3.3) rack (1.3.3)
rack-test (0.6.1) rack-test (0.6.1)
rack (>= 1.0) rack (>= 1.0)
rake (0.9.2) rake (0.9.2)
rdiscount (1.6.8) rdiscount (1.6.8)
rdoc (3.9.4)
rspec (2.6.0) rspec (2.6.0)
rspec-core (~> 2.6.0) rspec-core (~> 2.6.0)
rspec-expectations (~> 2.6.0) rspec-expectations (~> 2.6.0)
...@@ -99,21 +102,17 @@ GEM ...@@ -99,21 +102,17 @@ GEM
diff-lcs (~> 1.1.2) diff-lcs (~> 1.1.2)
rspec-mocks (2.6.0) rspec-mocks (2.6.0)
ruby-hmac (0.4.0) ruby-hmac (0.4.0)
ruby_parser (2.3.1)
sexp_processor (~> 3.0)
rubyzip (0.9.4) rubyzip (0.9.4)
selenium-webdriver (2.7.0) selenium-webdriver (2.7.0)
childprocess (>= 0.2.1) childprocess (>= 0.2.1)
ffi (>= 1.0.7) ffi (>= 1.0.7)
json_pure json_pure
rubyzip rubyzip
sexp_processor (3.0.7)
shoulda (2.11.3) shoulda (2.11.3)
slop (2.1.0)
sqlite3 (1.3.4) sqlite3 (1.3.4)
term-ansicolor (1.0.6) term-ansicolor (1.0.6)
tzinfo (0.3.29) tzinfo (0.3.31)
xml-simple (1.1.0) uuidtools (2.1.2)
xpath (0.1.4) xpath (0.1.4)
nokogiri (~> 1.3) nokogiri (~> 1.3)
...@@ -121,10 +120,9 @@ PLATFORMS ...@@ -121,10 +120,9 @@ PLATFORMS
ruby ruby
DEPENDENCIES DEPENDENCIES
activerecord appraisal (~> 0.4.0)
appraisal
aruba aruba
aws-s3 aws-sdk
bundler bundler
capybara capybara
cocaine (~> 0.2) cocaine (~> 0.2)
...@@ -132,10 +130,8 @@ DEPENDENCIES ...@@ -132,10 +130,8 @@ DEPENDENCIES
fakeweb fakeweb
fog fog
jruby-openssl jruby-openssl
mime-types
mocha mocha
pry paperclip!
rake rake
rdoc
shoulda shoulda
sqlite3 (~> 1.3.4) sqlite3 (~> 1.3.4)
...@@ -10,7 +10,7 @@ Given /^I generate a new rails application$/ do ...@@ -10,7 +10,7 @@ Given /^I generate a new rails application$/ do
gem "sqlite3" gem "sqlite3"
gem "capybara" gem "capybara"
gem "gherkin" gem "gherkin"
gem "aws-s3" gem "aws-sdk"
""" """
And I configure the application to use "paperclip" from this project And I configure the application to use "paperclip" from this project
And I reset Bundler environment variable And I reset Bundler environment variable
......
When /^I attach the file "([^"]*)" to "([^"]*)" on S3$/ do |file_path, field| When /^I attach the file "([^"]*)" to "([^"]*)" on S3$/ do |file_path, field|
definition = User.attachment_definitions[field.downcase.to_sym] definition = User.attachment_definitions[field.downcase.to_sym]
path = "http://s3.amazonaws.com/paperclip#{definition[:path]}" path = "https://paperclip.s3.amazonaws.com#{definition[:path]}"
path.gsub!(':filename', File.basename(file_path)) path.gsub!(':filename', File.basename(file_path))
path.gsub!(/:([^\/\.]+)/) do |match| path.gsub!(/:([^\/\.]+)/) do |match|
"([^\/\.]+)" "([^\/\.]+)"
......
PATH
remote: ../
specs:
paperclip (2.4.5)
activerecord (>= 2.3.0)
activesupport (>= 2.3.2)
cocaine (>= 0.0.2)
mime-types
GEM
remote: http://rubygems.org/
specs:
actionmailer (2.3.14)
actionpack (= 2.3.14)
actionpack (2.3.14)
activesupport (= 2.3.14)
rack (~> 1.1.0)
activerecord (2.3.14)
activesupport (= 2.3.14)
activeresource (2.3.14)
activesupport (= 2.3.14)
activesupport (2.3.14)
appraisal (0.4.0)
bundler
rake
aruba (0.4.6)
bcat (>= 0.6.1)
childprocess (>= 0.2.0)
cucumber (>= 1.0.2)
rdiscount (>= 1.6.8)
rspec (>= 2.6.0)
aws-s3 (0.6.2)
builder
mime-types
xml-simple
bcat (0.6.2)
rack (~> 1.0)
builder (3.0.0)
capybara (1.1.1)
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
selenium-webdriver (~> 2.0)
xpath (~> 0.1.4)
childprocess (0.2.2)
ffi (~> 1.0.6)
cocaine (0.2.0)
cucumber (1.0.6)
builder (>= 2.1.2)
diff-lcs (>= 1.1.2)
gherkin (~> 2.4.18)
json (>= 1.4.6)
term-ansicolor (>= 1.0.6)
diff-lcs (1.1.3)
excon (0.7.4)
fakeweb (1.3.0)
ffi (1.0.9)
fog (1.0.0)
builder
excon (~> 0.7.3)
formatador (~> 0.2.0)
mime-types
multi_json (~> 1.0.3)
net-scp (~> 1.0.4)
net-ssh (~> 2.1.4)
nokogiri (~> 1.5.0)
ruby-hmac
formatador (0.2.1)
gherkin (2.4.21)
json (>= 1.4.6)
json (1.6.1)
json_pure (1.6.1)
metaclass (0.0.1)
mime-types (1.16)
mocha (0.10.0)
metaclass (~> 0.0.1)
multi_json (1.0.3)
net-scp (1.0.4)
net-ssh (>= 1.99.1)
net-ssh (2.1.4)
nokogiri (1.5.0)
rack (1.1.2)
rack-test (0.6.1)
rack (>= 1.0)
rails (2.3.14)
actionmailer (= 2.3.14)
actionpack (= 2.3.14)
activerecord (= 2.3.14)
activeresource (= 2.3.14)
activesupport (= 2.3.14)
rake (>= 0.8.3)
rake (0.9.2)
rdiscount (1.6.8)
rspec (2.6.0)
rspec-core (~> 2.6.0)
rspec-expectations (~> 2.6.0)
rspec-mocks (~> 2.6.0)
rspec-core (2.6.4)
rspec-expectations (2.6.0)
diff-lcs (~> 1.1.2)
rspec-mocks (2.6.0)
ruby-hmac (0.4.0)
rubyzip (0.9.4)
selenium-webdriver (2.7.0)
childprocess (>= 0.2.1)
ffi (>= 1.0.7)
json_pure
rubyzip
shoulda (2.11.3)
sqlite3 (1.3.4)
term-ansicolor (1.0.6)
xml-simple (1.1.0)
xpath (0.1.4)
nokogiri (~> 1.3)
PLATFORMS
ruby
DEPENDENCIES
appraisal (~> 0.4.0)
aruba
aws-s3
bundler
capybara
cocaine (~> 0.2)
cucumber (~> 1.0.0)
fakeweb
fog
jruby-openssl
mocha
paperclip!
rails (~> 2.3.14)
rake
shoulda
sqlite3 (~> 1.3.4)
PATH
remote: ../
specs:
paperclip (2.4.5)
activerecord (>= 2.3.0)
activesupport (>= 2.3.2)
cocaine (>= 0.0.2)
mime-types
GEM
remote: http://rubygems.org/
specs:
abstract (1.0.0)
actionmailer (3.0.10)
actionpack (= 3.0.10)
mail (~> 2.2.19)
actionpack (3.0.10)
activemodel (= 3.0.10)
activesupport (= 3.0.10)
builder (~> 2.1.2)
erubis (~> 2.6.6)
i18n (~> 0.5.0)
rack (~> 1.2.1)
rack-mount (~> 0.6.14)
rack-test (~> 0.5.7)
tzinfo (~> 0.3.23)
activemodel (3.0.10)
activesupport (= 3.0.10)
builder (~> 2.1.2)
i18n (~> 0.5.0)
activerecord (3.0.10)
activemodel (= 3.0.10)
activesupport (= 3.0.10)
arel (~> 2.0.10)
tzinfo (~> 0.3.23)
activeresource (3.0.10)
activemodel (= 3.0.10)
activesupport (= 3.0.10)
activesupport (3.0.10)
appraisal (0.4.0)
bundler
rake
arel (2.0.10)
aruba (0.4.6)
bcat (>= 0.6.1)
childprocess (>= 0.2.0)
cucumber (>= 1.0.2)
rdiscount (>= 1.6.8)
rspec (>= 2.6.0)
aws-s3 (0.6.2)
builder
mime-types
xml-simple
bcat (0.6.2)
rack (~> 1.0)
builder (2.1.2)
capybara (1.1.1)
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
selenium-webdriver (~> 2.0)
xpath (~> 0.1.4)
childprocess (0.2.2)
ffi (~> 1.0.6)
cocaine (0.2.0)
cucumber (1.0.6)
builder (>= 2.1.2)
diff-lcs (>= 1.1.2)
gherkin (~> 2.4.18)
json (>= 1.4.6)
term-ansicolor (>= 1.0.6)
diff-lcs (1.1.3)
erubis (2.6.6)
abstract (>= 1.0.0)
excon (0.7.4)
fakeweb (1.3.0)
ffi (1.0.9)
fog (1.0.0)
builder
excon (~> 0.7.3)
formatador (~> 0.2.0)
mime-types
multi_json (~> 1.0.3)
net-scp (~> 1.0.4)
net-ssh (~> 2.1.4)
nokogiri (~> 1.5.0)
ruby-hmac
formatador (0.2.1)
gherkin (2.4.21)
json (>= 1.4.6)
i18n (0.5.0)
json (1.6.1)
json_pure (1.6.1)
mail (2.2.19)
activesupport (>= 2.3.6)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
metaclass (0.0.1)
mime-types (1.16)
mocha (0.10.0)
metaclass (~> 0.0.1)
multi_json (1.0.3)
net-scp (1.0.4)
net-ssh (>= 1.99.1)
net-ssh (2.1.4)
nokogiri (1.5.0)
polyglot (0.3.2)
rack (1.2.4)
rack-mount (0.6.14)
rack (>= 1.0.0)
rack-test (0.5.7)
rack (>= 1.0)
rails (3.0.10)
actionmailer (= 3.0.10)
actionpack (= 3.0.10)
activerecord (= 3.0.10)
activeresource (= 3.0.10)
activesupport (= 3.0.10)
bundler (~> 1.0)
railties (= 3.0.10)
railties (3.0.10)
actionpack (= 3.0.10)
activesupport (= 3.0.10)
rake (>= 0.8.7)
rdoc (~> 3.4)
thor (~> 0.14.4)
rake (0.9.2)
rdiscount (1.6.8)
rdoc (3.9.4)
rspec (2.6.0)
rspec-core (~> 2.6.0)
rspec-expectations (~> 2.6.0)
rspec-mocks (~> 2.6.0)
rspec-core (2.6.4)
rspec-expectations (2.6.0)
diff-lcs (~> 1.1.2)
rspec-mocks (2.6.0)
ruby-hmac (0.4.0)
rubyzip (0.9.4)
selenium-webdriver (2.7.0)
childprocess (>= 0.2.1)
ffi (>= 1.0.7)
json_pure
rubyzip
shoulda (2.11.3)
sqlite3 (1.3.4)
term-ansicolor (1.0.6)
thor (0.14.6)
treetop (1.4.10)
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.30)
xml-simple (1.1.0)
xpath (0.1.4)
nokogiri (~> 1.3)
PLATFORMS
ruby
DEPENDENCIES
appraisal (~> 0.4.0)
aruba
aws-s3
bundler
capybara
cocaine (~> 0.2)
cucumber (~> 1.0.0)
fakeweb
fog
jruby-openssl
mocha
paperclip!
rails (~> 3.0.10)
rake
shoulda
sqlite3 (~> 1.3.4)
PATH
remote: ../
specs:
paperclip (2.4.5)
activerecord (>= 2.3.0)
activesupport (>= 2.3.2)
cocaine (>= 0.0.2)
mime-types
GEM
remote: http://rubygems.org/
specs:
actionmailer (3.1.0)
actionpack (= 3.1.0)
mail (~> 2.3.0)
actionpack (3.1.0)
activemodel (= 3.1.0)
activesupport (= 3.1.0)
builder (~> 3.0.0)
erubis (~> 2.7.0)
i18n (~> 0.6)
rack (~> 1.3.2)
rack-cache (~> 1.0.3)
rack-mount (~> 0.8.2)
rack-test (~> 0.6.1)
sprockets (~> 2.0.0)
activemodel (3.1.0)
activesupport (= 3.1.0)
bcrypt-ruby (~> 3.0.0)
builder (~> 3.0.0)
i18n (~> 0.6)
activerecord (3.1.0)
activemodel (= 3.1.0)
activesupport (= 3.1.0)
arel (~> 2.2.1)
tzinfo (~> 0.3.29)
activeresource (3.1.0)
activemodel (= 3.1.0)
activesupport (= 3.1.0)
activesupport (3.1.0)
multi_json (~> 1.0)
appraisal (0.4.0)
bundler
rake
arel (2.2.1)
aruba (0.4.6)
bcat (>= 0.6.1)
childprocess (>= 0.2.0)
cucumber (>= 1.0.2)
rdiscount (>= 1.6.8)
rspec (>= 2.6.0)
aws-s3 (0.6.2)
builder
mime-types
xml-simple
bcat (0.6.2)
rack (~> 1.0)
bcrypt-ruby (3.0.1)
builder (3.0.0)
capybara (1.1.1)
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
selenium-webdriver (~> 2.0)
xpath (~> 0.1.4)
childprocess (0.2.2)
ffi (~> 1.0.6)
cocaine (0.2.0)
cucumber (1.0.6)
builder (>= 2.1.2)
diff-lcs (>= 1.1.2)
gherkin (~> 2.4.18)
json (>= 1.4.6)
term-ansicolor (>= 1.0.6)
diff-lcs (1.1.3)
erubis (2.7.0)
excon (0.7.4)
fakeweb (1.3.0)
ffi (1.0.9)
fog (1.0.0)
builder
excon (~> 0.7.3)
formatador (~> 0.2.0)
mime-types
multi_json (~> 1.0.3)
net-scp (~> 1.0.4)
net-ssh (~> 2.1.4)
nokogiri (~> 1.5.0)
ruby-hmac
formatador (0.2.1)
gherkin (2.4.21)
json (>= 1.4.6)
hike (1.2.1)
i18n (0.6.0)
json (1.6.1)
json_pure (1.6.1)
mail (2.3.0)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
metaclass (0.0.1)
mime-types (1.16)
mocha (0.10.0)
metaclass (~> 0.0.1)
multi_json (1.0.3)
net-scp (1.0.4)
net-ssh (>= 1.99.1)
net-ssh (2.1.4)
nokogiri (1.5.0)
polyglot (0.3.2)
rack (1.3.3)
rack-cache (1.0.3)
rack (>= 0.4)
rack-mount (0.8.3)
rack (>= 1.0.0)
rack-ssl (1.3.2)
rack
rack-test (0.6.1)
rack (>= 1.0)
rails (3.1.0)
actionmailer (= 3.1.0)
actionpack (= 3.1.0)
activerecord (= 3.1.0)
activeresource (= 3.1.0)
activesupport (= 3.1.0)
bundler (~> 1.0)
railties (= 3.1.0)
railties (3.1.0)
actionpack (= 3.1.0)
activesupport (= 3.1.0)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7)
rdoc (~> 3.4)
thor (~> 0.14.6)
rake (0.9.2)
rdiscount (1.6.8)
rdoc (3.9.4)
rspec (2.6.0)
rspec-core (~> 2.6.0)
rspec-expectations (~> 2.6.0)
rspec-mocks (~> 2.6.0)
rspec-core (2.6.4)
rspec-expectations (2.6.0)
diff-lcs (~> 1.1.2)
rspec-mocks (2.6.0)
ruby-hmac (0.4.0)
rubyzip (0.9.4)
selenium-webdriver (2.7.0)
childprocess (>= 0.2.1)
ffi (>= 1.0.7)
json_pure
rubyzip
shoulda (2.11.3)
sprockets (2.0.1)
hike (~> 1.2)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
sqlite3 (1.3.4)
term-ansicolor (1.0.6)
thor (0.14.6)
tilt (1.3.3)
treetop (1.4.10)
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.30)
xml-simple (1.1.0)
xpath (0.1.4)
nokogiri (~> 1.3)
PLATFORMS
ruby
DEPENDENCIES
appraisal (~> 0.4.0)
aruba
aws-s3
bundler
capybara
cocaine (~> 0.2)
cucumber (~> 1.0.0)
fakeweb
fog
jruby-openssl
mocha
paperclip!
rails (~> 3.1.0)
rake
shoulda
sqlite3 (~> 1.3.4)
...@@ -67,12 +67,21 @@ module Paperclip ...@@ -67,12 +67,21 @@ module Paperclip
# S3 (strictly speaking) does not support directories, you can still use a / to # S3 (strictly speaking) does not support directories, you can still use a / to
# separate parts of your file name. # separate parts of your file name.
# * +s3_host_name+: If you are using your bucket in Tokyo region etc, write host_name. # * +s3_host_name+: If you are using your bucket in Tokyo region etc, write host_name.
# * +s3_metadata+: These key/value pairs will be stored with the
# object. This option works by prefixing each key with
# "x-amz-meta-" before sending it as a header on the object
# upload request.
# * +s3_storage_class+: If this option is set to
# <tt>:reduced_redundancy</tt>, the object will be stored using Reduced
# Redundancy Storage. RRS enables customers to reduce their
# costs by storing non-critical, reproducible data at lower
# levels of redundancy than Amazon S3's standard storage.
module S3 module S3
def self.extended base def self.extended base
begin begin
require 'aws/s3' require 'aws/s3'
rescue LoadError => e rescue LoadError => e
e.message << " (You may need to install the aws-s3 gem)" e.message << " (You may need to install the aws-sdk gem)"
raise e raise e
end unless defined?(AWS::S3) end unless defined?(AWS::S3)
...@@ -85,7 +94,19 @@ module Paperclip ...@@ -85,7 +94,19 @@ module Paperclip
permission = permission.call(attachment, style) if permission.is_a?(Proc) permission = permission.call(attachment, style) if permission.is_a?(Proc)
(permission == :public_read) ? 'http' : 'https' (permission == :public_read) ? 'http' : 'https'
end end
@s3_headers = @options[:s3_headers] || {} @s3_metadata = @options[:s3_metadata] || {}
@s3_headers = (@options[:s3_headers] || {}).inject({}) do |headers,(name,value)|
case name.to_s
when /^x-amz-meta-(.*)/i
@s3_metadata[$1.downcase] = value
else
name = name.to_s.downcase.sub(/^x-amz-/,'').tr("-","_").to_sym
headers[name] = value
end
headers
end
@s3_headers[:storage_class] = @options[:s3_storage_class] if @options[:s3_storage_class]
unless @options[:url].to_s.match(/^:s3.*url$/) || @options[:url] == ":asset_host" unless @options[:url].to_s.match(/^:s3.*url$/) || @options[:url] == ":asset_host"
@options[:path] = @options[:path].gsub(/:url/, @options[:url]).gsub(/^:rails_root\/public\/system/, '') @options[:path] = @options[:path].gsub(/:url/, @options[:url]).gsub(/^:rails_root\/public\/system/, '')
...@@ -94,9 +115,6 @@ module Paperclip ...@@ -94,9 +115,6 @@ module Paperclip
@options[:url] = @options[:url].inspect if @options[:url].is_a?(Symbol) @options[:url] = @options[:url].inspect if @options[:url].is_a?(Symbol)
@http_proxy = @options[:http_proxy] || nil @http_proxy = @options[:http_proxy] || nil
if @http_proxy
@s3_options.merge!({:proxy => @http_proxy})
end
end end
Paperclip.interpolates(:s3_alias_url) do |attachment, style| Paperclip.interpolates(:s3_alias_url) do |attachment, style|
"#{attachment.s3_protocol(style)}://#{attachment.s3_host_alias}/#{attachment.path(style).gsub(%r{^/}, "")}" "#{attachment.s3_protocol(style)}://#{attachment.s3_host_alias}/#{attachment.path(style).gsub(%r{^/}, "")}"
...@@ -113,7 +131,9 @@ module Paperclip ...@@ -113,7 +131,9 @@ module Paperclip
end end
def expiring_url(time = 3600, style_name = default_style) def expiring_url(time = 3600, style_name = default_style)
path.nil? ? nil : s3_object.url_for(path(style_name), bucket_name, :expires_in => time, :use_ssl => (s3_protocol(style_name) == 'https')) if path
s3_object(style_name).url_for(:read, :expires => time, :secure => use_secure_protocol?(style_name)).to_s
end
end end
def s3_credentials def s3_credentials
...@@ -133,7 +153,39 @@ module Paperclip ...@@ -133,7 +153,39 @@ module Paperclip
def bucket_name def bucket_name
@bucket = @options[:bucket] || s3_credentials[:bucket] @bucket = @options[:bucket] || s3_credentials[:bucket]
@bucket = @bucket.call(self) if @bucket.is_a?(Proc) @bucket = @bucket.call(self) if @bucket.is_a?(Proc)
@bucket @bucket or raise ArgumentError, "missing required :bucket option"
end
def s3_interface
@s3_interface ||= begin
config = { :s3_endpoint => s3_host_name }
if using_http_proxy?
proxy_opts = { :host => http_proxy_host }
proxy_opts[:port] = http_proxy_port if http_proxy_port
if http_proxy_user
userinfo = http_proxy_user.to_s
userinfo += ":#{http_proxy_password}" if http_proxy_password
proxy_opts[:userinfo] = userinfo
end
config[:proxy_uri] = URI::HTTP.build(proxy_opts)
end
[:access_key_id, :secret_access_key].each do |opt|
config[opt] = s3_credentials[opt] if s3_credentials[opt]
end
AWS::S3.new(config.merge(@s3_options))
end
end
def s3_bucket
@s3_bucket ||= s3_interface.buckets[bucket_name]
end
def s3_object style_name = default_style
s3_bucket.objects[path(style_name).sub(%r{^/},'')]
end end
def using_http_proxy? def using_http_proxy?
...@@ -173,7 +225,7 @@ module Paperclip ...@@ -173,7 +225,7 @@ module Paperclip
def exists?(style = default_style) def exists?(style = default_style)
if original_filename if original_filename
s3_object.exists?(path(style), bucket_name) s3_object(style).exists?
else else
false false
end end
...@@ -202,30 +254,31 @@ module Paperclip ...@@ -202,30 +254,31 @@ module Paperclip
basename = File.basename(filename, extname) basename = File.basename(filename, extname)
file = Tempfile.new([basename, extname]) file = Tempfile.new([basename, extname])
file.binmode file.binmode
file.write(s3_object.value(path(style), bucket_name)) file.write(s3_object(style).read)
file.rewind file.rewind
return file return file
end end
def create_bucket def create_bucket
s3_bucket.create(bucket_name) s3_interface.buckets.create(bucket_name)
end end
def flush_writes #:nodoc: def flush_writes #:nodoc:
@queued_for_write.each do |style, file| @queued_for_write.each do |style, file|
begin begin
log("saving #{path(style)}") log("saving #{path(style)}")
s3_object.store(path(style), acl = @s3_permissions[style] || @s3_permissions[:default]
file, acl = acl.call(self, style) if acl.respond_to?(:call)
bucket_name, write_options = {
{:content_type => file.content_type.to_s.strip, :content_type => file.content_type.to_s.strip,
:access => s3_permissions(style), :acl => acl
}.merge(@s3_headers)) }
rescue AWS::S3::NoSuchBucket => e write_options[:metadata] = @s3_metadata unless @s3_metadata.empty?
write_options.merge!(@s3_headers)
s3_object(style).write(file, write_options)
rescue AWS::S3::Errors::NoSuchBucket => e
create_bucket create_bucket
retry retry
rescue AWS::S3::ResponseError => e
raise
end end
end end
...@@ -238,8 +291,8 @@ module Paperclip ...@@ -238,8 +291,8 @@ module Paperclip
@queued_for_delete.each do |path| @queued_for_delete.each do |path|
begin begin
log("deleting #{path}") log("deleting #{path}")
s3_object.delete(path, bucket_name) s3_bucket.objects[path.sub(%r{^/},'')].delete
rescue AWS::S3::ResponseError rescue AWS::Errors::Base => e
# Ignore this. # Ignore this.
end end
end end
...@@ -260,18 +313,6 @@ module Paperclip ...@@ -260,18 +313,6 @@ module Paperclip
end end
private :find_credentials private :find_credentials
def s3_object
establish_connection!
AWS::S3::S3Object
end
private :s3_object
def s3_bucket
establish_connection!
AWS::S3::Bucket
end
private :s3_bucket
def establish_connection! def establish_connection!
@connection ||= AWS::S3::Base.establish_connection!( @s3_options.merge( @connection ||= AWS::S3::Base.establish_connection!( @s3_options.merge(
:access_key_id => s3_credentials[:access_key_id], :access_key_id => s3_credentials[:access_key_id],
...@@ -279,6 +320,11 @@ module Paperclip ...@@ -279,6 +320,11 @@ module Paperclip
)) ))
end end
private :establish_connection! private :establish_connection!
def use_secure_protocol?(style_name)
s3_protocol(style_name) == "https"
end
private :use_secure_protocol?
end end
end end
end end
...@@ -28,7 +28,7 @@ Gem::Specification.new do |s| ...@@ -28,7 +28,7 @@ Gem::Specification.new do |s|
s.add_development_dependency('shoulda') s.add_development_dependency('shoulda')
s.add_development_dependency('appraisal', '~> 0.4.0') s.add_development_dependency('appraisal', '~> 0.4.0')
s.add_development_dependency('mocha') s.add_development_dependency('mocha')
s.add_development_dependency('aws-s3') s.add_development_dependency('aws-sdk')
s.add_development_dependency('sqlite3', '~> 1.3.4') s.add_development_dependency('sqlite3', '~> 1.3.4')
s.add_development_dependency('cucumber', '~> 1.0.0') s.add_development_dependency('cucumber', '~> 1.0.0')
s.add_development_dependency('aruba') s.add_development_dependency('aruba')
......
require './test/helper' require './test/helper'
require 'aws/s3' require 'aws'
unless ENV["S3_TEST_BUCKET"].blank? unless ENV["S3_TEST_BUCKET"].blank?
class S3LiveTest < Test::Unit::TestCase class S3LiveTest < Test::Unit::TestCase
...@@ -72,7 +72,7 @@ unless ENV["S3_TEST_BUCKET"].blank? ...@@ -72,7 +72,7 @@ unless ENV["S3_TEST_BUCKET"].blank?
rebuild_model :styles => { :thumb => "100x100", :square => "32x32#" }, rebuild_model :styles => { :thumb => "100x100", :square => "32x32#" },
:storage => :s3, :storage => :s3,
:bucket => ENV["S3_TEST_BUCKET"], :bucket => ENV["S3_TEST_BUCKET"],
:s3_credentials => File.new(File.join(File.dirname(__FILE__), "..", "s3.yml")) :s3_credentials => File.new(File.join(File.dirname(__FILE__), "..", "fixtures", "s3.yml"))
Dummy.delete_all Dummy.delete_all
@dummy = Dummy.new @dummy = Dummy.new
...@@ -120,9 +120,9 @@ unless ENV["S3_TEST_BUCKET"].blank? ...@@ -120,9 +120,9 @@ unless ENV["S3_TEST_BUCKET"].blank?
assert_match /.+\/question\?mark\.png/, @dummy.avatar.path assert_match /.+\/question\?mark\.png/, @dummy.avatar.path
end end
# should "return an escaped version for url" do should "return an escaped version for url" do
# assert_match /.+\/question%3Fmark\.png/, @dummy.avatar.url assert_match /.+\/question%3Fmark\.png/, @dummy.avatar.url
# end end
should "be accessible" do should "be accessible" do
assert_match /200 OK/, `curl -I "#{@dummy.avatar.url}"` assert_match /200 OK/, `curl -I "#{@dummy.avatar.url}"`
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment