OSS Ruby SDK
Aliyun Open Storage Service Ruby SDK.
Being Aliyun-launched cloud storage service for users, the Open Storage Service (OSS for short) features mass capacity, security, high cost-effectiveness and reliability. It enables users to upload or download data to or from any device on the Internet at any time and place, and manage data on the WEB page by using the simple REST interface.
Installation
Add this line to your application's Gemfile:
gem 'oss'
And then execute:
$ bundle
Or install it yourself as:
$ gem install oss
Usage
Create Account
Go to OSS website, create a new account for new user.
After account created, you can create the OSS instance and get the accessKeyId
and accessKeySecret
.
Rails Application
Config:
create oss.yml
file in your rails application config
path:
default: &default
access_key_id: ""
access_key_secret: ""
endpoint: ""
bucket: ""
production:
<<: *default
staging:
<<: *default
development:
<<: *default
test:
<<: *default
Rails Application Usage Demo:
http://git.oschina.net/raymond/oss-rails-demo
Quick Start
1. Initialize OSS API
# require the gem if you not set in Gemfile
require 'oss'
endpoint = 'oss-cn-hangzhou.aliyuncs.com'
@api = Oss::Api.new(endpoint, access_key_id, access_key_secret)
2. Create New Bucket
# set bucket name
bucket_name = 'bucket_name'
# set bucket acl
acl = 'public-read'
puts 'create bucket success' if @api.put_bucket(bucket_name, acl)
you can find more api options in API Doc OSS::Bucket
3. Upload Object
file = File.read('/path/to/your/file')
puts 'create object success' if @api.put_object('bucket_name', 'object_name', file)
you can find more api options in API Doc OSS::Object
4. List All Objects
bucket = @api.get_bucket('bucket_name')
p bucket.contents
you can find more api options in API Doc OSS::Bucket
5. Get(download) A Object
object = @api.get_object('bucket_name', 'object_name')
# show all file headers
p object.headers
# save file
file = File.new('/path/to/save', 'w')
file.puts object.body
file.close
you can find more api options in API Doc OSS::Object
6. Get Object URL
# get default url
puts @api.get_object_url('bucket_name', 'object_name')
# get internal url
puts @api.get_object_url('bucket_name', 'object_name', :from => 'internal')
# get cdn url
puts @api.get_object_url('bucket_name', 'object_name', :from => 'cdn', :cdn_domain => 'your.cdn.domain')
API
Service Operations
Class Oss::Service
.get_service(options)
List buckets in this account.
parameters:
options
Hash query parameters, default isnil
prefix
string search buckets usingprefix
keymarker
string search start frommarker
, includingmarker
keymax_keys
String max buckets, default is100
, limit to1000
service = @api.get_service(prefix: 'prefix')
Success will return service class object, use chain method get response params.
.buckets
return buckets Arrayservice.buckets.each do |bucket| puts bucket[:location] puts bucket[:name] puts bucket[:creation_date] end
.owner
return owner infoputs service.owner[:id] puts service.owner[:name]
.prefix, .marker, .max_keys, .is_truncated, .next_marker
return option infosputs service.prefix puts service.max_keys
.list_buckets
same as get_service, its a alias
Bucket Operations
Class Oss::Bucket
.put_bucket(bucket_name, acl)
Create a new bucket.
parameters:
name
String bucket nameacl
String set bucket acl,public-read-write
,public-read
,private
@api.put_bucket('bucket_name', 'public-read')
if success will return true
.put_bucket_acl(bucket_name, acl)
Update the bucket ACL.
parameters:
name
String bucket nameacl
String set bucket acl,public-read-write
,public-read
,private
@api.put_bucket_acl('bucket_name', 'public-read')
if success will return true
.put_bucket_logging(bucket_name, target_bucket, enable, target_prefix)
Update the bucket logging settings. Log file will create every one hour and name format:
parameters:
name
{String} bucket nametarget_bucket
{String} log storage target bucketenable
{Bool} enable or disable logtarget_prefix
{String} log file prefix
@api.put_bucket_logging('bucket_name', 'bucket_name', true, 'prefix-')
if success will return true
.put_bucket_website(bucket_name, index_doc, error_doc)
Set the bucket as a static website.
parameters:
bucket_name
{String} bucket nameindex_doc
{String} index file object keyerror_doc
{String} error file object key
@api.put_bucket_website('bucket_name', 'index.html', '404.html')
if success will return true
.put_bucket_referer(bucket_name, allow_empty, referer_list)
Set the bucket request Referer white list.
parameters:
bucket_name
{String} bucket nameallow_empty
{Bool} allow empty request referer or notreferer_list
{Array} Referer white list, e.g.: [ 'https://www.taobao.com', 'http://www.aliyun.com' ]
referer_list = [ 'https://www.taobao.com', 'http://www.aliyun.com' ]
@api.put_bucket_referer('bucket_name', true, referer_list)
if success will return true
.put_bucket_lifecycle(bucket_name, rules)
Set the bucket object lifecycle.
parameters:
bucket_name
{String} bucket namerules
{Array} rule config list, each Rule will contains blow properties:id
{String} rule id, if not set, OSS will auto create it with random string.prefix
{String} store prefixstatus
{Bool} rule status, true or false[days]
{Number} expire after the days[date]
{String} expire date, e.g.:2022-10-11T00:00:00.000Z
date and days only set one.
rules = [
{id: 'rule1', days: 300, prefix: 'pre-', status: true},
{id: 'rule2', date: '2022-10-11T00:00:00.000Z', prefix: 'log-', status: true}
]
@api.put_bucket_lifecycle('bucket_name', rules)
if success will return true
.get_bucket(bucket_name, options)
List objects in the bucket.
parameters:
bucket_name
{String} bucket nameoptions
query parameters, default isnil
[prefix]
{String} search object using prefix key[marker]
{String} search start from marker, including marker key[delimiter]
{String} delimiter search scope e.g. / only search current dir, not including subdir[max_keys]
{String|Number} max objects, default is 100, limit to 1000
list = @api.get_bucket('bucket_name')
Success will return service class object, use chain method get response params.
.contents
Success will return objects list on objects properties.
list.contents.each do |object|
puts object[:key]
puts object[:last_modified]
puts object[:etag]
puts object[:type]
...
end
name
{String} object name on osslastModified
{String} object last modified GMT date, e.g.: 2015-02-19T08:39:44.000Zetag
{String} object etag contains ", e.g.: "5B3C1A2E053D763E1B002CC607C5A0FE"type
{String} object type, e.g.: Normalsize
{String} object size, e.g.: 344606storage_class
{String} storage class type, e.g.: Standardowner
{Hash} object owner, includingid
anddisplay_name
.prefixes
{Array} prefix list.is_truncated
{Boolean} truncate or not.next_marker
{String} next marker string
.get_bucket_acl(bucket_name)
Get the bucket ACL.
parameters:
bucket_name
{String} bucket name
Success will return Hash:
grant
{String} acl settings stringowner
{Hash} object owner, includingid
anddisplay_name
.get_bucket_location(bucket_name)
Get the bucket ACL.
parameters:
bucket_name
{String} bucket name
Success will return location string.
puts @api.get_bucket_location('bucket_name')
.get_bucket_logging(bucket_name)
Get the bucket logging settings.
parameters:
bucket_name
{String} bucket name
Success will return Hash:
logging_enabled
{Bool} enable logging or nottarget_bucket
{String} log store buckettarget_prefix
{String} log file prefix
log = @api.get_bucket_logging('bucket_name')
puts log[:logging_enabled]
puts log[:target_bucket]
puts log[:target_prefix]
.get_bucket_referer(bucket_name)
Get the bucket request Referer white list.
parameters:
bucket_name
{String} bucket name
Success will return Hash:
allow_empty_referer
{Bool} allow empty request referer or notreferers
{Array} Referer white list
puts @api.get_bucket_referer('bucket_name')
.get_bucket_website(bucket_name)
Get the bucket website config.
parameters:
bucket_name
{String} bucket name
Success will return Hash:
index_doc
{String} index pageerror_doc
{String} error page, maybe nil
puts @api.get_bucket_website('bucket_name')
.get_bucket_lifecycle(bucket_name)
Get the bucket object lifecycle.
bucket_name
{String} bucket name
Success will return lifecycle rules Array:
id
{String} rule id, if not set, OSS will auto create it with random string.prefix
{String} store prefixstatus
{Bool} rule status, true or false[days]
{Number} expire after the days[date]
{String} expire date, e.g.:2022-10-11T00:00:00.000Z
date and days only has one.
puts @api.get_bucket_lifecycle('bucket_name')
.delete_bucket_logging(bucket_name)
Delete the bucket logging settings.
parameters:
bucket_name
{String} bucket name
Success will return true
puts @api.delete_bucket_logging('bucket_name')
.delete_bucket_website(bucket_name)
Delete the bucket website config.
parameters:
bucket_name
{String} bucket name
Success will return true
puts @api.delete_bucket_website('bucket_name')
.delete_bucket_lifecycle(bucket_name)
Delete the bucket object lifecycle.
parameters:
bucket_name
{String} bucket name
Success will return true
puts @api.delete_bucket_lifecycle('bucket_name')
.delete_bucket(bucket_name)
Delete an empty bucket.
bucket_name
{String} bucket name
Success will return true
puts @api.delete_bucket('bucket_name')
Object Operations
Class Oss::Object
.put_object(bucket_name, object, file, options)
Add an object to the bucket.
parameters:
bucket_name
{String} bucket nameobject
{String} object key namefile
{String} file stringoptions
{Hash} optional parametersexpires
{String} expires time (milliseconds) for download, e.g.: 3600000content_control
{String} cache control for download, e.g.: public, no-cachecontent_encoding
{String} object content encoding for downloadcontent_type
{String} object content typecontent_disposition
{String} object name for downloadencryption
{String} oss server side encryptionAES256
acl
{String} object acl
Success will return true
file = File.read('/path/to/your/file')
puts @api.put_object('bucket_name', 'object_name', file)
.copy_object(bucket_name, object, old_bucket, old_object, options)
To copy an existing object on OSS to form another object.
parameters:
bucket_name
{String} bucket nameobject
{String} object key nameold_bucket
{String} existing object bucketold_object
{String} existing objectoptions
{Hash} optional parametersencryption
{String} oss server side encryptionAES256
acl
{String} object acl headerif_none_match
{String} x-oss-copy-source-if-none-match headerif_match
{String} x-oss-copy-source-if-match headerif_unmodified_since
{String} x-oss-copy-source-if-unmodified-since headerif_modified_since
{String} x-oss-copy-source-if-modified-since headermetadata_directive
{String} x-oss-metadata-directive header
Success will return Hash:
last_modify
the object last modify timeetag
the object etag
result = @api.copy_object('bucket_name', 'object_name', 'old_bucket', 'old_object')
puts result[:last_modify]
puts result[:etag]
.get_object_url(bucket_name, object, options)
Get an object url from the bucket.
parameters:
bucket_name
{String} bucket nameobject
{String} object key nameoptions
{Hash} optional parametersfrom
{String} default nil,internal
get url from ECS internal network,cdn
get url from custom CDN networkcdn_domain
{String} iffrom
set withcdn
, set your custom CDN domain
Success will return url string
puts @api.get_object_url('bucket_name', 'object_name')
.get_object(bucket_name, object, options)
Get an object from the bucket.
parameters:
bucket_name
{String} bucket nameobject
{String} object key nameoptions
{Hash} optional parametersif_none_match
{String} x-oss-copy-source-if-none-match headerif_match
{String} x-oss-copy-source-if-match headerif_unmodified_since
{String} x-oss-copy-source-if-unmodified-since headerif_modified_since
{String} x-oss-copy-source-if-modified-since headerrange
{String} http range header
Success will return response object:
object = @api.get_object('bucket_name', 'object_name')
# show all file headers
p object.headers
# save file
file = File.new('/path/to/save', 'w')
file.puts object.body
file.close
.append_object(bucket_name, object, file, position, options)
Append file to a exist object.
parameters:
bucket_name
{String} bucket nameobject
{String} object key namefile
{String} append file contentposition
{Integer} append file positionoptions
{Hash} optional parameters
Success will return Hash:
hash_crc64ecma
{String} append object hash crc64next_append_position
{String} next append position
file = File.read('/path/to/your/file')
result = @api.append_object('bucket_name', 'object_name', file, 'old_object', 0)
puts result[:hash_crc64ecma]
puts result[:next_append_position]
.delete_object(bucket_name, object_name)
Delete the object.
parameters:
bucket_name
{String} bucket nameobject_name
{String} object name
Success will return true
puts @api.delete_object('bucket_name', 'object_name')
.delete_multiple_objects(bucket_name, objects)
Delete multiple objects.
parameters:
bucket_name
{String} bucket nameobjects
{Array} object names
Success will return success deleted object names
puts @api.delete_multiple_objects('bucket_name', ['object_name1', 'object_name2'])
.head_object(bucket_name, object_name, options)
Head an object and get the meta info.
parameters:
bucket_name
{String} bucket nameobject_name
{String} object nameoptions
{Hash} optional parametersif_none_match
{String} x-oss-copy-source-if-none-match headerif_match
{String} x-oss-copy-source-if-match headerif_unmodified_since
{String} x-oss-copy-source-if-unmodified-since headerif_modified_since
{String} x-oss-copy-source-if-modified-since header
Success will return response headers
puts @api.head_object('bucket_name', 'object_name')
.put_object_acl(bucket_name, object_name, acl)
Set the object ACL.
parameters:
bucket_name
{String} bucket nameobject_name
{String} object nameacl
{String} ACL control header
Success will return true
puts @api.put_object_acl('bucket_name', 'object_name', 'public-read')
.get_object_acl(bucket_name, object_name)
Get the object ACL.
parameters:
bucket_name
{String} bucket nameobject_name
{String} object name
Success will return Hash:
grant
{String} acl settings stringowner
{Hash} object owner, includingid
anddisplay_name
puts @api.get_object_acl('bucket_name', 'object_name')
.post_object(bucket_name, key, options)
Create form post upload parameters.
parameters:
bucket_name
{String} bucket namekey
form upload keyoptions
Form field
return form post need parameters including OSSAccessKeyId
Signature
@form_info = @api.post_object('bucket_name', 'object_name', )
# render @form_info in views
Multipart Upload Operations
Class Oss::Multipart
.initiate_multipart_upload(bucket_name, object_name, options)
The Initiate Multipart Upload interface must be called to notify OSS that a Multipart Upload event should be initiated before data transfer starts in the Multipart Upload mode. This interface will then return a globally unique Upload ID created by OSS to identify the Multipart Upload event. With the ID users can initiate related operations including stopping Multipart Upload, querying Multipart Upload, etc.
parameters:
bucket_name
{String} bucket nameobject_name
{String} object nameoptions
{Hash} optional parametersexpires
{String} expires time (milliseconds) for download, e.g.: 3600000content_control
{String} cache control for download, e.g.: public, no-cachecontent_encoding
{String} object content encoding for downloadcontent_disposition
{String} object name for downloadencryption
{String} oss server side encryptionAES256
Success will return Hash:
bucket
{String} bucket namekey
{String} keyupload_id
{String} upload_id
result = @api.initiate_multipart_upload('bucket_name', 'object_name')
put result[:bucket]
put result[:key]
put result[:upload_id]
.upload_part(bucket_name, object_name, upload_id, file, part_number, options)
After a Multipart Upload is initialized, data can be uploaded by part according to the specified Object name and Upload ID. Each part uploaded has an identification number (Part number, range: 1-10,000).
parameters:
bucket_name
{String} bucket nameobject_name
{String} object nameupload_id
{String} upload idpart_number
{Integer} upload part numberfile
{String} file contentoptions
{Hash} optional parameters
Success will return Hash:
etag
{String} part etagpart_number
{String} part_number
file = File.read('/file/to/path')
result = @api.upload_part('bucket_name', 'object_name', upload_id, 1, file)
put result[:etag]
put result[:part_number]
.upload_part_copy(bucket_name, object_name, upload_id, old_bucket, old_object, part_number, options)
The interface Upload Part Copy is used to upload a Part data by copying the data from an existing Object.
parameters:
bucket_name
{String} bucket nameobject_name
{String} object nameupload_id
{String} upload idold_bucket
{String} exist source bucket nameold_object
{String} exist source object namepart_number
{Integer} upload part numberoptions
{Hash} optional parametersif_none_match
{String} x-oss-copy-source-if-none-match headerif_match
{String} x-oss-copy-source-if-match headerif_unmodified_since
{String} x-oss-copy-source-if-unmodified-since headercopy_source_begin
{Integer} copy source begin bytecopy_source_end
{Integer} copy source end byte
Success will return Hash:
etag
{String} part etaglast_modify
{String} object last modify time
= {copy_source_begin: 0, copy_source_end: 1024}
result = @api.upload_part_copy('bucket_name', 'object_name', upload_id, 'old_bucket', 'old_object', 1, )
put result[:etag]
put result[:last_modify]
.complete_multipart_upload(bucket_name, object_name, upload_id, parts)
After all the Part data are uploaded, the API of Complete Multipart Upload must be called to complete the Multipart Upload of the entire file.
parameters:
bucket_name
{String} bucket nameobject_name
{String} object nameupload_id
{String} upload idparts
{Array} uploaded parts Hash includingpart_number
etag
Success will return Hash:
location
{String} storage locationbucket
{String} bucket namekey
{String} object keyetag
{String} object etag
parts = [{etag: 'etag1', part_number: 1}, {etag: 'etag2', part_number: 2}]
result = @api.complete_multipart_upload('bucket_name', 'object_name', upload_id, parts)
put result[:location]
put result[:bucket]
put result[:key]
put result[:etag]
.abort_multipart_upload(bucket_name, object_name, upload_id)
This interface can be used to abort a Multipart Upload event according to the corresponding Upload ID offered by the user.
parameters:
bucket_name
{String} bucket nameobject_name
{String} object nameupload_id
{String} upload id
Success will return true
puts @api.abort_multipart_upload('bucket_name', 'object_name', upload_id)
.list_multipart_upload(bucket_name, options)
This interface can list all Multipart Upload events under execution, which means all the events initialized but neither completed nor aborted.
parameters:
bucket_name
{String} bucket nameupload_id
{String} upload idoptions
{Hash} optional parametersdelimiter
{string} A character for grouping the names of Objects.prefix
{string} search object usingprefix
keykey_marker
{string} Used together with the upload-id-marker parameter to specify the initial position of returned resultsmax_uploads
{String} max uploads, default is100
, limit to1000
upload-id-marker
{String} Used together with the key-marker parameter to specify the initial position of return results.
Success will return the class object, use chain method get response params.
.uploads
return uploads Array including Hash:key
{String} upload keyupload_id
{String} upload idinitiated
{String} initiated time
list = @api.list_multipart_upload('bucket_name', upload_id)
list.uploads.each do |object|
puts object[:key]
puts object[:upload_id]
puts object[:initiated]
end
.list_parts(bucket_name, object_name, options)
The interface List Parts can be used to list all Parts corresponding to a specified Upload ID which have been successfully uploaded.
parameters:
bucket_name
{String} bucket nameobject_name
{String} object nameoptions
{Hash} optional parametersuploadId
{String} search upload idmax_parts
{String} search max partspart_number_marker
{String} search part number
Success will return the class object, use chain method get response params.
.parts
return parts Array including Hash:part_number
{String} part numberlast_modified
{String} last modified timeetag
{String} part etagsize
{String} part size
list = @api.list_parts('bucket_name', 'object_name')
list.parts.each do |part|
puts part[:part_number]
puts part[:last_modified]
puts part[:etag]
puts part[:size]
end
CORS (Cross-Origin Resource Sharing) Operations
Class Oss::Cors
.put_bucket_cors(bucket_name, rules)
The operation Put Bucket cors will set a CORS rule on a specified bucket. If a rule is already existent, the original rule will be overlaid.
parameters:
bucket_name
{String} bucket namerules
{Array} rules array e.g.[[{key: 'AllowedOrigin', value: '*'}, {key: 'AllowedMethod', value: 'GET'}], [{key: 'AllowedOrigin', value: 'http://www.a.com'}, {key: 'AllowedMethod', value: 'PUT'}]]
Success will return true
rules = [[{key: 'AllowedOrigin', value: '*'}, {key: 'AllowedMethod', value: 'GET'}], [{key: 'AllowedOrigin', value: 'http://www.a.com'}, {key: 'AllowedMethod', value: 'PUT'}]]
puts @api.put_bucket_cors('bucket_name', rules)
.get_bucket_cors(bucket_name)
The operation of Get Bucket cors operation is used to get the current CORS rules in the specified Bucket.
parameters:
bucket_name
{String} bucket name
Success will return rules Array
puts @api.get_bucket_cors('bucket_name')
.delete_bucket_cors(bucket_name)
The Delete Bucket cors operation is used to disable the CORS function corresponding to the specified Bucket and remove all the rules.
parameters:
bucket_name
{String} bucket name
Success will return true
puts @api.delete_bucket_cors('bucket_name')
.option_object(bucket_name, object_name, origin, request_method, request_headers)
Before sending the cross-origin request, the browser will first send a preflight request (OPTIONS) with specific source origin, HTTP method, and header information to OSS so that it can decide whether to send the real request.
parameters:
bucket_name
{String} bucket nameobject_name
{String} object nameorigin
{String} Origin headerrequest_method
{String} Access-Control-Request-Method headerrequest_headers
{String} Access-Control-Request-Headers header
Success will return response headers
result = @api.option_object('bucket_name', 'object_name', 'Origin', 'GET', request_headers)
puts result.headers
Gem API DOC
http://www.rubydoc.info/gems/oss/0.1.5/Oss
Run Rake Unit Test
id=accessKeyId secret=accessKeyIdSecret rake test -I --order=a
License
The gem is available as open source under the terms of the Apache 2.0 License.