aliyun-sdk 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -43,10 +43,14 @@ module Aliyun
43
43
  # A stream is any class that responds to :read(bytes, outbuf)
44
44
  #
45
45
  class StreamWriter
46
- def initialize
46
+ attr_reader :data_crc
47
+
48
+ def initialize(crc_enable = false, init_crc = 0)
47
49
  @buffer = ""
48
50
  @producer = Fiber.new { yield self if block_given? }
49
51
  @producer.resume
52
+ @data_crc = init_crc.to_i
53
+ @crc_enable = crc_enable
50
54
  end
51
55
 
52
56
  def read(bytes = nil, outbuf = nil)
@@ -84,6 +88,8 @@ module Aliyun
84
88
  # "". ios.read(positive-integer) returns nil.
85
89
  return nil if ret.empty? && !bytes.nil? && bytes > 0
86
90
 
91
+ @data_crc = Aliyun::OSS::Util.crc(ret, @data_crc) if @crc_enable
92
+
87
93
  ret
88
94
  end
89
95
 
@@ -115,8 +121,8 @@ module Aliyun
115
121
  # net_http_do_request(http, req, payload ? payload.to_s : nil,
116
122
  # &@block_response)
117
123
  class StreamPayload
118
- def initialize(&block)
119
- @stream = StreamWriter.new(&block)
124
+ def initialize(crc_enable = false, init_crc = 0, &block)
125
+ @stream = StreamWriter.new(crc_enable, init_crc, &block)
120
126
  end
121
127
 
122
128
  def read(bytes = nil)
@@ -129,7 +135,6 @@ module Aliyun
129
135
  def closed?
130
136
  false
131
137
  end
132
-
133
138
  end
134
139
 
135
140
  include Common::Logging
@@ -30,7 +30,7 @@ module Aliyun
30
30
  md5= Util.get_content_md5(states.to_json)
31
31
 
32
32
  @mutex.synchronize {
33
- File.open(file, 'w') {
33
+ File.open(file, 'wb') {
34
34
  |f| f.write(states.merge(md5: md5).to_json)
35
35
  }
36
36
  }
@@ -7,6 +7,7 @@ require 'time'
7
7
  module Aliyun
8
8
  module OSS
9
9
 
10
+
10
11
  ##
11
12
  # Protocol implement the OSS Open API which is low-level. User
12
13
  # should refer to {OSS::Client} for normal use.
@@ -534,9 +535,10 @@ module Aliyun
534
535
  headers[CALLBACK_HEADER] = opts[:callback].serialize
535
536
  end
536
537
 
538
+ payload = HTTP::StreamPayload.new(@config.upload_crc_enable, opts[:init_crc], &block)
537
539
  r = @http.put(
538
540
  {:bucket => bucket_name, :object => object_name},
539
- {:headers => headers, :body => HTTP::StreamPayload.new(&block)})
541
+ {:headers => headers, :body => payload})
540
542
 
541
543
  if r.code == 203
542
544
  e = CallbackError.new(r)
@@ -544,6 +546,11 @@ module Aliyun
544
546
  raise e
545
547
  end
546
548
 
549
+ if @config.upload_crc_enable && !r.headers[:x_oss_hash_crc64ecma].nil?
550
+ data_crc = payload.read.data_crc
551
+ Aliyun::OSS::Util.crc_check(data_crc, r.headers[:x_oss_hash_crc64ecma], 'put')
552
+ end
553
+
547
554
  logger.debug('Done put object')
548
555
  end
549
556
 
@@ -586,9 +593,18 @@ module Aliyun
586
593
 
587
594
  headers.merge!(to_lower_case(opts[:headers])) if opts.key?(:headers)
588
595
 
