aliyun-sdk 0.6.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +27 -0
  3. data/README.md +0 -0
  4. data/examples/aliyun/oss/bucket.rb +0 -0
  5. data/examples/aliyun/oss/callback.rb +0 -0
  6. data/examples/aliyun/oss/object.rb +0 -0
  7. data/examples/aliyun/oss/resumable_download.rb +0 -0
  8. data/examples/aliyun/oss/resumable_upload.rb +0 -0
  9. data/examples/aliyun/oss/streaming.rb +0 -0
  10. data/examples/aliyun/oss/using_sts.rb +0 -0
  11. data/examples/aliyun/sts/assume_role.rb +0 -0
  12. data/ext/crcx/crc64_ecma.c +0 -0
  13. data/ext/crcx/crcx.c +0 -0
  14. data/ext/crcx/crcx.h +0 -0
  15. data/ext/crcx/extconf.rb +0 -0
  16. data/lib/aliyun/common.rb +0 -0
  17. data/lib/aliyun/common/exception.rb +0 -0
  18. data/lib/aliyun/common/logging.rb +20 -3
  19. data/lib/aliyun/common/struct.rb +0 -0
  20. data/lib/aliyun/oss.rb +0 -0
  21. data/lib/aliyun/oss/bucket.rb +57 -32
  22. data/lib/aliyun/oss/client.rb +6 -2
  23. data/lib/aliyun/oss/config.rb +0 -0
  24. data/lib/aliyun/oss/download.rb +0 -0
  25. data/lib/aliyun/oss/exception.rb +0 -0
  26. data/lib/aliyun/oss/http.rb +8 -5
  27. data/lib/aliyun/oss/iterator.rb +0 -0
  28. data/lib/aliyun/oss/multipart.rb +0 -0
  29. data/lib/aliyun/oss/object.rb +0 -0
  30. data/lib/aliyun/oss/protocol.rb +116 -3
  31. data/lib/aliyun/oss/struct.rb +27 -2
  32. data/lib/aliyun/oss/upload.rb +0 -0
  33. data/lib/aliyun/oss/util.rb +6 -0
  34. data/lib/aliyun/sts.rb +0 -0
  35. data/lib/aliyun/sts/client.rb +1 -1
  36. data/lib/aliyun/sts/config.rb +0 -0
  37. data/lib/aliyun/sts/exception.rb +0 -0
  38. data/lib/aliyun/sts/protocol.rb +1 -1
  39. data/lib/aliyun/sts/struct.rb +0 -0
  40. data/lib/aliyun/sts/util.rb +0 -0
  41. data/lib/aliyun/version.rb +1 -1
  42. data/spec/aliyun/oss/bucket_spec.rb +143 -2
  43. data/spec/aliyun/oss/client/bucket_spec.rb +392 -22
  44. data/spec/aliyun/oss/client/client_spec.rb +25 -0
  45. data/spec/aliyun/oss/client/resumable_download_spec.rb +0 -0
  46. data/spec/aliyun/oss/client/resumable_upload_spec.rb +0 -0
  47. data/spec/aliyun/oss/http_spec.rb +0 -0
  48. data/spec/aliyun/oss/multipart_spec.rb +0 -0
  49. data/spec/aliyun/oss/object_spec.rb +95 -2
  50. data/spec/aliyun/oss/service_spec.rb +0 -0
  51. data/spec/aliyun/oss/util_spec.rb +51 -0
  52. data/spec/aliyun/sts/client_spec.rb +0 -0
  53. data/spec/aliyun/sts/util_spec.rb +0 -0
  54. data/tests/config.rb +0 -0
  55. data/tests/helper.rb +0 -0
  56. data/tests/test_bucket.rb +73 -0
  57. data/tests/test_content_encoding.rb +0 -0
  58. data/tests/test_content_type.rb +0 -0
  59. data/tests/test_crc_check.rb +0 -0
  60. data/tests/test_custom_headers.rb +0 -0
  61. data/tests/test_encoding.rb +0 -0
  62. data/tests/test_large_file.rb +0 -0
  63. data/tests/test_multipart.rb +0 -0
  64. data/tests/test_object_acl.rb +0 -0
  65. data/tests/test_object_key.rb +18 -0
  66. data/tests/test_object_url.rb +20 -0
  67. data/tests/test_resumable.rb +0 -0
  68. metadata +8 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: b400456da8877a797a2caecc64fd696f54f129f3
