aliyun-sdk 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3442046916c8942bc642201c55dc24cdd2c79c9a
4
- data.tar.gz: 1ca2020cb4d9a039dcbd86e84149974b1fd7b7f6
3
+ metadata.gz: 92abcf259fe7eaea3a58e48e8e9fa46b6e7a842e
4
+ data.tar.gz: c1c3c72bd651bc19bf42b1a325bf55003852487d
5
5
  SHA512:
6
- metadata.gz: 221810c807b825c02f518dc2f4580988dc369c45dcca4741b8ee8e3481996ac03027c1dba8cc10b997ccb317cfca9f0b2c0e251f48b74011bb53aa113ffc3955
7
- data.tar.gz: 8999b93dcf20f9aa5a3c69fb312cbbf77b3b24586089cbfdb199ccde137fc39ff181e1e81fdc79953ae5ed722476bf7955a6f650aa0f5639412d855574ca60e8
6
+ metadata.gz: a4221cfa8663737bed084077793f6acaed03fcd5912a3fd1741f5b71435c9ccc1b25071123c59801fc5613c64e38bd168206885d4b5221f2269cbb549e26c6dc
7
+ data.tar.gz: 86123f41ba9d877d6443df644e16053235fe473fb6d7ede26f9a64d9f50e44b27d4db2ba253c3959a42931c5dc54b0181f8075e91765f127074afe036a509dbd
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  ## Change Log
2
2
 
3
+ ### v0.3.2
4
+
5
+ - Allow setting custom HTTP headers in put/append/resumable_upload
6
+ - Allow setting object acl in put/append
7
+
3
8
  ### v0.3.1
4
9
 
5
10
  - Fix frozen string issue in OSSClient/STSClient config
@@ -25,10 +25,12 @@ end
25
25
 
26
26
  demo "Resumable download" do
27
27
  # 下载一个100M的文件
28
+ cpt_file = '/tmp/y.cpt'
29
+ File.delete(cpt_file) if File.exist?(cpt_file)
28
30
  start = Time.now
29
31
  puts "Start download: resumable => /tmp/y"
30
32
  bucket.resumable_download(
31
- 'resumable', '/tmp/y', :cpt_file => '/tmp/y.cpt') do |progress|
33
+ 'resumable', '/tmp/y', :cpt_file => cpt_file) do |progress|
32
34
  puts "Progress: #{(progress * 100).round(2)} %"
33
35
  end
34
36
  puts "Download complete. Cost: #{Time.now - start} seconds."
@@ -30,11 +30,14 @@ demo "Resumable upload" do
30
30
  (1..1024*1024).each{ |i| f.puts i.to_s.rjust(99, '0') }
31
31
  end
32
32
 
33
+ cpt_file = '/tmp/x.cpt'
34
+ File.delete(cpt_file) if File.exist?(cpt_file)
35
+
33
36
  # 上传一个100M的文件
34
37
  start = Time.now
35
38
  puts "Start upload: /tmp/x => resumable"
36
39
  bucket.resumable_upload(
37
- 'resumable', '/tmp/x', :cpt_file => '/tmp/x.cpt') do |progress|
40
+ 'resumable', '/tmp/x', :cpt_file => cpt_file) do |progress|
38
41
  puts "Progress: #{(progress * 100).round(2)} %"
39
42
  end
40
43
  puts "Upload complete. Cost: #{Time.now - start} seconds."
@@ -181,6 +181,8 @@ module Aliyun
181
181
  # @option opts [Callback] :callback 指定操作成功后OSS的
182
182
  # 上传回调,上传成功后OSS会向用户的应用服务器发一个HTTP POST请
183
183
  # 求,`:callback`参数指定这个请求的相关参数
184
+ # @option opts [Hash] :headers 指定请求的HTTP Header,不区分大小
185
+ # 写。这里指定的值会覆盖通过`:content_type`和`:metas`设置的值。
184
186
  # @yield [HTTP::StreamWriter] 如果调用的时候传递了block,则写入
185
187
  # 到object的数据由block指定
186
188
  # @example 流式上传数据
@@ -315,6 +317,8 @@ module Aliyun
315
317
  # @option opts [Hash] :metas 设置object的meta,这是一些用户自定
316
318
  # 义的属性,它们会和object一起存储,在{#get_object}的时候会
317
319
  # 返回这些meta。属性的key不区分大小写。例如:{ 'year' => '2015' }
320
+ # @option opts [Hash] :headers 指定请求的HTTP Header,不区分大小
321
+ # 写。这里指定的值会覆盖通过`:content_type`和`:metas`设置的值。
318
322
  # @example 流式上传数据
319
323
  # pos = append_object('x', 0){ |stream| 100.times { |i| stream << i.to_s } }
320
324
  # append_object('x', pos){ |stream| stream << get_data }