596
+ payload = HTTP::StreamPayload.new(@config.upload_crc_enable && !opts[:init_crc].nil?, opts[:init_crc], &block)
597
+
589
598
  r = @http.post(
590
599
  {:bucket => bucket_name, :object => object_name, :sub_res => sub_res},
591
- {:headers => headers, :body => HTTP::StreamPayload.new(&block)})
600
+ {:headers => headers, :body => payload})
601
+
602
+ if @config.upload_crc_enable &&
603
+ !r.headers[:x_oss_hash_crc64ecma].nil? &&
604
+ !opts[:init_crc].nil?
605
+ data_crc = payload.read.data_crc
606
+ Aliyun::OSS::Util.crc_check(data_crc, r.headers[:x_oss_hash_crc64ecma], 'append')
607
+ end
592
608
 
593
609
  logger.debug('Done append object')
594
610
 
@@ -759,11 +775,22 @@ module Aliyun
759
775
  rewrites[:expires].httpdate if rewrites.key?(:expires)
760
776
  end
761
777
 
778
+ data_crc = opts[:init_crc].nil? ? 0 : opts[:init_crc]
762
779
  r = @http.get(
763
780
  {:bucket => bucket_name, :object => object_name,
764
781
  :sub_res => sub_res},
765
782
  {:headers => headers}
766
- ) { |chunk| yield chunk if block_given? }
783
+ ) do |chunk|
784
+ if block_given?
785
+ # crc enable and no range and oss server support crc
786
+ data_crc = Aliyun::OSS::Util.crc(chunk, data_crc) if @config.download_crc_enable && range.nil?
787
+ yield chunk
788
+ end
789
+ end
790
+
791
+ if @config.download_crc_enable && range.nil? && !r.headers[:x_oss_hash_crc64ecma].nil?
792
+ Aliyun::OSS::Util.crc_check(data_crc, r.headers[:x_oss_hash_crc64ecma], 'get')
793
+ end
767
794
 
768
795
  h = r.headers
769
796
  metas = {}
@@ -1082,9 +1109,16 @@ module Aliyun
1082
1109
  "#{object_name}, txn id: #{txn_id}, part No: #{part_no}")
1083
1110
 
1084
1111
  sub_res = {'partNumber' => part_no, 'uploadId' => txn_id}
1112
+
1113
+ payload = HTTP::StreamPayload.new(@config.upload_crc_enable, &block)
1085
1114
  r = @http.put(
1086
1115
  {:bucket => bucket_name, :object => object_name, :sub_res => sub_res},
1087
- {:body => HTTP::StreamPayload.new(&block)})
1116
+ {:body => payload})
1117
+
1118
+ if @config.upload_crc_enable && !r.headers[:x_oss_hash_crc64ecma].nil?
1119
+ data_crc = payload.read.data_crc
1120
+ Aliyun::OSS::Util.crc_check(data_crc, r.headers[:x_oss_hash_crc64ecma], 'put')
1121
+ end
1088
1122
 
1089
1123
  logger.debug("Done upload part")
1090
1124
 
@@ -1378,6 +1412,18 @@ module Aliyun
1378
1412
  Util.sign(@config.access_key_secret, string_to_sign)
1379
1413
  end
1380
1414
 
1415
+ # Get the download crc status
1416
+ # @return true(download crc enable) or false(download crc disable)
1417
+ def download_crc_enable
1418
+ @config.download_crc_enable
1419
+ end
1420
+
1421
+ # Get the upload crc status
1422
+ # @return true(upload crc enable) or false(upload crc disable)
1423
+ def upload_crc_enable
1424
+ @config.upload_crc_enable
1425
+ end
1426
+
1381
1427
  private
1382
1428
 
1383
1429
  # Parse body content to xml document
@@ -1493,7 +1539,6 @@ module Aliyun
1493
1539
  result
1494
1540
  end
1495
1541
  end
1496
-
1497
1542
  end # Protocol
1498
1543
  end # OSS
1499
1544
  end # Aliyun
@@ -7,6 +7,7 @@ require 'digest/md5'
7
7
 
