Commit 357d0301 by Michiel Sikkes Committed by Prem Sichanugrist

Added expiring_url method to Fog Storage

IMPORTANT: There is a bug in the current release of Fog (1.3.1) that will
return a broken expiring URL when the bucket name is valid for a subdomain.
This is fixed per https://github.com/fog/fog/pull/857 but not released
in the gem yet. I have added currently FAILING tests for these cases that
should pass when a new Fog is released.
parent 49b833a4
...@@ -108,26 +108,25 @@ module Paperclip ...@@ -108,26 +108,25 @@ module Paperclip
def public_url(style = default_style) def public_url(style = default_style)
if @options[:fog_host] if @options[:fog_host]
host = if @options[:fog_host].respond_to?(:call) "#{dynamic_fog_host_for_style(style)}/#{path(style)}"
@options[:fog_host].call(self)
else
(@options[:fog_host] =~ /%d/) ? @options[:fog_host] % (path(style).hash % 4) : @options[:fog_host]
end
"#{host}/#{path(style)}"
else else
if fog_credentials[:provider] == 'AWS' if fog_credentials[:provider] == 'AWS'
if @options[:fog_directory].to_s =~ Fog::AWS_BUCKET_SUBDOMAIN_RESTRICTON_REGEX "https://#{host_name_for_directory}/#{path(style)}"
"https://#{@options[:fog_directory]}.s3.amazonaws.com/#{path(style)}"
else
# directory is not a valid subdomain, so use path style for access
"https://s3.amazonaws.com/#{@options[:fog_directory]}/#{path(style)}"
end
else else
directory.files.new(:key => path(style)).public_url directory.files.new(:key => path(style)).public_url
end end
end end
end end
def expiring_url(time = 3600, style = default_style)
expiring_url = directory.files.get_http_url(path(style), time)
if @options[:fog_host]
expiring_url[host_name_for_directory] = dynamic_fog_host_for_style(style)
end
return expiring_url
end
def parse_credentials(creds) def parse_credentials(creds)
creds = find_credentials(creds).stringify_keys creds = find_credentials(creds).stringify_keys
...@@ -147,6 +146,22 @@ module Paperclip ...@@ -147,6 +146,22 @@ module Paperclip
end end
private private
def dynamic_fog_host_for_style(style)
if @options[:fog_host].respond_to?(:call)
@options[:fog_host].call(self)
else
(@options[:fog_host] =~ /%d/) ? @options[:fog_host] % (path(style).hash % 4) : @options[:fog_host]
end
end
def host_name_for_directory
if @options[:fog_directory].to_s =~ Fog::AWS_BUCKET_SUBDOMAIN_RESTRICTON_REGEX
"#{@options[:fog_directory]}.s3.amazonaws.com"
else
"s3.amazonaws.com/#{@options[:fog_directory]}"
end
end
def find_credentials(creds) def find_credentials(creds)
case creds case creds
......
...@@ -198,6 +198,10 @@ class FogTest < Test::Unit::TestCase ...@@ -198,6 +198,10 @@ class FogTest < Test::Unit::TestCase
should "provide an url in subdomain style" do should "provide an url in subdomain style" do
assert_match /^https:\/\/papercliptests.s3.amazonaws.com\/avatars\/5k.png\?\d*$/, @dummy.avatar.url assert_match /^https:\/\/papercliptests.s3.amazonaws.com\/avatars\/5k.png\?\d*$/, @dummy.avatar.url
end end
should "provide an url that expires in subdomain style" do
assert_match /^http:\/\/papercliptests.s3.amazonaws.com\/avatars\/5k.png\?AWSAccessKeyId=.+$/, @dummy.avatar.expiring_url
end
end end
context "with an invalid bucket name for a subdomain" do context "with an invalid bucket name for a subdomain" do
...@@ -218,6 +222,10 @@ class FogTest < Test::Unit::TestCase ...@@ -218,6 +222,10 @@ class FogTest < Test::Unit::TestCase
should "provide an url in folder style" do should "provide an url in folder style" do
assert_match /^https:\/\/s3.amazonaws.com\/this_is_invalid\/avatars\/5k.png\?\d*$/, @dummy.avatar.url assert_match /^https:\/\/s3.amazonaws.com\/this_is_invalid\/avatars\/5k.png\?\d*$/, @dummy.avatar.url
end end
should "provide a url that expires in folder style" do
assert_match /^http:\/\/s3.amazonaws.com\/this_is_invalid\/avatars\/5k.png\?AWSAccessKeyId=.+$/, @dummy.avatar.expiring_url
end
end end
...@@ -249,6 +257,38 @@ class FogTest < Test::Unit::TestCase ...@@ -249,6 +257,38 @@ class FogTest < Test::Unit::TestCase
should "provide a public url" do should "provide a public url" do
assert_match /http:\/\/dynamicfoghost\.com/, @dummy.avatar.url assert_match /http:\/\/dynamicfoghost\.com/, @dummy.avatar.url
end end
end
context "with a custom fog_host" do
setup do
rebuild_model(@options.merge(:fog_host => "http://dynamicfoghost.com"))
@dummy = Dummy.new
@dummy.avatar = @file
@dummy.save
end
should "provide a public url" do
assert_match /http:\/\/dynamicfoghost\.com/, @dummy.avatar.url
end
should "provide an expiring url" do
assert_match /http:\/\/dynamicfoghost\.com/, @dummy.avatar.expiring_url
end
context "with an invalid bucket name for a subdomain" do
setup do
rebuild_model(@options.merge({:fog_directory => "this_is_invalid", :fog_host => "http://dynamicfoghost.com"}))
@dummy = Dummy.new
@dummy.avatar = @file
@dummy.save
end
should "provide an expiring url" do
assert_match /http:\/\/dynamicfoghost\.com/, @dummy.avatar.expiring_url
end
end
end end
context "with a proc for the fog_credentials evaluating a model method" do context "with a proc for the fog_credentials evaluating a model method" do
......
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