@@ -439,6 +443,8 @@ module Aliyun
439
443
  # @option opts [Callback] :callback 指定文件上传成功后OSS的
440
444
  # 上传回调,上传成功后OSS会向用户的应用服务器发一个HTTP POST请
441
445
  # 求,`:callback`参数指定这个请求的相关参数
446
+ # @option opts [Hash] :headers 指定请求的HTTP Header,不区分大小
447
+ # 写。这里指定的值会覆盖通过`:content_type`和`:metas`设置的值。
442
448
  # @yield [Float] 如果调用的时候传递了block,则会将上传进度交由
443
449
  # block处理,进度值是一个0-1之间的小数
444
450
  # @raise [CheckpointBrokenError] 如果cpt文件被损坏,则抛出此错误
@@ -207,16 +207,16 @@ module Aliyun
207
207
  sub_res = resources[:sub_res]
208
208
 
209
209
  headers = http_options[:headers] || {}
210
- headers['User-Agent'] = get_user_agent
211
- headers['Date'] = Time.now.httpdate
212
- headers['Content-Type'] ||= DEFAULT_CONTENT_TYPE
210
+ headers['user-agent'] = get_user_agent
211
+ headers['date'] = Time.now.httpdate
212
+ headers['content-type'] ||= DEFAULT_CONTENT_TYPE
213
213
  headers[STS_HEADER] = @config.sts_token if @config.sts_token
214
214
 
215
215
  if body = http_options[:body]
216
216
  if body.respond_to?(:read)
217
- headers['Transfer-Encoding'] = 'chunked'
217
+ headers['transfer-encoding'] = 'chunked'
218
218
  else
219
- headers['Content-MD5'] = Util.get_content_md5(body)
219
+ headers['content-md5'] = Util.get_content_md5(body)
220
220
  end
221
221
  end
222
222
 
@@ -227,7 +227,7 @@ module Aliyun
227
227
 
228
228
  if @config.access_key_id and @config.access_key_secret
229
229
  sig = Util.get_signature(@config.access_key_secret, verb, headers, res)
230
- headers['Authorization'] = "OSS #{@config.access_key_id}:#{sig}"
230
+ headers['authorization'] = "OSS #{@config.access_key_id}:#{sig}"
231
231
  end
232
232
 
233
233
  logger.debug("Send HTTP request, verb: #{verb}, resources: " \
@@ -295,7 +295,7 @@ module RestClient
295
295
  module Payload
296
296
  class Base
297
297
  def headers
298
- ({'Content-Length' => size.to_s} if size) || {}
298
+ ({'content-length' => size.to_s} if size) || {}
299
299
  end
300
300
  end
301
301
  end
@@ -8,7 +8,7 @@ module Aliyun
8
8
  #
9
9
  class Object < Common::Struct::Base
10
10
 
11
- attrs :key, :type, :size, :etag, :metas, :last_modified, :content_type
11
+ attrs :key, :type, :size, :etag, :metas, :last_modified, :headers
12
12
 
13
13
  end # Object
14
14
  end # OSS
@@ -499,6 +499,8 @@ module Aliyun
499
499
  # @param bucket_name [String] the bucket name
500
500
  # @param object_name [String] the object name
501
501
  # @param opts [Hash] Options
502
+ # @option opts [String] :acl specify the object's ACL. See
503
+ # {OSS::ACL}
502
504
  # @option opts [String] :content_type the HTTP Content-Type
503
505
  # for the file, if not specified client will try to determine
504
506
  # the type itself and fall back to HTTP::DEFAULT_CONTENT_TYPE
@@ -508,6 +510,9 @@ module Aliyun
508
510
  # with the object
509
511
  # @option opts [Callback] :callback the HTTP callback performed
510
512
  # by OSS after `put_object` succeeds
513
+ # @option opts [Hash] :headers custom HTTP headers, case
514
+ # insensitive. Headers specified here will overwrite `:metas`
515
+ # and `:content_type`
511
516
  # @yield [HTTP::StreamWriter] a stream writer is
512
517
  # yielded to the caller to which it can write chunks of data
513
518
  # streamingly
@@ -518,14 +523,17 @@ module Aliyun
518
523
  logger.debug("Begin put object, bucket: #{bucket_name}, object: "\
519
524
  "#{object_name}, options: #{opts}")
520
525
 
521
- headers = {'Content-Type' => opts[:content_type]}
526
+ headers = {'content-type' => opts[:content_type]}
527
+ headers['x-oss-object-acl'] = opts[:acl] if opts.key?(:acl)
528
+ to_lower_case(opts[:metas] || {})
529
+ .each { |k, v| headers["x-oss-meta-#{k.to_s}"] = v.to_s }
530
+
531
+ headers.merge!(to_lower_case(opts[:headers])) if opts.key?(:headers)
532
+
522
533
  if opts.key?(:callback)
523
534
  headers[CALLBACK_HEADER] = opts[:callback].serialize
524
535
  end
525
536
 
526
- (opts[:metas] || {})
527
- .each { |k, v| headers["x-oss-meta-#{k.to_s}"] = v.to_s }
528
-
529
537
  r = @http.put(
530
538
  {:bucket => bucket_name, :object => object_name},
531
539
  {:headers => headers, :body => HTTP::StreamPayload.new(&block)})
@@ -546,6 +554,8 @@ module Aliyun
546
554
  # @param object_name [String] the object name
547
555
  # @param position [Integer] the position to append
548
556
  # @param opts [Hash] Options
557
+ # @option opts [String] :acl specify the object's ACL. See
558
+ # {OSS::ACL}
549
559
  # @option opts [String] :content_type the HTTP Content-Type
550
560
  # for the file, if not specified client will try to determine
551
561
  # the type itself and fall back to HTTP::DEFAULT_CONTENT_TYPE
@@ -553,6 +563,9 @@ module Aliyun
553
563
  # @option opts [Hash<Symbol, String>] :metas key-value pairs
554
564
  # that serve as the object meta which will be stored together
555
565
  # with the object
566
+ # @option opts [Hash] :headers custom HTTP headers, case
567
+ # insensitive. Headers specified here will overwrite `:metas`
568
+ # and `:content_type`
556
569
  # @return [Integer] next position to append
557
570
  # @yield [HTTP::StreamWriter] a stream writer is
558
571
  # yielded to the caller to which it can write chunks of data
@@ -566,10 +579,13 @@ module Aliyun
566
579
  "#{object_name}, position: #{position}, options: #{opts}")