8
8
  module Aliyun
9
9
  module OSS
10
+
10
11
  ##
11
12
  # Util functions to help generate formatted Date, signatures,
12
13
  # etc.
@@ -75,6 +76,23 @@ module Aliyun
75
76
  end
76
77
  end
77
78
 
79
+ # Get a crc value of the data
80
+ def crc(data, init_crc = 0)
81
+ CrcX::crc64(init_crc, data, data.size)
82
+ end
83
+
84
+ # Calculate a value of the crc1 combine with crc2.
85
+ def crc_combine(crc1, crc2, len2)
86
+ CrcX::crc64_combine(crc1, crc2, len2)
87
+ end
88
+
89
+ def crc_check(crc_a, crc_b, operation)
90
+ if crc_a.nil? || crc_b.nil? || crc_a.to_i != crc_b.to_i
91
+ logger.error("The crc of #{operation} between client and oss is not inconsistent. crc_a=#{crc_a} crc_b=#{crc_b}")
92
+ fail CrcInconsistentError.new("The crc of #{operation} between client and oss is not inconsistent.")
93
+ end
94
+ end
95
+
78
96
  end # self
79
97
  end # Util
80
98
  end # OSS
@@ -86,4 +104,4 @@ class String
86
104
  return true if self =~ /^true$/i
87
105
  false
88
106
  end
89
- end
107
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Aliyun
4
4
 
5
- VERSION = "0.4.1"
5
+ VERSION = "0.5.0"
6
6
 
7
7
  end # Aliyun
@@ -591,6 +591,60 @@ module Aliyun
591
591
 
592
592
  end # acl, logging, cors, etc
593
593
 
594
+ context "crc" do
595
+ it "should download crc enable equal config setting" do
596
+ protocol = Protocol.new(
597
+ Config.new(:endpoint => @endpoint,
598
+ :access_key_id => 'xxx', :access_key_secret => 'yyy',
599
+ :download_crc_enable => 'true'))
600
+ expect(protocol.download_crc_enable).to eq(true)
601
+
602
+ protocol = Protocol.new(
603
+ Config.new(:endpoint => @endpoint,
604
+ :access_key_id => 'xxx', :access_key_secret => 'yyy',
605
+ :download_crc_enable => true))
606
+ expect(protocol.download_crc_enable).to eq(true)
607
+
608
+ protocol = Protocol.new(
609
+ Config.new(:endpoint => @endpoint,
610
+ :access_key_id => 'xxx', :access_key_secret => 'yyy',
611
+ :download_crc_enable => 'false'))
612
+ expect(protocol.download_crc_enable).to eq(false)
613
+
614
+ protocol = Protocol.new(
615
+ Config.new(:endpoint => @endpoint,
616
+ :access_key_id => 'xxx', :access_key_secret => 'yyy',
617
+ :download_crc_enable => false))
618
+ expect(protocol.download_crc_enable).to eq(false)
619
+ end
620
+
621
+ it "should upload crc enable equal config setting" do
622
+ protocol = Protocol.new(
623
+ Config.new(:endpoint => @endpoint,
624
+ :access_key_id => 'xxx', :access_key_secret => 'yyy',
625
+ :upload_crc_enable => 'true'))
626
+ expect(protocol.upload_crc_enable).to eq(true)
627
+
628
+ protocol = Protocol.new(
629
+ Config.new(:endpoint => @endpoint,
630
+ :access_key_id => 'xxx', :access_key_secret => 'yyy',
631
+ :upload_crc_enable => true))
632
+ expect(protocol.upload_crc_enable).to eq(true)
633
+
634
+ protocol = Protocol.new(
635
+ Config.new(:endpoint => @endpoint,
636
+ :access_key_id => 'xxx', :access_key_secret => 'yyy',
637
+ :upload_crc_enable => 'false'))
638
+ expect(protocol.upload_crc_enable).to eq(false)
639
+
640
+ protocol = Protocol.new(
641
+ Config.new(:endpoint => @endpoint,
642
+ :access_key_id => 'xxx', :access_key_secret => 'yyy',
643
+ :upload_crc_enable => false))
644
+ expect(protocol.upload_crc_enable).to eq(false)
645
+ end
646
+ end # crc
647
+
594
648
  end # Bucket
