class Aliyun::Connection
Attributes
The alias host
The external host
The internal host
The upload host according to the connection configurations
Public Class Methods
Initialize the OSS connection
@param [Hash] An options to specify connection details @option access_id [String] used to set “Authorization” request header @option access_key [String] the access key @option bucket [String] bucket used to access @option data_center [String] available data center name, e.g. 'cn-hangzhou' @option internal [true, false] if the service should be accessed through internal network @option host_alias [String] the alias of the host, such as the CDN domain name @option protocol [String] 'http' or 'https', default to 'http' @option protocol_relative_url [true, false] if to use protocol relative url, en.wikipedia.org/wiki/Wikipedia:Protocol-relative_URL @note both access_id and acces_key are related to authorization algorithm:
https://docs.aliyun.com/#/pub/oss/api-reference/access-control&signature-header
# File lib/aliyun/connection.rb, line 38 def initialize(options = {}) @aliyun_access_id = options[:access_id] @aliyun_access_key = options[:access_key] @aliyun_bucket = options[:bucket] @aliyun_protocol_relative_url = !!options[:protocol_relative_url] @aliyun_protocol = options[:protocol] || 'http' @aliyun_upload_host = "#{@aliyun_bucket}.#{get_endpoint(options)}" @aliyun_internal_host = "#{@aliyun_bucket}.#{get_endpoint(options.merge(internal: true))}" @aliyun_external_host = "#{@aliyun_bucket}.#{get_endpoint(options.merge(internal: false))}" @aliyun_alias_host = options[:host_alias] || @aliyun_upload_host end
Public Instance Methods
Delete a file from the OSS docs.aliyun.com/#/pub/oss/api-reference/object&DeleteObject
@param path [String] the path to retrieve the file on remote storage @return [String] the expired url to the file, if the file deleted successfully @return [nil] if the delete operation failed
# File lib/aliyun/connection.rb, line 122 def delete(path) path = format_path(path) bucket_path = get_bucket_path(path) date = gmtdate headers = { 'Host' => @aliyun_upload_host, 'Date' => date, 'Authorization' => sign('DELETE', bucket_path, '', '', date) } url = path_to_url(path) response = RestClient.delete(url, headers) response.code == 204 ? url : nil end
Determine if the file exists on the OSS docs.aliyun.com/#/pub/oss/api-reference/object&HeadObject
@param path [String] the path to retrieve the file on remote storage @return [true] if file exists @return [false] if file could not be found
# File lib/aliyun/connection.rb, line 161 def exists?(path) head(path).empty? ? false : true end
remove leading slashes in the path
@param path [String] the path to retrieve the file on remote storage @return [String] the new string after removing leading slashed
# File lib/aliyun/connection.rb, line 177 def format_path(path) path.blank? ? '' : path.gsub(%r{^/+}, '') end
Download the file from OSS docs.aliyun.com/#/pub/oss/api-reference/object&GetObject
@param path [String] the path to retrieve the file on remote storage @return [?] the file content consist of bytes
# File lib/aliyun/connection.rb, line 141 def get(path) path = format_path(path) bucket_path = get_bucket_path(path) date = gmtdate headers = { 'Host' => @aliyun_upload_host, 'Date' => date, 'Authorization' => sign('GET', bucket_path, '', '', date) } url = path_to_url(path) response = RestClient.get(url, headers) response.body end
A path consis of the bucket name and file name docs.aliyun.com/#/pub/oss/api-reference/access-control&signature-header
@param path [String] the path to retrieve the file on remote storage @return [String] the expected bucket path, e.g. “test-bucket/oss-api.pdf”
# File lib/aliyun/connection.rb, line 186 def get_bucket_path(path) [@aliyun_bucket, path].join('/') end
The GMT format time referenced from HTTP 1.1 docs.aliyun.com/#/pub/oss/api-reference/public-header
@return [String] a string represents the formated time, e.g. “Wed, 05 Sep. 2012 23:00:00 GMT”
# File lib/aliyun/connection.rb, line 169 def gmtdate Time.now.gmtime.strftime('%a, %d %b %Y %H:%M:%S GMT') end
Return the meta informations for a file specified by the path docs.aliyun.com/#/pub/oss/api-reference/object&HeadObject
@param path [String] the path of file storaged in Aliyun
OSS @return [Hash] the meta data of the file @note the example headers will be like:
{ {:date=>"Sun, 02 Aug 2015 02:42:45 GMT", :content_type=>"image/jpg", :content_length=>"125198", :connection=>"close", :accept_ranges=>"bytes", :etag=>"\"336262A42E5B99AFF5B8BC66611FC156\"", :last_modified=>"Sun, 01 Dec 2013 16:39:57 GMT", :server=>"AliyunOSS", :x_oss_object_type=>"Normal", :x_oss_request_id=>"55BD83A5D4C05BDFF4A329E0"}}
# File lib/aliyun/connection.rb, line 70 def head(path) path = format_path(path) bucket_path = get_bucket_path(path) date = gmtdate headers = { 'Host' => @aliyun_upload_host, 'Date' => date, 'Authorization' => sign('HEAD', bucket_path, '', '', date) } url = path_to_url(path) RestClient.head(url, headers).headers rescue RestClient::ResourceNotFound {} end
The full path contains host name to the file
@param path [String] the path to retrieve the file on remote storage @return [String] the expected full path, e.g. “martin-test.oss-cn-hangzhou.aliyuncs.com/oss-api.pdf”
# File lib/aliyun/connection.rb, line 194 def path_to_url(path) URI.encode(path =~ %r{^https?://} ? path : "http://#{aliyun_upload_host}/#{path}") end
Upload File to Aliyun
OSS docs.aliyun.com/#/pub/oss/api-reference/object&PutObject
@param path [String] the target storing path on the oss @param file [File] an instance of File represents a file to be uploaded @param options [Hash]
- content_type - MimeType value for the file, default is "image/jpg"
@return [String] The downloadable url of the uploaded file @return [nil] if the uploading failed
# File lib/aliyun/connection.rb, line 95 def put(path, file, options = {}) path = format_path(path) bucket_path = get_bucket_path(path) content_md5 = Digest::MD5.file(file).base64digest content_type = options[:content_type] || 'image/jpg' date = gmtdate url = path_to_url(path) auth_sign = sign('PUT', bucket_path, content_md5, content_type, date) headers = { 'Authorization' => auth_sign, 'Content-Md5' => content_md5, 'Content-Type' => content_type, 'Content-Length' => file.size, 'Date' => date, 'Host' => @aliyun_upload_host, 'Expect' => '100-Continue' } response = RestClient.put(url, file, headers) response.code == 200 ? path_to_url(path) : nil end
Private Instance Methods
The signature algorithm docs.aliyun.com/#/pub/oss/api-reference/access-control&signature-header
@param verb [String] the request verb, e.g. “GET” or “DELETE” @param content_md5 [String] the md5 value for the content to be uploaded @param content_type [String] the content type of the file, e.g. “application/pdf” @param date [String] the GMT formatted date string
# File lib/aliyun/connection.rb, line 207 def sign(verb, path, content_md5, content_type, date) canonicalized_oss_headers = '' canonicalized_resource = "/#{path}" string_to_sign = [ verb, content_md5, content_type, date, canonicalized_oss_headers + canonicalized_resource ].join("\n") digest = OpenSSL::Digest.new('sha1') h = OpenSSL::HMAC.digest(digest, @aliyun_access_key, string_to_sign) "OSS #{@aliyun_access_id}:#{Base64.encode64(h)}" end