567
580
 
568
581
  sub_res = {'append' => nil, 'position' => position}
569
- headers = {'Content-Type' => opts[:content_type]}
570
- (opts[:metas] || {})
582
+ headers = {'content-type' => opts[:content_type]}
583
+ headers['x-oss-object-acl'] = opts[:acl] if opts.key?(:acl)
584
+ to_lower_case(opts[:metas] || {})
571
585
  .each { |k, v| headers["x-oss-meta-#{k.to_s}"] = v.to_s }
572
586
 
587
+ headers.merge!(to_lower_case(opts[:headers])) if opts.key?(:headers)
588
+
573
589
  r = @http.post(
574
590
  {:bucket => bucket_name, :object => object_name, :sub_res => sub_res},
575
591
  {:headers => headers, :body => HTTP::StreamPayload.new(&block)})
@@ -721,7 +737,7 @@ module Aliyun
721
737
  rewrites = opts[:rewrite]
722
738
 
723
739
  headers = {}
724
- headers['Range'] = get_bytes_range(range) if range
740
+ headers['range'] = get_bytes_range(range) if range
725
741
  headers.merge!(get_conditions(conditions)) if conditions
726
742
 
727
743
  sub_res = {}
@@ -758,7 +774,7 @@ module Aliyun
758
774
  :etag => h[:etag],
759
775
  :metas => metas,
760
776
  :last_modified => wrap(h[:last_modified]) { |x| Time.parse(x) },
761
- :content_type => h[:content_type])
777
+ :headers => h)
762
778
 
763
779
  logger.debug("Done get object")
764
780
 
@@ -801,7 +817,7 @@ module Aliyun
801
817
  :etag => h[:etag],
802
818
  :metas => metas,
803
819
  :last_modified => wrap(h[:last_modified]) { |x| Time.parse(x) },
804
- :content_type => h[:content_type])
820
+ :headers => h)
805
821
 
806
822
  logger.debug("Done get object meta")
807
823
 
@@ -840,7 +856,7 @@ module Aliyun
840
856
  headers = {
841
857
  'x-oss-copy-source' =>
842
858
  @http.get_resource_path(bucket_name, src_object_name),
843
- 'Content-Type' => opts[:content_type]
859
+ 'content-type' => opts[:content_type]
844
860
  }
845
861
  (opts[:metas] || {})
846
862
  .each { |k, v| headers["x-oss-meta-#{k.to_s}"] = v.to_s }
@@ -982,9 +998,9 @@ module Aliyun
982
998
  "headers: #{headers.join(',')}")
983
999
 
984
1000
  h = {
985
- 'Origin' => origin,
986
- 'Access-Control-Request-Method' => method,
987
- 'Access-Control-Request-Headers' => headers.join(',')
1001
+ 'origin' => origin,
1002
+ 'access-control-request-method' => method,
1003
+ 'access-control-request-headers' => headers.join(',')
988
1004
  }
989
1005
 
