1
0
Fork 0
mirror of https://github.com/fog/fog.git synced 2022-11-09 13:51:43 -05:00

rebasing with master

This commit is contained in:
Kyle Rames 2013-02-25 08:26:15 -06:00
commit 950bda0f33
8 changed files with 345 additions and 70 deletions

View file

@ -6,7 +6,7 @@ module Fog
class Rackspace < Fog::Service
requires :rackspace_api_key, :rackspace_username
recognizes :rackspace_auth_url, :persistent
recognizes :rackspace_auth_url, :persistent, :rackspace_cdn_ssl
request_path 'fog/rackspace/requests/cdn'
request :get_containers
@ -14,9 +14,48 @@ module Fog
request :post_container
request :put_container
request :delete_object
module Base
URI_HEADERS = {
"X-Cdn-Ios-Uri" => :ios_uri,
"X-Cdn-Uri" => :uri,
"X-Cdn-Streaming-Uri" => :streaming_uri,
"X-Cdn-Ssl-Uri" => :ssl_uri
}.freeze
def publish_container(container, publish = true)
enabled = publish ? 'True' : 'False'
response = put_container(container.key, 'X-Cdn-Enabled' => enabled)
return {} unless publish
urls_from_headers(response.headers)
end
def urls(container)
begin
response = head_container(container.key)
return {} unless response.headers['X-Cdn-Enabled'] == 'True'
urls_from_headers response.headers
rescue Fog::Service::NotFound
{}
end
end
private
def urls_from_headers(headers)
h = {}
URI_HEADERS.keys.each do | header |
key = URI_HEADERS[header]
h[key] = headers[header]
end
h
end
end
class Mock
include Base
def self.data
@data ||= Hash.new do |hash, key|
hash[key] = {}
@ -34,20 +73,21 @@ module Fog
def data
self.class.data[@rackspace_username]
end
def purge(object)
return true if object.is_a? Fog::Storage::Rackspace::File
raise Fog::Errors::NotImplemented.new("#{object.class} does not support CDN purging") if object
end
def reset_data
self.class.data.delete(@rackspace_username)
end
def purge(object)
return true if object.is_a? Fog::Storage::Rackspace::File
raise Fog::Errors::NotImplemented.new("#{object.class} does not support CDN purging") if object
end
end
class Real
include Base
def initialize(options={})
@connection_options = options[:connection_options] || {}
credentials = Fog::Rackspace.authenticate(options, @connection_options)
@ -66,15 +106,6 @@ module Fog
end
end
def purge(object)
if object.is_a? Fog::Storage::Rackspace::File
delete_object object.directory.key, object.key
else
raise Fog::Errors::NotImplemented.new("#{object.class} does not support CDN purging") if object
end
true
end
def enabled?
@enabled
end
@ -82,6 +113,15 @@ module Fog
def reload
@cdn_connection.reset
end
def purge(file)
unless file.is_a? Fog::Storage::Rackspace::File
raise Fog::Errors::NotImplemented.new("#{object.class} does not support CDN purging")
end
delete_object file.directory.key, file.key
true
end
def request(params, parse_json = true)
begin

View file

