require 'xmlsimple' module Fog module Storage class Aliyun < Fog::Service recognizes :aliyun_oss_endpoint, :aliyun_oss_location, :aliyun_oss_bucket, :aliyun_accesskey_id, :aliyun_accesskey_secret model_path 'fog/aliyun/models/storage' model :directory collection :directories model :file collection :files request_path 'fog/aliyun/requests/storage' request :copy_object request :delete_bucket request :delete_object request :get_bucket request :get_object request :get_object_http_url request :get_object_https_url request :head_object request :put_bucket request :put_object request :list_buckets request :list_objects request :get_containers request :get_container request :delete_container request :put_container class Real # Initialize connection to OSS # # ==== Notes # options parameter must include values for :aliyun_oss_endpoint, :aliyun_accesskey_id, # :aliyun_secret_access_key, :aliyun_oss_location and :aliyun_oss_bucket in order to create a connection. # if you haven't set these values in the configuration file. # # ==== Examples # sdb = Fog::Storage.new(:provider=>'aliyun', # :aliyun_accesskey_id => your_:aliyun_accesskey_id, # :aliyun_secret_access_key => your_aliyun_secret_access_key # ) # # ==== Parameters # * options<~Hash> - config arguments for connection. Defaults to {}. # # ==== Returns # * OSS object with connection to aliyun. attr_reader :aliyun_accesskey_id attr_reader :aliyun_accesskey_secret attr_reader :aliyun_oss_endpoint attr_reader :aliyun_oss_location attr_reader :aliyun_oss_bucket def initialize(options={}) #initialize the parameters @aliyun_oss_endpoint = options[:aliyun_oss_endpoint] @aliyun_oss_location = options[:aliyun_oss_location] @aliyun_accesskey_id = options[:aliyun_accesskey_id] @aliyun_accesskey_secret = options[:aliyun_accesskey_secret] @aliyun_oss_bucket = options[:aliyun_oss_bucket] #check for the parameters missing_credentials = Array.new missing_credentials << :aliyun_oss_endpoint unless @aliyun_oss_endpoint missing_credentials << :aliyun_oss_location unless @aliyun_oss_location missing_credentials << :aliyun_accesskey_id unless @aliyun_accesskey_id missing_credentials << :aliyun_accesskey_secret unless @aliyun_accesskey_secret raise ArgumentError, "Missing required arguments: #{missing_credentials.join(', ')}" unless missing_credentials.empty? @connection_options = options[:connection_options] || {} uri = URI.parse(@aliyun_oss_endpoint) @host = uri.host @path = uri.path @port = uri.port @scheme = uri.scheme @persistent = options[:persistent] || false end def reload @connection.reset end def request(params) method = params[:method] time = Time.new.utc date = time.strftime("%a, %d %b %Y %H:%M:%S GMT") endpoint = params[:endpoint] if endpoint uri = URI.parse(endpoint) host = uri.host path = uri.path port = uri.port scheme = uri.scheme else host = @host path = @path port = @port scheme = @scheme end bucket = params[:bucket] if bucket tmpHost = bucket + '.' + host else tmpHost = host end @connection = Fog::Core::Connection.new("#{scheme}://#{tmpHost}", @persistent, @connection_options) contentType = params[:contentType] begin headers = "" if params[:headers] params[:headers].each do |k,v| if k != "Range" headers += "#{k}:#{v}\n" end end end signature = sign(method, date, contentType, params[:resource], headers) response = @connection.request(params.merge({ :headers => { 'Content-Type' => contentType, 'Authorization' =>'OSS '+@aliyun_accesskey_id+':'+signature, 'Date' => date }.merge!(params[:headers] || {}), :path => "#{path}/#{params[:path]}", :query => params[:query] })) rescue Excon::Errors::HTTPStatusError => error raise case error when Excon::Errors::NotFound Fog::Storage::Aliyun::NotFound.slurp(error) else error end end response end #copmute signature def sign (method, date, contentType, resource=nil, headers = nil) contentmd5 = "" if resource canonicalizedResource = "/"+resource else canonicalizedResource = "/" end if headers canonicalizedOSSHeaders = headers else canonicalizedOSSHeaders = "" end if contentType contentTypeStr = contentType else contentTypeStr = "" end stringToSign = method+"\n"+contentmd5+"\n"+contentTypeStr+"\n"+date+"\n"+canonicalizedOSSHeaders+canonicalizedResource digVer = OpenSSL::Digest.new("sha1") digest = OpenSSL::HMAC.digest(digVer, @aliyun_accesskey_secret, stringToSign) signature = Base64.encode64(digest) signature[-1] = "" return signature end end class Mock def initialize(options={}) @aliyun_oss_endpoint = options[:aliyun_oss_endpoint] @aliyun_oss_location = options[:aliyun_oss_location] @aliyun_accesskey_id = options[:aliyun_accesskey_id] @aliyun_accesskey_secret = options[:aliyun_accesskey_secret] @aliyun_oss_bucket = options[:aliyun_oss_bucket] #missing_credentials = Array.new #missing_credentials << :aliyun_oss_endpoint unless @aliyun_oss_endpoint #missing_credentials << :aliyun_oss_location unless @aliyun_oss_location #missing_credentials << :aliyun_accesskey_id unless @aliyun_accesskey_id #missing_credentials << :aliyun_accesskey_secret unless @aliyun_accesskey_secret #raise ArgumentError, "Missing required arguments: #{missing_credentials.join(', ')}" unless missing_credentials.empty? @connection_options = options[:connection_options] || {} #uri = URI.parse(@aliyun_oss_endpoint) #@host = uri.host #@path = uri.path #@port = uri.port #@scheme = uri.scheme #@persistent = options[:persistent] || false end end end end end