990
1006
  r = @http.options(
@@ -1017,16 +1033,21 @@ module Aliyun
1017
1033
  # @option opts [Hash<Symbol, String>] :metas key-value pairs
1018
1034
  # that serve as the object meta which will be stored together
1019
1035
  # with the object
1036
+ # @option opts [Hash] :headers custom HTTP headers, case
1037
+ # insensitive. Headers specified here will overwrite `:metas`
1038
+ # and `:content_type`
1020
1039
  # @return [String] the upload id
1021
1040
  def initiate_multipart_upload(bucket_name, object_name, opts = {})
1022
1041
  logger.info("Begin initiate multipart upload, bucket: "\
1023
1042
  "#{bucket_name}, object: #{object_name}, options: #{opts}")
1024
1043
 
1025
1044
  sub_res = {'uploads' => nil}
1026
- headers = {'Content-Type' => opts[:content_type]}
1027
- (opts[:metas] || {})
1045
+ headers = {'content-type' => opts[:content_type]}
1046
+ to_lower_case(opts[:metas] || {})
1028
1047
  .each { |k, v| headers["x-oss-meta-#{k.to_s}"] = v.to_s }
1029
1048
 
1049
+ headers.merge!(to_lower_case(opts[:headers])) if opts.key?(:headers)
1050
+
1030
1051
  r = @http.post(
1031
1052
  {:bucket => bucket_name, :object => object_name,
1032
1053
  :sub_res => sub_res},
@@ -1092,7 +1113,7 @@ module Aliyun
1092
1113
  'x-oss-copy-source' =>
1093
1114
  @http.get_resource_path(bucket_name, source_object)
1094
1115
  }
1095
- headers['Range'] = get_bytes_range(range) if range
1116
+ headers['range'] = get_bytes_range(range) if range
1096
1117
  headers.merge!(get_copy_conditions(conditions)) if conditions
1097
1118
 
1098
1119
  sub_res = {'partNumber' => part_no, 'uploadId' => txn_id}
@@ -1392,14 +1413,14 @@ module Aliyun
1392
1413
  # @return [Hash] conditions for HTTP headers
1393
1414
  def get_conditions(conditions)
1394
1415
  {
1395
- :if_modified_since => 'If-Modified-Since',
1396
- :if_unmodified_since => 'If-Unmodified-Since',
1416
+ :if_modified_since => 'if-modified-since',
1417
+ :if_unmodified_since => 'if-unmodified-since',
1397
1418
  }.reduce({}) { |h, (k, v)|
1398
1419
  conditions.key?(k)? h.merge(v => conditions[k].httpdate) : h
1399
1420
  }.merge(
1400
1421
  {
1401
- :if_match_etag => 'If-Match',
1402
- :if_unmatch_etag => 'If-None-Match'
1422
+ :if_match_etag => 'if-match',
1423
+ :if_unmatch_etag => 'if-none-match'
1403
1424
  }.reduce({}) { |h, (k, v)|
1404
1425
  conditions.key?(k)? h.merge(v => conditions[k]) : h
1405
1426
  }
@@ -1445,6 +1466,16 @@ module Aliyun
1445
1466
  kv.each { |k, v| hash[k] = v.call(hash[k]) if hash.key?(k) }
1446
1467
  end
1447
1468
 
1469
+ # Convert hash keys to lower case Non-Recursively
1470
+ # @param hash [Hash] the hash to be converted
1471
+ # @return [Hash] hash with lower case keys
1472
+ def to_lower_case(hash)
1473
+ hash.reduce({}) do |result, (k, v)|
1474
+ result[k.to_s.downcase] = v
1475
+ result
1476
+ end
1477
+ end
1478
+
1448
1479
  end # Protocol
1449
1480
  end # OSS
1450
1481
  end # Aliyun
@@ -24,9 +24,9 @@ module Aliyun
24
24
  def get_signature(key, verb, headers, resources)
25
25
  logger.debug("Sign, headers: #{headers}, resources: #{resources}")
26
26
 
27
- content_md5 = headers['Content-MD5'] || ""
28
- content_type = headers['Content-Type'] || ""
29
- date = headers['Date']
27
+ content_md5 = headers['content-md5'] || ""
28
+ content_type = headers['content-type'] || ""
29
+ date = headers['date']
30
30
 
31
31
  cano_headers = headers.select { |k, v| k.start_with?(HEADER_PREFIX) }
32
32
  .map { |k, v| [k.downcase.strip, v.strip] }
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Aliyun
4
4
 
5
- VERSION = "0.3.1"
5
+ VERSION = "0.3.2"
6
6
 
7
7
  end # Aliyun
@@ -239,6 +239,17 @@ module Aliyun
239
239
  .with(:body => content, :query => {})
240
240
  end
241
241
 
242
+ it "should put object with acl" do
243
+ key = 'ruby'
244
+ stub_request(:put, object_url(key))
245
+
246
+ @bucket.put_object(key, :acl => ACL::PUBLIC_READ)
247
+
248
+ expect(WebMock)
249
+ .to have_requested(:put, object_url(key))
250
+ .with(:headers => {'X-Oss-Object-Acl' => ACL::PUBLIC_READ})
251
+ end
252
+
242
253
  it "should put object with callback" do
243
254
  key = 'ruby'
244
255
  stub_request(:put, object_url(key))
@@ -276,6 +287,37 @@ module Aliyun
276
287
  .with { |req| req.headers.key?('X-Oss-Callback') }
277
288
  end
278
289
 
290
+ it "should set custom headers when put object" do
291
+ key = 'ruby'
292
+ stub_request(:put, object_url(key))
293
+
294
+ @bucket.put_object(
295
+ key, headers: {'cache-control' => 'xxx', 'expires' => 'yyy'})
296
+
297
+ headers = {}
298
+ expect(WebMock).to have_requested(:put, object_url(key))
299
+ .with { |req| headers = req.headers }
300
+ expect(headers['Cache-Control']).to eq('xxx')
301
+ expect(headers['Expires']).to eq('yyy')
302
+ end
303
+
304
+ it "should set custom headers when append object" do
305
+ key = 'ruby'
306
+ query = {'append' => '', 'position' => 11}
307
+ stub_request(:post, object_url(key)).with(:query => query)
308
+
309
+ @bucket.append_object(
310
+ key, 11,
311
+ headers: {'CACHE-CONTROL' => 'nocache', 'EXPIRES' => 'seripxe'})
312
+
313
+ headers = {}
314
+ expect(WebMock).to have_requested(:post, object_url(key))
315
+ .with(:query => query)
316
+ .with { |req| headers = req.headers }
317
+ expect(headers['Cache-Control']).to eq('nocache')
318
+ expect(headers['Expires']).to eq('seripxe')
319
+ end
320
+
279
321
  it "should get object to file" do
280
322
  key = 'ruby'
281
323
  # 100 KB
@@ -334,6 +376,19 @@ module Aliyun
334
376
  :headers => {'Content-Type' => 'text/html'})
335
377
  end
336
378
 
379
+ it "should append object with acl" do
380
+ key = 'ruby'
381
+ query = {'append' => '', 'position' => 11}
382
+ stub_request(:post, object_url(key)).with(:query => query)
383
+
384
+ @bucket.append_object(key, 11, :acl => ACL::PUBLIC_READ_WRITE)
385
+
386
+ expect(WebMock)
387
+ .to have_requested(:post, object_url(key))
388
+ .with(:query => query,
389
+ :headers => {'X-Oss-Object-Acl' => ACL::PUBLIC_READ_WRITE})
390
+ end
391
+
337
392
  it "should answer object exists?" do
338
393
  key = 'ruby'
339
394
 
@@ -115,27 +115,15 @@ module Aliyun
115
115
  body: 'hello world',
116
116
  host: 'server.com'
117
117
  )