4
- data.tar.gz: 0bc030c00b7bc81a234bfa7ac52db10a1cbc7f71
2
+ SHA256:
3
+ metadata.gz: 9ed62a6f5a59df2499c7fd4028b4aecfad8506018ef7a3425b1c7627e0f8ddc8
4
+ data.tar.gz: eb47336dccf3d526466e6cbf5fbf3a845c4f9b8be5d34a5b7f7a55cd6b87f693
5
5
  SHA512:
6
- metadata.gz: 71786966777a2ebcbbdf370bf436c8d5d983e710f0fca4f2f2c7e63ea8dab9fc51982b457a4cdfeeb3085cb4509260cd8646b15de374bd41b0ca114ae647d121
7
- data.tar.gz: b03108695f1e78fae5c0ab4dc2da904b9af2409e93d4bb0529da78a1fa10f28e1f2548165890dc7710f35b364765559ecdcc60d2e5444f9035489fb5a737e831
6
+ metadata.gz: 4ee2ee99edbc2d8adbaa2d5dcf1cc2b661ee5430af90b8f5f95f6e4c7508fc878b4d83bc93c03d52efa8ea90796448e04992475ec8decc1756b886139d72c01a
7
+ data.tar.gz: 20d032b6e0c0537d2b6fbcc8d94aaba85e666c643a495bf2093418d731c5655c665a46523b17d11c9361edf683db418a9000e435e98afdaf53f4588a8c7bc794
@@ -1,5 +1,32 @@
1
1
  ## Change Log
2
2
 
3
+ ### v0.8.0 / 2020-08-17
4
+
5
+ - add bucket encryption
6
+ - add bucket versioning
7
+ - add env parameter to set default log level
8
+
9
+ ### v0.7.3 / 2020-06-28
10
+
11
+ - add variable control log output path
12
+
13
+
14
+ ### v0.7.2 / 2020-06-05
15
+
16
+ - add env parameter to descide whether output log file
17
+
18
+ ### v0.7.1 / 2019-11-16
19
+
20
+ - add the validity check of bucket name
21
+ - add parameters argument for buclet.object_url api
22
+ - fix http.get_request_url function bug
23
+ - fix warning constant ::Fixnum is deprecated
24
+ - support rest-client 2.1.0
25
+
26
+ ### v0.7.0 / 2018-06-05
27
+
28
+ - deps: upgrade nokogiri to > 1.6 and ruby version >= 2.0
29
+
3
30
  ### v0.6.0 / 2017-07-23
4
31
 
5
32
  - deps: upgrade rest-client to 2.x
data/README.md CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -11,7 +11,6 @@ module Aliyun
11
11
  # logger.info(xxx)
12
12
  module Logging
13
13
 
14
- DEFAULT_LOG_FILE = "./aliyun_sdk.log"
15
14
  MAX_NUM_LOG = 100
16
15
  ROTATE_SIZE = 10 * 1024 * 1024
17
16
 
@@ -34,13 +33,31 @@ module Aliyun
34
33
 
35
34
  def self.logger
36
35
  unless @logger
36
+ # Environment parameter ALIYUN_OSS_SDK_LOG_PATH used to set output log to a file,do not output log if not set
37
+ @log_file ||= ENV["ALIYUN_OSS_SDK_LOG_PATH"]
37
38
  @logger = Logger.new(
38
- @log_file ||= DEFAULT_LOG_FILE, MAX_NUM_LOG, ROTATE_SIZE)
39
- @logger.level = Logger::INFO
39
+ @log_file, MAX_NUM_LOG, ROTATE_SIZE)
40
+ @logger.level = get_env_log_level || Logger::INFO
40
41
  end