595
649
 
596
650
  end # OSS
@@ -549,6 +549,72 @@ module Aliyun
549
549
  end
550
550
  end # multipart operations
551
551
 
552
+ context "crc" do
553
+ it "should download crc enable equal config setting" do
554
+ bucket = Client.new(
555
+ :endpoint => @endpoint,
556
+ :access_key_id => 'xxx', :access_key_secret => 'yyy',
557
+ :download_crc_enable => 'true').get_bucket(@bucket_name)
558
+ expect(bucket.download_crc_enable).to eq(true)
559
+
560
+ bucket = Client.new(
561
+ :endpoint => @endpoint,
562
+ :access_key_id => 'xxx', :access_key_secret => 'yyy',
563
+ :download_crc_enable => true).get_bucket(@bucket_name)
564
+ expect(bucket.download_crc_enable).to eq(true)
565
+
566
+ bucket = Client.new(
567
+ :endpoint => @endpoint,
568
+ :access_key_id => 'xxx', :access_key_secret => 'yyy',
569
+ :download_crc_enable => 'false').get_bucket(@bucket_name)
570
+ expect(bucket.download_crc_enable).to eq(false)
571
+
572
+ bucket = Client.new(
573
+ :endpoint => @endpoint,
574
+ :access_key_id => 'xxx', :access_key_secret => 'yyy',
575
+ :download_crc_enable => false).get_bucket(@bucket_name)
576
+ expect(bucket.download_crc_enable).to eq(false)
577
+
578
+ # check default value
579
+ bucket = Client.new(
580
+ :endpoint => @endpoint,
581
+ :access_key_id => 'xxx', :access_key_secret => 'yyy').get_bucket(@bucket_name)
582
+ expect(bucket.download_crc_enable).to eq(false)
583
+ end
584
+
585
+ it "should upload crc enable equal config setting" do
586
+ bucket = Client.new(
587
+ :endpoint => @endpoint,
588
+ :access_key_id => 'xxx', :access_key_secret => 'yyy',
589
+ :upload_crc_enable => 'true').get_bucket(@bucket_name)
590
+ expect(bucket.upload_crc_enable).to eq(true)
591
+
592
+ bucket = Client.new(
593
+ :endpoint => @endpoint,
594
+ :access_key_id => 'xxx', :access_key_secret => 'yyy',
595
+ :upload_crc_enable => true).get_bucket(@bucket_name)
596
+ expect(bucket.upload_crc_enable).to eq(true)
597
+
598
+ bucket = Client.new(
599
+ :endpoint => @endpoint,
600
+ :access_key_id => 'xxx', :access_key_secret => 'yyy',
601
+ :upload_crc_enable => 'false').get_bucket(@bucket_name)
602
+ expect(bucket.upload_crc_enable).to eq(false)
603
+
604
+ bucket = Client.new(
605
+ :endpoint => @endpoint,
606
+ :access_key_id => 'xxx', :access_key_secret => 'yyy',
607
+ :upload_crc_enable => false).get_bucket(@bucket_name)
608
+ expect(bucket.upload_crc_enable).to eq(false)
609
+
610
+ # check default value
611
+ bucket = Client.new(
612
+ :endpoint => @endpoint,
613
+ :access_key_id => 'xxx', :access_key_secret => 'yyy').get_bucket(@bucket_name)
614
+ expect(bucket.upload_crc_enable).to eq(true)
615
+ end
616
+ end # crc
617
+
552
618
  end # Bucket
553
619
  end # OSS
554
620
  end # Aliyun
