aliyun-sdk 0.3.1 → 0.3.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.
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