41
42
  @logger
42
43
  end
43
44
 
45
+ def self.get_env_log_level
46
+ return unless ENV["ALIYUN_OSS_SDK_LOG_LEVEL"]
47
+ case ENV["ALIYUN_OSS_SDK_LOG_LEVEL"].upcase
48
+ when "DEBUG"
49
+ Logger::DEBUG
50
+ when "WARN"
51
+ Logger::WARN
52
+ when "ERROR"
53
+ Logger::ERROR
54
+ when "FATAL"
55
+ Logger::FATAL
56
+ when "UNKNOWN"
57
+ Logger::UNKNOWN
58
+ end
59
+ end
60
+
44
61
  end # logging
45
62
  end # Common
46
63
  end # Aliyun
File without changes
File without changes
@@ -47,6 +47,34 @@ module Aliyun
47
47
  end
48
48
  end
49
49
 
50
+ # 获取Bucket的versioning配置
51
+ # @return [BucketVersioning] Bucket的versioning配置
52
+ def versioning
53
+ @protocol.get_bucket_versioning(name)
54
+ end
55
+
56
+ # 设置Bucket的versioning配置
57
+ # @param versioning [BucketVersioning] versioning配置
58
+ def versioning=(versioning)
59
+ @protocol.put_bucket_versioning(name, versioning)
60
+ end
61
+
62
+ # 获取Bucket的encryption配置
63
+ # @return [BucketEncryption] Bucket的encryption配置
64
+ def encryption
65
+ @protocol.get_bucket_encryption(name)
66
+ end
67
+
68
+ # 设置Bucket的encryption配置
69
+ # @param encryption [BucketEncryption] encryption配置
70
+ def encryption=(encryption)
71
+ if encryption.enabled?
72
+ @protocol.put_bucket_encryption(name, encryption)
73
+ else
74
+ @protocol.delete_bucket_encryption(name)
75
+ end
76
+ end
77
+
50
78
  # 获取Bucket的website配置
51
79
  # @return [BucketWebsite] Bucket的website配置
52
80
  def website
@@ -588,42 +616,39 @@ module Aliyun
588
616
  # 获取Object的URL
589
617
  # @param [String] key Object的key
590
618
  # @param [Boolean] sign 是否对URL进行签名,默认为是
591
- # @param [Fixnum] expiry URL的有效时间,单位为秒,默认为60s
619
+ # @param [Integer] expiry URL的有效时间,单位为秒,默认为60s
620
+ # @param [Hash] parameters 附加的query参数,默认为空
592
621
  # @return [String] 用于直接访问Object的URL
593
- def object_url(key, sign = true, expiry = 60)
594
- url = @protocol.get_request_url(name, key)
595
- return url unless sign
596
-
597
- expires = Time.now.to_i + expiry
598
- query = {
599
- 'Expires' => expires.to_s,
600
- 'OSSAccessKeyId' => CGI.escape(access_key_id)
601
- }
602
-
603
- sub_res = []
604
- if @protocol.get_sts_token
605
- sub_res << "security-token=#{@protocol.get_sts_token}"
606
- query['security-token'] = CGI.escape(@protocol.get_sts_token)
607
- end
608
-
609
- resource = "/#{name}/#{key}"
610
- unless sub_res.empty?
611
- resource << "?#{sub_res.join('&')}"
612
- end
622
+ def object_url(key, sign = true, expiry = 60, parameters = {})
623
+ url = @protocol.get_request_url(name, key).gsub('%2F', '/')
624
+ query = parameters.dup
625
+
626
+ if sign
627
+ #header
628
+ expires = Time.now.to_i + expiry
629
+ headers = {
630
+ 'date' => expires.to_s,
631
+ }
632
+
633
+ #query
634
+ if @protocol.get_sts_token
635
+ query['security-token'] = @protocol.get_sts_token
636
+ end
613
637
 