118
- prg = []
119
118
  @bucket.resumable_upload(
120
- @object_key, @file,
121
- :part_size => 10, :callback => callback) { |p| prg << p }
119
+ @object_key, @file, part_size: 10, callback: callback)
122
120
 
123
121
  expect(WebMock).to have_requested(
124
122
  :post, /#{object_url}\?uploads.*/).times(1)
125
123
 
126
- part_numbers = Set.new([])
127
- upload_ids = Set.new([])
128
-
129
124
  expect(WebMock).to have_requested(
130
- :put, /#{object_url}\?partNumber.*/).with{ |req|
131
- query = parse_query_from_uri(req.uri)
132
- part_numbers << query['partNumber']
133
- upload_ids << query['uploadId']
134
- }.times(10)
135
-
136
- expect(part_numbers.to_a).to match_array((1..10).map{ |x| x.to_s })
137
- expect(upload_ids.to_a).to match_array(['upload_id'])
138
-
125
+ :put, /#{object_url}\?partNumber.*/)
126
+ .times(10)
139
127
  expect(WebMock)
140
128
  .to have_requested(
141
129
  :post, /#{object_url}\?uploadId.*/)
@@ -143,7 +131,6 @@ module Aliyun
143
131
  .times(1)
144
132
 
145
133
  expect(File.exist?("#{@file}.cpt")).to be false
146
- expect(prg.size).to eq(10)
147
134
  end
148
135
 
149
136
  it "should raise CallbackError when callback failed" do
@@ -162,28 +149,17 @@ module Aliyun
162
149
  body: 'hello world',
163
150
  host: 'server.com'
164
151
  )
165
- prg = []
166
152
  expect {
167
153
  @bucket.resumable_upload(
168
- @object_key, @file,
169
- :part_size => 10, :callback => callback) { |p| prg << p }
154
+ @object_key, @file, part_size: 10, callback: callback)
170
155
  }.to raise_error(CallbackError, err(message))
