class Fog::Aliyun::Storage::Real
Attributes
Initialize connection to OSS
Notes¶ ↑
options parameter must include values for :aliyun_accesskey_id, :aliyun_secret_access_key and :aliyun_oss_bucket in order to create a connection. :aliyun_oss_location will be replaced by :aliyun_region_id, and it has a default value cn-hangzhou if :aliyun_oss_endpoint is not specified, it will be generated by method region_to_endpoint
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.
Public Class Methods
# File lib/fog/aliyun/storage.rb, line 84 def initialize(options = {}) # initialize the parameters @aliyun_region_id = options[:aliyun_region_id] || options[:aliyun_oss_location] || DEFAULT_REGION @aliyun_oss_endpoint = options[:aliyun_oss_endpoint] || region_to_endpoint(@aliyun_region_id) @aliyun_accesskey_id = options[:aliyun_accesskey_id] @aliyun_accesskey_secret = options[:aliyun_accesskey_secret] @aliyun_oss_bucket = options[:aliyun_oss_bucket] @aliyun_oss_sdk_log_path=options[:aliyun_oss_sdk_log_path] if @aliyun_oss_sdk_log_path && !::File.exist?(@aliyun_oss_sdk_log_path) `touch #{@aliyun_oss_sdk_log_path}` end ENV["ALIYUN_OSS_SDK_LOG_PATH"] = @aliyun_oss_sdk_log_path # check for the parameters missing_credentials = [] missing_credentials << :aliyun_oss_bucket unless @aliyun_oss_bucket 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] || {} endpoint = @aliyun_oss_endpoint @aliyun_oss_endpoint = "#{DEFAULT_SCHEME}://#{endpoint}" unless endpoint.start_with?(DEFAULT_SCHEME) uri = URI.parse(@aliyun_oss_endpoint) @host = uri.host @path = uri.path @scheme = uri.scheme || DEFAULT_SCHEME @port = uri.port || DEFAULT_SCHEME_PORT[@scheme] @persistent = options[:persistent] || false @oss_client = AliyunOssSdk::Client.new( :endpoint => @aliyun_oss_endpoint, :access_key_id => @aliyun_accesskey_id, :access_key_secret => @aliyun_accesskey_secret ) # initiate a aliyun oss ruby sdk config and using sdk http to invoke the OSS openapi @oss_config = AliyunOssSdk::Config.new( :endpoint => @aliyun_oss_endpoint, :access_key_id => @aliyun_accesskey_id, :access_key_secret => @aliyun_accesskey_secret ) @oss_http = AliyunOssSdk::HTTP.new(@oss_config) @oss_protocol = AliyunOssSdk::Protocol.new(@oss_config) end
Public Instance Methods
Abort a multipart upload
@param [String] bucket_name Name of bucket to abort multipart upload on @param [String] object_name Name of object to abort multipart upload on @param [String] upload_id Id of upload to add part to
@see help.aliyun.com/document_detail/31996.html
# File lib/fog/aliyun/requests/storage/abort_multipart_upload.rb, line 15 def abort_multipart_upload(bucket_name, object_name, upload_id) @oss_protocol.abort_multipart_upload(bucket_name, object_name, upload_id) end
# File lib/fog/aliyun/requests/storage/get_bucket.rb, line 7 def bucket_exists?(bucket_name) @oss_client.bucket_exists?(bucket_name) end
Complete a multipart upload
@param [String] bucket_name Name of bucket to complete multipart upload for @param [String] object_name Name of object to complete multipart upload for @param [String] upload_id Id of upload to add part to @param [Array] parts Array of etag and number as Strings for parts
@see help.aliyun.com/document_detail/31995.html
# File lib/fog/aliyun/requests/storage/complete_multipart_upload.rb, line 15 def complete_multipart_upload(bucket_name, object_name, upload_id, parts) @oss_protocol.complete_multipart_upload(bucket_name, object_name, upload_id, parts) end
Copy object
Parameters¶ ↑
-
source_bucket_name<~String> - Name of source bucket
-
source_object_name<~String> - Name of source object
-
target_bucket_name<~String> - Name of bucket to create copy in
-
target_object_name<~String> - Name for new copy of object
-
options<~Hash> - Additional headers options={}
# File lib/fog/aliyun/requests/storage/copy_object.rb, line 15 def copy_object(source_bucket_name, source_object_name, target_bucket_name, target_object_name, options = {}) headers = { 'x-oss-copy-source' => "/#{source_bucket_name}#{object_to_path(source_object_name)}" }.merge!(options) resources = { :bucket => target_bucket_name, :object => target_object_name } http_options = { :headers => headers } @oss_http.put(resources, http_options) end
Delete multiple objects from OSS
@param bucket_name [String] Name of bucket containing object to delete @param object_names [Array] Array of object names to delete
@see help.aliyun.com/document_detail/31983.html
# File lib/fog/aliyun/requests/storage/delete_multiple_objects.rb, line 13 def delete_multiple_objects(bucket_name, object_names, options = {}) bucket = @oss_client.get_bucket(bucket_name) bucket.batch_delete_objects(object_names, options) end
Delete an existing object
Parameters¶ ↑
-
bucket_name<~String> - Name of bucket to delete
-
object_name<~String> - Name of object to delete
# File lib/fog/aliyun/requests/storage/delete_object.rb, line 13 def delete_object(bucket_name, object_name, options = {}) # TODO Support versionId # if version_id = options.delete('versionId') # query = {'versionId' => version_id} # else # query = {} # end @oss_http.delete({:bucket => bucket_name, :object => object_name}, {:headers => options}) end
# File lib/fog/aliyun/storage.rb, line 149 def escape(string) string.gsub(/([^a-zA-Z0-9_.\-~\/]+)/) { "%" + $1.unpack("H2" * $1.bytesize).join("%").upcase } end
# File lib/fog/aliyun/requests/storage/get_bucket.rb, line 11 def get_bucket(bucket_name, options = {}) unless bucket_name raise ArgumentError.new('bucket_name is required') end # Set the GetBucket max limitation to 1000 maxKeys = options[:max_keys] || 1000 maxKeys = maxKeys.to_i maxKeys = [maxKeys, 1000].min options[:limit] = maxKeys options.delete(:max_keys) @oss_protocol.list_objects(bucket_name, options) end
# File lib/fog/aliyun/requests/storage/get_bucket.rb, line 31 def get_bucket_CORSRules(bucket_name) @oss_protocol.get_bucket_cors(bucket_name) end
# File lib/fog/aliyun/requests/storage/get_bucket.rb, line 27 def get_bucket_acl(bucket_name) @oss_protocol.get_bucket_acl(bucket_name) end
# File lib/fog/aliyun/requests/storage/get_bucket.rb, line 35 def get_bucket_lifecycle(bucket_name) @oss_protocol.get_bucket_lifecycle(bucket_name) end
Get location constraint for an OSS bucket
@param bucket_name [String] name of bucket to get location constraint for
@see help.aliyun.com/document_detail/31967.html
note: The OSS Ruby sdk does not support get_bucket_location
and there needs to parse response
# File lib/fog/aliyun/requests/storage/get_bucket_location.rb, line 15 def get_bucket_location(bucket_name) data = @oss_http.get({:bucket => bucket_name, :sub_res => { 'location' => nil} }, {}) doc = parse_xml(data.body) doc.at_css("LocationConstraint").text end
# File lib/fog/aliyun/requests/storage/get_bucket.rb, line 39 def get_bucket_logging(bucket_name) @oss_protocol.get_bucket_logging(bucket_name) end
# File lib/fog/aliyun/requests/storage/get_bucket.rb, line 43 def get_bucket_referer(bucket_name) @oss_protocol.get_bucket_referer(bucket_name) end
# File lib/fog/aliyun/requests/storage/get_bucket.rb, line 47 def get_bucket_website(bucket_name) @oss_protocol.get_bucket_website(bucket_name) end
Get details for object
Parameters¶ ↑
-
object_name<~String> - Name of object to look for
# File lib/fog/aliyun/requests/storage/get_object.rb, line 12 def get_object(bucket_name, object_name, options = {}, &block) options = options.reject { |_key, value| value.nil? } unless bucket_name raise ArgumentError.new('bucket_name is required') end unless object_name raise ArgumentError.new('object_name is required') end # Using OSS ruby SDK to fix performance issue http_options = { :headers => {} } http_options[:query] = options.delete('query') || {} http_options[:headers].merge!(options) if options['If-Modified-Since'] http_options[:headers]['If-Modified-Since'] = Fog::Time.at(options['If-Modified-Since'].to_i).to_date_header end if options['If-Unmodified-Since'] http_options[:headers]['If-Unmodified-Since'] = Fog::Time.at(options['If-Unmodified-Since'].to_i).to_date_header end if block_given? http_options[:response_block] = Proc.new {} end resources = { :bucket => bucket_name, :object => object_name } @oss_http.get(resources, http_options, &block) end
Get access control list for an S3 object
@param bucket_name [String] name of bucket containing object @param object_name [String] name of object to get access control list for @param options [Hash] @option options versionId [String] specify a particular version to retrieve
# File lib/fog/aliyun/requests/storage/get_object_acl.rb, line 13 def get_object_acl(bucket_name, object_name, options = {}) unless bucket_name raise ArgumentError.new('bucket_name is required') end unless object_name raise ArgumentError.new('object_name is required') end # At present, sdk does not support versionId # if version_id = options.delete('versionId') # query['versionId'] = version_id # end @oss_protocol.get_object_acl(bucket_name, object_name) end
Get an expiring object http url
Parameters¶ ↑
-
bucket_name<~String> - Name of bucket
-
object_name<~String> - Name of object to get expiring url for
-
expires<~Integer> - An expiry time for this url
Returns¶ ↑
-
response<~Excon::Response>:
-
body<~String> - url for object
-
# File lib/fog/aliyun/requests/storage/get_object_http_url.rb, line 19 def get_object_http_url_public(bucket_name, object_name, expires) bucket = @oss_client.get_bucket(bucket_name) acl = bucket.acl() if acl == 'private' expires_time = (Time.now.to_i + (expires.nil? ? 0 : expires.to_i)).to_s resource = bucket_name + '/' + object_name signature = sign('GET', expires_time, nil, resource) 'http://' + bucket_name + '.' + @host + '/' + object_name + '?OSSAccessKeyId=' + @aliyun_accesskey_id + '&Expires=' + expires_time + '&Signature=' + Addressable::URI.encode_component(signature, Addressable::URI::CharacterClasses::UNRESERVED + '|') elsif acl == 'public-read' || acl == 'public-read-write' 'http://' + bucket_name + '.' + @host + '/' + object_name else 'acl is wrong with value:' + acl end end
Get an expiring object https url from Cloud Files
Parameters¶ ↑
-
bucket_name<~String> - Name of bucket
-
object_name<~String> - Name of object to get expiring url for
-
expires<~Integer> - An expiry time for this url
Returns¶ ↑
-
response<~Excon::Response>:
-
body<~String> - url for object
-
# File lib/fog/aliyun/requests/storage/get_object_https_url.rb, line 19 def get_object_https_url_public(bucket_name, object_name, expires) bucket = @oss_client.get_bucket(bucket_name) acl = bucket.acl() if acl == 'private' expires_time = (Time.now.to_i + (expires.nil? ? 0 : expires.to_i)).to_s resource = bucket_name + '/' + object_name signature = sign('GET', expires_time, nil, resource) 'https://' + bucket_name + '.' + @host + '/' + object_name + '?OSSAccessKeyId=' + @aliyun_accesskey_id + '&Expires=' + expires_time + '&Signature=' + Addressable::URI.encode_component(signature, Addressable::URI::CharacterClasses::UNRESERVED + '|') elsif acl == 'public-read' || acl == 'public-read-write' 'https://' + bucket_name + '.' + @host + '/' + object_name else 'acl is wrong with value:' + acl end end
List information about OSS buckets for authorized user
# File lib/fog/aliyun/requests/storage/get_service.rb, line 7 def get_service @oss_protocol.list_buckets end
Get headers for object
Parameters¶ ↑
-
object_name<~String> - Name of object to look for
# File lib/fog/aliyun/requests/storage/head_object.rb, line 12 def head_object(bucket_name, object_name, options={}) unless bucket_name raise ArgumentError.new('bucket_name is required') end unless object_name raise ArgumentError.new('object_name is required') end # Currently, the ruby sdk does not support versionId # if version_id = options.delete('versionId') # query = {'versionId' => version_id} # end headers = {} headers['If-Modified-Since'] = Fog::Time.at(options['If-Modified-Since'].to_i).to_date_header if options['If-Modified-Since'] headers['If-Unmodified-Since'] = Fog::Time.at(options['If-Unmodified-Since'].to_i).to_date_header if options['If-Modified-Since'] headers.merge!(options) resources = { :bucket => bucket_name, :object => object_name } http_options = { :headers => headers } @oss_http.head(resources, http_options) end
Initiate a multipart upload
@param bucket_name [String] Name of bucket to create @param object_name [String] Name of object to create @param options [Hash]
@see help.aliyun.com/document_detail/31992.html
# File lib/fog/aliyun/requests/storage/initiate_multipart_upload.rb, line 13 def initiate_multipart_upload(bucket_name, object_name, options = {}) @oss_protocol.initiate_multipart_upload(bucket_name, object_name, options) end
# File lib/fog/aliyun/requests/storage/list_buckets.rb, line 7 def list_buckets(options = {}) maxKeys = options[:max_keys] || 1000 maxKeys = maxKeys.to_i maxKeys = [maxKeys, 1000].min options[:limit] = maxKeys options.delete(:max_keys) @oss_protocol.list_buckets(options) end
# File lib/fog/aliyun/requests/storage/list_objects.rb, line 17 def list_multipart_uploads(bucket_name, _options = {}) @oss_protocol.list_multipart_uploads(bucket_name, _options) end
# File lib/fog/aliyun/requests/storage/list_objects.rb, line 7 def list_objects(bucket_name, options = {}) maxKeys = options[:max_keys] || 1000 maxKeys = maxKeys.to_i maxKeys = [maxKeys, 1000].min options[:limit] = maxKeys options.delete(:max_keys) @oss_protocol.list_objects(bucket_name, options) end
# File lib/fog/aliyun/requests/storage/list_objects.rb, line 21 def list_parts(bucket_name, object_name, upload_id, _options = {}) @oss_protocol.list_parts(bucket_name, object_name, upload_id, _options) end
# File lib/fog/aliyun/storage.rb, line 145 def object_to_path(object_name=nil) '/' + escape(object_name.to_s).gsub('%2F','/') end
# File lib/fog/aliyun/requests/storage/put_bucket.rb, line 7 def put_bucket(bucket_name, options = {}) @oss_protocol.create_bucket(bucket_name, options) end
Put details for object
Parameters¶ ↑
-
bucket_name<~String> - Name of bucket to look for
-
object_name<~String> -
Object
of object to look for -
data<~File>
-
options<~Hash>
# File lib/fog/aliyun/requests/storage/put_object.rb, line 15 def put_object(bucket_name, object_name, data, options = {}) if data.is_a? ::File @oss_protocol.put_object(bucket_name, object_name, options)do |sw| while line = data.read(16*1024) sw.write(line) end end else content=StringIO.new(data.dup) @oss_protocol.put_object(bucket_name, object_name, options)do |sw| while line=content.read(16*1024) sw.write(line) end end content.close end end
# File lib/fog/aliyun/storage.rb, line 136 def region_to_endpoint(region = nil) case region.to_s when '' "oss-#{DEFAULT_REGION}.aliyuncs.com" else "oss-#{region}.aliyuncs.com" end end
# File lib/fog/aliyun/storage.rb, line 132 def reload @connection.reset end
# File lib/fog/aliyun/storage.rb, line 155 def request(params) method = params[:method] time = Time.new.utc date = time.strftime('%a, %d %b %Y %H:%M:%S GMT') bucket = params[:bucket] tmpHost = if bucket bucket + '.' + @host else @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| headers += "#{k}:#{v}\n" if k != 'Range' 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::Aliyun::Storage::NotFound.slurp(error) else error end end response end
copmute signature
# File lib/fog/aliyun/storage.rb, line 198 def sign(method, date, contentType, resource = nil, headers = nil) contentmd5 = '' canonicalizedResource = if resource '/' + resource else '/' end canonicalizedOSSHeaders = headers || '' contentTypeStr = contentType || '' 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] = '' signature end
Upload a part for a multipart upload
@param bucket_name [String] Name of bucket to add part to @param object_name [String] Name of object to add part to @param upload_id [String] Id of upload to add part to @param part_number [String] Index of part in upload @param data [File||String] Content for part
@see help.aliyun.com/document_detail/31993.html
# File lib/fog/aliyun/requests/storage/upload_part.rb, line 16 def upload_part(bucket_name, object_name, upload_id, part_number, data) @oss_protocol.upload_part(bucket_name, object_name, upload_id, part_number) do |sw| sw.write(data) end end
Private Instance Methods
# File lib/fog/aliyun/requests/storage/get_bucket_location.rb, line 23 def parse_xml(content) doc = Nokogiri::XML(content) do |config| config.options |= Nokogiri::XML::ParseOptions::NOBLANKS end doc end