614
- string_to_sign = "" <<
615
- "GET\n" << # method
616
- "\n" << # Content-MD5
617
- "\n" << # Content-Type
618
- "#{expires}\n" <<
619
- "#{resource}"
638
+ res = {
639
+ :path => @protocol.get_resource_path(name, key),
640
+ :sub_res => query,
641
+ }
642
+ signature = Util.get_signature(@protocol.get_access_key_secret, 'GET', headers, res)
620
643
 
621
- signature = sign(string_to_sign)
622
- query_string =
623
- query.merge('Signature' => CGI.escape(signature))
624
- .map { |k, v| "#{k}=#{v}" }.join('&')
644
+ query['Expires'] = expires.to_s
645
+ query['OSSAccessKeyId'] = @protocol.get_access_key_id
646
+ query['Signature'] = signature
647
+ end
625
648
 
626
- [url, query_string].join('?')
649
+ query_string = query.map { |k, v| v ? [k, CGI.escape(v)].join("=") : k }.join("&")
650
+ link_char = query_string.empty? ? '' : '?'
651
+ [url, query_string].join(link_char)
627
652
  end
628
653
 
629
654
  # 获取用户所设置的ACCESS_KEY_ID
@@ -34,9 +34,9 @@ module Aliyun
34
34
  # 是否开启CRC校验,默认为不开启(false)
35
35
  # @option opts [String] :sts_token [可选] 指定STS的
36
36
  # SecurityToken,如果指定,则使用STS授权访问
37
- # @option opts [Fixnum] :open_timeout [可选] 指定建立连接的超时
37
+ # @option opts [Integer] :open_timeout [可选] 指定建立连接的超时
38
38
  # 时间,默认为10秒
39
- # @option opts [Fixnum] :read_timeout [可选] 指定等待响应的超时
39
+ # @option opts [Integer] :read_timeout [可选] 指定等待响应的超时
40
40
  # 时间,默认为120秒
41
41
  # @example 标准endpoint
42
42
  # oss-cn-hangzhou.aliyuncs.com
@@ -70,6 +70,7 @@ module Aliyun
70
70
  # @param opts [Hash] 创建Bucket的属性(可选)
71
71
  # @option opts [:location] [String] 指定bucket所在的区域,默认为oss-cn-hangzhou
72
72
  def create_bucket(name, opts = {})
73
+ Util.ensure_bucket_name_valid(name)
73
74
  @protocol.create_bucket(name, opts)
74
75
  end
75
76
 
@@ -77,6 +78,7 @@ module Aliyun
77
78
  # @param name [String] Bucket名字
78
79
  # @note 如果要删除的Bucket不为空(包含有object),则删除会失败
79
80
  def delete_bucket(name)
81
+ Util.ensure_bucket_name_valid(name)
80
82
  @protocol.delete_bucket(name)
81
83
  end
82
84
 
@@ -84,6 +86,7 @@ module Aliyun
84
86
  # @param name [String] Bucket名字
85
87
  # @return [Boolean] 如果Bucket存在则返回true,否则返回false
86
88
  def bucket_exists?(name)
89
+ Util.ensure_bucket_name_valid(name)
87
90
  exist = false
88
91
 
89
92
  begin
@@ -102,6 +105,7 @@ module Aliyun
102
105
  # @param name [String] Bucket名字
103
106
  # @return [Bucket] Bucket对象
104
107
  def get_bucket(name)
108
+ Util.ensure_bucket_name_valid(name)
105
109
  Bucket.new({:name => name}, @protocol)
106
110
  end
107
111
 
File without changes
File without changes
File without changes
@@ -121,12 +121,13 @@ module Aliyun
121
121
 