@@ -76,6 +76,32 @@ module Aliyun
76
76
  r = s.read(1000)
77
77
  expect(r.size).to eq(64)
78
78
  end
79
+
80
+ it "should read with a correct crc" do
81
+ content = "hello world"
82
+ content_crc = Aliyun::OSS::Util.crc(content)
83
+ s = HTTP::StreamWriter.new(true) do |sr|
84
+ sr << content
85
+ end
86
+
87
+ r = s.read(content.size + 1)
88
+ expect(r.size).to eq(content.size)
89
+ expect(s.data_crc).to eq(content_crc)
90
+ end
91
+
92
+ it "should read with a correct crc when setting init_crc" do
93
+ content = "hello world"
94
+ init_crc = 100
95
+ content_crc = Aliyun::OSS::Util.crc(content, init_crc)
96
+
97
+ s = HTTP::StreamWriter.new(true, init_crc) do |sr|
98
+ sr << content
99
+ end
100
+
101
+ r = s.read(content.size + 1)
102
+ expect(r.size).to eq(content.size)
103
+ expect(s.data_crc).to eq(content_crc)
104
+ end
79
105
  end # StreamWriter
80
106
 
81
107
  end # HTTP
@@ -23,6 +23,15 @@ module Aliyun
23
23
  "#{@bucket}.#{@endpoint}/#{@object}"
24
24
  end
25
25
 
26
+ def crc_protocol
27
+ Protocol.new(
28
+ Config.new(:endpoint => @endpoint,
29
+ :access_key_id => 'xxx',
30
+ :access_key_secret => 'yyy',
31
+ :upload_crc_enable => true,
32
+ :download_crc_enable => true))
33
+ end
34
+
26
35
  def mock_txn_id(txn_id)
27
36
  Nokogiri::XML::Builder.new do |xml|
28
37
  xml.InitiateMultipartUploadResult {
@@ -207,6 +216,42 @@ module Aliyun
207
216
  .with(:body => nil, :query => query)
208
217
  end
209
218
 
219
+ it "should raise crc exception on error" do
220
+ txn_id = 'xxxyyyzzz'
221
+ part_no = 1
222
+ query = {'partNumber' => part_no, 'uploadId' => txn_id}
223
+
224
+ content = "hello world"
225
+ content_crc = Aliyun::OSS::Util.crc(content)
226
+
227
+ stub_request(:put, request_path).with(:query => query).to_return(
228
+ :status => 200, :headers => {:x_oss_hash_crc64ecma => content_crc + 1})
229
+
230
+ expect {
231
+ crc_protocol.upload_part(@bucket, @object, txn_id, part_no) do |body|
232
+ body << content
233
+ end
234
+ }.to raise_error(CrcInconsistentError, "The crc of put between client and oss is not inconsistent.")
235
+ end
236
+
237
+ it "should not raise crc exception on error" do
238
+ txn_id = 'xxxyyyzzz'
239
+ part_no = 1
240
+ query = {'partNumber' => part_no, 'uploadId' => txn_id}
241
+
242
+ content = "hello world"
243
+ content_crc = Aliyun::OSS::Util.crc(content)
244
+
245
+ stub_request(:put, request_path).with(:query => query).to_return(
246
+ :status => 200, :headers => {:x_oss_hash_crc64ecma => content_crc})
247
+
248
+ expect {
249
+ crc_protocol.upload_part(@bucket, @object, txn_id, part_no) do |body|
250
+ body << content
251
+ end
252
+ }.not_to raise_error
253
+ end
254
+
210
255
  end # upload part
211
256
 
212
257
  context "Upload part by copy object" do
@@ -17,6 +17,15 @@ module Aliyun
17
17
  @bucket = 'rubysdk-bucket'
18
18
  end
19
19
 
20
+ def crc_protocol
21
+ Protocol.new(
22
+ Config.new(:endpoint => @endpoint,
23
+ :access_key_id => 'xxx',
24
+ :access_key_secret => 'yyy',
25
+ :upload_crc_enable => true,
26
+ :download_crc_enable => true))
27
+ end
28
+
20
29
  def get_request_path(object = nil)
21
30
  p = "#{@bucket}.#{@endpoint}/"
22
31
  p += CGI.escape(object) if object
@@ -190,6 +199,35 @@ module Aliyun
190
199
  'x-oss-meta-people' => 'mary'})