@ -13,6 +13,8 @@ module Fog
attribute :bytes, :aliases => 'X-Container-Bytes-Used', :type => :integer
attribute :count, :aliases => 'X-Container-Object-Count', :type => :integer
attribute :cdn_cname
attr_writer :public, :public_url
def metadata=(hash)
if hash.is_a? Fog::Storage::Rackspace::Metadata
@ -34,7 +36,7 @@ module Fog
def destroy
requires :key
service.delete_container(key)
service.cdn.post_container(key, 'X-CDN-Enabled' => 'False')
service.cdn.publish_container(self, false) if cdn_enabled?
true
rescue Excon::Errors::NotFound
false
@ -49,55 +51,59 @@ module Fog
end
end
def public=(new_public)
@public = new_public
def public?
if @public.nil?
@public ||= (key && public_url) ? true : false
end
@public
end
def public?
@public ||= !public_url.nil?
def reload
@public = nil
@urls = nil
@files = nil
super
end
def public_url
requires :key
@public_url ||= begin
begin response = service.cdn.head_container(key)
if response.headers['X-Cdn-Enabled'] == 'True'
if service.rackspace_cdn_ssl == true
response.headers['X-Cdn-Ssl-Uri']
else
cdn_cname || response.headers['X-Cdn-Uri']
end
end
rescue Fog::Service::NotFound
nil
end
end
def public_url
return nil if urls.empty?
return urls[:ssl_uri] if service.ssl?
cdn_cname || urls[:uri]
end
def ios_url
urls[:ios_uri]
end
def streaming_url
urls[:streaming_uri]
end
def save
requires :key
headers = attributes[:metadata].nil? ? {} : metadata.to_headers
service.put_container(key, headers)
if service.cdn && public?
# if public and CDN connection then update cdn to public
uri_header = 'X-CDN-URI'
if service.rackspace_cdn_ssl == true
uri_header = 'X-CDN-SSL-URI'
end
@public_url = service.cdn.put_container(key, 'X-CDN-Enabled' => 'True').headers[uri_header]
elsif service.cdn && !public?
service.cdn.put_container(key, 'X-CDN-Enabled' => 'False')
@public_url = nil
elsif !service.cdn && public?
# if public but no CDN connection then error
raise(Fog::Storage::Rackspace::Error.new("Directory can not be set as :public without a CDN provided"))
end
create_container
raise Fog::Storage::Rackspace::Error.new("Directory can not be set as :public without a CDN provided") if public? && !cdn_enabled?
@urls = service.cdn.publish_container(self, public?)
true
end
private
def cdn_enabled?
service.cdn && service.cdn.enabled?
end
def urls
requires :key
return {} unless cdn_enabled?
@urls ||= service.cdn.urls(self)
end
def create_container
headers = attributes[:metadata].nil? ? {} : metadata.to_headers
service.put_container(key, headers)
end
end
end
end
end

View file

@ -14,6 +14,8 @@ module Fog
attribute :last_modified, :aliases => ['last_modified', 'Last-Modified'], :type => :time
attribute :access_control_allow_origin, :aliases => ['Access-Control-Allow-Origin']
attribute :origin, :aliases => ['Origin']
attr_writer :public
attr_accessor :directory
attr_writer :public
@ -71,12 +73,19 @@ module Fog
def public?
directory.public?
end
def public_url
requires :key
self.collection.get_url(self.key)
Files::file_url directory.public_url, key
end
def ios_url
Files::file_url directory.ios_url, key
end
def streaming_url
Files::file_url directory.streaming_url, key
end
def purge_from_cdn
if public?
service.cdn.purge(self)
@ -99,7 +108,6 @@ module Fog
self.content_type ||= Fog::Storage.get_content_type(body)
true
end
private

View file

@ -70,10 +70,10 @@ module Fog
def get_url(key)
requires :directory
if self.directory.public_url
"#{self.directory.public_url}/#{Fog::Rackspace.escape(key, '/')}"
Files::file_url directory.public_url, key
end
end
def head(key, options = {})
requires :directory
data = service.head_object(directory.key, key)
@ -90,8 +90,12 @@ module Fog
super({ :directory => directory }.merge!(attributes))
end
end
def self.file_url(path, key)
return nil unless path
"#{path}/#{Fog::Rackspace.escape(key, '/')}"
end
end
end
end
end

View file

@ -38,7 +38,8 @@ module Fog
:provider => 'Rackspace',
:rackspace_api_key => @rackspace_api_key,
:rackspace_auth_url => @rackspace_auth_url,
:rackspace_username => @rackspace_username
:rackspace_username => @rackspace_username,
:rackspace_cdn_ssl => @rackspace_cdn_ssl
)
if @cdn.enabled?
@cdn
@ -97,6 +98,10 @@ module Fog
Excon.defaults[:ssl_verify_peer] = false if options[:rackspace_servicenet] == true
@connection = Fog::Connection.new("#{@scheme}://#{@host}:#{@port}", @persistent, @connection_options)
end
def ssl?
!rackspace_cdn_ssl.nil?
end
def reload
@connection.reset

