Skip to content
Browse files

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 fog/fog#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.
  • Loading branch information...
1 parent 49b833a commit 357d0301ba65bd759fc050518d16b23364c8b9e1 @michiels michiels committed with sikachu Apr 22, 2012
Showing with 68 additions and 13 deletions.
  1. +28 −13 lib/paperclip/storage/fog.rb
  2. +40 −0 test/storage/fog_test.rb
View
41 lib/paperclip/storage/fog.rb
@@ -108,26 +108,25 @@ def flush_deletes
def public_url(style = default_style)
if @options[:fog_host]
- host = 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
-
- "#{host}/#{path(style)}"
+ "#{dynamic_fog_host_for_style(style)}/#{path(style)}"
else
if fog_credentials[:provider] == 'AWS'
- if @options[:fog_directory].to_s =~ Fog::AWS_BUCKET_SUBDOMAIN_RESTRICTON_REGEX
- "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
+ "https://#{host_name_for_directory}/#{path(style)}"
else
directory.files.new(:key => path(style)).public_url
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)
creds = find_credentials(creds).stringify_keys
@@ -147,6 +146,22 @@ def copy_to_local_file(style, local_dest_path)
end
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)
case creds
View
40 test/storage/fog_test.rb
@@ -198,6 +198,10 @@ class FogTest < Test::Unit::TestCase
should "provide an url in subdomain style" do
assert_match /^https:\/\/papercliptests.s3.amazonaws.com\/avatars\/5k.png\?\d*$/, @dummy.avatar.url
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
context "with an invalid bucket name for a subdomain" do
@@ -218,6 +222,10 @@ class FogTest < Test::Unit::TestCase
should "provide an url in folder style" do
assert_match /^https:\/\/s3.amazonaws.com\/this_is_invalid\/avatars\/5k.png\?\d*$/, @dummy.avatar.url
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
@@ -249,6 +257,38 @@ class FogTest < Test::Unit::TestCase
should "provide a public url" do
assert_match /http:\/\/dynamicfoghost\.com/, @dummy.avatar.url
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
context "with a proc for the fog_credentials evaluating a model method" do

0 comments on commit 357d030

Please sign in to comment.
Something went wrong with that request. Please try again.