191
200
  end
192
201
 
202
+ it "should raise crc exception on error" do
203
+ object_name = 'ruby'
204
+ url = get_request_path(object_name)
205
+ content = "hello world"
206
+ content_crc = Aliyun::OSS::Util.crc(content)
207
+ stub_request(:put, url).to_return(
208
+ :status => 200, :headers => {:x_oss_hash_crc64ecma => content_crc.to_i + 1})
209
+ expect(crc_protocol.upload_crc_enable).to eq(true)
210
+ expect {
211
+ crc_protocol.put_object(@bucket, object_name) do |c|
212
+ c << content
213
+ end
214
+ }.to raise_error(CrcInconsistentError, "The crc of put between client and oss is not inconsistent.")
215
+ end
216
+
217
+ it "should not raise crc exception on error" do
218
+ object_name = 'ruby'
219
+ url = get_request_path(object_name)
220
+ content = "hello world"
221
+ content_crc = Aliyun::OSS::Util.crc(content)
222
+ stub_request(:put, url).to_return(
223
+ :status => 200, :headers => {:x_oss_hash_crc64ecma => content_crc})
224
+ expect(crc_protocol.upload_crc_enable).to eq(true)
225
+ expect {
226
+ crc_protocol.put_object(@bucket, object_name) do |c|
227
+ c << content
228
+ end
229
+ }.not_to raise_error
230
+ end
193
231
  end # put object
194
232
 
195
233
  context "Append object" do
@@ -290,6 +328,72 @@ module Aliyun
290
328
  'x-oss-meta-year' => '2015',
291
329
  'x-oss-meta-people' => 'mary'})
292
330
  end
331
+
332
+ it "should raise crc exception on error" do
333
+ object_name = 'ruby'
334
+ url = get_request_path(object_name)
335
+ content = "hello world"
336
+ content_crc = Aliyun::OSS::Util.crc(content)
337
+
338
+ query = {'append' => '', 'position' => 11}
339
+ return_headers = {'x-oss-next-append-position' => '101', :x_oss_hash_crc64ecma => content_crc.to_i + 1}
340
+ stub_request(:post, url).with(:query => query)
341
+ .to_return(:headers => return_headers)
342
+ expect(crc_protocol.upload_crc_enable).to eq(true)
343
+ expect {
344
+ crc_protocol.append_object(@bucket, object_name, 11, :init_crc => 0) do |c|
345
+ c << content
346
+ end
347
+ }.to raise_error(CrcInconsistentError, "The crc of append between client and oss is not inconsistent.")
348
+ end
349
+
350
+ it "should not raise crc exception with init_crc" do
351
+ object_name = 'ruby'
352
+ url = get_request_path(object_name)
353
+ content = "hello world"
354
+ content_crc = Aliyun::OSS::Util.crc(content)
355
+
356
+ query = {'append' => '', 'position' => 11}
357
+ return_headers = {'x-oss-next-append-position' => '101', :x_oss_hash_crc64ecma => content_crc}
358
+ stub_request(:post, url).with(:query => query)
359
+ .to_return(:headers => return_headers)
360
+
361
+ expect(crc_protocol.upload_crc_enable).to eq(true)
362
+ next_pos = 0
363
+ expect {
364
+ next_pos = crc_protocol.append_object(@bucket, object_name, 11, :init_crc => 0) do |c|
365
+ c << content
366
+ end
367
+ }.not_to raise_error
368
+
369
+ expect(WebMock).to have_requested(:post, url)
370
+ .with(:body => content, :query => query)
371
+ expect(next_pos).to eq(101)
372
+ end
373
+
374
+ it "should not raise crc exception without init_crc" do
375
+ object_name = 'ruby'
376
+ url = get_request_path(object_name)
377
+ content = "hello world"
378
+ content_crc = Aliyun::OSS::Util.crc(content)
379
+
380
+ query = {'append' => '', 'position' => 11}
381
+ return_headers = {'x-oss-next-append-position' => '101', :x_oss_hash_crc64ecma => content_crc + 1}
382
+ stub_request(:post, url).with(:query => query)
383
+ .to_return(:headers => return_headers)
384
+
385
+ expect(crc_protocol.upload_crc_enable).to eq(true)
386
+ next_pos = 0
387
+ expect {
388
+ next_pos = crc_protocol.append_object(@bucket, object_name, 11) do |c|
389
+ c << content
390
+ end
391
+ }.not_to raise_error
392
+
393
+ expect(WebMock).to have_requested(:post, url)
394
+ .with(:body => content, :query => query)
395
+ expect(next_pos).to eq(101)
396
+ end
293
397
  end # append object