171
156
 
172
157
  expect(WebMock).to have_requested(
173
158
  :post, /#{object_url}\?uploads.*/).times(1)
174
159
 
175
- part_numbers = Set.new([])
176
- upload_ids = Set.new([])
177
-
178
160
  expect(WebMock).to have_requested(
179
- :put, /#{object_url}\?partNumber.*/).with{ |req|
180
- query = parse_query_from_uri(req.uri)
181
- part_numbers << query['partNumber']
182
- upload_ids << query['uploadId']
183
- }.times(10)
184
-
185
- expect(part_numbers.to_a).to match_array((1..10).map{ |x| x.to_s })
186
- expect(upload_ids.to_a).to match_array(['upload_id'])
161
+ :put, /#{object_url}\?partNumber.*/)
162
+ .times(10)
187
163
 
188
164
  expect(WebMock)
189
165
  .to have_requested(
@@ -192,7 +168,27 @@ module Aliyun
192
168
  .times(1)
193
169
 
194
170
  expect(File.exist?("#{@file}.cpt")).to be true
195
- expect(prg.size).to eq(10)
171
+ end
172
+
173
+ it "should upload file with custom headers" do
174
+ stub_request(:post, /#{object_url}\?uploads.*/)
175
+ .to_return(:body => mock_txn_id('upload_id'))
176
+ stub_request(:put, /#{object_url}\?partNumber.*/)
177
+ stub_request(:post, /#{object_url}\?uploadId.*/)
178
+
179
+ @bucket.resumable_upload(
180
+ @object_key, @file,
181
+ part_size: 10,
182
+ headers: {'cache-CONTROL' => 'cacheit', 'CONTENT-disposition' => 'oh;yeah'})
183
+
184
+ headers = {}
185
+ expect(WebMock).to have_requested(
186
+ :post, /#{object_url}\?uploads.*/)
187
+ .with { |req| headers = req.headers }.times(1)
188
+
189
+ expect(headers['Cache-Control']).to eq('cacheit')
190
+ expect(headers['Content-Disposition']).to eq('oh;yeah')
191
+ expect(File.exist?("#{@file}.cpt")).to be false
196
192
  end
197
193
 
198
194
  it "should restart when begin txn fails" do
@@ -23,22 +23,22 @@ module Aliyun
23
23
  key = 'helloworld'
24
24
  date = 'Fri, 30 Oct 2015 07:21:00 GMT'
25
25
 
26
- signature = Util.get_signature(key, 'GET', {'Date' => date}, {})
26
+ signature = Util.get_signature(key, 'GET', {'date' => date}, {})
27
27
  expect(signature).to eq("u8QKAAj/axKX4JhHXa5DYfYSPxE=")
28
28
 
29
29
  signature = Util.get_signature(
30
- key, 'PUT', {'Date' => date}, {:path => '/bucket'})
30
+ key, 'PUT', {'date' => date}, {:path => '/bucket'})
31
31
  expect(signature).to eq("lMKrMCJIuGygd8UsdMA+S0QOAsQ=")
32
32
 
33
33
  signature = Util.get_signature(
34
34
  key, 'PUT',
35
- {'Date' => date, 'x-oss-copy-source' => '/bucket/object-old'},
35
+ {'date' => date, 'x-oss-copy-source' => '/bucket/object-old'},
36
36
  {:path => '/bucket/object-new'})
37
37
  expect(signature).to eq("McYUmBaErN//yvE9voWRhCgvsIc=")
38
38
 
39
39
  signature = Util.get_signature(
40
40
  key, 'PUT',
41
- {'Date' => date},
41
+ {'date' => date},
42
42
  {:path => '/bucket/object-new',
43
43
  :sub_res => {'append' => nil, 'position' => 0}})
44
44
  expect(signature).to eq("7Oh2wobzeg6dw/cWYbF/2m6s6qc=")
@@ -43,15 +43,15 @@ class TestContentType < Minitest::Test
43
43
  @types.each do |k, v|
44
44
  key = get_key('from_key', k)
45
45
  @bucket.put_object(key)
46
- assert_equal v, @bucket.get_object(key).content_type
46
+ assert_equal v, @bucket.get_object(key).headers[:content_type]
47
47
 
48
48
  copy_key = get_key('copy.from_key', k)
49
49
  @bucket.copy_object(key, copy_key)
50
- assert_equal v, @bucket.get_object(copy_key).content_type
50
+ assert_equal v, @bucket.get_object(copy_key).headers[:content_type]
51
51
 
52
52
  append_key = get_key('append.from_key', k)
53
53
  @bucket.append_object(append_key, 0)
54
- assert_equal v, @bucket.get_object(append_key).content_type
54
+ assert_equal v, @bucket.get_object(append_key).headers[:content_type]
55
55
  end
56
56
  end
57
57
 
@@ -63,15 +63,15 @@ class TestContentType < Minitest::Test
63
63
 
64
64
  key = get_key('from_file', k)
65
65
  @bucket.put_object(key, :file => upload_file)
66
- assert_equal v, @bucket.get_object(key).content_type
66
+ assert_equal v, @bucket.get_object(key).headers[:content_type]
67
67
 
68
68
  append_key = get_key('append.from_file', k)
69
69
  @bucket.append_object(append_key, 0, :file => upload_file)
70
- assert_equal v, @bucket.get_object(append_key).content_type
70
+ assert_equal v, @bucket.get_object(append_key).headers[:content_type]
71
71
 
72
72
  multipart_key = get_key('multipart.from_file', k)
73
73
  @bucket.resumable_upload(multipart_key, upload_file)
74
- assert_equal v, @bucket.get_object(multipart_key).content_type
74
+ assert_equal v, @bucket.get_object(multipart_key).headers[:content_type]
75
75
  end
76
76
  end
77
77
 
@@ -82,19 +82,19 @@ class TestContentType < Minitest::Test
82
82
 
83
83
  key = get_key('from_user', k)
84
84
  @bucket.put_object(key, :file => upload_file, :content_type => v)
85
- assert_equal v, @bucket.get_object(key).content_type
85
+ assert_equal v, @bucket.get_object(key).headers[:content_type]
86
86
 
87
87
  copy_key = get_key('copy.from_user', k)
88
88
  @bucket.copy_object(key, copy_key, :content_type => v)
89
- assert_equal v, @bucket.get_object(copy_key).content_type
89
+ assert_equal v, @bucket.get_object(copy_key).headers[:content_type]
90
90
 
91
91
  append_key = get_key('append.from_user', k)
92
92
  @bucket.append_object(append_key, 0, :file => upload_file, :content_type => v)
93
- assert_equal v, @bucket.get_object(append_key).content_type
93
+ assert_equal v, @bucket.get_object(append_key).headers[:content_type]
94
94
 
95
95
  multipart_key = get_key('multipart.from_file', k)
96
96
  @bucket.resumable_upload(multipart_key, upload_file, :content_type => v)
97
- assert_equal v, @bucket.get_object(multipart_key).content_type
97
+ assert_equal v, @bucket.get_object(multipart_key).headers[:content_type]
98
98
  end
99
99
  end
100
100
  end
@@ -0,0 +1,75 @@
1
+ require 'minitest/autorun'
2
+ require 'yaml'
3
+ $LOAD_PATH.unshift(File.expand_path("../../lib", __FILE__))
4
+ require 'aliyun/oss'
5
+ require 'zlib'
6
+
7
+ class TestCustomHeaders < Minitest::Test
8
+ def setup
9
+ Aliyun::Common::Logging.set_log_level(Logger::DEBUG)
10
+ conf_file = '~/.oss.yml'
11
+ conf = YAML.load(File.read(File.expand_path(conf_file)))
12
+ client = Aliyun::OSS::Client.new(
13
+ :endpoint => conf['endpoint'],
14
+ :cname => conf['cname'],
15
+ :access_key_id => conf['access_key_id'],
16
+ :access_key_secret => conf['access_key_secret'])
17
+ @bucket = client.get_bucket(conf['bucket'])
18
+
19
+ @prefix = "tests/custom_headers/"
20
+ end
21
+
22
+ def get_key(k)
23
+ "#{@prefix}#{k}"
24
+ end
25
+
26
+ def test_custom_headers
27
+ key = get_key('ruby')
28
+ cache_control = 'max-age: 3600'
29
+ @bucket.put_object(key, headers: {'cache-control' => cache_control})
30
+ obj = @bucket.get_object(key)
31
+ assert_equal cache_control, obj.headers[:cache_control]
32
+
33
+ content_disposition = 'attachment; filename="fname.ext"'
34
+ @bucket.put_object(
35
+ key,
36
+ headers: {'cache-control' => cache_control,
37
+ 'CONTENT-DISPOSITION' => content_disposition})
38
+ obj = @bucket.get_object(key)
39
+ assert_equal cache_control, obj.headers[:cache_control]
40
+ assert_equal content_disposition, obj.headers[:content_disposition]
41
+
42
+ content_encoding = 'deflate'
43
+ expires = (Time.now + 3600).httpdate
44
+ @bucket.put_object(
45
+ key,
46
+ headers: {'cache-control' => cache_control,
47
+ 'CONTENT-DISPOSITION' => content_disposition,
48
+ 'content-ENCODING' => content_encoding,
49
+ 'EXPIRES' => expires }) do |s|
50
+ s << Zlib::Deflate.deflate('hello world')
51
+ end
52
+
53
+ content = ''
54
+ obj = @bucket.get_object(key) { |c| content << c }
55
+ assert_equal 'hello world', content
56
+ assert_equal cache_control, obj.headers[:cache_control]
57
+ assert_equal content_disposition, obj.headers[:content_disposition]
58
+ assert_equal content_encoding, obj.headers[:content_encoding]
59
+ assert_equal expires, obj.headers[:expires]
60
+ end
61
+
62
+ def test_headers_overwrite
63
+ key = get_key('rails')
64
+ @bucket.put_object(
65
+ key,
66
+ content_type: 'text/html',
67
+ metas: {'hello' => 'world'},
68
+ headers: {'content-type' => 'application/json',
69
+ 'x-oss-meta-hello' => 'bar'}) { |s| s << 'hello world' }
70
+ obj = @bucket.get_object(key)
71
+
72
+ assert_equal 'application/json', obj.headers[:content_type]
73
+ assert_equal ({'hello' => 'bar'}), obj.metas
74
+ end
75
+ end
@@ -0,0 +1,54 @@
1
+ require 'minitest/autorun'
2
+ require 'yaml'
3
+ $LOAD_PATH.unshift(File.expand_path("../../lib", __FILE__))
4
+ require 'aliyun/oss'
5
+
6
+ class TestObjectACL < Minitest::Test
7
+ def setup
8
+ Aliyun::Common::Logging.set_log_level(Logger::DEBUG)
9
+ conf_file = '~/.oss.yml'
10
+ conf = YAML.load(File.read(File.expand_path(conf_file)))
11
+ client = Aliyun::OSS::Client.new(
12
+ :endpoint => conf['endpoint'],
13
+ :cname => conf['cname'],
14
+ :access_key_id => conf['access_key_id'],
15
+ :access_key_secret => conf['access_key_secret'])
16
+ @bucket = client.get_bucket(conf['bucket'])
17
+
18
+ @prefix = "tests/object_acl/"
19
+ end
20
+
21
+ def get_key(k)
22
+ "#{@prefix}#{k}"
23
+ end
24
+
25
+ def test_put_object
26
+ key = get_key('put')
27
+
28
+ @bucket.put_object(key, acl: Aliyun::OSS::ACL::PRIVATE)
29
+ acl = @bucket.get_object_acl(key)
30
+
31
+ assert_equal Aliyun::OSS::ACL::PRIVATE, acl
32
+
33
+ @bucket.put_object(key, acl: Aliyun::OSS::ACL::PUBLIC_READ)
34
+ acl = @bucket.get_object_acl(key)
35
+
36
+ assert_equal Aliyun::OSS::ACL::PUBLIC_READ, acl
37
+ end
38
+
39
+ def test_append_object
40
+ key = get_key('append-1')
41
+
42
+ @bucket.append_object(key, 0, acl: Aliyun::OSS::ACL::PRIVATE)
43
+ acl = @bucket.get_object_acl(key)
44
+
45
+ assert_equal Aliyun::OSS::ACL::PRIVATE, acl
46
+
47
+ key = get_key('append-2')
48
+
49
+ @bucket.put_object(key, acl: Aliyun::OSS::ACL::PUBLIC_READ)
50
+ acl = @bucket.get_object_acl(key)
51
+
52
+ assert_equal Aliyun::OSS::ACL::PUBLIC_READ, acl
53
+ end
54
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aliyun-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tianlong Wu
@@ -180,9 +180,11 @@ files:
180
180
  - spec/aliyun/sts/client_spec.rb
181
181
  - spec/aliyun/sts/util_spec.rb
182
182
  - tests/test_content_type.rb
183
+ - tests/test_custom_headers.rb
183
184
  - tests/test_encoding.rb
184
185
  - tests/test_large_file.rb
185
186
  - tests/test_multipart.rb
187
+ - tests/test_object_acl.rb
186
188
  - tests/test_object_key.rb
187
189
  - tests/test_resumable.rb
188
190
  homepage: https://github.com/aliyun/aliyun-oss-ruby-sdk
@@ -223,8 +225,10 @@ test_files:
223
225
  - spec/aliyun/sts/client_spec.rb
224
226
  - spec/aliyun/sts/util_spec.rb
225
227
  - tests/test_content_type.rb
228
+ - tests/test_custom_headers.rb
226
229
  - tests/test_encoding.rb
227
230
  - tests/test_large_file.rb
228
231
  - tests/test_multipart.rb
232
+ - tests/test_object_acl.rb
229
233
  - tests/test_object_key.rb
230
234
  - tests/test_resumable.rb