Skip to content
Browse files

Merge pull request #1000 from yob/rackspace_temp_urls

Rackspace Temp/Expiring URLs
  • Loading branch information...
2 parents 2299347 + 15596e4 commit 4f29f79e9d97d905746237853ad1ff1673ef5b3c @brianhartsock brianhartsock committed Aug 7, 2012
View
51 lib/fog/rackspace/requests/storage/get_object_https_url.rb
@@ -0,0 +1,51 @@
+module Fog
+ module Storage
+ class Rackspace
+
+ class Real
+
+ # Get an expiring object https url from Cloud Files
+ #
+ # ==== Parameters
+ # * container<~String> - Name of container containing object
+ # * object<~String> - Name of object to get expiring url for
+ # * expires<~Time> - An expiry time for this url
+ #
+ # ==== Returns
+ # * response<~Excon::Response>:
+ # * body<~String> - url for object
+ #
+ # ==== See Also
+ # http://docs.rackspace.com/files/api/v1/cf-devguide/content/Create_TempURL-d1a444.html
+ def get_object_https_url(container, object, expires, options = {})
+ if @rackspace_temp_url_key.nil?
+ raise ArgumentError, "Storage must my instantiated with the :rackspace_temp_url_key option"
+ end
+
+ method = 'GET'
+ expires = expires.to_i
+ object_path_escaped = "#{@path}/#{Fog::Rackspace.escape(container)}/#{Fog::Rackspace.escape(object,"/")}"
+ object_path_unescaped = "#{@path}/#{Fog::Rackspace.escape(container)}/#{object}"
+ string_to_sign = "#{method}\n#{expires}\n#{object_path_unescaped}"
+
+ hmac = Fog::HMAC.new('sha1', @rackspace_temp_url_key)
+ sig = sig_to_hex(hmac.sign(string_to_sign))
+
+ "https://#{@host}#{object_path_escaped}?temp_url_sig=#{sig}&temp_url_expires=#{expires}"
+ end
+
+ private
+
+ def sig_to_hex(str)
+ str.unpack("C*").map { |c|
+ c.to_s(16)
+ }.map { |h|
+ h.size == 1 ? "0#{h}" : h
+ }.join
+ end
+
+ end
+
+ end
+ end
+end
View
37 lib/fog/rackspace/requests/storage/post_set_meta_temp_url_key.rb
@@ -0,0 +1,37 @@
+module Fog
+ module Storage
+ class Rackspace
+
+ class Real
+
+ # Set the account wide Temp URL Key. This is a secret key that's
+ # used to generate signed expiring URLs.
+ #
+ # Once the key has been set with this request you should create new
+ # Storage objects with the :rackspace_temp_url_key option then use
+ # the get_object_https_url method to generate expirign URLs.
+ #
+ # *** CAUTION *** changing this secret key will invalidate any expiring
+ # URLS generated with old keys.
+ #
+ # ==== Parameters
+ # * key<~String> - The new Temp URL Key
+ #
+ # ==== Returns
+ # * response<~Excon::Response>
+ #
+ # ==== See Also
+ # http://docs.rackspace.com/files/api/v1/cf-devguide/content/Set_Account_Metadata-d1a4460.html
+ def post_set_meta_temp_url_key(key)
+ request(
+ :expects => [201, 202, 204],
+ :method => 'POST',
+ :headers => {'X-Account-Meta-Temp-Url-Key' => key}
+ )
+ end
+
+ end
+
+ end
+ end
+end
View
4 lib/fog/rackspace/storage.rb
@@ -7,6 +7,7 @@ class Rackspace < Fog::Service
requires :rackspace_api_key, :rackspace_username
recognizes :rackspace_auth_url, :rackspace_servicenet, :rackspace_cdn_ssl, :persistent
+ recognizes :rackspace_temp_url_key
model_path 'fog/rackspace/models/storage'
model :directory
@@ -21,12 +22,14 @@ class Rackspace < Fog::Service
request :get_container
request :get_containers
request :get_object
+ request :get_object_https_url
request :head_container
request :head_containers
request :head_object
request :put_container
request :put_object
request :put_object_manifest
+ request :post_set_meta_temp_url_key
module Utils
@@ -86,6 +89,7 @@ def initialize(options={})
@rackspace_servicenet = options[:rackspace_servicenet]
@rackspace_auth_token = options[:rackspace_auth_token]
@rackspace_storage_url = options[:rackspace_storage_url]
+ @rackspace_temp_url_key = options[:rackspace_temp_url_key]
@rackspace_must_reauthenticate = false
@connection_options = options[:connection_options] || {}
authenticate
View
17 tests/rackspace/requests/storage/account_tests.rb
@@ -0,0 +1,17 @@
+Shindo.tests('Fog::Storage[:rackspace] | account requests', [:rackspace]) do
+
+ tests('success') do
+
+ tests("#post_set_meta_temp_url_key('super_secret_key')").succeeds do
+ pending if Fog.mocking?
+ Fog::Storage[:rackspace].post_set_meta_temp_url_key('super_secret_key')
+ end
+
+ end
+
+ tests('failure') do
+
+ end
+
+
+end
View
29 tests/rackspace/requests/storage/object_tests.rb
@@ -35,6 +35,33 @@
Fog::Storage[:rackspace].delete_object('fogobjecttests', 'fog_object')
end
+ # an object key with no special characters
+ tests("#get_object_https_url('fogobjecttests', 'fog_object','expiration timestamp')").succeeds do
+ pending if Fog.mocking?
+ expires_at = 1344149532 # 2012-08-05 16:52:12 +1000
+ storage = Fog::Storage::Rackspace.new(:rackspace_temp_url_key => "super_secret")
+ object_url = storage.get_object_https_url('fogobjecttests', 'fog_object', expires_at)
+ object_url =~ /https:\/\/.*clouddrive.com\/[^\/]+\/[^\/]+\/fogobjecttests\/fog_object\?temp_url_sig=8abd27f8345b6f3c5fceb9ef71d8ac59ffb15500&temp_url_expires=1344149532/
+ end
+
+ # an object key nested under a /
+ tests("#get_object_https_url('fogobjecttests', 'fog/object','expiration timestamp')").succeeds do
+ pending if Fog.mocking?
+ expires_at = 1344149532 # 2012-08-05 16:52:12 +1000
+ storage = Fog::Storage::Rackspace.new(:rackspace_temp_url_key => "super_secret")
+ object_url = storage.get_object_https_url('fogobjecttests', 'fog/object', expires_at)
+ object_url =~ /https:\/\/.*clouddrive.com\/[^\/]+\/[^\/]+\/fogobjecttests\/fog\/object\?temp_url_sig=1dc1de4544f75cf9eba85bde500059472c94adcd&temp_url_expires=1344149532/
+ end
+
+ # an object key containing a -
+ tests("#get_object_https_url('fogobjecttests', 'fog-object','expiration timestamp')").succeeds do
+ pending if Fog.mocking?
+ expires_at = 1344149532 # 2012-08-05 16:52:12 +1000
+ storage = Fog::Storage::Rackspace.new(:rackspace_temp_url_key => "super_secret")
+ object_url = storage.get_object_https_url('fogobjecttests', 'fog-object', expires_at)
+ object_url =~ /https:\/\/.*clouddrive.com\/[^\/]+\/[^\/]+\/fogobjecttests\/fog%2Dobject\?temp_url_sig=f664ec159300d91b2cb735249c630645b55b87a1&temp_url_expires=1344149532/
+ end
+
end
tests('failure') do
@@ -75,4 +102,4 @@
@directory.destroy
end
-end
+end

0 comments on commit 4f29f79

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