aliyun-oss-sdk 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/README.md +195 -0
- data/Rakefile +10 -0
- data/aliyun-oss.gemspec +32 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/aliyun/oss.rb +21 -0
- data/lib/aliyun/oss/authorization.rb +117 -0
- data/lib/aliyun/oss/client.rb +635 -0
- data/lib/aliyun/oss/http.rb +87 -0
- data/lib/aliyun/oss/multipart/part.rb +32 -0
- data/lib/aliyun/oss/rule/cors.rb +61 -0
- data/lib/aliyun/oss/rule/lifecycle.rb +56 -0
- data/lib/aliyun/oss/utils.rb +49 -0
- data/lib/aliyun/oss/version.rb +5 -0
- data/lib/aliyun/oss/xml_builder.rb +11 -0
- metadata +202 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 25f9ea0e6c34c0a6d15ff9c7f1c5b7063eab4c74
|
4
|
+
data.tar.gz: 3ff1e1a73d6b74bbaec4ff7e23179197197978ae
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 12ca936fc5538dac82a12a6dd1ec3057f12d31bf0bd163931e6bc98b0215070abbd76c6191d8de1ae4e8d346249217c7a7ebad8948aed0a871bb5471117e3568
|
7
|
+
data.tar.gz: 5917b901eed5f2b8182719474418b212382bfdd678c93a95a29ef3ea33e3aa4d169715f153648281837edd02cb84a5a83f36cfb81b01b6f518f7c890adf6c6f1
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,195 @@
|
|
1
|
+
# Aliyun OSS SDK
|
2
|
+
|
3
|
+
[![Coverage Status](https://coveralls.io/repos/zlx/ruby-oss-sdk/badge.svg?branch=master&service=bitbucket)](https://coveralls.io/bitbucket/zlx/ruby-oss-sdk?branch=master)
|
4
|
+
|
5
|
+
-----
|
6
|
+
|
7
|
+
|
8
|
+
It provide One-to-one Ruby interface for Aliyun OSS Restful API. I try to keep things natural and reasonable, but there are always some places are leaky, welcome to give me advice and modification. Thank you!
|
9
|
+
|
10
|
+
|
11
|
+
## Document
|
12
|
+
|
13
|
+
+ [ALiyun OSS API](https://docs.aliyun.com/#/pub/oss/api-reference/overview)
|
14
|
+
+ [Ruby Document]()
|
15
|
+
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
### Quick Start
|
20
|
+
|
21
|
+
require 'aliyun/oss'
|
22
|
+
|
23
|
+
# ACCESS_KEY/SECRET_KEY is your access credentials, Aliyun provide three ways, read detail at https://docs.aliyun.com/#/pub/oss/product-documentation/acl&RESTAuthentication
|
24
|
+
# host: your bucket's data center host, eg: oss-cn-hangzhou.aliyuncs.com, visit https://docs.aliyun.com/#/pub/oss/product-documentation/domain-region#menu2 get full list
|
25
|
+
# bucket: your bucket name
|
26
|
+
|
27
|
+
client = Aliyun::OSS::Client.new('ACCESS_KEY', 'SECRET_KEY', host: 'oss-cn-hangzhou.aliyuncs.com', bucket: 'oss-sdk-dev-hangzhou')
|
28
|
+
|
29
|
+
# Get all objects in this bucket
|
30
|
+
# use prefix,marker,delimiter, max-keys to filter results
|
31
|
+
client.bucket_list_objects()
|
32
|
+
|
33
|
+
# Upload objects
|
34
|
+
client.bucket_create_object('image.png', File.new('path/to/image.png'), { 'Content-Type' => 'image/png' })
|
35
|
+
|
36
|
+
# Get Object
|
37
|
+
client.bucket_get_object('image.png')
|
38
|
+
|
39
|
+
|
40
|
+
### Share your files
|
41
|
+
|
42
|
+
Sometimes, you want to share some file in your private bucket with your friends , but you donot want to share your AccessKey, thus, Aliyun provide alternative way: [Put signature in URL](https://docs.aliyun.com/#/pub/oss/api-reference/access-control&signature-url)
|
43
|
+
|
44
|
+
We provide a method to calculate signature for you:
|
45
|
+
|
46
|
+
# Return Singature string
|
47
|
+
Aliyun::Oss::Authorization.get_temporary_signature('SECRET_KEY', Time.now.to_i + 60*60, verb: 'GET', bucket: 'bucket-name', key: 'object-name')
|
48
|
+
|
49
|
+
|
50
|
+
### Directly POST file to Aliyun OSS
|
51
|
+
|
52
|
+
Sometime we may allow user directly upload image or file to Aliyun to improve the upload speed. thus you may need POST form: [Post Object](https://docs.aliyun.com/#/pub/oss/api-reference/object&PostObject)
|
53
|
+
|
54
|
+
With Post Form, we need Post Policy to restrict permissions, here we provide two methods that you may interesting:
|
55
|
+
|
56
|
+
# policy your policy in hash
|
57
|
+
# Return base64 string which can used to fill your form field: policy
|
58
|
+
client.get_base64_policy(policy)
|
59
|
+
|
60
|
+
# Get Signature for policy
|
61
|
+
# Return Signature with policy, can used to fill your form field: Signature
|
62
|
+
client.get_policy_signature(SECRET_KEY, policy)
|
63
|
+
|
64
|
+
|
65
|
+
### Full API
|
66
|
+
|
67
|
+
|
68
|
+
###### Bucket #####
|
69
|
+
|
70
|
+
# Get all buckets information
|
71
|
+
client.list_buckets
|
72
|
+
|
73
|
+
# Create new buckets
|
74
|
+
client.bucket_create('oss-sdk-dev-beijing-no1', 'oss-cn-beijing', 'public-read')
|
75
|
+
|
76
|
+
# Delete bucket
|
77
|
+
client.bucket_delete(name)
|
78
|
+
|
79
|
+
# Get all objects in this bucket
|
80
|
+
# use prefix,marker,delimiter, max-keys to filter results
|
81
|
+
client.bucket_list_objects()
|
82
|
+
|
83
|
+
|
84
|
+
#### Get information of this bucket ####
|
85
|
+
|
86
|
+
client.bucket_get_acl
|
87
|
+
client.bucket_get_cors
|
88
|
+
client.bucket_get_lifecycle
|
89
|
+
client.bucket_get_location
|
90
|
+
client.bucket_get_logging
|
91
|
+
client.bucket_get_referer
|
92
|
+
client.bucket_get_website
|
93
|
+
|
94
|
+
|
95
|
+
##### Set the bucket properties ####
|
96
|
+
|
97
|
+
# set cors for bucket
|
98
|
+
rule = Aliyun::Oss::Rule::Cors.new({ allowed_methods: ['get'], allowed_origins: ['*'] })
|
99
|
+
client.bucket_enable_cors([rule])
|
100
|
+
client.bucket_disable_cors # Disable and remove existing cors
|
101
|
+
|
102
|
+
# Set lifecycle for bucket
|
103
|
+
rule1 = Aliyun::Oss::Rule::LifeCycle.new({ prefix: 'logs-prod-', days: 7, enable: true })
|
104
|
+
rule2 = Aliyun::Oss::Rule::LifeCycle.new({ prefix: 'logs-dev', date: Time.now + 24*60*60, enable: true })
|
105
|
+
client.bucket_enable_lifecycle([rule1, rule2])
|
106
|
+
client.bucket_disable_lifecycle # Disable and remove existing lifecycle
|
107
|
+
|
108
|
+
# Enable access logging for bucket
|
109
|
+
client.bucket_enable_logging('logs-oss-sdk', 'logs-')
|
110
|
+
client.bucket_disable_logging # Disable logging
|
111
|
+
|
112
|
+
# Set bucket to static web sites hosted mode.
|
113
|
+
client.bucket_enable_website('index.html', 'error.html')
|
114
|
+
client.bucket_disable_website # Disable static web sites hosted mode
|
115
|
+
|
116
|
+
# Set Referer for this bucket
|
117
|
+
client.bucket_set_referer(['http://www.aliyun.com'], false)
|
118
|
+
|
119
|
+
# Set ACL for bucket
|
120
|
+
# supported value: public-read-write | public-read | private
|
121
|
+
client.bucket_set_acl('public-read')
|
122
|
+
|
123
|
+
|
124
|
+
#### Object ####
|
125
|
+
|
126
|
+
# Upload object to bucket
|
127
|
+
client.bucket_create_object("image.png", File.new("path/to/image.png"), { 'Content-Type' => 'image/png' })
|
128
|
+
|
129
|
+
# Copy object from other bucket
|
130
|
+
client.bucket_copy_object('new_image.png', 'origin-bucket-name', 'origin.png', { 'x-oss-metadata-directive' => 'REPLACE' })
|
131
|
+
|
132
|
+
# Get a Object
|
133
|
+
client.bucket_get_object("image.png")
|
134
|
+
|
135
|
+
# Get meta information of object
|
136
|
+
client.bucket_get_meta_object("image.png")
|
137
|
+
|
138
|
+
# Get object ACL
|
139
|
+
client.bucket_get_object_acl("image.png")
|
140
|
+
|
141
|
+
# Set object ACL
|
142
|
+
client.bucket_set_object_acl("image.png", 'public-read-write')
|
143
|
+
|
144
|
+
# upload object with append
|
145
|
+
# it will create a Appendable object
|
146
|
+
# https://docs.aliyun.com/#/pub/oss/api-reference/object&AppendObject
|
147
|
+
client.bucket_append_object("secret.zip", Bin Data, 0) # return the last position, 100203
|
148
|
+
client.bucket_append_object("secret.zip", Bin Data, 100203)
|
149
|
+
|
150
|
+
# Delete Object
|
151
|
+
client.bucket_delete_object('secret.zip)
|
152
|
+
|
153
|
+
# Delete Multiple objects
|
154
|
+
client.bucket_delete_objects(['secret.zip', 'image.png'], true)
|
155
|
+
|
156
|
+
|
157
|
+
|
158
|
+
#### Multipart Upload ####
|
159
|
+
|
160
|
+
# Init a Multipart Upload event
|
161
|
+
client.bucket_init_multipart("Exciting-Ruby.mp4", { 'Content-Type' => 'video/mp4' }) # return upload ID "98A6524428734723BE8F81D72B5295EE"
|
162
|
+
|
163
|
+
# Upload files
|
164
|
+
client.bucket_multipart_upload("Exciting-Ruby.mp4", 1, "98A6524428734723BE8F81D72B5295EE", file1) # return etag for use later
|
165
|
+
client.bucket_multipart_upload("Exciting-Ruby.mp4", 2, "98A6524428734723BE8F81D72B5295EE", file2)
|
166
|
+
client.bucket_multipart_upload("Exciting-Ruby.mp4", 3, "98A6524428734723BE8F81D72B5295EE", file3)
|
167
|
+
|
168
|
+
# Copy from existing object
|
169
|
+
client.bucket_multipart_copy_upload("Exciting-Ruby.mp4", 4, "98A6524428734723BE8F81D72B5295EE", source_bucket: 'original-bucket-name', source_key: 'original-file', range: 'bytes=0-10000')
|
170
|
+
|
171
|
+
# List uploaded parts for a Multipart Upload event
|
172
|
+
client.bucket_list_parts("sample_multipart.data", "98A6524428734723BE8F81D72B5295EE")
|
173
|
+
|
174
|
+
# Complete a Multipart Upload event
|
175
|
+
part1 = Aliyun::Oss::Multipart::Part.new({ number: 1, etag: 'etag1' })
|
176
|
+
part2 = Aliyun::Oss::Multipart::Part.new({ number: 2, etag: 'etag2' })
|
177
|
+
part3 = Aliyun::Oss::Multipart::Part.new({ number: 3, etag: 'etag3' })
|
178
|
+
client.bucket_complete_multipart("Exciting-Ruby.mp4", "98A6524428734723BE8F81D72B5295EE", [part1, part2, part3])
|
179
|
+
|
180
|
+
# Abort a Multipart Upload event
|
181
|
+
# abort will remove all uploaded parts
|
182
|
+
# invoke a few time to confirm all parts are deleted for concurrency access
|
183
|
+
client.bucket_abort_multipart("Exciting-Ruby.mp4", "9FB6F32C2DC24E04B813963B58E29E68")
|
184
|
+
|
185
|
+
|
186
|
+
|
187
|
+
|
188
|
+
## Authors && Contributors
|
189
|
+
|
190
|
+
- [Newell Zhu](https://github.com/zlx_star)
|
191
|
+
|
192
|
+
|
193
|
+
## License
|
194
|
+
|
195
|
+
licensed under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0.html)
|
data/Rakefile
ADDED
data/aliyun-oss.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'aliyun/oss/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'aliyun-oss-sdk'
|
8
|
+
spec.version = Aliyun::Oss::VERSION
|
9
|
+
spec.authors = ['Newell Zhu']
|
10
|
+
spec.email = ['zlx.star@gmail.com']
|
11
|
+
|
12
|
+
spec.summary = 'Aliyun OSS Ruby SDK'
|
13
|
+
spec.description = 'Aliyun OSS Ruby SDK'
|
14
|
+
spec.homepage = 'http://github.com/aliyun/ruby-oss-sdk'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.bindir = 'exe'
|
18
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_dependency 'httparty'
|
22
|
+
spec.add_dependency 'gyoku'
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.10'
|
25
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
26
|
+
spec.add_development_dependency 'minitest'
|
27
|
+
spec.add_development_dependency 'mocha'
|
28
|
+
spec.add_development_dependency 'pry-byebug'
|
29
|
+
spec.add_development_dependency 'webmock'
|
30
|
+
spec.add_development_dependency 'timecop'
|
31
|
+
spec.add_development_dependency 'simplecov'
|
32
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'aliyun/oss'
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require 'irb'
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/lib/aliyun/oss.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'aliyun/oss/version'
|
2
|
+
|
3
|
+
module Aliyun
|
4
|
+
module Oss
|
5
|
+
autoload :Utils, 'aliyun/oss/utils'
|
6
|
+
autoload :Client, 'aliyun/oss/client'
|
7
|
+
autoload :Http, 'aliyun/oss/http'
|
8
|
+
autoload :XmlBuilder, 'aliyun/oss/xml_builder'
|
9
|
+
autoload :Authorization, 'aliyun/oss/authorization'
|
10
|
+
|
11
|
+
module Rule
|
12
|
+
autoload :LifeCycle, 'aliyun/oss/rule/lifecycle'
|
13
|
+
autoload :Cors, 'aliyun/oss/rule/cors'
|
14
|
+
end
|
15
|
+
|
16
|
+
module Multipart
|
17
|
+
autoload :Part, 'aliyun/oss/multipart/part'
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'openssl'
|
3
|
+
require 'digest'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module Aliyun
|
7
|
+
module Oss
|
8
|
+
class Authorization
|
9
|
+
PROVIDER = 'OSS'
|
10
|
+
|
11
|
+
# Get temporary Signature
|
12
|
+
#
|
13
|
+
# @see {https://docs.aliyun.com/#/pub/oss/api-reference/access-control&signature-url Tempoorary Signature}
|
14
|
+
#
|
15
|
+
# @param secret_key [String] Secret Key
|
16
|
+
# @param expires [Integer] the number of seconds since January 1, 1970 UTC. used to specified expired time
|
17
|
+
# @param [Hash] options other options
|
18
|
+
# @option options [String] :key the object name
|
19
|
+
# @option options [String] :bucket bucket name
|
20
|
+
# @option options [String] :verb, Request Method
|
21
|
+
# @option options [Hash] :query Query Params
|
22
|
+
# @option options [Hash] :headers Headers Params
|
23
|
+
#
|
24
|
+
# @return [String]
|
25
|
+
def self.get_temporary_signature(secret_key, expire_time, options = {})
|
26
|
+
content_string = concat_content_string(options[:verb], expire_time, options)
|
27
|
+
URI.escape(signature(secret_key, content_string).strip)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Get base64 encoded string, used to fill policy field
|
31
|
+
#
|
32
|
+
# @see {https://docs.aliyun.com/#/pub/oss/api-reference/object&PostObject Post Object}
|
33
|
+
#
|
34
|
+
# @param secret_key [String] Secret Key
|
35
|
+
# @param policy [Hash] Policy {https://docs.aliyun.com/#/pub/oss/api-reference/object&PostObject#menu7 Detail}
|
36
|
+
#
|
37
|
+
# @return [String]
|
38
|
+
def self.get_base64_policy(policy)
|
39
|
+
Base64.encode64(JSON.generate(policy).force_encoding('utf-8')).delete("\n")
|
40
|
+
end
|
41
|
+
|
42
|
+
# Get Signature for policy
|
43
|
+
#
|
44
|
+
# @see {https://docs.aliyun.com/#/pub/oss/api-reference/object&PostObject}
|
45
|
+
#
|
46
|
+
# @param secret_key [String] Secret Key
|
47
|
+
# @param policy [Hash] Policy {https://docs.aliyun.com/#/pub/oss/api-reference/object&PostObject#menu7 Detail}
|
48
|
+
#
|
49
|
+
# @return [String]
|
50
|
+
def self.get_policy_signature(secret_key, policy)
|
51
|
+
signature(secret_key, get_base64_policy(policy)).strip
|
52
|
+
end
|
53
|
+
|
54
|
+
# @private
|
55
|
+
#
|
56
|
+
# Get authorization key
|
57
|
+
#
|
58
|
+
# @see {https://docs.aliyun.com/#/pub/oss/api-reference/access-control&signature-header Authorization}
|
59
|
+
#
|
60
|
+
# @return [String] the authorization string
|
61
|
+
def self.get_authorization(access_key, secret_key, options = {})
|
62
|
+
content_string = concat_content_string(options[:verb], options[:date], options)
|
63
|
+
signature_string = signature(secret_key, content_string)
|
64
|
+
"#{PROVIDER} #{access_key}:#{signature_string.strip}"
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def self.concat_content_string(verb, time, options = {})
|
70
|
+
headers = options.fetch(:headers, {})
|
71
|
+
|
72
|
+
cononicalized_oss_headers = get_cononicalized_oss_headers(headers)
|
73
|
+
cononicalized_resource = get_cononicalized_resource(*options.values_at(:bucket, :key, :query))
|
74
|
+
|
75
|
+
if cononicalized_oss_headers
|
76
|
+
[
|
77
|
+
verb.upcase,
|
78
|
+
headers['Content-MD5'],
|
79
|
+
headers['Content-Type'],
|
80
|
+
time,
|
81
|
+
cononicalized_oss_headers,
|
82
|
+
cononicalized_resource
|
83
|
+
].join("\n")
|
84
|
+
else
|
85
|
+
[
|
86
|
+
verb.upcase,
|
87
|
+
headers['Content-MD5'],
|
88
|
+
headers['Content-Type'],
|
89
|
+
time,
|
90
|
+
cononicalized_resource
|
91
|
+
].join("\n")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.signature(secret_key, content_string)
|
96
|
+
utf8_string = content_string.force_encoding('utf-8')
|
97
|
+
Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new, secret_key, utf8_string))
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.get_cononicalized_oss_headers(headers)
|
101
|
+
oss_headers = (headers || {}).select { |key, _| key.to_s.downcase.start_with?('x-oss-') }
|
102
|
+
return if oss_headers.empty?
|
103
|
+
|
104
|
+
oss_headers.keys.sort.map { |key| "#{key.downcase}:#{oss_headers[key]}" }.join("\n")
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.get_cononicalized_resource(bucket, key, query)
|
108
|
+
cononicalized_resource = '/'
|
109
|
+
cononicalized_resource += "#{bucket}/" if bucket
|
110
|
+
cononicalized_resource += key if key
|
111
|
+
return cononicalized_resource if query.nil? || query.empty?
|
112
|
+
|
113
|
+
cononicalized_resource + '?' + query.keys.sort.map { |key| "#{key}=#{query[key]}" }.join('&')
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,635 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'openssl'
|
3
|
+
require 'digest'
|
4
|
+
require 'httparty'
|
5
|
+
|
6
|
+
module Aliyun
|
7
|
+
module Oss
|
8
|
+
class Client
|
9
|
+
attr_reader :access_key, :secret_key, :bucket
|
10
|
+
|
11
|
+
# Initialize a object
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# Aliyun::Oss::Client.new("ACCESS_KEY", "SECRET_KEY", host: "oss-cn-beijing.aliyuncs.com", bucket: 'oss-sdk-beijing')
|
15
|
+
#
|
16
|
+
# @param access_key [String] access_key obtained from aliyun
|
17
|
+
# @param secret_key [String] secret_key obtained from aliyun
|
18
|
+
# @option options [String] :host host for bucket's data center
|
19
|
+
# @option options [String] :bucket Bucket name
|
20
|
+
#
|
21
|
+
# @return [Client] the object
|
22
|
+
def initialize(access_key, secret_key, options = {})
|
23
|
+
@access_key = access_key
|
24
|
+
@secret_key = secret_key
|
25
|
+
@options = options
|
26
|
+
@bucket = options[:bucket]
|
27
|
+
end
|
28
|
+
|
29
|
+
# List buckets
|
30
|
+
#
|
31
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/service&GetService GetService (ListBucket
|
32
|
+
#
|
33
|
+
# @param options [Hash] options
|
34
|
+
# @option options [String] :prefix Filter buckets with prefix
|
35
|
+
# @option options [String] :marker Bucket name should after marker in alphabetical order
|
36
|
+
# @option options [Integer] :max-keys (100) Limit number of buckets, the maxinum should <= 1000
|
37
|
+
#
|
38
|
+
# @return [Object{buckets}]
|
39
|
+
def list_buckets(options = {})
|
40
|
+
query = Utils.hash_slice(options, 'prefix', 'marker', 'max-keys')
|
41
|
+
http.get('/', query: query)
|
42
|
+
end
|
43
|
+
|
44
|
+
# List objects in the bucket
|
45
|
+
#
|
46
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&GetBucket Get Bucket (List Object)
|
47
|
+
#
|
48
|
+
# @param options [Hash] options
|
49
|
+
# @option options [String] :prefix Filter objects with prefix
|
50
|
+
# @option options [String] :marker Result should after marker in alphabetical order
|
51
|
+
# @option options [Integer] :max-keys (100) Limit number of objects, the maxinum should <= 1000
|
52
|
+
# @option options [String] :delimiter Used to group objects with delimiter
|
53
|
+
# @option options [String] :encoding-type Encoding type used for unsupported character
|
54
|
+
#
|
55
|
+
# @return [Object{objects}]
|
56
|
+
def bucket_list_objects(options = {})
|
57
|
+
accepted_keys = ['prefix', 'marker', 'max-keys', 'delimiter', 'encoding-type']
|
58
|
+
query = Utils.hash_slice(options, *accepted_keys)
|
59
|
+
http.get('/', query: query, bucket: bucket)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Create bucket
|
63
|
+
#
|
64
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&PutBucket Put Bucket
|
65
|
+
#
|
66
|
+
# @example
|
67
|
+
# oss.client.bucket_create('oss-sdk-dev-hangzhou-xxx')
|
68
|
+
#
|
69
|
+
# @param name [String] Specify bucket name
|
70
|
+
# @param location [String] Specify the bucket's data center location, can be one of below:
|
71
|
+
# oss-cn-hangzhou,oss-cn-qingdao,oss-cn-beijing,oss-cn-hongkong,
|
72
|
+
# oss-cn-shenzhen,oss-cn-shanghai,oss-us-west-1 ,oss-ap-southeast-1
|
73
|
+
# @param acl [String] Specify the bucket's access. (see #bucket_set_acl)
|
74
|
+
#
|
75
|
+
# @return [Response]
|
76
|
+
def bucket_create(name, location = 'oss-cn-hangzhou', acl = 'private')
|
77
|
+
query = { 'acl' => true }
|
78
|
+
headers = { 'x-oss-acl' => acl }
|
79
|
+
|
80
|
+
configuration = { 'CreateBucketConfiguration' => { 'LocationConstraint' => location } }
|
81
|
+
body = Utils.to_xml(configuration)
|
82
|
+
|
83
|
+
http.put('/', query: query, headers: headers, body: body, bucket: name, location: location)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Delete bucket
|
87
|
+
#
|
88
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&DeleteBucket Delete Bucket
|
89
|
+
#
|
90
|
+
# @param name [String] bucket name want to delete
|
91
|
+
#
|
92
|
+
# @return [Response]
|
93
|
+
def bucket_delete(name)
|
94
|
+
http.delete('/', bucket: name)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Used to modify the bucket access.
|
98
|
+
#
|
99
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&PutBucketACL Put Bucket Acl
|
100
|
+
#
|
101
|
+
# @param acl [String] supported value: public-read-write | public-read | private
|
102
|
+
def bucket_set_acl(acl)
|
103
|
+
query = { 'acl' => true }
|
104
|
+
headers = { 'x-oss-acl' => acl }
|
105
|
+
http.put('/', query: query, headers: headers, bucket: bucket)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Used to enable access logging.
|
109
|
+
#
|
110
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&PutBucketLogging Put Bucket Logging
|
111
|
+
#
|
112
|
+
# @param target_bucket [String] specifies the bucket where you want Aliyun OSS to store server access logs.
|
113
|
+
# @param target_prefix [String] this element lets you specify a prefix for the objects that the log files will be stored.
|
114
|
+
def bucket_enable_logging(target_bucket, target_prefix = nil)
|
115
|
+
query = { 'logging' => true }
|
116
|
+
|
117
|
+
logging = { 'TargetBucket' => target_bucket }
|
118
|
+
logging.merge!('TargetPrefix' => target_prefix) if target_prefix
|
119
|
+
body = Utils.to_xml('BucketLoggingStatus' => { 'LoggingEnabled' => logging })
|
120
|
+
|
121
|
+
http.put('/', query: query, body: body, bucket: bucket)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Used to disable access logging.
|
125
|
+
#
|
126
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&DeleteBucketLogging Delete Bucket Logging
|
127
|
+
def bucket_disable_logging
|
128
|
+
query = { 'logging' => false }
|
129
|
+
http.delete('/', query: query, bucket: bucket)
|
130
|
+
end
|
131
|
+
|
132
|
+
# Used to enable static website hosted mode.
|
133
|
+
#
|
134
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&PutBucketWebsite Put Bucket Website
|
135
|
+
#
|
136
|
+
# @param suffix [String] A suffix that is appended to a request that is for a directory on the website endpoint (e.g. if the suffix is index.html and you make a request to samplebucket/images/ the data that is returned will be for the object with the key name images/index.html) The suffix must not be empty and must not include a slash character.
|
137
|
+
# @param key [String] The object key name to use when a 4XX class error occurs
|
138
|
+
def bucket_enable_website(suffix, key = nil)
|
139
|
+
query = { 'website' => true }
|
140
|
+
|
141
|
+
website_configuration = { 'IndexDocument' => { 'Suffix' => suffix } }
|
142
|
+
website_configuration.merge!('ErrorDocument' => { 'Key' => key }) if key
|
143
|
+
body = Utils.to_xml('WebsiteConfiguration' => website_configuration)
|
144
|
+
|
145
|
+
http.put('/', query: query, body: body, bucket: bucket)
|
146
|
+
end
|
147
|
+
|
148
|
+
# Used to disable website hostted mode.
|
149
|
+
#
|
150
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&DeleteBucketWebsite Delete Bucket Website
|
151
|
+
def bucket_disable_website
|
152
|
+
query = { 'website' => false }
|
153
|
+
http.delete('/', query: query, bucket: bucket)
|
154
|
+
end
|
155
|
+
|
156
|
+
# Used to set referer for bucket.
|
157
|
+
#
|
158
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&PutBucketReferer Put Bucket Referer
|
159
|
+
#
|
160
|
+
# @param referers [Array<String>] white list for allowed referer.
|
161
|
+
# @param allowed_empty [Boolean] whether allow empty refer.
|
162
|
+
#
|
163
|
+
# @return [Response]
|
164
|
+
def bucket_set_referer(referers = [], allowed_empty = false)
|
165
|
+
query = { 'referer' => true }
|
166
|
+
|
167
|
+
referer_configuration = { 'RefererConfiguration' => { 'AllowEmptyReferer' => allowed_empty, 'RefererList' => { 'Referer' => referers } } }
|
168
|
+
body = Utils.to_xml(referer_configuration)
|
169
|
+
|
170
|
+
http.put('/', query: query, body: body, bucket: bucket)
|
171
|
+
end
|
172
|
+
|
173
|
+
# Used to enable and set lifecycle for bucket
|
174
|
+
#
|
175
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&PutBucketLifecycle Put Bucket Lifecycle
|
176
|
+
#
|
177
|
+
# @param rules [Array<Rule::LifeCycle>] rules for lifecycle
|
178
|
+
#
|
179
|
+
# @return [Response]
|
180
|
+
def bucket_enable_lifecycle(rules = [])
|
181
|
+
query = { 'lifecycle' => true }
|
182
|
+
|
183
|
+
body = Utils.to_xml('LifecycleConfiguration' => {
|
184
|
+
'Rule' => rules.map(&:to_hash)
|
185
|
+
})
|
186
|
+
|
187
|
+
http.put('/', query: query, body: body, bucket: bucket)
|
188
|
+
end
|
189
|
+
|
190
|
+
# Used to disable lifecycle for bucket.
|
191
|
+
#
|
192
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&DeleteBucketLifecycle Delete Bucket Lifecycle
|
193
|
+
def bucket_disable_lifecycle
|
194
|
+
query = { 'lifecycle' => false }
|
195
|
+
http.delete('/', query: query, bucket: bucket)
|
196
|
+
end
|
197
|
+
|
198
|
+
# Used to enable CORS and set rules for bucket
|
199
|
+
#
|
200
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/cors&PutBucketcors Put Bucket cors
|
201
|
+
#
|
202
|
+
# @param rules [Array<Rule::Cors>] array of rule
|
203
|
+
#
|
204
|
+
# @return [Response]
|
205
|
+
def bucket_enable_cors(rules = [])
|
206
|
+
query = { 'cors' => true }
|
207
|
+
|
208
|
+
body = Utils.to_xml('CORSConfiguration' => {
|
209
|
+
'CORSRule' => rules.map(&:to_hash)
|
210
|
+
})
|
211
|
+
|
212
|
+
http.put('/', query: query, body: body, bucket: bucket)
|
213
|
+
end
|
214
|
+
|
215
|
+
# Used to disable cors and clear rules for bucket
|
216
|
+
#
|
217
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/cors&DeleteBucketcors Delete Bucket cors
|
218
|
+
#
|
219
|
+
# @return [Response]
|
220
|
+
def bucket_disable_cors
|
221
|
+
query = { 'cors' => false }
|
222
|
+
http.delete('/', query: query, bucket: bucket)
|
223
|
+
end
|
224
|
+
|
225
|
+
# OPTIONS Object
|
226
|
+
#
|
227
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/cors&OptionObject OPTIONS Object
|
228
|
+
#
|
229
|
+
# @param origin [String] the requested source domain, denoting cross-domain request.
|
230
|
+
# @param request_method [String] the actual request method will be used.
|
231
|
+
# @param request_headers [Array<String>] the actual used headers except simple headers will be used.
|
232
|
+
# @param object_name [String] the object name will be visit.
|
233
|
+
#
|
234
|
+
# @return [Response]
|
235
|
+
def bucket_preflight(origin, request_method, request_headers = [], object_name = nil)
|
236
|
+
uri = object_name ? "/#{object_name}" : '/'
|
237
|
+
|
238
|
+
headers = { 'Origin' => origin, 'Access-Control-Request-Method' => request_method }
|
239
|
+
unless request_headers.empty?
|
240
|
+
headers.merge!('Access-Control-Request-Headers' => request_headers.join(','))
|
241
|
+
end
|
242
|
+
|
243
|
+
http.options(uri, headers: headers, bucket: bucket, key: object_name)
|
244
|
+
end
|
245
|
+
|
246
|
+
# Get ACL for bucket
|
247
|
+
#
|
248
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&GetBucketAcl Get Bucket ACL
|
249
|
+
#
|
250
|
+
# @return [Response]
|
251
|
+
def bucket_get_acl
|
252
|
+
query = { 'acl' => true }
|
253
|
+
http.get('/', query: query, bucket: bucket)
|
254
|
+
end
|
255
|
+
|
256
|
+
# Get the location information of the Bucket's data center
|
257
|
+
#
|
258
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&GetBucketLocation Get Bucket Location
|
259
|
+
#
|
260
|
+
# @return [Response]
|
261
|
+
def bucket_get_location
|
262
|
+
query = { 'location' => true }
|
263
|
+
http.get('/', query: query, bucket: bucket)
|
264
|
+
end
|
265
|
+
|
266
|
+
# Get the log configuration of Bucket
|
267
|
+
#
|
268
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&GetBucketLogging Get Bucket Logging
|
269
|
+
#
|
270
|
+
# @return [Response]
|
271
|
+
def bucket_get_logging
|
272
|
+
query = { 'logging' => true }
|
273
|
+
http.get('/', query: query, bucket: bucket)
|
274
|
+
end
|
275
|
+
|
276
|
+
# Get the bucket state of static website hosting.
|
277
|
+
#
|
278
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&GetBucketWebsite Get Bucket Website
|
279
|
+
#
|
280
|
+
# @return [Response]
|
281
|
+
def bucket_get_website
|
282
|
+
query = { 'website' => true }
|
283
|
+
http.get('/', query: query, bucket: bucket)
|
284
|
+
end
|
285
|
+
|
286
|
+
# Get the referer configuration of bucket
|
287
|
+
#
|
288
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&GetBucketReferer Get Bucket Referer
|
289
|
+
#
|
290
|
+
# @return [Response]
|
291
|
+
def bucket_get_referer
|
292
|
+
query = { 'referer' => true }
|
293
|
+
http.get('/', query: query, bucket: bucket)
|
294
|
+
end
|
295
|
+
|
296
|
+
# Get the lifecycle configuration of bucket
|
297
|
+
#
|
298
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&GetBucketLifecycle Get Bucket Lifecycle
|
299
|
+
#
|
300
|
+
# @return [Response]
|
301
|
+
def bucket_get_lifecycle
|
302
|
+
query = { 'lifecycle' => true }
|
303
|
+
http.get('/', query: query, bucket: bucket)
|
304
|
+
end
|
305
|
+
|
306
|
+
# Get the CORS rules of bucket
|
307
|
+
#
|
308
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/cors&GetBucketcors Get Bucket cors
|
309
|
+
#
|
310
|
+
# @return [Response]
|
311
|
+
def bucket_get_cors
|
312
|
+
query = { 'cors' => true }
|
313
|
+
http.get('/', query: query, bucket: bucket)
|
314
|
+
end
|
315
|
+
|
316
|
+
# Upload file to bucket
|
317
|
+
#
|
318
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/object&PutObject Put Object
|
319
|
+
#
|
320
|
+
# @param key [String] Specify object name
|
321
|
+
# @param file [File, Bin data] Specify need upload resource
|
322
|
+
# @param [Hash] headers Specify other options
|
323
|
+
# @option headers [String] :Content-Type ('application/x-www-form-urlencoded') Specify Content-Type for the object
|
324
|
+
# @option headers [String] :Cache-Control Specify the caching behavior when download from browser, ref {https://www.ietf.org/rfc/rfc2616.txt?spm=5176.730001.3.128.Y5W4bu&file=rfc2616.txt RFC2616}
|
325
|
+
# @option headers [String] :Content-Disposition Specify the name when download, ref {https://www.ietf.org/rfc/rfc2616.txt?spm=5176.730001.3.128.Y5W4bu&file=rfc2616.txt RFC2616}
|
326
|
+
# @option headers [String] :Content-Encoding Specify the content encoding when download, ref {https://www.ietf.org/rfc/rfc2616.txt?spm=5176.730001.3.128.Y5W4bu&file=rfc2616.txt RFC2616}
|
327
|
+
# @option headers [String] :Content-MD5 RFC 1864 according to the agreement of the message Content (not including head) are calculated MD5 value 128 bits number, the number is base64 encoding for the Content of a message - MD5 value.The legality of the examination of the request headers can be used for information (a message content is consistent with send).Although the request header is optional, OSS recommend that users use the end-to-end check request header.
|
328
|
+
# @option headers [Integer] :Expires Specify the expiration time (milliseconds)
|
329
|
+
# @option headers [String] :x-oss-server-side-encryption Specify the oss server-side encryption algorithm when the object was created. supported value: 'AES256'
|
330
|
+
# @option headers [String] :x-oss-object-acl Specify the oss access when the object was created. supported value: public-read-write | public-read | private
|
331
|
+
# @option headers [Hash] other options will insert into headers when upload, such as user meta headers, eg: headers with prefix: x-oss-meta-
|
332
|
+
#
|
333
|
+
# @return [Response]
|
334
|
+
def bucket_create_object(key, file, headers = {})
|
335
|
+
http.put("/#{key}", headers: headers, body: Utils.to_data(file), bucket: bucket, key: key)
|
336
|
+
end
|
337
|
+
|
338
|
+
# Copy an existing object in OSS into another object
|
339
|
+
#
|
340
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/object&CopyObject Copy Object
|
341
|
+
#
|
342
|
+
# @param key [String] the object name
|
343
|
+
# @param source_bucket [String] the source bucket name
|
344
|
+
# @param source_key [String] the source object name
|
345
|
+
# @param [Hash] headers
|
346
|
+
# @option options [String] :source_bucket the source bucket name
|
347
|
+
# @option options [String] :source_key the source object name
|
348
|
+
# @option options [String] :x-oss-copy-source-if-match If the specified ETag match the source object ETag, normal transfer and return 200; Otherwise return 412(precondition)
|
349
|
+
# @option options [String] :x-oss-copy-source-if-none-match If the specified ETag not match the source object ETag, normal transfer and return 200; Otherwise return 304(Not Modified)
|
350
|
+
# @option options [String] :x-oss-copy-source-if-unmodified-since If the specified time is equal to or later than the source object last modification time, normal transfer ans return 200; Otherwise returns 412(precondition)
|
351
|
+
# @option options [String] :x-oss-copy-source-if-modified-since If the specified time is earlier than the source object last modification time, normal transfer ans return 200; Otherwise returns 304(not modified)
|
352
|
+
# @option options [String] :x-oss-metadata-directive ('COPY') supported value: COPY, REPLACE;
|
353
|
+
# @option options [String] :x-oss-server-side-encryption supported value: AES256
|
354
|
+
# @option options [String] :x-oss-object-acl supported value: public-read,private,public-read-write
|
355
|
+
#
|
356
|
+
# @return [Response]
|
357
|
+
def bucket_copy_object(key, source_bucket, source_key, headers = {})
|
358
|
+
fail('source_bucket must be not empty!') if source_bucket.nil? || source_bucket.empty?
|
359
|
+
fail('source_key must be not empty!') if source_key.nil? || source_key.empty?
|
360
|
+
|
361
|
+
headers.merge!('x-oss-copy-source' => "/#{source_bucket}/#{source_key}")
|
362
|
+
|
363
|
+
http.put("/#{key}", headers: headers, bucket: bucket, key: key)
|
364
|
+
end
|
365
|
+
|
366
|
+
# Append data to a object, will create Appendable object
|
367
|
+
#
|
368
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/object&AppendObject Append Object
|
369
|
+
#
|
370
|
+
# @param key [String] object name
|
371
|
+
# @param file [file, bin data] the data to append
|
372
|
+
# @param position [Integer] append to position of object
|
373
|
+
# @option headers (see #bucket_create_object)
|
374
|
+
#
|
375
|
+
def bucket_append_object(key, file, position = 0, headers = {})
|
376
|
+
query = { 'append' => true, 'position' => position }
|
377
|
+
|
378
|
+
body = Utils.to_data(file)
|
379
|
+
|
380
|
+
http.post("/#{key}", query: query, headers: headers, body: body, bucket: bucket, key: key)
|
381
|
+
end
|
382
|
+
|
383
|
+
# Get the object
|
384
|
+
#
|
385
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/object&GetObject Get Object
|
386
|
+
#
|
387
|
+
# @param key [String] the object name
|
388
|
+
# @param query [Hash] query params
|
389
|
+
# @option query [String] :response-content-type Specify the header Content-Type in response
|
390
|
+
# @option query [String] :response-content-language Specify the header Content-Language in response
|
391
|
+
# @option query [String] :response-expires Specify the header Expires in response
|
392
|
+
# @option query [String] :response-cache-control Specify the header Cache-Control in response
|
393
|
+
# @option query [String] :response-content-disposition Specify the header Content-Disposition in response
|
394
|
+
# @option query [String] :response-content-encoding Specify the header Content-encoding in response
|
395
|
+
# @param headers [Hash] headers
|
396
|
+
# @option headers [String] :Range Specify the range of the file. Such as "bytes=0-9" means the 10 characters from 0 to 9.
|
397
|
+
# @option headers [String] :If-Modified-Since If the specified time is earlier than the file last modification time, return 200 OK; Otherwise returns 304(not modified)
|
398
|
+
# @option headers [String] :If-Unmodified-Since If the specified time is equal to or later than the file last modification time, normal transfer ans return 200; Otherwise returns 412(precondition)
|
399
|
+
# @option headers [String] :If-Match If the specified ETag match the object ETag, normal transfer and return 200; Otherwise return 412(precondition)
|
400
|
+
# @option headers [String] :If-None-Match If the specified ETag not match the object ETag, normal transfer and return 200; Otherwise return 304(Not Modified)
|
401
|
+
#
|
402
|
+
# @return [Response]
|
403
|
+
def bucket_get_object(key, query = {}, headers = {})
|
404
|
+
http.get("/#{key}", query: query, headers: headers, bucket: bucket, key: key)
|
405
|
+
end
|
406
|
+
|
407
|
+
# Delete object from bucket
|
408
|
+
#
|
409
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/object&DeleteObject Delete Object
|
410
|
+
#
|
411
|
+
# @param key [String] the object name
|
412
|
+
#
|
413
|
+
# @return [Response]
|
414
|
+
def bucket_delete_object(key)
|
415
|
+
http.delete("/#{key}", bucket: bucket, key: key)
|
416
|
+
end
|
417
|
+
|
418
|
+
# Delete multiple objects, at max 1000 at once
|
419
|
+
#
|
420
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/object&DeleteMultipleObjects Delete Multiple Objects
|
421
|
+
#
|
422
|
+
# @param keys [Array<String>] the object names
|
423
|
+
# @param quiet [Boolean] Specify response mode: false(Quiet) return results for error objects, true(Verbose) return results of every objects
|
424
|
+
#
|
425
|
+
# @return [Response]
|
426
|
+
def bucket_delete_objects(keys, quiet = false)
|
427
|
+
query = { 'delete' => true }
|
428
|
+
|
429
|
+
key_objects = keys.map { |key| { 'Key' => key } }
|
430
|
+
body = Utils.to_xml('Delete' => { 'Object' => key_objects, 'Quiet' => quiet })
|
431
|
+
|
432
|
+
http.post('/', query: query, body: body, bucket: bucket)
|
433
|
+
end
|
434
|
+
|
435
|
+
# Get meta information of object
|
436
|
+
#
|
437
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/object&HeadObject Head Object
|
438
|
+
#
|
439
|
+
# @param key [String] object name
|
440
|
+
# @param headers [Hash] headers
|
441
|
+
# @option headers [String] :If-Modified-Since If the specified time is earlier than the file last modification time, return 200 OK; Otherwise returns 304(not modified)
|
442
|
+
# @option headers [String] :If-Unmodified-Since If the specified time is equal to or later than the file last modification time, normal transfer ans return 200; Otherwise returns 412(precondition)
|
443
|
+
# @option headers [String] :If-Match If the specified ETag match the object ETag, normal transfer and return 200; Otherwise return 412(precondition)
|
444
|
+
# @option headers [String] :If-None-Match If the specified ETag not match the object ETag, normal transfer and return 200; Otherwise return 304(Not Modified)
|
445
|
+
#
|
446
|
+
# @return [Response]
|
447
|
+
def bucket_get_meta_object(key, headers = {})
|
448
|
+
http.head("/#{key}", headers: headers, bucket: bucket, key: key)
|
449
|
+
end
|
450
|
+
|
451
|
+
# Get access of object
|
452
|
+
#
|
453
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/object&GetObjectACL Get Object ACL
|
454
|
+
#
|
455
|
+
# @param key [String] object name
|
456
|
+
#
|
457
|
+
# @return [Response]
|
458
|
+
def bucket_get_object_acl(key)
|
459
|
+
query = { 'acl' => true }
|
460
|
+
http.get("/#{key}", query: query, bucket: bucket, key: key)
|
461
|
+
end
|
462
|
+
|
463
|
+
# Set access of object
|
464
|
+
#
|
465
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/object&PutObjectACL Put Object ACL
|
466
|
+
#
|
467
|
+
# @param key [String] object name
|
468
|
+
# @param acl [String] access value, supported value: private, public-read, public-read-write
|
469
|
+
#
|
470
|
+
# @return [Response]
|
471
|
+
def bucket_set_object_acl(key, acl)
|
472
|
+
query = { 'acl' => true }
|
473
|
+
headers = { 'x-oss-object-acl' => acl }
|
474
|
+
http.put("/#{key}", query: query, headers: headers, bucket: bucket, key: key)
|
475
|
+
end
|
476
|
+
|
477
|
+
# Initialize a Multipart Upload event, before using Multipart Upload mode to transmit data, we has to call the interface to notify the OSS initialize a Multipart Upload events.
|
478
|
+
#
|
479
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/multipart-upload&InitiateMultipartUpload Initiate Multipart Upload
|
480
|
+
#
|
481
|
+
# @param key [String] object name
|
482
|
+
# @param headers [Hash] headers
|
483
|
+
# @option headers [String] :Content-Type ('application/x-www-form-urlencoded') Specify Content-Type for the object
|
484
|
+
# @option headers [String] :Cache-Control Specify the caching behavior when download from browser, ref https://www.ietf.org/rfc/rfc2616.txt?spm=5176.730001.3.128.Y5W4bu&file=rfc2616.txt RFC2616}
|
485
|
+
# @option headers [String] :Content-Disposition Specify the name when download, ref https://www.ietf.org/rfc/rfc2616.txt?spm=5176.730001.3.128.Y5W4bu&file=rfc2616.txt RFC2616}
|
486
|
+
# @option headers [String] :Content-Encoding Specify the content encoding when download, ref https://www.ietf.org/rfc/rfc2616.txt?spm=5176.730001.3.128.Y5W4bu&file=rfc2616.txt RFC2616}
|
487
|
+
# @option headers [Integer] :Expires Specify the expiration time (milliseconds)
|
488
|
+
# @option headers [String] :x-oss-server-side-encryption Specify the oss server-side encryption algorithm when the object was created. supported value: 'AES256'#
|
489
|
+
#
|
490
|
+
# @return [Response]
|
491
|
+
def bucket_init_multipart(key, headers = {})
|
492
|
+
query = { 'uploads' => true }
|
493
|
+
http.post("/#{key}", query: query, headers: headers, bucket: bucket, key: key)
|
494
|
+
end
|
495
|
+
|
496
|
+
# Upload object in part.
|
497
|
+
#
|
498
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/multipart-upload&UploadPart Upload Part
|
499
|
+
#
|
500
|
+
# @param key [String] object name
|
501
|
+
# @param number [Integer] the part number, Range in 1~10000.
|
502
|
+
# @param upload_id [String] the upload ID return by #bucket_init_multipart
|
503
|
+
# @param file [File, bin data] the upload data
|
504
|
+
#
|
505
|
+
# @return [Response]
|
506
|
+
def bucket_multipart_upload(key, number, upload_id, file)
|
507
|
+
fail('number must present!') if number.nil?
|
508
|
+
fail('upload_id must present!') if upload_id.nil? || upload_id.empty?
|
509
|
+
|
510
|
+
query = { 'partNumber' => number.to_s, 'uploadId' => upload_id }
|
511
|
+
|
512
|
+
http.put("/#{key}", query: query, body: Utils.to_data(file), bucket: bucket, key: key)
|
513
|
+
end
|
514
|
+
|
515
|
+
# Upload a Part from an existing Object Copy data.
|
516
|
+
#
|
517
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/multipart-upload&UploadPartCopy Upload Part Copy
|
518
|
+
#
|
519
|
+
# @param key [String] object name
|
520
|
+
# @param number [Integer] the part number, Range in 1~10000.
|
521
|
+
# @param upload_id [String] the upload ID return by #bucket_init_multipart
|
522
|
+
# @param options [Hash] options
|
523
|
+
# @option options [String] :source_bucket the source bucket name
|
524
|
+
# @option options [String] :source_key the source object name
|
525
|
+
# @option options [String] :range the Range bytes, not set means the whole object
|
526
|
+
# @option options [String] :x-oss-copy-source-if-match If the specified ETag match the source object ETag, normal transfer and return 200; Otherwise return 412(precondition)
|
527
|
+
# @option options [String] :x-oss-copy-source-if-none-match If the specified ETag not match the source object ETag, normal transfer and return 200; Otherwise return 304(Not Modified)
|
528
|
+
# @option options [String] :x-oss-copy-source-if-unmodified-since If the specified time is equal to or later than the source object last modification time, normal transfer ans return 200; Otherwise returns 412(precondition)
|
529
|
+
# @option options [String] :x-oss-copy-source-if-modified-since If the specified time is earlier than the source object last modification time, normal transfer ans return 200; Otherwise returns 304(not modified)
|
530
|
+
#
|
531
|
+
# @return [Response]
|
532
|
+
def bucket_multipart_copy_upload(key, number, upload_id, options = {})
|
533
|
+
fail('source_bucket must present!') if options[:source_bucket].to_s.empty?
|
534
|
+
fail('source_key must present!') if options[:source_key].to_s.empty?
|
535
|
+
|
536
|
+
query = { 'partNumber' => number, 'uploadId' => upload_id }
|
537
|
+
|
538
|
+
source_bucket = options.delete(:source_bucket)
|
539
|
+
source_key = options.delete(:source_key)
|
540
|
+
|
541
|
+
headers = {}
|
542
|
+
headers.merge!('x-oss-copy-source' => "/#{source_bucket}/#{source_key}")
|
543
|
+
headers.merge!('x-oss-copy-source-range' => options.delete(:range)) if options.key?(:range)
|
544
|
+
headers.merge!(options)
|
545
|
+
|
546
|
+
http.put("/#{key}", query: query, headers: headers, bucket: bucket, key: key)
|
547
|
+
end
|
548
|
+
|
549
|
+
# Complete a Multipart Upload event.
|
550
|
+
#
|
551
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/multipart-upload&CompleteMultipartUpload Complete Multipart Upload
|
552
|
+
#
|
553
|
+
# @param key [String] object name
|
554
|
+
# @param upload_id [String] the upload ID return by #bucket_init_multipart
|
555
|
+
# @param parts [Array<Multipart:Part>] parts
|
556
|
+
#
|
557
|
+
# @return [Response]
|
558
|
+
def bucket_complete_multipart(key, upload_id, parts = [])
|
559
|
+
fail('parts must present!') if parts.nil? || parts.empty?
|
560
|
+
fail('upload_id must present!') if upload_id.nil?
|
561
|
+
|
562
|
+
query = { 'uploadId' => upload_id }
|
563
|
+
|
564
|
+
body = Utils.to_xml('CompleteMultipartUpload' => {
|
565
|
+
'Part' => parts.map(&:to_hash)
|
566
|
+
})
|
567
|
+
|
568
|
+
http.post("/#{key}", query: query, body: body, bucket: bucket, key: key)
|
569
|
+
end
|
570
|
+
|
571
|
+
# Abort a Multipart Upload event
|
572
|
+
#
|
573
|
+
# @note After abort the Multipart Upload, the Uploaded data will be deleted
|
574
|
+
# @note When abort a Multipart Upload event, if there are still part upload belonging to this event, then theree parts will not be removed. So if there is a concurrent access, in order to release the space on the OSS completely, you need to call #bucket_abort_multipart a few times.
|
575
|
+
#
|
576
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/multipart-upload&AbortMultipartUpload Abort Multipart Upload
|
577
|
+
#
|
578
|
+
# @param key [String] the object name
|
579
|
+
# @param upload_id [String] the upload ID return by #bucket_init_multipart
|
580
|
+
#
|
581
|
+
# @return [Response]
|
582
|
+
def bucket_abort_multipart(key, upload_id)
|
583
|
+
query = { 'uploadId' => upload_id }
|
584
|
+
http.delete("/#{key}", query: query, bucket: bucket, key: key)
|
585
|
+
end
|
586
|
+
|
587
|
+
# List existing opened Multipart Upload event.
|
588
|
+
#
|
589
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/multipart-upload&ListMultipartUploads List Multipart Uploads
|
590
|
+
#
|
591
|
+
# @param options [Hash] options
|
592
|
+
# @option options [String] :prefix Filter objects with prefix
|
593
|
+
# @option options [String] :delimiter Used to group objects with delimiter
|
594
|
+
# @option options [Integer] :max-uploads (1000) Limit number of Multipart Upload events, the maxinum should <= 1000
|
595
|
+
# @option options [String] :encoding-type Encoding type used for unsupported character
|
596
|
+
# @option options [String] :key-marker with upload-id-marker used to specify the result range.
|
597
|
+
# @option options [String] :upload-id-marker with key-marker used to specify the result range.
|
598
|
+
#
|
599
|
+
# @return [Response]
|
600
|
+
def bucket_list_multiparts(options = {})
|
601
|
+
accepted_keys = ['prefix', 'key-marker', 'upload-id-marker', 'max-uploads', 'delimiter', 'encoding-type']
|
602
|
+
|
603
|
+
query = Utils.hash_slice(options, *accepted_keys).merge('uploads' => true)
|
604
|
+
|
605
|
+
http.get('/', query: query, bucket: bucket)
|
606
|
+
end
|
607
|
+
|
608
|
+
# List uploaded parts for Multipart Upload event
|
609
|
+
#
|
610
|
+
# @see https://docs.aliyun.com/#/pub/oss/api-reference/multipart-upload&ListParts List Parts
|
611
|
+
#
|
612
|
+
# @param key [String] the object name
|
613
|
+
# @param upload_id [String] the upload ID return by #bucket_init_multipart
|
614
|
+
# @param options [Hash] options
|
615
|
+
# @option options [Integer] :max-parts (1000) Limit number of parts, the maxinum should <= 1000
|
616
|
+
# @option options [Integer] :part-number-marker Specify the start part, return parts which number large than the specified value
|
617
|
+
# @option options [String] :encoding-type Encoding type used for unsupported character in xml 1.0
|
618
|
+
#
|
619
|
+
# @return [Response]
|
620
|
+
def bucket_list_parts(key, upload_id, options = {})
|
621
|
+
accepted_keys = ['max-parts', 'part-number-marker', 'encoding-type']
|
622
|
+
|
623
|
+
query = Utils.hash_slice(options, *accepted_keys).merge('uploadId' => upload_id)
|
624
|
+
|
625
|
+
http.get("/#{key}", query: query, bucket: bucket, key: key)
|
626
|
+
end
|
627
|
+
|
628
|
+
private
|
629
|
+
|
630
|
+
def http
|
631
|
+
@http = Http.new(access_key, secret_key, @options[:host])
|
632
|
+
end
|
633
|
+
end
|
634
|
+
end
|
635
|
+
end
|