aws 2.5.8 → 2.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/s3/s3_interface.rb +168 -2
- metadata +2 -2
data/lib/s3/s3_interface.rb
CHANGED
@@ -113,6 +113,14 @@ module Aws
|
|
113
113
|
out_string << '?torrent' if path[/[&?]torrent($|&|=)/]
|
114
114
|
out_string << '?location' if path[/[&?]location($|&|=)/]
|
115
115
|
out_string << '?logging' if path[/[&?]logging($|&|=)/] # this one is beta, no support for now
|
116
|
+
#... also deal with params for multipart uploads API
|
117
|
+
out_string << '?uploads' if path[/\?uploads$/]
|
118
|
+
if path[/\?uploadId=(.*)$/]
|
119
|
+
out_string << "?uploadId=#{$1}"
|
120
|
+
end
|
121
|
+
if path[/\?partNumber=(\d*)&uploadId=(.*)$/]
|
122
|
+
out_string << "?partNumber=#{$1}&uploadId=#{$2}"
|
123
|
+
end
|
116
124
|
out_string
|
117
125
|
end
|
118
126
|
|
@@ -338,7 +346,7 @@ module Aws
|
|
338
346
|
begin
|
339
347
|
internal_bucket = bucket.dup
|
340
348
|
unless internal_options.nil? || internal_options.empty?
|
341
|
-
internal_bucket << '?'
|
349
|
+
internal_bucket << '?'
|
342
350
|
internal_bucket << internal_options.map { |k, v| "#{k.to_s}=#{CGI::escape v.to_s}" }.join('&')
|
343
351
|
end
|
344
352
|
req_hash = generate_rest_request('GET', headers.merge(:url=>internal_bucket))
|
@@ -518,6 +526,112 @@ module Aws
|
|
518
526
|
r[:verified_md5] ? (return r) : (raise AwsError.new("Uploaded object failed MD5 checksum verification: #{r.inspect}"))
|
519
527
|
end
|
520
528
|
|
529
|
+
# Initiates a multipart upload and returns an upload ID or an exception
|
530
|
+
# http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadInitiate.html
|
531
|
+
#
|
532
|
+
# s3.initiate_multipart('my_awesome_bucket', 'hugeObject') => WL7dk8sqbtk3Rg641HHWaNeG6RxI4fzS8V0YvuQAfs5Hbk6WNZOU1z_AhGv
|
533
|
+
#
|
534
|
+
# The returned uploadId must be retained for use in uploading parts; see
|
535
|
+
# http://docs.amazonwebservices.com/AmazonS3/latest/dev/mpuoverview.html
|
536
|
+
#
|
537
|
+
def initiate_multipart(bucket, key, headers={})
|
538
|
+
req_hash = generate_rest_request('POST', headers.merge(:url =>"#{bucket}/#{CGI::escape key}?uploads"))
|
539
|
+
request_info(req_hash, S3InitiateMultipartUploadParser.new)
|
540
|
+
rescue
|
541
|
+
on_exception
|
542
|
+
end
|
543
|
+
|
544
|
+
# Uploads a part in a multipart upload - returns an Etag for the part or an exception
|
545
|
+
# http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadUploadPart.html
|
546
|
+
#
|
547
|
+
# Among the parameters required, clients must supply the uploadId (obtained from the initiate_multipart method call) as
|
548
|
+
# well as the partNumber for this part (user-specified, determining the sequence for reassembly).
|
549
|
+
#
|
550
|
+
# s3.upload_part('my_awesome_bucket', 'hugeObject', "WL7dk8sqbtk3Rg641HHWaNeG6RxI", "2", File.open('localfilename.dat'))
|
551
|
+
# => "b54357faf0632cce46e942fa68356b38"
|
552
|
+
#
|
553
|
+
# The return Etag must be retained for use in the completion of the multipart upload; see
|
554
|
+
# http://docs.amazonwebservices.com/AmazonS3/latest/dev/mpuoverview.html
|
555
|
+
#
|
556
|
+
def upload_part(bucket, key, uploadId, partNumber, data, headers={})
|
557
|
+
if (data.respond_to?(:binmode))
|
558
|
+
data.binmode
|
559
|
+
end
|
560
|
+
if data.is_a?(String)
|
561
|
+
data = StringIO.new(data)
|
562
|
+
end
|
563
|
+
data_size = data.respond_to?(:lstat) ? data.lstat.size :
|
564
|
+
(data.respond_to?(:size) ? data.size : 0)
|
565
|
+
if (data_size >= USE_100_CONTINUE_PUT_SIZE)
|
566
|
+
headers['expect'] = '100-continue'
|
567
|
+
end
|
568
|
+
req_hash = generate_rest_request('PUT', headers.merge(:url =>"#{bucket}/#{CGI::escape key}?partNumber=#{partNumber}&uploadId=#{uploadId}",
|
569
|
+
:data => data,
|
570
|
+
'Content-Length' => data_size.to_s))
|
571
|
+
request_info(req_hash, S3UploadPartParser.new)
|
572
|
+
rescue
|
573
|
+
on_exception
|
574
|
+
end
|
575
|
+
|
576
|
+
|
577
|
+
# Completes a multipart upload, returning true or an exception
|
578
|
+
# http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadComplete.html
|
579
|
+
#
|
580
|
+
# Clients must specify the uploadId (obtained from the initiate_multipart call) and the reassembly manifest hash
|
581
|
+
# which specifies the each partNumber corresponding etag (obtained from the upload_part call):
|
582
|
+
#
|
583
|
+
# s3.complete_multipart('my_awesome_bucket', 'hugeObject', "WL7dk8sqbtk3Rg641HHWaNeG6RxI",
|
584
|
+
# {"1"=>"a54357aff0632cce46d942af68356b38", "2"=>"0c78aef83f66abc1fa1e8477f296d394"}) => true
|
585
|
+
#
|
586
|
+
# See http://docs.amazonwebservices.com/AmazonS3/latest/dev/mpuoverview.html
|
587
|
+
#
|
588
|
+
def complete_multipart(bucket, key, uploadId, manifest_hash, headers={})
|
589
|
+
parts_string = manifest_hash.inject("") do |res, (part,etag)|
|
590
|
+
res<< <<END_PARTS
|
591
|
+
<Part>
|
592
|
+
<PartNumber>#{part}</PartNumber>
|
593
|
+
<ETag>"#{etag}"</ETag>
|
594
|
+
</Part>
|
595
|
+
END_PARTS
|
596
|
+
res
|
597
|
+
end
|
598
|
+
data = <<EOS
|
599
|
+
<CompleteMultipartUpload>
|
600
|
+
#{parts_string}
|
601
|
+
</CompleteMultipartUpload>
|
602
|
+
EOS
|
603
|
+
req_hash = generate_rest_request('POST', headers.merge(:url => "#{bucket}/#{CGI::escape key}?uploadId=#{uploadId}",
|
604
|
+
:data => data))
|
605
|
+
request_info(req_hash, RightHttp2xxParser.new)
|
606
|
+
rescue
|
607
|
+
on_exception
|
608
|
+
end
|
609
|
+
|
610
|
+
# List parts of a multipart upload, returning a hash or an exception
|
611
|
+
# http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadListParts.html
|
612
|
+
#
|
613
|
+
# response looks like:
|
614
|
+
#
|
615
|
+
# { :bucket=>"mariosFoo_awesome_test_bucket_000A1",
|
616
|
+
# :key=>"mariosFoosegmented",
|
617
|
+
# :upload_id=>"jQKX7JdJBTrbvLn9apUPIXkt14FHdp6nMZVg--"
|
618
|
+
# :parts=> [ {:part_number=>"1", :last_modified=>"2012-10-30T15:06:28.000Z",
|
619
|
+
# :etag=>"\"78f871f6f01673a4aca05b1f8e26df08\"", :size=>"6276589"},
|
620
|
+
# {:part_number=>"2", :last_modified=>"2012-10-30T15:08:22.000Z",
|
621
|
+
# :etag=>"\"e7b94a1e959ca066026da3ec63aad321\"", :size=>"7454095"}] }
|
622
|
+
#
|
623
|
+
# Clients must specify the uploadId (obtained from the initiate_multipart call)
|
624
|
+
#
|
625
|
+
# s3.list_parts('my_awesome_bucket', 'hugeObject', "WL7dk8sqbtk3Rg641HHWaNeG6RxI",
|
626
|
+
#
|
627
|
+
# See http://docs.amazonwebservices.com/AmazonS3/latest/dev/mpuoverview.html
|
628
|
+
#
|
629
|
+
def list_parts(bucket, key, uploadId, headers={})
|
630
|
+
req_hash = generate_rest_request('GET', headers.merge(:url=>"#{bucket}/#{CGI::escape key}?uploadId=#{uploadId}"))
|
631
|
+
request_info(req_hash, S3ListMultipartPartsParser.new)
|
632
|
+
end
|
633
|
+
|
634
|
+
|
521
635
|
# Retrieves object data from Amazon. Returns a +hash+ or an exception.
|
522
636
|
#
|
523
637
|
# s3.get('my_awesome_bucket', 'log/curent/1.log') #=>
|
@@ -544,7 +658,6 @@ module Aws
|
|
544
658
|
# end
|
545
659
|
# foo.close
|
546
660
|
#
|
547
|
-
|
548
661
|
def get(bucket, key, headers={}, &block)
|
549
662
|
req_hash = generate_rest_request('GET', headers.merge(:url=>"#{bucket}/#{CGI::escape key}"))
|
550
663
|
request_info(req_hash, S3HttpResponseBodyParser.new, &block)
|
@@ -1235,6 +1348,53 @@ module Aws
|
|
1235
1348
|
end
|
1236
1349
|
end
|
1237
1350
|
|
1351
|
+
class S3InitiateMultipartUploadParser < AwsParser # :nodoc:
|
1352
|
+
def reset
|
1353
|
+
@result = ""
|
1354
|
+
end
|
1355
|
+
|
1356
|
+
def tagend(name)
|
1357
|
+
@result = @text if name == 'UploadId'
|
1358
|
+
end
|
1359
|
+
|
1360
|
+
end
|
1361
|
+
|
1362
|
+
class S3ListMultipartPartsParser < AwsParser # :nodoc:
|
1363
|
+
def reset
|
1364
|
+
@result = {}
|
1365
|
+
@result[:parts] = []
|
1366
|
+
@current_part={}
|
1367
|
+
end
|
1368
|
+
|
1369
|
+
def tagstart(name, attributes)
|
1370
|
+
@current_part={} if name=='Part'
|
1371
|
+
end
|
1372
|
+
|
1373
|
+
def tagend(name)
|
1374
|
+
case name
|
1375
|
+
when 'PartNumber'
|
1376
|
+
@current_part[:part_number] = @text
|
1377
|
+
when 'ETag'
|
1378
|
+
@current_part[:etag] = @text
|
1379
|
+
when 'Size'
|
1380
|
+
@current_part[:size] = @text
|
1381
|
+
when 'LastModified'
|
1382
|
+
@current_part[:last_modified] = @text
|
1383
|
+
when 'Bucket'
|
1384
|
+
@result[:bucket] = @text
|
1385
|
+
when 'Key'
|
1386
|
+
@result[:key] = @text
|
1387
|
+
when 'UploadId'
|
1388
|
+
@result[:upload_id] = @text
|
1389
|
+
when 'Part'
|
1390
|
+
@result[:parts] << @current_part
|
1391
|
+
end
|
1392
|
+
end
|
1393
|
+
|
1394
|
+
end
|
1395
|
+
|
1396
|
+
|
1397
|
+
|
1238
1398
|
#-----------------------------------------------------------------
|
1239
1399
|
# PARSERS: Non XML
|
1240
1400
|
#-----------------------------------------------------------------
|
@@ -1274,6 +1434,12 @@ module Aws
|
|
1274
1434
|
end
|
1275
1435
|
end
|
1276
1436
|
|
1437
|
+
class S3UploadPartParser < S3HttpResponseParser # :nodoc:
|
1438
|
+
def parse(response)
|
1439
|
+
@result = headers_to_string(response.to_hash)["etag"].gsub!("\"", "")
|
1440
|
+
end
|
1441
|
+
end
|
1442
|
+
|
1277
1443
|
end
|
1278
1444
|
|
1279
1445
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aws
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.6.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2012-
|
14
|
+
date: 2012-11-28 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: uuidtools
|