View file

@ -0,0 +1,78 @@
Shindo.tests('Fog::CDN::Rackspace', ['rackspace']) do
pending if Fog.mocking?
def container_meta_attributes
@cdn.head_container(@directory.key).headers
end
def clear_metadata
@instance.metadata.tap do |metadata|
metadata.each_pair {|k, v| metadata[k] = nil }
end
end
directory_attributes = {
# Add a random suffix to prevent collision
:key => "fogfilestests-#{rand(65536)}"
}
@directory = Fog::Storage[:rackspace].directories.create(directory_attributes)
@cdn = @directory.service.cdn
begin
tests('publish_container').succeeds do
returns(nil, "CDN is not enabled") { container_meta_attributes['X-CDN-Enabled'] }
urls = @cdn.publish_container @directory
returns(true, "hash contains expected urls") { Fog::CDN::Rackspace::Base::URI_HEADERS.values.all? { |url_type| urls[url_type] } }
returns("True", "CDN is enabled") { container_meta_attributes['X-Cdn-Enabled'] }
end
tests('urls') do
tests('CDN enabled container').returns(false) do
@cdn.publish_container @directory
@cdn.urls(@directory).empty?
end
tests('Non-CDN enabled container').returns(true) do
@cdn.publish_container @directory, false
@cdn.urls(@directory).empty?
end
tests('Non-existent container').returns(true) do
non_existent_container = Fog::Storage::Rackspace::Directory.new :key => "non-existent"
@cdn.urls(non_existent_container).empty?
end
end
tests('urls_from_headers') do
headers = {
"X-Cdn-Streaming-Uri"=>"http://168e307d41afe64f1a62-d1e9259b2132e81da48ed3e1e802ef22.r2.stream.cf1.rackcdn.com",
"X-Cdn-Uri"=>"http://6e8f4bf5125c9c2e4e3a-d1e9259b2132e81da48ed3e1e802ef22.r2.cf1.rackcdn.com",
"Date"=>"Fri, 15 Feb 2013 18:36:41 GMT",
"Content-Length"=>"0",
"X-Trans-Id"=>"tx424df53b79bc43fe994d3cec0c4d2d8a",
"X-Ttl"=>"3600",
"X-Cdn-Ssl-Uri"=>"https://f83cb7d39e0b9ff9581b-d1e9259b2132e81da48ed3e1e802ef22.ssl.cf1.rackcdn.com",
"X-Cdn-Ios-Uri"=>"http://a590286a323fec6aed22-d1e9259b2132e81da48ed3e1e802ef22.iosr.cf1.rackcdn.com",
"X-Cdn-Enabled"=>"True",
"Content-Type"=>"text/html; charset=UTF-8",
"X-Log-Retention"=>"False"
}
urls = @cdn.send(:urls_from_headers, headers)
returns(4) { urls.size }
returns("http://168e307d41afe64f1a62-d1e9259b2132e81da48ed3e1e802ef22.r2.stream.cf1.rackcdn.com") { urls[:streaming_uri] }
returns("http://6e8f4bf5125c9c2e4e3a-d1e9259b2132e81da48ed3e1e802ef22.r2.cf1.rackcdn.com") { urls[:uri] }
returns("https://f83cb7d39e0b9ff9581b-d1e9259b2132e81da48ed3e1e802ef22.ssl.cf1.rackcdn.com") { urls[:ssl_uri] }
returns("http://a590286a323fec6aed22-d1e9259b2132e81da48ed3e1e802ef22.iosr.cf1.rackcdn.com") { urls[:ios_uri] }
end
tests('purge') do
pending
end
ensure
@directory.destroy if @directory
end
end

View file

