Skip to content
This repository has been archived by the owner on Jul 13, 2023. It is now read-only.

Commit

Permalink
Add :use_accelerate_endpoint option when using S3
Browse files Browse the repository at this point in the history
[Amazon S3 Transfer
Acceleration](http://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html)
enables fast, easy, and secure transfers of files over long distances
between your client and an S3 bucket. And
[aws-sdk](https://github.com/aws/aws-sdk-ruby) has allowed us to enable
this feature in version 2.3.0 (more detail is
[here](aws/aws-sdk-ruby#1163)).

You can now pass a configuration option (:use_accelerate_endpoint) when
config Paperclip with S3. You can enable the [Amazon S3 Transfer
Acceleration](http://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html)
by set this option:
```:use_accelerate_endpoint => true```

[fixes #2291]
  • Loading branch information
gagoit authored and tute committed Aug 28, 2016
1 parent 544fa14 commit b55b0f2
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 0 deletions.
2 changes: 2 additions & 0 deletions NEWS
@@ -1,5 +1,7 @@
master:

* Improvement: Added `:use_accelerate_endpoint` option when using S3 to enable
[Amazon S3 Transfer Acceleration](http://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html)
* Improvement: make the fingerprint digest configurable per attachment. The
default remains MD5 but this will change in a future version because it is
not considered secure anymore against intentional file corruption. For more
Expand Down
15 changes: 15 additions & 0 deletions lib/paperclip/storage/s3.rb
Expand Up @@ -102,6 +102,8 @@ module Storage
# 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.
# * +use_accelerate_endpoint+: Use accelerate endpoint
# http://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html
#
# You can set storage class on a per style bases by doing the following:
# :s3_storage_class => {
Expand Down Expand Up @@ -152,6 +154,13 @@ def self.extended base
@options[:url] = @options[:url].inspect if @options[:url].is_a?(Symbol)

@http_proxy = @options[:http_proxy] || nil

if @options.has_key?(:use_accelerate_endpoint) &&
Gem::Version.new(Aws::VERSION) < Gem::Version.new("2.3.0")
raise LoadError, ":use_accelerate_endpoint is only available from aws-sdk version 2.3.0. Please upgrade aws-sdk to a newer version."
end

@use_accelerate_endpoint = @options[:use_accelerate_endpoint]
end

Paperclip.interpolates(:s3_alias_url) do |attachment, style|
Expand Down Expand Up @@ -232,6 +241,8 @@ def s3_interface
config[:proxy_uri] = URI::HTTP.build(proxy_opts)
end

config[:use_accelerate_endpoint] = use_accelerate_endpoint?

[:access_key_id, :secret_access_key, :credential_provider, :credentials].each do |opt|
config[opt] = s3_credentials[opt] if s3_credentials[opt]
end
Expand All @@ -257,6 +268,10 @@ def s3_object style_name = default_style
s3_bucket.object style_name_as_path(style_name)
end

def use_accelerate_endpoint?
!!@use_accelerate_endpoint
end

def using_http_proxy?
!!@http_proxy
end
Expand Down
53 changes: 53 additions & 0 deletions spec/paperclip/storage/s3_spec.rb
Expand Up @@ -282,6 +282,59 @@ class << @dummy
end
end

context "use_accelerate_endpoint", if: aws_accelerate_available? do
context "defaults to false" do
before do
rebuild_model(
storage: :s3,
s3_credentials: {},
bucket: "bucket",
path: ":attachment/:basename:dotextension",
s3_host_name: "s3-ap-northeast-1.amazonaws.com",
s3_region: "ap-northeast-1",
)
@dummy = Dummy.new
@dummy.avatar = stringy_file
@dummy.stubs(:new_record?).returns(false)
end

it "returns a url based on an :s3_host_name path" do
assert_match %r{^//s3-ap-northeast-1.amazonaws.com/bucket/avatars/data[^\.]},
@dummy.avatar.url
end

it "uses the S3 client with the use_accelerate_endpoint config is false" do
expect(@dummy.avatar.s3_bucket.client.config.use_accelerate_endpoint).to be(false)
end
end

context "set to true", if: aws_accelerate_available? do
before do
rebuild_model(
storage: :s3,
s3_credentials: {},
bucket: "bucket",
path: ":attachment/:basename:dotextension",
s3_host_name: "s3-accelerate.amazonaws.com",
s3_region: "ap-northeast-1",
use_accelerate_endpoint: true,
)
@dummy = Dummy.new
@dummy.avatar = stringy_file
@dummy.stubs(:new_record?).returns(false)
end

it "returns a url based on an :s3_host_name path" do
assert_match %r{^//s3-accelerate.amazonaws.com/bucket/avatars/data[^\.]},
@dummy.avatar.url
end

it "uses the S3 client with the use_accelerate_endpoint config is true" do
expect(@dummy.avatar.s3_bucket.client.config.use_accelerate_endpoint).to be(true)
end
end
end

context "An attachment that uses S3 for storage and has styles that return different file types" do
before do
rebuild_model (aws2_add_region).merge storage: :s3,
Expand Down
1 change: 1 addition & 0 deletions spec/spec_helper.rb
Expand Up @@ -38,6 +38,7 @@
config.include TestData
config.include Reporting
config.extend VersionHelper
config.extend ConditionalFilterHelper
config.mock_framework = :mocha
config.before(:all) do
rebuild_model
Expand Down
5 changes: 5 additions & 0 deletions spec/support/conditional_filter_helper.rb
@@ -0,0 +1,5 @@
module ConditionalFilterHelper
def aws_accelerate_available?
(Gem::Version.new(Aws::VERSION) >= Gem::Version.new("2.3.0"))
end
end

0 comments on commit b55b0f2

Please sign in to comment.