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.
@@ -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.upcase, time, headers, conon_headers, conon_resource)
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, resource)
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
- c_headers,
102
- resource
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
- cononicalized_resource = '/'
140
- cononicalized_resource += "#{bucket}/" if bucket
141
- cononicalized_resource += key if key
142
- return cononicalized_resource if query.nil? || query.empty?
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 = query.keys.sort.map { |k| "#{k}=#{query[k]}" }.join('&')
145
- cononicalized_resource + '?' + query_str
134
+ query_str.empty? ? conon_resource : conon_resource + '?' + query_str
146
135
  end
147
136
  end
148
137
  end
@@ -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
- attr_reader :access_key, :secret_key
7
- attr_accessor :bucket
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 = Http.new(access_key, secret_key, @options[:host])
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