aliyun-sdk 0.5.0 → 0.7.3
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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +25 -0
- data/README.md +174 -172
- data/examples/aliyun/oss/bucket.rb +0 -0
- data/examples/aliyun/oss/callback.rb +0 -0
- data/examples/aliyun/oss/object.rb +0 -0
- data/examples/aliyun/oss/resumable_download.rb +0 -0
- data/examples/aliyun/oss/resumable_upload.rb +0 -0
- data/examples/aliyun/oss/streaming.rb +0 -0
- data/examples/aliyun/oss/using_sts.rb +0 -0
- data/examples/aliyun/sts/assume_role.rb +0 -0
- data/ext/crcx/crc64_ecma.c +0 -0
- data/ext/crcx/crcx.c +0 -0
- data/ext/crcx/crcx.h +0 -0
- data/ext/crcx/extconf.rb +0 -0
- data/lib/aliyun/common.rb +0 -0
- data/lib/aliyun/common/exception.rb +0 -0
- data/lib/aliyun/common/logging.rb +3 -2
- data/lib/aliyun/common/struct.rb +0 -0
- data/lib/aliyun/oss.rb +0 -0
- data/lib/aliyun/oss/bucket.rb +29 -32
- data/lib/aliyun/oss/client.rb +6 -2
- data/lib/aliyun/oss/config.rb +0 -0
- data/lib/aliyun/oss/download.rb +0 -0
- data/lib/aliyun/oss/exception.rb +0 -0
- data/lib/aliyun/oss/http.rb +25 -46
- data/lib/aliyun/oss/iterator.rb +0 -0
- data/lib/aliyun/oss/multipart.rb +0 -0
- data/lib/aliyun/oss/object.rb +0 -0
- data/lib/aliyun/oss/protocol.rb +27 -12
- data/lib/aliyun/oss/struct.rb +2 -2
- data/lib/aliyun/oss/upload.rb +0 -0
- data/lib/aliyun/oss/util.rb +6 -0
- data/lib/aliyun/sts.rb +0 -0
- data/lib/aliyun/sts/client.rb +1 -1
- data/lib/aliyun/sts/config.rb +0 -0
- data/lib/aliyun/sts/exception.rb +0 -0
- data/lib/aliyun/sts/protocol.rb +3 -3
- data/lib/aliyun/sts/struct.rb +0 -0
- data/lib/aliyun/sts/util.rb +0 -0
- data/lib/aliyun/version.rb +1 -1
- data/spec/aliyun/oss/bucket_spec.rb +140 -18
- data/spec/aliyun/oss/client/bucket_spec.rb +276 -30
- data/spec/aliyun/oss/client/client_spec.rb +26 -1
- data/spec/aliyun/oss/client/resumable_download_spec.rb +0 -0
- data/spec/aliyun/oss/client/resumable_upload_spec.rb +0 -0
- data/spec/aliyun/oss/http_spec.rb +0 -0
- data/spec/aliyun/oss/multipart_spec.rb +10 -10
- data/spec/aliyun/oss/object_spec.rb +109 -16
- data/spec/aliyun/oss/service_spec.rb +0 -0
- data/spec/aliyun/oss/util_spec.rb +51 -0
- data/spec/aliyun/sts/client_spec.rb +0 -0
- data/spec/aliyun/sts/util_spec.rb +0 -0
- data/tests/config.rb +0 -0
- data/tests/helper.rb +0 -0
- data/tests/test_content_encoding.rb +0 -0
- data/tests/test_content_type.rb +0 -0
- data/tests/test_crc_check.rb +0 -0
- data/tests/test_custom_headers.rb +0 -0
- data/tests/test_encoding.rb +0 -0
- data/tests/test_large_file.rb +0 -0
- data/tests/test_multipart.rb +0 -0
- data/tests/test_object_acl.rb +0 -0
- data/tests/test_object_key.rb +18 -0
- data/tests/test_object_url.rb +20 -0
- data/tests/test_resumable.rb +0 -0
- metadata +8 -10
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/ext/crcx/crc64_ecma.c
CHANGED
File without changes
|
data/ext/crcx/crcx.c
CHANGED
File without changes
|
data/ext/crcx/crcx.h
CHANGED
File without changes
|
data/ext/crcx/extconf.rb
CHANGED
File without changes
|
data/lib/aliyun/common.rb
CHANGED
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,8 +33,10 @@ 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
|
-
|
39
|
+
@log_file, MAX_NUM_LOG, ROTATE_SIZE)
|
39
40
|
@logger.level = Logger::INFO
|
40
41
|
end
|
41
42
|
@logger
|
data/lib/aliyun/common/struct.rb
CHANGED
File without changes
|
data/lib/aliyun/oss.rb
CHANGED
File without changes
|
data/lib/aliyun/oss/bucket.rb
CHANGED
@@ -588,42 +588,39 @@ module Aliyun
|
|
588
588
|
# 获取Object的URL
|
589
589
|
# @param [String] key Object的key
|
590
590
|
# @param [Boolean] sign 是否对URL进行签名,默认为是
|
591
|
-
# @param [
|
591
|
+
# @param [Integer] expiry URL的有效时间,单位为秒,默认为60s
|
592
|
+
# @param [Hash] parameters 附加的query参数,默认为空
|
592
593
|
# @return [String] 用于直接访问Object的URL
|
593
|
-
def object_url(key, sign = true, expiry = 60)
|
594
|
-
url = @protocol.get_request_url(name, key)
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
resource = "/#{name}/#{key}"
|
610
|
-
unless sub_res.empty?
|
611
|
-
resource << "?#{sub_res.join('&')}"
|
612
|
-
end
|
594
|
+
def object_url(key, sign = true, expiry = 60, parameters = {})
|
595
|
+
url = @protocol.get_request_url(name, key).gsub('%2F', '/')
|
596
|
+
query = parameters.dup
|
597
|
+
|
598
|
+
if sign
|
599
|
+
#header
|
600
|
+
expires = Time.now.to_i + expiry
|
601
|
+
headers = {
|
602
|
+
'date' => expires.to_s,
|
603
|
+
}
|
604
|
+
|
605
|
+
#query
|
606
|
+
if @protocol.get_sts_token
|
607
|
+
query['security-token'] = @protocol.get_sts_token
|
608
|
+
end
|
613
609
|
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
"#{resource}"
|
610
|
+
res = {
|
611
|
+
:path => @protocol.get_resource_path(name, key),
|
612
|
+
:sub_res => query,
|
613
|
+
}
|
614
|
+
signature = Util.get_signature(@protocol.get_access_key_secret, 'GET', headers, res)
|
620
615
|
|
621
|
-
|
622
|
-
|
623
|
-
query
|
624
|
-
|
616
|
+
query['Expires'] = expires.to_s
|
617
|
+
query['OSSAccessKeyId'] = @protocol.get_access_key_id
|
618
|
+
query['Signature'] = signature
|
619
|
+
end
|
625
620
|
|
626
|
-
[
|
621
|
+
query_string = query.map { |k, v| v ? [k, CGI.escape(v)].join("=") : k }.join("&")
|
622
|
+
link_char = query_string.empty? ? '' : '?'
|
623
|
+
[url, query_string].join(link_char)
|
627
624
|
end
|
628
625
|
|
629
626
|
# 获取用户所设置的ACCESS_KEY_ID
|
data/lib/aliyun/oss/client.rb
CHANGED
@@ -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 [
|
37
|
+
# @option opts [Integer] :open_timeout [可选] 指定建立连接的超时
|
38
38
|
# 时间,默认为10秒
|
39
|
-
# @option opts [
|
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
|
|
data/lib/aliyun/oss/config.rb
CHANGED
File without changes
|
data/lib/aliyun/oss/download.rb
CHANGED
File without changes
|
data/lib/aliyun/oss/exception.rb
CHANGED
File without changes
|
data/lib/aliyun/oss/http.rb
CHANGED
@@ -105,35 +105,11 @@ module Aliyun
|
|
105
105
|
false
|
106
106
|
end
|
107
107
|
|
108
|
-
def inspect
|
109
|
-
"@buffer: " + @buffer[0, 32].inspect + "...#{@buffer.size} bytes"
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
# RestClient requires the payload to respones to :read(bytes)
|
114
|
-
# and return a stream.
|
115
|
-
# We are not doing the real read here, just return a
|
116
|
-
# readable stream for RestClient playload.rb treats it as:
|
117
|
-
# def read(bytes=nil)
|
118
|
-
# @stream.read(bytes)
|
119
|
-
# end
|
120
|
-
# alias :to_s :read
|
121
|
-
# net_http_do_request(http, req, payload ? payload.to_s : nil,
|
122
|
-
# &@block_response)
|
123
|
-
class StreamPayload
|
124
|
-
def initialize(crc_enable = false, init_crc = 0, &block)
|
125
|
-
@stream = StreamWriter.new(crc_enable, init_crc, &block)
|
126
|
-
end
|
127
|
-
|
128
|
-
def read(bytes = nil)
|
129
|
-
@stream
|
130
|
-
end
|
131
|
-
|
132
108
|
def close
|
133
109
|
end
|
134
110
|
|
135
|
-
def
|
136
|
-
|
111
|
+
def inspect
|
112
|
+
"@buffer: " + @buffer[0, 32].inspect + "...#{@buffer.size} bytes"
|
137
113
|
end
|
138
114
|
end
|
139
115
|
|
@@ -145,12 +121,13 @@ module Aliyun
|
|
145
121
|
|
146
122
|
def get_request_url(bucket, object)
|
147
123
|
url = @config.endpoint.dup
|
124
|
+
url.query = nil
|
125
|
+
url.fragment = nil
|
148
126
|
isIP = !!(url.host =~ Resolv::IPv4::Regex)
|
149
127
|
url.host = "#{bucket}." + url.host if bucket && !@config.cname && !isIP
|
150
128
|
url.path = '/'
|
151
129
|
url.path << "#{bucket}/" if bucket && isIP
|
152
|
-
url.path <<
|
153
|
-
|
130
|
+
url.path << CGI.escape(object) if object
|
154
131
|
url.to_s
|
155
132
|
end
|
156
133
|
|
@@ -281,44 +258,46 @@ module Aliyun
|
|
281
258
|
headers[:params] = (sub_res || {}).merge(http_options[:query] || {})
|
282
259
|
|
283
260
|
block_response = ->(r) { handle_response(r, &block) } if block
|
284
|
-
|
261
|
+
request = RestClient::Request.new(
|
285
262
|
:method => verb,
|
286
263
|
:url => get_request_url(bucket, object),
|
287
264
|
:headers => headers,
|
288
265
|
:payload => http_options[:body],
|
289
266
|
:block_response => block_response,
|
290
267
|
:open_timeout => @config.open_timeout || OPEN_TIMEOUT,
|
291
|
-
:
|
292
|
-
)
|
293
|
-
|
294
|
-
if
|
295
|
-
e = ServerError.new(
|
268
|
+
:read_timeout => @config.read_timeout || READ_TIMEOUT
|
269
|
+
)
|
270
|
+
response = request.execute do |resp, &blk|
|
271
|
+
if resp.code >= 300
|
272
|
+
e = ServerError.new(resp)
|
296
273
|
logger.error(e.to_s)
|
297
274
|
raise e
|
298
275
|
else
|
299
|
-
|
276
|
+
resp.return!(&blk)
|
300
277
|
end
|
301
278
|
end
|
302
279
|
|
303
280
|
# If streaming read_body is used, we need to create the
|
304
281
|
# RestClient::Response ourselves
|
305
|
-
unless
|
306
|
-
if
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
282
|
+
unless response.is_a?(RestClient::Response)
|
283
|
+
if response.code.to_i >= 300
|
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)
|
289
|
+
e = ServerError.new(response)
|
311
290
|
logger.error(e.to_s)
|
312
291
|
raise e
|
313
292
|
end
|
314
|
-
|
315
|
-
|
293
|
+
response = RestClient::Response.create(nil, response, request)
|
294
|
+
response.return!
|
316
295
|
end
|
317
296
|
|
318
|
-
logger.debug("Received HTTP response, code: #{
|
319
|
-
"#{
|
297
|
+
logger.debug("Received HTTP response, code: #{response.code}, headers: " \
|
298
|
+
"#{response.headers}, body: #{response.body}")
|
320
299
|
|
321
|
-
|
300
|
+
response
|
322
301
|
end
|
323
302
|
|
324
303
|
def get_user_agent
|
data/lib/aliyun/oss/iterator.rb
CHANGED
File without changes
|
data/lib/aliyun/oss/multipart.rb
CHANGED
File without changes
|
data/lib/aliyun/oss/object.rb
CHANGED
File without changes
|
data/lib/aliyun/oss/protocol.rb
CHANGED
@@ -346,10 +346,10 @@ module Aliyun
|
|
346
346
|
xml.Date Time.utc(
|
347
347
|
r.expiry.year, r.expiry.month, r.expiry.day)
|
348
348
|
.iso8601.sub('Z', '.000Z')
|
349
|
-
elsif r.expiry.is_a?(
|
349
|
+
elsif r.expiry.is_a?(Integer)
|
350
350
|
xml.Days r.expiry
|
351
351
|
else
|
352
|
-
fail ClientError, "Expiry must be a Date or
|
352
|
+
fail ClientError, "Expiry must be a Date or Integer."
|
353
353
|
end
|
354
354
|
}
|
355
355
|
}
|
@@ -535,7 +535,7 @@ module Aliyun
|
|
535
535
|
headers[CALLBACK_HEADER] = opts[:callback].serialize
|
536
536
|
end
|
537
537
|
|
538
|
-
payload = HTTP::
|
538
|
+
payload = HTTP::StreamWriter.new(@config.upload_crc_enable, opts[:init_crc], &block)
|
539
539
|
r = @http.put(
|
540
540
|
{:bucket => bucket_name, :object => object_name},
|
541
541
|
{:headers => headers, :body => payload})
|
@@ -547,7 +547,7 @@ module Aliyun
|
|
547
547
|
end
|
548
548
|
|
549
549
|
if @config.upload_crc_enable && !r.headers[:x_oss_hash_crc64ecma].nil?
|
550
|
-
data_crc = payload.
|
550
|
+
data_crc = payload.data_crc
|
551
551
|
Aliyun::OSS::Util.crc_check(data_crc, r.headers[:x_oss_hash_crc64ecma], 'put')
|
552
552
|
end
|
553
553
|
|
@@ -593,16 +593,17 @@ module Aliyun
|
|
593
593
|
|
594
594
|
headers.merge!(to_lower_case(opts[:headers])) if opts.key?(:headers)
|
595
595
|
|
596
|
-
payload = HTTP::
|
596
|
+
payload = HTTP::StreamWriter.new(
|
597
|
+
@config.upload_crc_enable && !opts[:init_crc].nil?, opts[:init_crc], &block)
|
597
598
|
|
598
599
|
r = @http.post(
|
599
600
|
{:bucket => bucket_name, :object => object_name, :sub_res => sub_res},
|
600
601
|
{:headers => headers, :body => payload})
|
601
602
|
|
602
|
-
if @config.upload_crc_enable &&
|
603
|
-
!r.headers[:x_oss_hash_crc64ecma].nil? &&
|
603
|
+
if @config.upload_crc_enable &&
|
604
|
+
!r.headers[:x_oss_hash_crc64ecma].nil? &&
|
604
605
|
!opts[:init_crc].nil?
|
605
|
-
data_crc = payload.
|
606
|
+
data_crc = payload.data_crc
|
606
607
|
Aliyun::OSS::Util.crc_check(data_crc, r.headers[:x_oss_hash_crc64ecma], 'append')
|
607
608
|
end
|
608
609
|
|
@@ -780,7 +781,7 @@ module Aliyun
|
|
780
781
|
{:bucket => bucket_name, :object => object_name,
|
781
782
|
:sub_res => sub_res},
|
782
783
|
{:headers => headers}
|
783
|
-
) do |chunk|
|
784
|
+
) do |chunk|
|
784
785
|
if block_given?
|
785
786
|
# crc enable and no range and oss server support crc
|
786
787
|
data_crc = Aliyun::OSS::Util.crc(chunk, data_crc) if @config.download_crc_enable && range.nil?
|
@@ -1110,13 +1111,13 @@ module Aliyun
|
|
1110
1111
|
|
1111
1112
|
sub_res = {'partNumber' => part_no, 'uploadId' => txn_id}
|
1112
1113
|
|
1113
|
-
payload = HTTP::
|
1114
|
+
payload = HTTP::StreamWriter.new(@config.upload_crc_enable, &block)
|
1114
1115
|
r = @http.put(
|
1115
1116
|
{:bucket => bucket_name, :object => object_name, :sub_res => sub_res},
|
1116
1117
|
{:body => payload})
|
1117
1118
|
|
1118
1119
|
if @config.upload_crc_enable && !r.headers[:x_oss_hash_crc64ecma].nil?
|
1119
|
-
data_crc = payload.
|
1120
|
+
data_crc = payload.data_crc
|
1120
1121
|
Aliyun::OSS::Util.crc_check(data_crc, r.headers[:x_oss_hash_crc64ecma], 'put')
|
1121
1122
|
end
|
1122
1123
|
|
@@ -1393,12 +1394,26 @@ module Aliyun
|
|
1393
1394
|
@http.get_request_url(bucket, object)
|
1394
1395
|
end
|
1395
1396
|
|
1397
|
+
# Get bucket/object resource path
|
1398
|
+
# @param [String] bucket the bucket name
|
1399
|
+
# @param [String] object the bucket name
|
1400
|
+
# @return [String] resource path for the bucket/object
|
1401
|
+
def get_resource_path(bucket, object = nil)
|
1402
|
+
@http.get_resource_path(bucket, object)
|
1403
|
+
end
|
1404
|
+
|
1396
1405
|
# Get user's access key id
|
1397
1406
|
# @return [String] the access key id
|
1398
1407
|
def get_access_key_id
|
1399
1408
|
@config.access_key_id
|
1400
1409
|
end
|
1401
1410
|
|
1411
|
+
# Get user's access key secret
|
1412
|
+
# @return [String] the access key secret
|
1413
|
+
def get_access_key_secret
|
1414
|
+
@config.access_key_secret
|
1415
|
+
end
|
1416
|
+
|
1402
1417
|
# Get user's STS token
|
1403
1418
|
# @return [String] the STS token
|
1404
1419
|
def get_sts_token
|
@@ -1516,7 +1531,7 @@ module Aliyun
|
|
1516
1531
|
def get_bytes_range(range)
|
1517
1532
|
if range &&
|
1518
1533
|
(!range.is_a?(Array) || range.size != 2 ||
|
1519
|
-
!range.at(0).is_a?(
|
1534
|
+
!range.at(0).is_a?(Integer) || !range.at(1).is_a?(Integer))
|
1520
1535
|
fail ClientError, "Range must be an array containing 2 Integers."
|
1521
1536
|
end
|
1522
1537
|
|
data/lib/aliyun/oss/struct.rb
CHANGED
@@ -107,10 +107,10 @@ module Aliyun
|
|
107
107
|
# * id [String] the unique id of a rule
|
108
108
|
# * enabled [Boolean] whether to enable this rule
|
109
109
|
# * prefix [String] the prefix objects to apply this rule
|
110
|
-
# * expiry [Date] or [
|
110
|
+
# * expiry [Date] or [Integer] the expire time of objects
|
111
111
|
# * if expiry is a Date, it specifies the absolute date to
|
112
112
|
# expire objects
|
113
|
-
# * if expiry is a
|
113
|
+
# * if expiry is a Integer, it specifies the relative date to
|
114
114
|
# expire objects: how many days after the object's last
|
115
115
|
# modification time to expire the object
|
116
116
|
# @example Specify expiry as Date
|
data/lib/aliyun/oss/upload.rb
CHANGED
File without changes
|
data/lib/aliyun/oss/util.rb
CHANGED
data/lib/aliyun/sts.rb
CHANGED
File without changes
|
data/lib/aliyun/sts/client.rb
CHANGED
@@ -25,7 +25,7 @@ module Aliyun
|
|
25
25
|
# @param role [String] the role arn
|
26
26
|
# @param session [String] the session name
|
27
27
|
# @param policy [STS::Policy] the policy
|
28
|
-
# @param duration [
|
28
|
+
# @param duration [Integer] the duration seconds for the
|
29
29
|
# requested token
|
30
30
|
# @return [STS::Token] the sts token
|
31
31
|
def assume_role(role, session, policy = nil, duration = 3600)
|