lib/fog/storage/google_xml/real.rb
module Fog
module Storage
class GoogleXML
class Real
include Utils
# Initialize connection to Google Storage
#
# ==== Notes
# options parameter must include values for :google_storage_access_key_id and
# :google_storage_secret_access_key in order to create a connection
#
# ==== Examples
# google_storage = Storage.new(
# :google_storage_access_key_id => your_google_storage_access_key_id,
# :google_storage_secret_access_key => your_google_storage_secret_access_key
# )
#
# ==== Parameters
# * options<~Hash> - config arguments for connection. Defaults to {}.
#
# ==== Returns
# * Storage object with connection to google.
def initialize(options = {})
@google_storage_access_key_id = options[:google_storage_access_key_id]
@google_storage_secret_access_key = options[:google_storage_secret_access_key]
@connection_options = options[:connection_options] || {}
@hmac = Fog::HMAC.new("sha1", @google_storage_secret_access_key)
@host = options[:host] || "storage.googleapis.com"
@persistent = options.fetch(:persistent, true)
@port = options[:port] || 443
@scheme = options[:scheme] || "https"
@path_style = options[:path_style] || false
end
def reload
@connection.reset if @connection
end
def signature(params)
string_to_sign = <<-DATA
#{params[:method]}
#{params[:headers]['Content-MD5']}
#{params[:headers]['Content-Type']}
#{params[:headers]['Date']}
DATA
google_headers = {}
canonical_google_headers = ""
params[:headers].each do |key, value|
google_headers[key] = value if key[0..6] == "x-goog-"
end
google_headers = google_headers.sort_by { |a| a[0] }
google_headers.each do |key, value|
canonical_google_headers << "#{key}:#{value}\n"
end
string_to_sign << canonical_google_headers.to_s
canonical_resource = "/"
if subdomain = params.delete(:subdomain)
canonical_resource << "#{CGI.escape(subdomain).downcase}/"
end
canonical_resource << params[:path].to_s
canonical_resource << "?"
(params[:query] || {}).keys.each do |key|
if %w(acl cors location logging requestPayment versions versioning).include?(key)
canonical_resource << "#{key}&"
end
end
canonical_resource.chop!
string_to_sign << canonical_resource.to_s
signed_string = @hmac.sign(string_to_sign)
Base64.encode64(signed_string).chomp!
end
def connection(scheme, host, port)
uri = "#{scheme}://#{host}:#{port}"
if @persistent
unless uri == @connection_uri
@connection_uri = uri
reload
@connection = nil
end
else
@connection = nil
end
@connection ||= Fog::XML::Connection.new(uri, @persistent, @connection_options)
end
private
def request(params, &block)
params = request_params(params)
scheme = params.delete(:scheme)
host = params.delete(:host)
port = params.delete(:port)
params[:headers]["Date"] = Fog::Time.now.to_date_header
params[:headers]["Authorization"] = "GOOG1 #{@google_storage_access_key_id}:#{signature(params)}"
connection(scheme, host, port).request(params, &block)
end
end
end
end
end