122
122
  def get_request_url(bucket, object)
123
123
  url = @config.endpoint.dup
124
+ url.query = nil
125
+ url.fragment = nil
124
126
  isIP = !!(url.host =~ Resolv::IPv4::Regex)
125
127
  url.host = "#{bucket}." + url.host if bucket && !@config.cname && !isIP
126
128
  url.path = '/'
127
129
  url.path << "#{bucket}/" if bucket && isIP
128
- url.path << "#{CGI.escape(object)}" if object
129
-
130
+ url.path << CGI.escape(object) if object
130
131
  url.to_s
131
132
  end
132
133
 
@@ -280,9 +281,11 @@ module Aliyun
280
281
  # RestClient::Response ourselves
281
282
  unless response.is_a?(RestClient::Response)
282
283
  if response.code.to_i >= 300
283
- response = RestClient::Response.create(
284
- RestClient::Request.decode(response['content-encoding'], response.body),
285
- response, request)
284
+ body = response.body
285
+ if RestClient::version < '2.1.0'
286
+ body = RestClient::Request.decode(response['content-encoding'], response.body)
287
+ end
288
+ response = RestClient::Response.create(body, response, request)
286
289
  e = ServerError.new(response)
287
290
  logger.error(e.to_s)
288
291
  raise e
File without changes
File without changes
File without changes
@@ -212,6 +212,105 @@ module Aliyun
212
212
  logger.info("Done delete bucket logging")
213
213
  end
214
214
 
215
+ # Put bucket versioning settings
216
+ # @param name [String] the bucket name
217
+ # @param versioning [BucketVersioning] versioning options
218
+ def put_bucket_versioning(name, versioning)
219
+ logger.info("Begin put bucket versioning, "\
220
+ "name: #{name}, versioning: #{versioning}")
221
+
222
+ sub_res = {'versioning' => nil}
223
+ body = Nokogiri::XML::Builder.new do |xml|
224
+ xml.VersioningConfiguration {
225
+ xml.Status versioning.status
226
+ }
227
+ end.to_xml
228
+
229
+ @http.put(
230
+ {:bucket => name, :sub_res => sub_res},
231
+ {:body => body})
232
+
233
+ logger.info("Done put bucket versioning")
234
+ end
235
+
236
+ # Get bucket versioning settings
237
+ # @param name [String] the bucket name
238
+ # @return [BucketVersioning] versioning options of this bucket
239
+ def get_bucket_versioning(name)
240
+ logger.info("Begin get bucket versioning, name: #{name}")
241
+
242
+ sub_res = {'versioning' => nil}
243
+ r = @http.get({:bucket => name, :sub_res => sub_res})
244
+
245
+ doc = parse_xml(r.body)
246
+
247
+ versioning_node = doc.at_css("VersioningConfiguration")
248
+ opts = {
249
+ :status => get_node_text(versioning_node, 'Status')
250
+ }
251
+
252
+ logger.info("Done get bucket versioning")
253
+
254
+ BucketVersioning.new(opts)
255
+ end
256
+
257
+ # Put bucket encryption settings
258
+ # @param name [String] the bucket name
259
+ # @param encryption [BucketEncryption] encryption options
260
+ def put_bucket_encryption(name, encryption)
261
+ logger.info("Begin put bucket encryption, "\
262
+ "name: #{name}, encryption: #{encryption}")
263
+
264
+ sub_res = {'encryption' => nil}
265
+ body = Nokogiri::XML::Builder.new do |xml|
266
+ xml.ServerSideEncryptionRule {
267
+ xml.ApplyServerSideEncryptionByDefault {
268
+ xml.SSEAlgorithm encryption.sse_algorithm
269
+ xml.KMSMasterKeyID encryption.kms_master_key_id if encryption.kms_master_key_id
270
+ }
271
+ }
272
+ end.to_xml
273
+
274
+ @http.put(
275
+ {:bucket => name, :sub_res => sub_res},
276
+ {:body => body})
277
+
278
+ logger.info("Done put bucket encryption")
279
+ end
280
+
281
+ # Get bucket encryption settings
282
+ # @param name [String] the bucket name
283
+ # @return [BucketEncryption] encryption options of this bucket
284
+ def get_bucket_encryption(name)
285
+ logger.info("Begin get bucket encryption, name: #{name}")
286
+
287
+ sub_res = {'encryption' => nil}
288
+ r = @http.get({:bucket => name, :sub_res => sub_res})
289
+
290
+ doc = parse_xml(r.body)
291
+
292
+ encryption_node = doc.at_css("ApplyServerSideEncryptionByDefault")
293
+ opts = {
294
+ :sse_algorithm => get_node_text(encryption_node, 'SSEAlgorithm'),
295
+ :kms_master_key_id => get_node_text(encryption_node, 'KMSMasterKeyID')
296
+ }
297
+
298
+ logger.info("Done get bucket encryption")
299
+
300
+ BucketEncryption.new(opts)
301
+ end
302
+
303
+ # Delete bucket encryption settings, a.k.a. disable bucket encryption
304
+ # @param name [String] the bucket name
305
+ def delete_bucket_encryption(name)
306
+ logger.info("Begin delete bucket encryption, name: #{name}")
307
+
308
+ sub_res = {'encryption' => nil}
309
+ @http.delete({:bucket => name, :sub_res => sub_res})
310
+
311
+ logger.info("Done delete bucket encryption")
312
+ end
313
+
215
314
  # Put bucket website settings
