aliyun-oss-sdk 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +137 -151
- data/aliyun-oss.gemspec +1 -2
- data/lib/aliyun/oss/api/bucket_multiparts.rb +184 -0
- data/lib/aliyun/oss/api/bucket_objects.rb +204 -0
- data/lib/aliyun/oss/api/bucket_property.rb +246 -0
- data/lib/aliyun/oss/api/buckets.rb +89 -0
- data/lib/aliyun/oss/authorization.rb +21 -32
- data/lib/aliyun/oss/client.rb +11 -683
- data/lib/aliyun/oss/client/bucket_objects.rb +5 -6
- data/lib/aliyun/oss/client/buckets.rb +11 -5
- data/lib/aliyun/oss/http.rb +1 -1
- data/lib/aliyun/oss/struct/bucket.rb +4 -0
- data/lib/aliyun/oss/struct/directory.rb +25 -0
- data/lib/aliyun/oss/struct/file.rb +8 -0
- data/lib/aliyun/oss/struct/multipart.rb +2 -2
- data/lib/aliyun/oss/struct/object.rb +22 -1
- data/lib/aliyun/oss/struct/part.rb +2 -8
- data/lib/aliyun/oss/utils.rb +6 -0
- data/lib/aliyun/oss/version.rb +1 -1
- data/todo.md +1 -0
- data/wiki/multipart.md +3 -3
- data/wiki/object_based/bucket.md +125 -0
- data/wiki/object_based/cors.md +71 -0
- data/wiki/object_based/error.md +70 -0
- data/wiki/object_based/get_start.md +93 -0
- data/wiki/object_based/installation.md +15 -0
- data/wiki/object_based/lifecycle.md +88 -0
- data/wiki/object_based/multipart.md +133 -0
- data/wiki/object_based/object.md +324 -0
- metadata +69 -43
- checksums.yaml +0 -7
@@ -7,6 +7,12 @@ module Aliyun
|
|
7
7
|
module Oss
|
8
8
|
class Authorization
|
9
9
|
PROVIDER = 'OSS'
|
10
|
+
OVERRIDE_RESPONSE_LIST = %w(
|
11
|
+
response-content-type response-content-language response-cache-control
|
12
|
+
logging response-content-encoding acl uploadId uploads partNumber group
|
13
|
+
link delete website location objectInfo response-expires
|
14
|
+
response-content-disposition cors lifecycle restore qos referer append
|
15
|
+
position)
|
10
16
|
|
11
17
|
# Get temporary Signature
|
12
18
|
#
|
@@ -81,36 +87,17 @@ module Aliyun
|
|
81
87
|
*options.values_at(:bucket, :key, :query)
|
82
88
|
)
|
83
89
|
|
84
|
-
join_values(verb
|
90
|
+
join_values(verb, time, headers, conon_headers, conon_resource)
|
85
91
|
end
|
86
92
|
|
87
|
-
def self.join_values(verb, time, headers, conon_headers,
|
88
|
-
if conon_headers
|
89
|
-
join_with_conon_headers(verb, time, headers, conon_headers, resource)
|
90
|
-
else
|
91
|
-
join_without_conon_headers(verb, time, headers, resource)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def self.join_with_conon_headers(verb, time, headers, c_headers, resource)
|
93
|
+
def self.join_values(verb, time, headers, conon_headers, conon_resource)
|
96
94
|
[
|
97
95
|
verb,
|
98
|
-
headers['Content-MD5'],
|
99
|
-
headers['Content-Type'],
|
96
|
+
headers['Content-MD5'].to_s.strip,
|
97
|
+
headers['Content-Type'].to_s.strip,
|
100
98
|
time,
|
101
|
-
|
102
|
-
|
103
|
-
].join("\n")
|
104
|
-
end
|
105
|
-
|
106
|
-
def self.join_without_conon_headers(verb, time, headers, resource)
|
107
|
-
[
|
108
|
-
verb,
|
109
|
-
headers['Content-MD5'],
|
110
|
-
headers['Content-Type'],
|
111
|
-
time,
|
112
|
-
resource
|
113
|
-
].join("\n")
|
99
|
+
conon_headers
|
100
|
+
].join("\n") + conon_resource
|
114
101
|
end
|
115
102
|
|
116
103
|
def self.signature(secret_key, content_string)
|
@@ -132,17 +119,19 @@ module Aliyun
|
|
132
119
|
|
133
120
|
oss_headers.keys.sort.map do |key|
|
134
121
|
"#{key.downcase}:#{oss_headers[key]}"
|
135
|
-
end.join("\n")
|
122
|
+
end.join("\n") + "\n"
|
136
123
|
end
|
137
124
|
|
138
125
|
def self.get_cononicalized_resource(bucket, key, query)
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
return
|
126
|
+
conon_resource = '/'
|
127
|
+
conon_resource += "#{bucket}/" if bucket
|
128
|
+
conon_resource += key if key
|
129
|
+
return conon_resource if query.nil? || query.empty?
|
130
|
+
|
131
|
+
query_str = query.keys.select { |k| OVERRIDE_RESPONSE_LIST.include?(k) }
|
132
|
+
.sort.map { |k| "#{k}=#{query[k]}" }.join('&')
|
143
133
|
|
144
|
-
query_str
|
145
|
-
cononicalized_resource + '?' + query_str
|
134
|
+
query_str.empty? ? conon_resource : conon_resource + '?' + query_str
|
146
135
|
end
|
147
136
|
end
|
148
137
|
end
|
data/lib/aliyun/oss/client.rb
CHANGED
@@ -1,10 +1,18 @@
|
|
1
|
+
require 'aliyun/oss/api/buckets'
|
2
|
+
require 'aliyun/oss/api/bucket_property'
|
3
|
+
require 'aliyun/oss/api/bucket_objects'
|
4
|
+
require 'aliyun/oss/api/bucket_multiparts'
|
1
5
|
require 'aliyun/oss/client/clients'
|
2
6
|
|
3
7
|
module Aliyun
|
4
8
|
module Oss
|
5
9
|
class Client
|
6
|
-
|
7
|
-
|
10
|
+
include Aliyun::Oss::Api::Buckets
|
11
|
+
include Aliyun::Oss::Api::BucketProperty
|
12
|
+
include Aliyun::Oss::Api::BucketObjects
|
13
|
+
include Aliyun::Oss::Api::BucketMultiparts
|
14
|
+
|
15
|
+
attr_reader :access_key, :secret_key, :bucket
|
8
16
|
|
9
17
|
# Initialize a object
|
10
18
|
#
|
@@ -26,690 +34,10 @@ module Aliyun
|
|
26
34
|
@services = {}
|
27
35
|
end
|
28
36
|
|
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 [Response]
|
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 [Response]
|
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
|
-
# @raise [RequestError]
|
76
|
-
#
|
77
|
-
# @return [Response]
|
78
|
-
def bucket_create(name, location = 'oss-cn-hangzhou', acl = 'private')
|
79
|
-
query = { 'acl' => true }
|
80
|
-
headers = { 'x-oss-acl' => acl }
|
81
|
-
|
82
|
-
body = XmlGenerator.generate_create_bucket_xml(location)
|
83
|
-
|
84
|
-
http.put('/', query: query, headers: headers, body: body, bucket: name, location: location)
|
85
|
-
end
|
86
|
-
|
87
|
-
# Delete bucket
|
88
|
-
#
|
89
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&DeleteBucket Delete Bucket
|
90
|
-
#
|
91
|
-
# @param name [String] bucket name want to delete
|
92
|
-
#
|
93
|
-
# @raise [RequestError]
|
94
|
-
#
|
95
|
-
# @return [Response]
|
96
|
-
def bucket_delete(name)
|
97
|
-
http.delete('/', bucket: name)
|
98
|
-
end
|
99
|
-
|
100
|
-
# Used to modify the bucket access.
|
101
|
-
#
|
102
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&PutBucketACL Put Bucket Acl
|
103
|
-
#
|
104
|
-
# @param acl [String] supported value: public-read-write | public-read | private
|
105
|
-
# @raise [RequestError]
|
106
|
-
#
|
107
|
-
# @return [Response]
|
108
|
-
def bucket_set_acl(acl)
|
109
|
-
query = { 'acl' => true }
|
110
|
-
headers = { 'x-oss-acl' => acl }
|
111
|
-
http.put('/', query: query, headers: headers, bucket: bucket)
|
112
|
-
end
|
113
|
-
|
114
|
-
# Used to enable access logging.
|
115
|
-
#
|
116
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&PutBucketLogging Put Bucket Logging
|
117
|
-
#
|
118
|
-
# @param target_bucket [String] specifies the bucket where you want Aliyun OSS to store server access logs.
|
119
|
-
# @param target_prefix [String] this element lets you specify a prefix for the objects that the log files will be stored.
|
120
|
-
#
|
121
|
-
# @raise [RequestError]
|
122
|
-
#
|
123
|
-
# @return [Response]
|
124
|
-
def bucket_enable_logging(target_bucket, target_prefix = nil)
|
125
|
-
query = { 'logging' => true }
|
126
|
-
|
127
|
-
body = XmlGenerator.generate_enable_logging_xml(target_bucket,
|
128
|
-
target_prefix)
|
129
|
-
|
130
|
-
http.put('/', query: query, body: body, bucket: bucket)
|
131
|
-
end
|
132
|
-
|
133
|
-
# Used to disable access logging.
|
134
|
-
#
|
135
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&DeleteBucketLogging Delete Bucket Logging
|
136
|
-
#
|
137
|
-
# @raise [RequestError]
|
138
|
-
#
|
139
|
-
# @return [Response]
|
140
|
-
def bucket_disable_logging
|
141
|
-
query = { 'logging' => false }
|
142
|
-
http.delete('/', query: query, bucket: bucket)
|
143
|
-
end
|
144
|
-
|
145
|
-
# Used to enable static website hosted mode.
|
146
|
-
#
|
147
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&PutBucketWebsite Put Bucket Website
|
148
|
-
#
|
149
|
-
# @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.
|
150
|
-
# @param key [String] The object key name to use when a 4XX class error occurs
|
151
|
-
#
|
152
|
-
# @raise [RequestError]
|
153
|
-
#
|
154
|
-
# @return [Response]
|
155
|
-
def bucket_enable_website(suffix, key = nil)
|
156
|
-
query = { 'website' => true }
|
157
|
-
|
158
|
-
body = XmlGenerator.generate_enable_website_xml(suffix, key)
|
159
|
-
|
160
|
-
http.put('/', query: query, body: body, bucket: bucket)
|
161
|
-
end
|
162
|
-
|
163
|
-
# Used to disable website hostted mode.
|
164
|
-
#
|
165
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&DeleteBucketWebsite Delete Bucket Website
|
166
|
-
#
|
167
|
-
# @raise [RequestError]
|
168
|
-
#
|
169
|
-
# @return [Response]
|
170
|
-
def bucket_disable_website
|
171
|
-
query = { 'website' => false }
|
172
|
-
http.delete('/', query: query, bucket: bucket)
|
173
|
-
end
|
174
|
-
|
175
|
-
# Used to set referer for bucket.
|
176
|
-
#
|
177
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&PutBucketReferer Put Bucket Referer
|
178
|
-
#
|
179
|
-
# @param referers [Array<String>] white list for allowed referer.
|
180
|
-
# @param allowed_empty [Boolean] whether allow empty refer.
|
181
|
-
#
|
182
|
-
# @raise [RequestError]
|
183
|
-
#
|
184
|
-
# @return [Response]
|
185
|
-
def bucket_set_referer(referers = [], allowed_empty = false)
|
186
|
-
query = { 'referer' => true }
|
187
|
-
|
188
|
-
body = XmlGenerator.generate_set_referer_xml(referers, allowed_empty)
|
189
|
-
|
190
|
-
http.put('/', query: query, body: body, bucket: bucket)
|
191
|
-
end
|
192
|
-
|
193
|
-
# Used to enable and set lifecycle for bucket
|
194
|
-
#
|
195
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&PutBucketLifecycle Put Bucket Lifecycle
|
196
|
-
#
|
197
|
-
# @param rules [Array<Aliyun::Oss::Struct::LifeCycle>] rules for lifecycle
|
198
|
-
#
|
199
|
-
# @raise [RequestError]
|
200
|
-
# @raise [Aliyun::Oss::InvalidLifeCycleRuleError]
|
201
|
-
# if rule invalid
|
202
|
-
#
|
203
|
-
# @return [Response]
|
204
|
-
def bucket_enable_lifecycle(rules = [])
|
205
|
-
query = { 'lifecycle' => true }
|
206
|
-
|
207
|
-
rules = Utils.wrap(rules)
|
208
|
-
|
209
|
-
rules.each do |rule|
|
210
|
-
unless rule.valid?
|
211
|
-
fail Aliyun::Oss::InvalidLifeCycleRuleError, rule.inspect
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
body = XmlGenerator.generate_lifecycle_rules(rules)
|
216
|
-
|
217
|
-
http.put('/', query: query, body: body, bucket: bucket)
|
218
|
-
end
|
219
|
-
|
220
|
-
# Used to disable lifecycle for bucket.
|
221
|
-
#
|
222
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&DeleteBucketLifecycle Delete Bucket Lifecycle
|
223
|
-
def bucket_disable_lifecycle
|
224
|
-
query = { 'lifecycle' => false }
|
225
|
-
http.delete('/', query: query, bucket: bucket)
|
226
|
-
end
|
227
|
-
|
228
|
-
# Used to enable CORS and set rules for bucket
|
229
|
-
#
|
230
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/cors&PutBucketcors Put Bucket cors
|
231
|
-
#
|
232
|
-
# @param rules [Array<Aliyun::Oss::Struct::Cors>] array of rule
|
233
|
-
#
|
234
|
-
# @raise [RequestError]
|
235
|
-
# @raise [InvalidCorsRule]
|
236
|
-
# if rule invalid
|
237
|
-
#
|
238
|
-
# @return [Response]
|
239
|
-
def bucket_enable_cors(rules = [])
|
240
|
-
query = { 'cors' => true }
|
241
|
-
|
242
|
-
rules = Utils.wrap(rules)
|
243
|
-
|
244
|
-
rules.each do |rule|
|
245
|
-
unless rule.valid?
|
246
|
-
fail Aliyun::Oss::InvalidCorsRuleError, rule.inspect
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
|
-
body = XmlGenerator.generate_cors_rules(rules)
|
251
|
-
|
252
|
-
http.put('/', query: query, body: body, bucket: bucket)
|
253
|
-
end
|
254
|
-
|
255
|
-
# Used to disable cors and clear rules for bucket
|
256
|
-
#
|
257
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/cors&DeleteBucketcors Delete Bucket cors
|
258
|
-
#
|
259
|
-
# @raise [RequestError]
|
260
|
-
#
|
261
|
-
# @return [Response]
|
262
|
-
def bucket_disable_cors
|
263
|
-
query = { 'cors' => false }
|
264
|
-
http.delete('/', query: query, bucket: bucket)
|
265
|
-
end
|
266
|
-
|
267
|
-
# OPTIONS Object
|
268
|
-
#
|
269
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/cors&OptionObject OPTIONS Object
|
270
|
-
#
|
271
|
-
# @param object_key [String] the object name want to visit.
|
272
|
-
# @param origin [String] the requested source domain, denoting cross-domain request.
|
273
|
-
# @param request_method [String] the actual request method will be used.
|
274
|
-
# @param request_headers [Array<String>] the actual used headers except simple headers will be used.
|
275
|
-
#
|
276
|
-
# @raise [RequestError]
|
277
|
-
#
|
278
|
-
# @return [Response]
|
279
|
-
def bucket_preflight(object_key, origin, request_method, request_headers = [])
|
280
|
-
path = object_key ? "/#{object_key}" : '/'
|
281
|
-
|
282
|
-
headers = {
|
283
|
-
'Origin' => origin,
|
284
|
-
'Access-Control-Request-Method' => request_method
|
285
|
-
}
|
286
|
-
|
287
|
-
unless request_headers.empty?
|
288
|
-
value = request_headers.join(',')
|
289
|
-
headers.merge!('Access-Control-Request-Headers' => value)
|
290
|
-
end
|
291
|
-
|
292
|
-
http.options(path, headers: headers, bucket: bucket, key: object_key)
|
293
|
-
end
|
294
|
-
|
295
|
-
# Get ACL for bucket
|
296
|
-
#
|
297
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&GetBucketAcl Get Bucket ACL
|
298
|
-
#
|
299
|
-
# @return [Response]
|
300
|
-
def bucket_get_acl
|
301
|
-
query = { 'acl' => true }
|
302
|
-
http.get('/', query: query, bucket: bucket)
|
303
|
-
end
|
304
|
-
|
305
|
-
# Get the location information of the Bucket's data center
|
306
|
-
#
|
307
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&GetBucketLocation Get Bucket Location
|
308
|
-
#
|
309
|
-
# @return [Response]
|
310
|
-
def bucket_get_location
|
311
|
-
query = { 'location' => true }
|
312
|
-
http.get('/', query: query, bucket: bucket)
|
313
|
-
end
|
314
|
-
|
315
|
-
# Get the log configuration of Bucket
|
316
|
-
#
|
317
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&GetBucketLogging Get Bucket Logging
|
318
|
-
#
|
319
|
-
# @raise [RequestError]
|
320
|
-
#
|
321
|
-
# @return [Response]
|
322
|
-
def bucket_get_logging
|
323
|
-
query = { 'logging' => true }
|
324
|
-
http.get('/', query: query, bucket: bucket)
|
325
|
-
end
|
326
|
-
|
327
|
-
# Get the bucket state of static website hosting.
|
328
|
-
#
|
329
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&GetBucketWebsite Get Bucket Website
|
330
|
-
#
|
331
|
-
# @return [Response]
|
332
|
-
def bucket_get_website
|
333
|
-
query = { 'website' => true }
|
334
|
-
http.get('/', query: query, bucket: bucket)
|
335
|
-
end
|
336
|
-
|
337
|
-
# Get the referer configuration of bucket
|
338
|
-
#
|
339
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&GetBucketReferer Get Bucket Referer
|
340
|
-
#
|
341
|
-
# @return [Response]
|
342
|
-
def bucket_get_referer
|
343
|
-
query = { 'referer' => true }
|
344
|
-
http.get('/', query: query, bucket: bucket)
|
345
|
-
end
|
346
|
-
|
347
|
-
# Get the lifecycle configuration of bucket
|
348
|
-
#
|
349
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/bucket&GetBucketLifecycle Get Bucket Lifecycle
|
350
|
-
#
|
351
|
-
# @return [Response]
|
352
|
-
def bucket_get_lifecycle
|
353
|
-
query = { 'lifecycle' => true }
|
354
|
-
http.get('/', query: query, bucket: bucket)
|
355
|
-
end
|
356
|
-
|
357
|
-
# Get the CORS rules of bucket
|
358
|
-
#
|
359
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/cors&GetBucketcors Get Bucket cors
|
360
|
-
#
|
361
|
-
# @return [Response]
|
362
|
-
def bucket_get_cors
|
363
|
-
query = { 'cors' => true }
|
364
|
-
http.get('/', query: query, bucket: bucket)
|
365
|
-
end
|
366
|
-
|
367
|
-
# Upload file to bucket
|
368
|
-
#
|
369
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/object&PutObject Put Object
|
370
|
-
#
|
371
|
-
# @param key [String] Specify object name
|
372
|
-
# @param file [File, Bin data] Specify need upload resource
|
373
|
-
# @param [Hash] headers Specify other options
|
374
|
-
# @option headers [String] :Content-Type ('application/x-www-form-urlencoded') Specify Content-Type for the object
|
375
|
-
# @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}
|
376
|
-
# @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}
|
377
|
-
# @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}
|
378
|
-
# @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.
|
379
|
-
# @option headers [Integer] :Expires Specify the expiration time (milliseconds)
|
380
|
-
# @option headers [String] :x-oss-server-side-encryption Specify the oss server-side encryption algorithm when the object was created. supported value: 'AES256'
|
381
|
-
# @option headers [String] :x-oss-object-acl Specify the oss access when the object was created. supported value: public-read-write | public-read | private
|
382
|
-
# @option headers [Hash] other options will insert into headers when upload, such as user meta headers, eg: headers with prefix: x-oss-meta-
|
383
|
-
#
|
384
|
-
# @return [Response]
|
385
|
-
def bucket_create_object(key, file, headers = {})
|
386
|
-
http.put("/#{key}", headers: headers, body: Utils.to_data(file), bucket: bucket, key: key)
|
387
|
-
end
|
388
|
-
|
389
|
-
# Copy an existing object in OSS into another object
|
390
|
-
#
|
391
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/object&CopyObject Copy Object
|
392
|
-
#
|
393
|
-
# @param key [String] the object name
|
394
|
-
# @param source_bucket [String] the source bucket name
|
395
|
-
# @param source_key [String] the source object name
|
396
|
-
# @param [Hash] headers
|
397
|
-
# @option options [String] :source_bucket the source bucket name
|
398
|
-
# @option options [String] :source_key the source object name
|
399
|
-
# @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)
|
400
|
-
# @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)
|
401
|
-
# @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)
|
402
|
-
# @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)
|
403
|
-
# @option options [String] :x-oss-metadata-directive ('COPY') supported value: COPY, REPLACE;
|
404
|
-
# @option options [String] :x-oss-server-side-encryption supported value: AES256
|
405
|
-
# @option options [String] :x-oss-object-acl supported value: public-read, private, public-read-write
|
406
|
-
#
|
407
|
-
# @raise [RequestError]
|
408
|
-
#
|
409
|
-
# @return [Response]
|
410
|
-
def bucket_copy_object(key, source_bucket, source_key, headers = {})
|
411
|
-
fail('source_bucket must be not empty!') if source_bucket.nil? || source_bucket.empty?
|
412
|
-
fail('source_key must be not empty!') if source_key.nil? || source_key.empty?
|
413
|
-
|
414
|
-
headers.merge!('x-oss-copy-source' => "/#{source_bucket}/#{source_key}")
|
415
|
-
|
416
|
-
http.put("/#{key}", headers: headers, bucket: bucket, key: key)
|
417
|
-
end
|
418
|
-
|
419
|
-
# Append data to a object, will create Appendable object
|
420
|
-
#
|
421
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/object&AppendObject Append Object
|
422
|
-
#
|
423
|
-
# @param key [String] object name
|
424
|
-
# @param file [file, bin data] the data to append
|
425
|
-
# @param position [Integer] append to position of object
|
426
|
-
# @option headers (see #bucket_create_object)
|
427
|
-
#
|
428
|
-
# @raise [RequestError]
|
429
|
-
#
|
430
|
-
# @return [Response]
|
431
|
-
def bucket_append_object(key, file, position = 0, headers = {})
|
432
|
-
query = { 'append' => true, 'position' => position }
|
433
|
-
|
434
|
-
body = Utils.to_data(file)
|
435
|
-
|
436
|
-
http.post("/#{key}", query: query, headers: headers, body: body, bucket: bucket, key: key)
|
437
|
-
end
|
438
|
-
|
439
|
-
# Get the object
|
440
|
-
#
|
441
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/object&GetObject Get Object
|
442
|
-
#
|
443
|
-
# @param key [String] the object name
|
444
|
-
# @param query [Hash] query params
|
445
|
-
# @option query [String] :response-content-type Specify the header Content-Type in response
|
446
|
-
# @option query [String] :response-content-language Specify the header Content-Language in response
|
447
|
-
# @option query [String] :response-expires Specify the header Expires in response
|
448
|
-
# @option query [String] :response-cache-control Specify the header Cache-Control in response
|
449
|
-
# @option query [String] :response-content-disposition Specify the header Content-Disposition in response
|
450
|
-
# @option query [String] :response-content-encoding Specify the header Content-encoding in response
|
451
|
-
# @param headers [Hash] headers
|
452
|
-
# @option headers [String] :Range Specify the range of the file. Such as "bytes=0-9" means the 10 characters from 0 to 9.
|
453
|
-
# @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)
|
454
|
-
# @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)
|
455
|
-
# @option headers [String] :If-Match If the specified ETag match the object ETag, normal transfer and return 200; Otherwise return 412(precondition)
|
456
|
-
# @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)
|
457
|
-
#
|
458
|
-
# @return [Response]
|
459
|
-
def bucket_get_object(key, query = {}, headers = {})
|
460
|
-
http.get("/#{key}", query: query, headers: headers, bucket: bucket, key: key)
|
461
|
-
end
|
462
|
-
|
463
|
-
# Delete object from bucket
|
464
|
-
#
|
465
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/object&DeleteObject Delete Object
|
466
|
-
#
|
467
|
-
# @param key [String] the object name
|
468
|
-
#
|
469
|
-
# @return [Response]
|
470
|
-
def bucket_delete_object(key)
|
471
|
-
http.delete("/#{key}", bucket: bucket, key: key)
|
472
|
-
end
|
473
|
-
|
474
|
-
# Delete multiple objects, at max 1000 at once
|
475
|
-
#
|
476
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/object&DeleteMultipleObjects Delete Multiple Objects
|
477
|
-
#
|
478
|
-
# @param keys [Array<String>] the object names
|
479
|
-
# @param quiet [Boolean] Specify response mode: false(Quiet) return results for error objects, true(Verbose) return results of every objects
|
480
|
-
#
|
481
|
-
# @return [Response]
|
482
|
-
def bucket_delete_objects(keys, quiet = false)
|
483
|
-
query = { 'delete' => true }
|
484
|
-
|
485
|
-
body = XmlGenerator.generate_delete_objects_xml(keys, quiet)
|
486
|
-
|
487
|
-
http.post('/', query: query, body: body, bucket: bucket)
|
488
|
-
end
|
489
|
-
|
490
|
-
# Get meta information of object
|
491
|
-
#
|
492
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/object&HeadObject Head Object
|
493
|
-
#
|
494
|
-
# @param key [String] object name
|
495
|
-
# @param headers [Hash] headers
|
496
|
-
# @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)
|
497
|
-
# @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)
|
498
|
-
# @option headers [String] :If-Match If the specified ETag match the object ETag, normal transfer and return 200; Otherwise return 412(precondition)
|
499
|
-
# @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)
|
500
|
-
#
|
501
|
-
# @raise [RequestError]
|
502
|
-
#
|
503
|
-
# @return [Response]
|
504
|
-
def bucket_get_meta_object(key, headers = {})
|
505
|
-
http.head("/#{key}", headers: headers, bucket: bucket, key: key)
|
506
|
-
end
|
507
|
-
|
508
|
-
# Get access of object
|
509
|
-
#
|
510
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/object&GetObjectACL Get Object ACL
|
511
|
-
#
|
512
|
-
# @param key [String] object name
|
513
|
-
#
|
514
|
-
# @raise [RequestError]
|
515
|
-
#
|
516
|
-
# @return [Response]
|
517
|
-
def bucket_get_object_acl(key)
|
518
|
-
query = { 'acl' => true }
|
519
|
-
http.get("/#{key}", query: query, bucket: bucket, key: key)
|
520
|
-
end
|
521
|
-
|
522
|
-
# Set access of object
|
523
|
-
#
|
524
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/object&PutObjectACL Put Object ACL
|
525
|
-
#
|
526
|
-
# @param key [String] object name
|
527
|
-
# @param acl [String] access value, supported value: private, public-read, public-read-write
|
528
|
-
#
|
529
|
-
# @raise [RequestError]
|
530
|
-
#
|
531
|
-
# @return [Response]
|
532
|
-
def bucket_set_object_acl(key, acl)
|
533
|
-
query = { 'acl' => true }
|
534
|
-
headers = { 'x-oss-object-acl' => acl }
|
535
|
-
http.put("/#{key}", query: query, headers: headers, bucket: bucket, key: key)
|
536
|
-
end
|
537
|
-
|
538
|
-
# 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.
|
539
|
-
#
|
540
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/multipart-upload&InitiateMultipartUpload Initiate Multipart Upload
|
541
|
-
#
|
542
|
-
# @param key [String] object name
|
543
|
-
# @param headers [Hash] headers
|
544
|
-
# @option headers [String] :Content-Type ('application/x-www-form-urlencoded') Specify Content-Type for the object
|
545
|
-
# @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}
|
546
|
-
# @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}
|
547
|
-
# @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}
|
548
|
-
# @option headers [Integer] :Expires Specify the expiration time (milliseconds)
|
549
|
-
# @option headers [String] :x-oss-server-side-encryption Specify the oss server-side encryption algorithm when the object was created. supported value: 'AES256'#
|
550
|
-
#
|
551
|
-
# @return [Response]
|
552
|
-
def bucket_init_multipart(key, headers = {})
|
553
|
-
query = { 'uploads' => true }
|
554
|
-
http.post("/#{key}", query: query, headers: headers, bucket: bucket, key: key)
|
555
|
-
end
|
556
|
-
|
557
|
-
# Upload object in part.
|
558
|
-
#
|
559
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/multipart-upload&UploadPart Upload Part
|
560
|
-
#
|
561
|
-
# @param key [String] object name
|
562
|
-
# @param number [Integer] the part number, Range in 1~10000.
|
563
|
-
# @param upload_id [String] the upload ID return by #bucket_init_multipart
|
564
|
-
# @param file [File, bin data] the upload data
|
565
|
-
#
|
566
|
-
# @raise [RequestError]
|
567
|
-
# @raise [MultipartPartNumberEmptyError]
|
568
|
-
# @raise [MultipartUploadIdEmptyError]
|
569
|
-
#
|
570
|
-
# @return [Response]
|
571
|
-
def bucket_multipart_upload(upload_id, key, number, file)
|
572
|
-
fail MultipartPartNumberEmptyError if number.nil?
|
573
|
-
fail MultipartUploadIdEmptyError if upload_id.nil? || upload_id.empty?
|
574
|
-
|
575
|
-
query = { 'partNumber' => number.to_s, 'uploadId' => upload_id }
|
576
|
-
|
577
|
-
http.put("/#{key}", query: query, body: Utils.to_data(file), bucket: bucket, key: key)
|
578
|
-
end
|
579
|
-
|
580
|
-
# Upload a Part from an existing Object Copy data.
|
581
|
-
#
|
582
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/multipart-upload&UploadPartCopy Upload Part Copy
|
583
|
-
#
|
584
|
-
# @param key [String] object name
|
585
|
-
# @param number [Integer] the part number, Range in 1~10000.
|
586
|
-
# @param upload_id [String] the upload ID return by #bucket_init_multipart
|
587
|
-
# @param options [Hash] options
|
588
|
-
# @option options [String] :source_bucket the source bucket name
|
589
|
-
# @option options [String] :source_key the source object name
|
590
|
-
# @option options [String] :range the Range bytes, not set means the whole object, eg: bytes=100-6291756
|
591
|
-
# @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)
|
592
|
-
# @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)
|
593
|
-
# @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)
|
594
|
-
# @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)
|
595
|
-
#
|
596
|
-
# @raise [RequestError]
|
597
|
-
# @raise [MultipartSourceBucketEmptyError]
|
598
|
-
# @raise [MultipartSourceKeyEmptyError]
|
599
|
-
#
|
600
|
-
# @return [Response]
|
601
|
-
def bucket_multipart_copy_upload(upload_id, key, number, options = {})
|
602
|
-
source_bucket = options.delete(:source_bucket).to_s
|
603
|
-
source_key = options.delete(:source_key).to_s
|
604
|
-
range = options.delete(:range)
|
605
|
-
|
606
|
-
fail MultipartSourceBucketEmptyError if source_bucket.empty?
|
607
|
-
fail MultipartSourceKeyEmptyError if source_key.empty?
|
608
|
-
|
609
|
-
query = { 'partNumber' => number, 'uploadId' => upload_id }
|
610
|
-
headers = copy_upload_headers(source_bucket, source_key, range, options)
|
611
|
-
|
612
|
-
http.put("/#{key}", query: query, headers: headers, bucket: bucket, key: key)
|
613
|
-
end
|
614
|
-
|
615
|
-
# Complete a Multipart Upload event.
|
616
|
-
#
|
617
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/multipart-upload&CompleteMultipartUpload Complete Multipart Upload
|
618
|
-
#
|
619
|
-
# @param key [String] object name
|
620
|
-
# @param upload_id [String] the upload ID return by #bucket_init_multipart
|
621
|
-
# @param parts [Array<Aliyun::Oss::Multipart:Part>] parts
|
622
|
-
#
|
623
|
-
# @raise [RequestError]
|
624
|
-
# @raise [MultipartPartsEmptyError]
|
625
|
-
# @raise [MultipartUploadIdEmptyError]
|
626
|
-
#
|
627
|
-
# @return [Response]
|
628
|
-
def bucket_complete_multipart(upload_id, key, parts = [])
|
629
|
-
fail MultipartPartsEmptyError if parts.nil? || parts.empty?
|
630
|
-
fail MultipartUploadIdEmptyError if upload_id.nil?
|
631
|
-
|
632
|
-
query = { 'uploadId' => upload_id }
|
633
|
-
|
634
|
-
body = XmlGenerator.generate_complete_multipart_xml(parts)
|
635
|
-
|
636
|
-
http.post("/#{key}", query: query, body: body, bucket: bucket, key: key)
|
637
|
-
end
|
638
|
-
|
639
|
-
# Abort a Multipart Upload event
|
640
|
-
#
|
641
|
-
# @note After abort the Multipart Upload, the Uploaded data will be deleted
|
642
|
-
# @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.
|
643
|
-
#
|
644
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/multipart-upload&AbortMultipartUpload Abort Multipart Upload
|
645
|
-
#
|
646
|
-
# @param key [String] the object name
|
647
|
-
# @param upload_id [String] the upload ID return by #bucket_init_multipart
|
648
|
-
#
|
649
|
-
# @raise [RequestError]
|
650
|
-
#
|
651
|
-
# @return [Response]
|
652
|
-
def bucket_abort_multipart(upload_id, key)
|
653
|
-
query = { 'uploadId' => upload_id }
|
654
|
-
http.delete("/#{key}", query: query, bucket: bucket, key: key)
|
655
|
-
end
|
656
|
-
|
657
|
-
# List existing opened Multipart Upload event.
|
658
|
-
#
|
659
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/multipart-upload&ListMultipartUploads List Multipart Uploads
|
660
|
-
#
|
661
|
-
# @param options [Hash] options
|
662
|
-
# @option options [String] :prefix Filter objects with prefix
|
663
|
-
# @option options [String] :delimiter Used to group objects with delimiter
|
664
|
-
# @option options [Integer] :max-uploads (1000) Limit number of Multipart Upload events, the maxinum should <= 1000
|
665
|
-
# @option options [String] :encoding-type Encoding type used for unsupported character
|
666
|
-
# @option options [String] :key-marker with upload-id-marker used to specify the result range.
|
667
|
-
# @option options [String] :upload-id-marker with key-marker used to specify the result range.
|
668
|
-
#
|
669
|
-
# @return [Response]
|
670
|
-
def bucket_list_multiparts(options = {})
|
671
|
-
accepted_keys = ['prefix', 'key-marker', 'upload-id-marker', 'max-uploads', 'delimiter', 'encoding-type']
|
672
|
-
|
673
|
-
query = Utils.hash_slice(options, *accepted_keys)
|
674
|
-
.merge('uploads' => true)
|
675
|
-
|
676
|
-
http.get('/', query: query, bucket: bucket)
|
677
|
-
end
|
678
|
-
|
679
|
-
# List uploaded parts for Multipart Upload event
|
680
|
-
#
|
681
|
-
# @see https://docs.aliyun.com/#/pub/oss/api-reference/multipart-upload&ListParts List Parts
|
682
|
-
#
|
683
|
-
# @param key [String] the object name
|
684
|
-
# @param upload_id [Integer] the upload ID return by #bucket_init_multipart
|
685
|
-
# @param options [Hash] options
|
686
|
-
# @option options [Integer] :max-parts (1000) Limit number of parts, the maxinum should <= 1000
|
687
|
-
# @option options [Integer] :part-number-marker Specify the start part, return parts which number large than the specified value
|
688
|
-
# @option options [String] :encoding-type Encoding type used for unsupported character in xml 1.0
|
689
|
-
#
|
690
|
-
# @return [Response]
|
691
|
-
def bucket_list_parts(upload_id, key, options = {})
|
692
|
-
accepted_keys = ['max-parts', 'part-number-marker', 'encoding-type']
|
693
|
-
|
694
|
-
query = Utils.hash_slice(options, *accepted_keys).merge('uploadId' => upload_id)
|
695
|
-
|
696
|
-
http.get("/#{key}", query: query, bucket: bucket, key: key)
|
697
|
-
end
|
698
|
-
|
699
37
|
private
|
700
38
|
|
701
39
|
def http
|
702
|
-
@http
|
703
|
-
end
|
704
|
-
|
705
|
-
def copy_upload_headers(source_bucket, source_key, range, options)
|
706
|
-
copy_source = "/#{source_bucket}/#{source_key}"
|
707
|
-
|
708
|
-
headers = {}
|
709
|
-
headers.merge!('x-oss-copy-source' => copy_source)
|
710
|
-
headers.merge!('x-oss-copy-source-range' => range) if range
|
711
|
-
headers.merge!(options)
|
712
|
-
headers
|
40
|
+
@http ||= Http.new(access_key, secret_key, @options[:host])
|
713
41
|
end
|
714
42
|
end
|
715
43
|
end
|