294
398
 
295
399
  context "Copy object" do
@@ -557,6 +661,55 @@ module Aliyun
557
661
  expect(WebMock).to have_requested(:get, url)
558
662
  .with(:body => nil, :query => query)
559
663
  end
664
+
665
+
666
+ it "should raise crc exception on error" do
667
+ object_name = 'ruby'
668
+ url = get_request_path(object_name)
669
+ content = "hello world"
670
+ content_crc = Aliyun::OSS::Util.crc(content)
671
+ stub_request(:get, url).to_return(
672
+ :status => 200, :body => content, :headers => {:x_oss_hash_crc64ecma => content_crc.to_i + 1})
673
+ response_content = ""
674
+ expect(crc_protocol.download_crc_enable).to eq(true)
675
+ expect {
676
+ crc_protocol.get_object(@bucket, object_name) {|c| response_content << c}
677
+ }.to raise_error(CrcInconsistentError, "The crc of get between client and oss is not inconsistent.")
678
+ end
679
+
680
+ it "should not raise crc exception on error" do
681
+ object_name = 'ruby'
682
+ url = get_request_path(object_name)
683
+ content = "hello world"
684
+ content_crc = Aliyun::OSS::Util.crc(content)
685
+ stub_request(:get, url).to_return(
686
+ :status => 200, :body => content, :headers => {:x_oss_hash_crc64ecma => content_crc})
687
+ response_content = ""
688
+ expect(crc_protocol.download_crc_enable).to eq(true)
689
+ expect {
690
+ crc_protocol.get_object(@bucket, object_name) {|c| response_content << c}
691
+ }.not_to raise_error
692
+ expect(response_content).to eq(content)
693
+ end
694
+
695
+ it "should not raise crc exception on error when setting range" do
696
+ object_name = 'ruby'
697
+ url = get_request_path(object_name)
698
+ content = "hello world 0123456789"
699
+ content_crc = Aliyun::OSS::Util.crc(content)
700
+ stub_request(:get, url).to_return(
701
+ :status => 200, :body => content, :headers => {:x_oss_hash_crc64ecma => content_crc.to_i + 1})
702
+ response_content = ""
703
+ expect(crc_protocol.download_crc_enable).to eq(true)
704
+ expect {
705
+ crc_protocol.get_object(@bucket, object_name, {range: [0, 10]}) {|c| response_content << c}
706
+ }.not_to raise_error
707
+ expect(WebMock).to have_requested(:get, url)
708
+ .with(:body => nil, :query => {},
709
+ :headers => {
710
+ 'Range' => 'bytes=0-9'
711
+ })
712
+ end
560
713
  end # Get object
561
714
 
562
715
  context "Get object meta" do