216
315
  # @param name [String] the bucket name
217
316
  # @param website [BucketWebsite] the bucket website options
@@ -346,10 +445,10 @@ module Aliyun
346
445
  xml.Date Time.utc(
347
446
  r.expiry.year, r.expiry.month, r.expiry.day)
348
447
  .iso8601.sub('Z', '.000Z')
349
- elsif r.expiry.is_a?(Fixnum)
448
+ elsif r.expiry.is_a?(Integer)
350
449
  xml.Days r.expiry
351
450
  else
352
- fail ClientError, "Expiry must be a Date or Fixnum."
451
+ fail ClientError, "Expiry must be a Date or Integer."
353
452
  end
354
453
  }
355
454
  }
@@ -1394,12 +1493,26 @@ module Aliyun
1394
1493
  @http.get_request_url(bucket, object)
1395
1494
  end
1396
1495
 
1496
+ # Get bucket/object resource path
1497
+ # @param [String] bucket the bucket name
1498
+ # @param [String] object the bucket name
1499
+ # @return [String] resource path for the bucket/object
1500
+ def get_resource_path(bucket, object = nil)
1501
+ @http.get_resource_path(bucket, object)
1502
+ end
1503
+
1397
1504
  # Get user's access key id
1398
1505
  # @return [String] the access key id
1399
1506
  def get_access_key_id
1400
1507
  @config.access_key_id
1401
1508
  end
1402
1509
 
1510
+ # Get user's access key secret
1511
+ # @return [String] the access key secret
1512
+ def get_access_key_secret
1513
+ @config.access_key_secret
1514
+ end
1515
+
1403
1516
  # Get user's STS token
1404
1517
  # @return [String] the STS token
1405
1518
  def get_sts_token
@@ -1517,7 +1630,7 @@ module Aliyun
1517
1630
  def get_bytes_range(range)
1518
1631
  if range &&
1519
1632
  (!range.is_a?(Array) || range.size != 2 ||
1520
- !range.at(0).is_a?(Fixnum) || !range.at(1).is_a?(Fixnum))
1633
+ !range.at(0).is_a?(Integer) || !range.at(1).is_a?(Integer))
1521
1634
  fail ClientError, "Range must be an array containing 2 Integers."
1522
1635
  end
1523
1636