OSS Ruby SDK

Gem Version

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 is nil
    • prefix string search buckets using prefix key
    • marker string search start from marker, including marker key
    • max_keys String max buckets, default is 100, limit to 1000
service = @api.get_service(prefix: 'prefix')

Success will return service class object, use chain method get response params.

  • .buckets return buckets Array

    service.buckets.each do |bucket|
    puts bucket[:location]
    puts bucket[:name]
    puts bucket[:creation_date]
    end
    
  • .owner return owner info

    puts service.owner[:id]
    puts service.owner[:name]
    
  • .prefix, .marker, .max_keys, .is_truncated, .next_marker return option infos

    puts 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 name
  • acl 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 name
  • acl 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: -YYYY-mm-DD-HH-MM-SS-UniqueString.

parameters:

  • name {String} bucket name
  • target_bucket {String} log storage target bucket
  • enable {Bool} enable or disable log
  • target_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 name
  • index_doc {String} index file object key
  • error_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:

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 name
  • rules {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 prefix
    • status {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 name
  • options query parameters, default is nil
    • [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 oss
  • lastModified {String} object last modified GMT date, e.g.: 2015-02-19T08:39:44.000Z
  • etag {String} object etag contains ", e.g.: "5B3C1A2E053D763E1B002CC607C5A0FE"
  • type {String} object type, e.g.: Normal
  • size {String} object size, e.g.: 344606
  • storage_class {String} storage class type, e.g.: Standard
  • owner {Hash} object owner, including id and display_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 string
  • owner {Hash} object owner, including id and display_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 not
  • target_bucket {String} log store bucket
  • target_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 not
  • referers {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 page
  • error_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 prefix
  • status {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 name
  • object {String} object key name
  • file {String} file string
  • options {Hash} optional parameters
    • expires {String} expires time (milliseconds) for download, e.g.: 3600000
    • content_control {String} cache control for download, e.g.: public, no-cache
    • content_encoding {String} object content encoding for download
    • content_type {String} object content type
    • content_disposition {String} object name for download
    • encryption {String} oss server side encryption AES256
    • 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 name
  • object {String} object key name
  • old_bucket {String} existing object bucket
  • old_object {String} existing object
  • options {Hash} optional parameters
    • encryption {String} oss server side encryption AES256
    • acl {String} object acl header
    • if_none_match {String} x-oss-copy-source-if-none-match header
    • if_match {String} x-oss-copy-source-if-match header
    • if_unmodified_since {String} x-oss-copy-source-if-unmodified-since header
    • if_modified_since {String} x-oss-copy-source-if-modified-since header
    • metadata_directive {String} x-oss-metadata-directive header

Success will return Hash:

  • last_modify the object last modify time
  • etag 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 name
  • object {String} object key name
  • options {Hash} optional parameters
    • from {String} default nil, internal get url from ECS internal network, cdn get url from custom CDN network
    • cdn_domain {String} if from set with cdn, 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 name
  • object {String} object key name
  • options {Hash} optional parameters
    • if_none_match {String} x-oss-copy-source-if-none-match header
    • if_match {String} x-oss-copy-source-if-match header
    • if_unmodified_since {String} x-oss-copy-source-if-unmodified-since header
    • if_modified_since {String} x-oss-copy-source-if-modified-since header
    • range {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 name
  • object {String} object key name
  • file {String} append file content
  • position {Integer} append file position
  • options {Hash} optional parameters

Success will return Hash:

  • hash_crc64ecma {String} append object hash crc64
  • next_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 name
  • object_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 name
  • objects {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 name
  • object_name {String} object name
  • options {Hash} optional parameters
    • if_none_match {String} x-oss-copy-source-if-none-match header
    • if_match {String} x-oss-copy-source-if-match header
    • if_unmodified_since {String} x-oss-copy-source-if-unmodified-since header
    • if_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 name
  • object_name {String} object name
  • acl {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 name
  • object_name {String} object name

Success will return Hash:

  • grant {String} acl settings string
  • owner {Hash} object owner, including id and display_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 name
  • key form upload key
  • options Form field

return form post need parameters including OSSAccessKeyId Signature

@form_info = @api.post_object('bucket_name', 'object_name', options)
# 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 name
  • object_name {String} object name
  • options {Hash} optional parameters
    • expires {String} expires time (milliseconds) for download, e.g.: 3600000
    • content_control {String} cache control for download, e.g.: public, no-cache
    • content_encoding {String} object content encoding for download
    • content_disposition {String} object name for download
    • encryption {String} oss server side encryption AES256

Success will return Hash:

  • bucket {String} bucket name
  • key {String} key
  • upload_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 name
  • object_name {String} object name
  • upload_id {String} upload id
  • part_number {Integer} upload part number
  • file {String} file content
  • options {Hash} optional parameters

Success will return Hash:

  • etag {String} part etag
  • part_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 name
  • object_name {String} object name
  • upload_id {String} upload id
  • old_bucket {String} exist source bucket name
  • old_object {String} exist source object name
  • part_number {Integer} upload part number
  • options {Hash} optional parameters
    • if_none_match {String} x-oss-copy-source-if-none-match header
    • if_match {String} x-oss-copy-source-if-match header
    • if_unmodified_since {String} x-oss-copy-source-if-unmodified-since header
    • copy_source_begin {Integer} copy source begin byte
    • copy_source_end {Integer} copy source end byte

Success will return Hash:

  • etag {String} part etag
  • last_modify {String} object last modify time
options = {copy_source_begin: 0, copy_source_end: 1024}
result = @api.upload_part_copy('bucket_name', 'object_name', upload_id, 'old_bucket', 'old_object', 1, options)
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 name
  • object_name {String} object name
  • upload_id {String} upload id
  • parts {Array} uploaded parts Hash including part_number etag

Success will return Hash:

  • location {String} storage location
  • bucket {String} bucket name
  • key {String} object key
  • etag {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 name
  • object_name {String} object name
  • upload_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 name
  • upload_id {String} upload id
  • options {Hash} optional parameters
    • delimiter {string} A character for grouping the names of Objects.
    • prefix {string} search object using prefix key
    • key_marker {string} Used together with the upload-id-marker parameter to specify the initial position of returned results
    • max_uploads {String} max uploads, default is 100, limit to 1000
    • 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 key
  • upload_id {String} upload id
  • initiated {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 name
  • object_name {String} object name
  • options {Hash} optional parameters
    • uploadId {String} search upload id
    • max_parts {String} search max parts
    • part_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 number
  • last_modified {String} last modified time
  • etag {String} part etag
  • size {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 name
  • rules {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 name
  • object_name {String} object name
  • origin {String} Origin header
  • request_method {String} Access-Control-Request-Method header
  • request_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.