@ -14,15 +14,87 @@ Shindo.tests('Fog::Rackspace::Storage | directory', ['rackspace']) do
}
model_tests(@service.directories, directory_attributes, Fog.mocking?) do
tests('#public_url').returns(nil) do
@instance.public_url
end
tests('#public?').returns(false) do
@instance.public?
end
tests('#public_url') do
tests('http').returns(nil) do
@instance.public_url
end
@instance.cdn_cname = "my_cname.com"
tests('cdn_cname').returns(nil) do
@instance.public_url
end
@instance.cdn_cname = nil
@service.instance_variable_set "@rackspace_cdn_ssl", true
tests('ssl').returns(nil) do
@instance.public_url
end
@service.instance_variable_set "@rackspace_cdn_ssl", nil
end
tests('#ios_url').returns(nil) do
@instance.ios_url
end
tests('#streaming_url').returns(nil) do
@instance.streaming_url
end
tests('cdn') do
@instance.public = true
@instance.save
tests('#public?').returns(true) do
@instance.public?
end
tests('#public_url') do
tests('http').returns(0) do
@instance.public_url =~ /http:\/\//
end
@instance.cdn_cname = "my_cname.com"
tests('cdn_cname').returns(0) do
@instance.public_url =~ /my_cname\.com/
end
@instance.cdn_cname = nil
@service.instance_variable_set "@rackspace_cdn_ssl", true
tests('ssl').returns(0) do
@instance.public_url =~ /https:\/\/.+\.ssl\./
end
@service.instance_variable_set "@rackspace_cdn_ssl", nil
end
tests('#ios_url').returns(0) do
@instance.ios_url =~ /http:\/\/.+\.iosr\./
end
tests('#streaming_url').returns(0) do
@instance.streaming_url =~ /http:\/\/.+\.stream\./
end
end
tests("reload") do
@instance.reload
returns(nil) { @instance.instance_variable_get("@urls") }
returns(nil) { @instance.instance_variable_get("@files") }
returns(nil) { @instance.instance_variable_get("@public") }
end
end
directory_attributes[:metadata] = {:draft => 'true'}
tests('metadata') do
pending if Fog.mocking?
model_tests(@service.directories, directory_attributes, Fog.mocking?) do
tests('sets metadata on create').returns('true') do
@instance.metadata.data
@ -65,5 +137,5 @@ Shindo.tests('Fog::Rackspace::Storage | directory', ['rackspace']) do
end
end
end

View file

@ -88,6 +88,68 @@ Shindo.tests('Fog::Rackspace::Storage | file', ['rackspace']) do
ensure
@file.destroy if @file
end
tests('urls') do
tests('no CDN') do
tests('#public_url') do
tests('http').returns(nil) do
@instance.public_url
end
@directory.cdn_cname = "my_cname.com"
tests('cdn_cname').returns(nil) do
@instance.public_url
end
@directory.cdn_cname = nil
@directory.service.instance_variable_set "@rackspace_cdn_ssl", true
tests('ssl').returns(nil) do
@instance.public_url
end
@directory.service.instance_variable_set "@rackspace_cdn_ssl", nil
end
tests('#ios_url').returns(nil) do
@instance.ios_url
end
tests('#streaming_url').returns(nil) do
@instance.streaming_url
end
end
tests('With CDN') do
tests('#public_url') do
@directory.public = true
@directory.save
tests('http').returns(0) do
@instance.public_url =~ /http:\/\/.*#{@instance.key}/
end
@directory.cdn_cname = "my_cname.com"
tests('cdn_cname').returns(0) do
@instance.public_url =~ /my_cname\.com.*#{@instance.key}/
end
@directory.cdn_cname = nil
@directory.service.instance_variable_set "@rackspace_cdn_ssl", true
tests('ssl').returns(0) do
@instance.public_url =~ /https:\/\/.+\.ssl\..*#{@instance.key}/
end
@directory.service.instance_variable_set "@rackspace_cdn_ssl", nil
end
tests('#ios_url').returns(0) do
@instance.ios_url =~ /http:\/\/.+\.iosr\..*#{@instance.key}/
end
tests('#streaming_url').returns(0) do
@instance.streaming_url =~ /http:\/\/.+\.stream\..*#{@instance.key}/
end
end
end
tests('#metadata keys') do