aws-sdk-s3 1.48.0 → 1.60.0
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 +4 -4
- data/lib/aws-sdk-s3/bucket.rb +183 -54
- data/lib/aws-sdk-s3/bucket_acl.rb +9 -1
- data/lib/aws-sdk-s3/bucket_cors.rb +18 -1
- data/lib/aws-sdk-s3/bucket_lifecycle.rb +2 -1
- data/lib/aws-sdk-s3/bucket_lifecycle_configuration.rb +3 -1
- data/lib/aws-sdk-s3/bucket_logging.rb +11 -1
- data/lib/aws-sdk-s3/bucket_notification.rb +7 -3
- data/lib/aws-sdk-s3/bucket_policy.rb +2 -0
- data/lib/aws-sdk-s3/bucket_request_payment.rb +10 -0
- data/lib/aws-sdk-s3/bucket_tagging.rb +10 -1
- data/lib/aws-sdk-s3/bucket_versioning.rb +26 -0
- data/lib/aws-sdk-s3/bucket_website.rb +15 -4
- data/lib/aws-sdk-s3/client.rb +5133 -519
- data/lib/aws-sdk-s3/client_api.rb +33 -0
- data/lib/aws-sdk-s3/customizations/bucket.rb +44 -13
- data/lib/aws-sdk-s3/customizations/object.rb +65 -43
- data/lib/aws-sdk-s3/encryption/client.rb +4 -0
- data/lib/aws-sdk-s3/file_part.rb +9 -6
- data/lib/aws-sdk-s3/file_uploader.rb +13 -12
- data/lib/aws-sdk-s3/multipart_file_uploader.rb +14 -11
- data/lib/aws-sdk-s3/multipart_upload.rb +31 -16
- data/lib/aws-sdk-s3/multipart_upload_part.rb +38 -29
- data/lib/aws-sdk-s3/object.rb +330 -129
- data/lib/aws-sdk-s3/object_acl.rb +25 -7
- data/lib/aws-sdk-s3/object_summary.rb +243 -117
- data/lib/aws-sdk-s3/object_version.rb +67 -46
- data/lib/aws-sdk-s3/plugins/bucket_arn.rb +211 -0
- data/lib/aws-sdk-s3/plugins/bucket_dns.rb +7 -7
- data/lib/aws-sdk-s3/plugins/bucket_name_restrictions.rb +23 -3
- data/lib/aws-sdk-s3/plugins/iad_regional_endpoint.rb +59 -0
- data/lib/aws-sdk-s3/plugins/md5s.rb +3 -4
- data/lib/aws-sdk-s3/plugins/s3_signer.rb +16 -6
- data/lib/aws-sdk-s3/presigned_post.rb +4 -0
- data/lib/aws-sdk-s3/presigner.rb +6 -2
- data/lib/aws-sdk-s3/resource.rb +4 -2
- data/lib/aws-sdk-s3/types.rb +3027 -635
- data/lib/aws-sdk-s3.rb +1 -1
- metadata +6 -4
|
@@ -143,12 +143,15 @@ module Aws::S3
|
|
|
143
143
|
EncodingType = Shapes::StringShape.new(name: 'EncodingType')
|
|
144
144
|
Encryption = Shapes::StructureShape.new(name: 'Encryption')
|
|
145
145
|
EncryptionConfiguration = Shapes::StructureShape.new(name: 'EncryptionConfiguration')
|
|
146
|
+
End = Shapes::IntegerShape.new(name: 'End')
|
|
146
147
|
EndEvent = Shapes::StructureShape.new(name: 'EndEvent')
|
|
147
148
|
Error = Shapes::StructureShape.new(name: 'Error')
|
|
148
149
|
ErrorDocument = Shapes::StructureShape.new(name: 'ErrorDocument')
|
|
149
150
|
Errors = Shapes::ListShape.new(name: 'Errors', flattened: true)
|
|
150
151
|
Event = Shapes::StringShape.new(name: 'Event')
|
|
151
152
|
EventList = Shapes::ListShape.new(name: 'EventList', flattened: true)
|
|
153
|
+
ExistingObjectReplication = Shapes::StructureShape.new(name: 'ExistingObjectReplication')
|
|
154
|
+
ExistingObjectReplicationStatus = Shapes::StringShape.new(name: 'ExistingObjectReplicationStatus')
|
|
152
155
|
Expiration = Shapes::StringShape.new(name: 'Expiration')
|
|
153
156
|
ExpirationStatus = Shapes::StringShape.new(name: 'ExpirationStatus')
|
|
154
157
|
ExpiredObjectDeleteMarker = Shapes::BooleanShape.new(name: 'ExpiredObjectDeleteMarker')
|
|
@@ -310,11 +313,14 @@ module Aws::S3
|
|
|
310
313
|
MetadataEntry = Shapes::StructureShape.new(name: 'MetadataEntry')
|
|
311
314
|
MetadataKey = Shapes::StringShape.new(name: 'MetadataKey')
|
|
312
315
|
MetadataValue = Shapes::StringShape.new(name: 'MetadataValue')
|
|
316
|
+
Metrics = Shapes::StructureShape.new(name: 'Metrics')
|
|
313
317
|
MetricsAndOperator = Shapes::StructureShape.new(name: 'MetricsAndOperator')
|
|
314
318
|
MetricsConfiguration = Shapes::StructureShape.new(name: 'MetricsConfiguration')
|
|
315
319
|
MetricsConfigurationList = Shapes::ListShape.new(name: 'MetricsConfigurationList', flattened: true)
|
|
316
320
|
MetricsFilter = Shapes::StructureShape.new(name: 'MetricsFilter')
|
|
317
321
|
MetricsId = Shapes::StringShape.new(name: 'MetricsId')
|
|
322
|
+
MetricsStatus = Shapes::StringShape.new(name: 'MetricsStatus')
|
|
323
|
+
Minutes = Shapes::IntegerShape.new(name: 'Minutes')
|
|
318
324
|
MissingMeta = Shapes::IntegerShape.new(name: 'MissingMeta')
|
|
319
325
|
MultipartUpload = Shapes::StructureShape.new(name: 'MultipartUpload')
|
|
320
326
|
MultipartUploadId = Shapes::StringShape.new(name: 'MultipartUploadId')
|
|
@@ -433,6 +439,9 @@ module Aws::S3
|
|
|
433
439
|
ReplicationRuleStatus = Shapes::StringShape.new(name: 'ReplicationRuleStatus')
|
|
434
440
|
ReplicationRules = Shapes::ListShape.new(name: 'ReplicationRules', flattened: true)
|
|
435
441
|
ReplicationStatus = Shapes::StringShape.new(name: 'ReplicationStatus')
|
|
442
|
+
ReplicationTime = Shapes::StructureShape.new(name: 'ReplicationTime')
|
|
443
|
+
ReplicationTimeStatus = Shapes::StringShape.new(name: 'ReplicationTimeStatus')
|
|
444
|
+
ReplicationTimeValue = Shapes::StructureShape.new(name: 'ReplicationTimeValue')
|
|
436
445
|
RequestCharged = Shapes::StringShape.new(name: 'RequestCharged')
|
|
437
446
|
RequestPayer = Shapes::StringShape.new(name: 'RequestPayer')
|
|
438
447
|
RequestPaymentConfiguration = Shapes::StructureShape.new(name: 'RequestPaymentConfiguration')
|
|
@@ -463,6 +472,7 @@ module Aws::S3
|
|
|
463
472
|
SSEKMSEncryptionContext = Shapes::StringShape.new(name: 'SSEKMSEncryptionContext')
|
|
464
473
|
SSEKMSKeyId = Shapes::StringShape.new(name: 'SSEKMSKeyId')
|
|
465
474
|
SSES3 = Shapes::StructureShape.new(name: 'SSES3')
|
|
475
|
+
ScanRange = Shapes::StructureShape.new(name: 'ScanRange')
|
|
466
476
|
SelectObjectContentEventStream = Shapes::StructureShape.new(name: 'SelectObjectContentEventStream')
|
|
467
477
|
SelectObjectContentOutput = Shapes::StructureShape.new(name: 'SelectObjectContentOutput')
|
|
468
478
|
SelectObjectContentRequest = Shapes::StructureShape.new(name: 'SelectObjectContentRequest')
|
|
@@ -477,6 +487,7 @@ module Aws::S3
|
|
|
477
487
|
SourceSelectionCriteria = Shapes::StructureShape.new(name: 'SourceSelectionCriteria')
|
|
478
488
|
SseKmsEncryptedObjects = Shapes::StructureShape.new(name: 'SseKmsEncryptedObjects')
|
|
479
489
|
SseKmsEncryptedObjectsStatus = Shapes::StringShape.new(name: 'SseKmsEncryptedObjectsStatus')
|
|
490
|
+
Start = Shapes::IntegerShape.new(name: 'Start')
|
|
480
491
|
StartAfter = Shapes::StringShape.new(name: 'StartAfter')
|
|
481
492
|
Stats = Shapes::StructureShape.new(name: 'Stats')
|
|
482
493
|
StatsEvent = Shapes::StructureShape.new(name: 'StatsEvent')
|
|
@@ -889,6 +900,8 @@ module Aws::S3
|
|
|
889
900
|
Destination.add_member(:storage_class, Shapes::ShapeRef.new(shape: StorageClass, location_name: "StorageClass"))
|
|
890
901
|
Destination.add_member(:access_control_translation, Shapes::ShapeRef.new(shape: AccessControlTranslation, location_name: "AccessControlTranslation"))
|
|
891
902
|
Destination.add_member(:encryption_configuration, Shapes::ShapeRef.new(shape: EncryptionConfiguration, location_name: "EncryptionConfiguration"))
|
|
903
|
+
Destination.add_member(:replication_time, Shapes::ShapeRef.new(shape: ReplicationTime, location_name: "ReplicationTime"))
|
|
904
|
+
Destination.add_member(:metrics, Shapes::ShapeRef.new(shape: Metrics, location_name: "Metrics"))
|
|
892
905
|
Destination.struct_class = Types::Destination
|
|
893
906
|
|
|
894
907
|
Encryption.add_member(:encryption_type, Shapes::ShapeRef.new(shape: ServerSideEncryption, required: true, location_name: "EncryptionType"))
|
|
@@ -914,6 +927,9 @@ module Aws::S3
|
|
|
914
927
|
|
|
915
928
|
EventList.member = Shapes::ShapeRef.new(shape: Event)
|
|
916
929
|
|
|
930
|
+
ExistingObjectReplication.add_member(:status, Shapes::ShapeRef.new(shape: ExistingObjectReplicationStatus, required: true, location_name: "Status"))
|
|
931
|
+
ExistingObjectReplication.struct_class = Types::ExistingObjectReplication
|
|
932
|
+
|
|
917
933
|
ExposeHeaders.member = Shapes::ShapeRef.new(shape: ExposeHeader)
|
|
918
934
|
|
|
919
935
|
FilterRule.add_member(:name, Shapes::ShapeRef.new(shape: FilterRuleName, location_name: "Name"))
|
|
@@ -1499,6 +1515,10 @@ module Aws::S3
|
|
|
1499
1515
|
MetadataEntry.add_member(:value, Shapes::ShapeRef.new(shape: MetadataValue, location_name: "Value"))
|
|
1500
1516
|
MetadataEntry.struct_class = Types::MetadataEntry
|
|
1501
1517
|
|
|
1518
|
+
Metrics.add_member(:status, Shapes::ShapeRef.new(shape: MetricsStatus, required: true, location_name: "Status"))
|
|
1519
|
+
Metrics.add_member(:event_threshold, Shapes::ShapeRef.new(shape: ReplicationTimeValue, required: true, location_name: "EventThreshold"))
|
|
1520
|
+
Metrics.struct_class = Types::Metrics
|
|
1521
|
+
|
|
1502
1522
|
MetricsAndOperator.add_member(:prefix, Shapes::ShapeRef.new(shape: Prefix, location_name: "Prefix"))
|
|
1503
1523
|
MetricsAndOperator.add_member(:tags, Shapes::ShapeRef.new(shape: TagSet, location_name: "Tag", metadata: {"flattened"=>true}))
|
|
1504
1524
|
MetricsAndOperator.struct_class = Types::MetricsAndOperator
|
|
@@ -1918,6 +1938,7 @@ module Aws::S3
|
|
|
1918
1938
|
ReplicationRule.add_member(:filter, Shapes::ShapeRef.new(shape: ReplicationRuleFilter, location_name: "Filter"))
|
|
1919
1939
|
ReplicationRule.add_member(:status, Shapes::ShapeRef.new(shape: ReplicationRuleStatus, required: true, location_name: "Status"))
|
|
1920
1940
|
ReplicationRule.add_member(:source_selection_criteria, Shapes::ShapeRef.new(shape: SourceSelectionCriteria, location_name: "SourceSelectionCriteria"))
|
|
1941
|
+
ReplicationRule.add_member(:existing_object_replication, Shapes::ShapeRef.new(shape: ExistingObjectReplication, location_name: "ExistingObjectReplication"))
|
|
1921
1942
|
ReplicationRule.add_member(:destination, Shapes::ShapeRef.new(shape: Destination, required: true, location_name: "Destination"))
|
|
1922
1943
|
ReplicationRule.add_member(:delete_marker_replication, Shapes::ShapeRef.new(shape: DeleteMarkerReplication, location_name: "DeleteMarkerReplication"))
|
|
1923
1944
|
ReplicationRule.struct_class = Types::ReplicationRule
|
|
@@ -1933,6 +1954,13 @@ module Aws::S3
|
|
|
1933
1954
|
|
|
1934
1955
|
ReplicationRules.member = Shapes::ShapeRef.new(shape: ReplicationRule)
|
|
1935
1956
|
|
|
1957
|
+
ReplicationTime.add_member(:status, Shapes::ShapeRef.new(shape: ReplicationTimeStatus, required: true, location_name: "Status"))
|
|
1958
|
+
ReplicationTime.add_member(:time, Shapes::ShapeRef.new(shape: ReplicationTimeValue, required: true, location_name: "Time"))
|
|
1959
|
+
ReplicationTime.struct_class = Types::ReplicationTime
|
|
1960
|
+
|
|
1961
|
+
ReplicationTimeValue.add_member(:minutes, Shapes::ShapeRef.new(shape: Minutes, location_name: "Minutes"))
|
|
1962
|
+
ReplicationTimeValue.struct_class = Types::ReplicationTimeValue
|
|
1963
|
+
|
|
1936
1964
|
RequestPaymentConfiguration.add_member(:payer, Shapes::ShapeRef.new(shape: Payer, required: true, location_name: "Payer"))
|
|
1937
1965
|
RequestPaymentConfiguration.struct_class = Types::RequestPaymentConfiguration
|
|
1938
1966
|
|
|
@@ -1997,6 +2025,10 @@ module Aws::S3
|
|
|
1997
2025
|
|
|
1998
2026
|
SSES3.struct_class = Types::SSES3
|
|
1999
2027
|
|
|
2028
|
+
ScanRange.add_member(:start, Shapes::ShapeRef.new(shape: Start, location_name: "Start"))
|
|
2029
|
+
ScanRange.add_member(:end, Shapes::ShapeRef.new(shape: End, location_name: "End"))
|
|
2030
|
+
ScanRange.struct_class = Types::ScanRange
|
|
2031
|
+
|
|
2000
2032
|
SelectObjectContentEventStream.add_member(:records, Shapes::ShapeRef.new(shape: RecordsEvent, event: true, location_name: "Records"))
|
|
2001
2033
|
SelectObjectContentEventStream.add_member(:stats, Shapes::ShapeRef.new(shape: StatsEvent, event: true, location_name: "Stats"))
|
|
2002
2034
|
SelectObjectContentEventStream.add_member(:progress, Shapes::ShapeRef.new(shape: ProgressEvent, event: true, location_name: "Progress"))
|
|
@@ -2019,6 +2051,7 @@ module Aws::S3
|
|
|
2019
2051
|
SelectObjectContentRequest.add_member(:request_progress, Shapes::ShapeRef.new(shape: RequestProgress, location_name: "RequestProgress"))
|
|
2020
2052
|
SelectObjectContentRequest.add_member(:input_serialization, Shapes::ShapeRef.new(shape: InputSerialization, required: true, location_name: "InputSerialization"))
|
|
2021
2053
|
SelectObjectContentRequest.add_member(:output_serialization, Shapes::ShapeRef.new(shape: OutputSerialization, required: true, location_name: "OutputSerialization"))
|
|
2054
|
+
SelectObjectContentRequest.add_member(:scan_range, Shapes::ShapeRef.new(shape: ScanRange, location_name: "ScanRange"))
|
|
2022
2055
|
SelectObjectContentRequest.struct_class = Types::SelectObjectContentRequest
|
|
2023
2056
|
|
|
2024
2057
|
SelectParameters.add_member(:input_serialization, Shapes::ShapeRef.new(shape: InputSerialization, required: true, location_name: "InputSerialization"))
|
|
@@ -3,6 +3,20 @@ require 'uri'
|
|
|
3
3
|
module Aws
|
|
4
4
|
module S3
|
|
5
5
|
class Bucket
|
|
6
|
+
# Save the old initialize method so that we can call 'super'.
|
|
7
|
+
old_initialize = instance_method(:initialize)
|
|
8
|
+
# Define a new initialize method that extracts out a bucket ARN.
|
|
9
|
+
define_method(:initialize) do |*args|
|
|
10
|
+
old_initialize.bind(self).call(*args)
|
|
11
|
+
bucket_name, region, arn = Plugins::BucketARN.resolve_arn!(
|
|
12
|
+
name,
|
|
13
|
+
client.config.region,
|
|
14
|
+
client.config.s3_use_arn_region
|
|
15
|
+
)
|
|
16
|
+
@name = bucket_name
|
|
17
|
+
@client.config.region = region
|
|
18
|
+
@arn = arn
|
|
19
|
+
end
|
|
6
20
|
|
|
7
21
|
# Deletes all objects and versioned objects from this bucket
|
|
8
22
|
#
|
|
@@ -31,10 +45,10 @@ module Aws
|
|
|
31
45
|
# each attempt.
|
|
32
46
|
#
|
|
33
47
|
# @return [void]
|
|
34
|
-
def delete!
|
|
48
|
+
def delete!(options = {})
|
|
35
49
|
options = {
|
|
36
50
|
initial_wait: 1.3,
|
|
37
|
-
max_attempts: 3
|
|
51
|
+
max_attempts: 3
|
|
38
52
|
}.merge(options)
|
|
39
53
|
|
|
40
54
|
attempts = 0
|
|
@@ -43,20 +57,30 @@ module Aws
|
|
|
43
57
|
delete
|
|
44
58
|
rescue Errors::BucketNotEmpty
|
|
45
59
|
attempts += 1
|
|
46
|
-
if attempts >= options[:max_attempts]
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
retry
|
|
51
|
-
end
|
|
60
|
+
raise if attempts >= options[:max_attempts]
|
|
61
|
+
|
|
62
|
+
Kernel.sleep(options[:initial_wait]**attempts)
|
|
63
|
+
retry
|
|
52
64
|
end
|
|
53
65
|
end
|
|
54
66
|
|
|
55
67
|
# Returns a public URL for this bucket.
|
|
56
68
|
#
|
|
57
|
-
#
|
|
58
|
-
#
|
|
59
|
-
#
|
|
69
|
+
# @example
|
|
70
|
+
#
|
|
71
|
+
# bucket = s3.bucket('bucket-name')
|
|
72
|
+
# bucket.url
|
|
73
|
+
# #=> "https://bucket-name.s3.amazonaws.com"
|
|
74
|
+
#
|
|
75
|
+
# It will also work when provided an Access Point ARN.
|
|
76
|
+
#
|
|
77
|
+
# @example
|
|
78
|
+
#
|
|
79
|
+
# bucket = s3.bucket(
|
|
80
|
+
# 'arn:aws:s3:us-east-1:123456789012:accesspoint:myendpoint'
|
|
81
|
+
# )
|
|
82
|
+
# bucket.url
|
|
83
|
+
# #=> "https://myendpoint-123456789012.s3-accesspoint.us-west-2.amazonaws.com"
|
|
60
84
|
#
|
|
61
85
|
# You can pass `virtual_host: true` to use the bucket name as the
|
|
62
86
|
# host name.
|
|
@@ -73,6 +97,8 @@ module Aws
|
|
|
73
97
|
def url(options = {})
|
|
74
98
|
if options[:virtual_host]
|
|
75
99
|
"http://#{name}"
|
|
100
|
+
elsif @arn
|
|
101
|
+
Plugins::BucketARN.resolve_url!(URI.parse(s3_bucket_url), @arn).to_s
|
|
76
102
|
else
|
|
77
103
|
s3_bucket_url
|
|
78
104
|
end
|
|
@@ -93,7 +119,7 @@ module Aws
|
|
|
93
119
|
client.config.credentials,
|
|
94
120
|
client.config.region,
|
|
95
121
|
name,
|
|
96
|
-
{url: url}.merge(options)
|
|
122
|
+
{ url: url }.merge(options)
|
|
97
123
|
)
|
|
98
124
|
end
|
|
99
125
|
|
|
@@ -101,6 +127,7 @@ module Aws
|
|
|
101
127
|
def load
|
|
102
128
|
@data = client.list_buckets.buckets.find { |b| b.name == name }
|
|
103
129
|
raise "unable to load bucket #{name}" if @data.nil?
|
|
130
|
+
|
|
104
131
|
self
|
|
105
132
|
end
|
|
106
133
|
|
|
@@ -114,12 +141,16 @@ module Aws
|
|
|
114
141
|
url.path += '/' unless url.path[-1] == '/'
|
|
115
142
|
url.path += Seahorse::Util.uri_escape(name)
|
|
116
143
|
end
|
|
144
|
+
if (client.config.region == 'us-east-1') &&
|
|
145
|
+
(client.config.s3_us_east_1_regional_endpoint == 'legacy')
|
|
146
|
+
url.host = Plugins::IADRegionalEndpoint.legacy_host(url.host)
|
|
147
|
+
end
|
|
117
148
|
url.to_s
|
|
118
149
|
end
|
|
119
150
|
|
|
120
151
|
def bucket_as_hostname?(https)
|
|
121
152
|
Plugins::BucketDns.dns_compatible?(name, https) &&
|
|
122
|
-
|
|
153
|
+
!client.config.force_path_style
|
|
123
154
|
end
|
|
124
155
|
|
|
125
156
|
end
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
module Aws
|
|
2
2
|
module S3
|
|
3
3
|
class Object
|
|
4
|
-
|
|
5
4
|
alias size content_length
|
|
6
5
|
|
|
7
6
|
# Copies another object to this object. Use `multipart_copy: true`
|
|
8
7
|
# for large objects. This is required for objects that exceed 5GB.
|
|
9
8
|
#
|
|
10
|
-
# @param [S3::Object, S3::ObjectVersion, S3::ObjectSummary, String, Hash]
|
|
11
|
-
# Where to copy object data from. `source` must be one of the
|
|
9
|
+
# @param [S3::Object, S3::ObjectVersion, S3::ObjectSummary, String, Hash]
|
|
10
|
+
# source Where to copy object data from. `source` must be one of the
|
|
11
|
+
# following:
|
|
12
12
|
#
|
|
13
13
|
# * {Aws::S3::Object}
|
|
14
14
|
# * {Aws::S3::ObjectSummary}
|
|
@@ -103,8 +103,9 @@ module Aws
|
|
|
103
103
|
ObjectCopier.new(self, options).copy_to(target, options)
|
|
104
104
|
end
|
|
105
105
|
|
|
106
|
-
# Copies and deletes the current object. The object will only be
|
|
107
|
-
#
|
|
106
|
+
# Copies and deletes the current object. The object will only be deleted
|
|
107
|
+
# if the copy operation succeeds.
|
|
108
|
+
#
|
|
108
109
|
# @param (see Object#copy_to)
|
|
109
110
|
# @option (see Object#copy_to)
|
|
110
111
|
# @return [void]
|
|
@@ -129,10 +130,7 @@ module Aws
|
|
|
129
130
|
client.config.credentials,
|
|
130
131
|
client.config.region,
|
|
131
132
|
bucket_name,
|
|
132
|
-
{
|
|
133
|
-
key: key,
|
|
134
|
-
url: bucket.url,
|
|
135
|
-
}.merge(options)
|
|
133
|
+
{ key: key, url: bucket.url }.merge(options)
|
|
136
134
|
)
|
|
137
135
|
end
|
|
138
136
|
|
|
@@ -186,10 +184,10 @@ module Aws
|
|
|
186
184
|
#
|
|
187
185
|
def presigned_url(http_method, params = {})
|
|
188
186
|
presigner = Presigner.new(client: client)
|
|
189
|
-
presigner.presigned_url(
|
|
190
|
-
|
|
191
|
-
key: key
|
|
192
|
-
)
|
|
187
|
+
presigner.presigned_url(
|
|
188
|
+
"#{http_method.downcase}_object",
|
|
189
|
+
params.merge(bucket: bucket_name, key: key)
|
|
190
|
+
)
|
|
193
191
|
end
|
|
194
192
|
|
|
195
193
|
# Returns the public (un-signed) URL for this object.
|
|
@@ -199,7 +197,8 @@ module Aws
|
|
|
199
197
|
#
|
|
200
198
|
# To use virtual hosted bucket url (disables https):
|
|
201
199
|
#
|
|
202
|
-
# s3.bucket('my.bucket.com').object('key')
|
|
200
|
+
# s3.bucket('my.bucket.com').object('key')
|
|
201
|
+
# .public_url(virtual_host: true)
|
|
203
202
|
# #=> "http://my.bucket.com/key"
|
|
204
203
|
#
|
|
205
204
|
# @option options [Boolean] :virtual_host (false) When `true`, the bucket
|
|
@@ -216,11 +215,12 @@ module Aws
|
|
|
216
215
|
|
|
217
216
|
# Uploads a stream in a streaming fashion to the current object in S3.
|
|
218
217
|
#
|
|
219
|
-
#
|
|
220
|
-
#
|
|
221
|
-
#
|
|
218
|
+
# Passed chunks automatically split into multipart upload parts and the
|
|
219
|
+
# parts are uploaded in parallel. This allows for streaming uploads that
|
|
220
|
+
# never touch the disk.
|
|
222
221
|
#
|
|
223
|
-
#
|
|
222
|
+
# Note that this is known to have issues in JRuby until jruby-9.1.15.0,
|
|
223
|
+
# so avoid using this with older versions of JRuby.
|
|
224
224
|
#
|
|
225
225
|
# @example Streaming chunks of data
|
|
226
226
|
# obj.upload_stream do |write_stream|
|
|
@@ -235,17 +235,15 @@ module Aws
|
|
|
235
235
|
# IO.copy_stream(STDIN, write_stream)
|
|
236
236
|
# end
|
|
237
237
|
#
|
|
238
|
-
# @option options [Integer] :thread_count
|
|
239
|
-
#
|
|
240
|
-
# Default `:thread_count` is `10`.
|
|
238
|
+
# @option options [Integer] :thread_count (10) The number of parallel
|
|
239
|
+
# multipart uploads
|
|
241
240
|
#
|
|
242
|
-
# @option options [Boolean] :tempfile
|
|
243
|
-
#
|
|
244
|
-
#
|
|
241
|
+
# @option options [Boolean] :tempfile (false) Normally read data is stored
|
|
242
|
+
# in memory when building the parts in order to complete the underlying
|
|
243
|
+
# multipart upload. By passing `:tempfile => true` data read will be
|
|
245
244
|
# temporarily stored on disk reducing the memory footprint vastly.
|
|
246
|
-
# Default `:tempfile` is `false`.
|
|
247
245
|
#
|
|
248
|
-
# @option options [Integer] :part_size
|
|
246
|
+
# @option options [Integer] :part_size (5242880)
|
|
249
247
|
# Define how big each part size but the last should be.
|
|
250
248
|
# Default `:part_size` is `5 * 1024 * 1024`.
|
|
251
249
|
#
|
|
@@ -264,9 +262,12 @@ module Aws
|
|
|
264
262
|
client: client,
|
|
265
263
|
thread_count: uploading_options.delete(:thread_count),
|
|
266
264
|
tempfile: uploading_options.delete(:tempfile),
|
|
267
|
-
part_size: uploading_options.delete(:part_size)
|
|
265
|
+
part_size: uploading_options.delete(:part_size)
|
|
266
|
+
)
|
|
267
|
+
uploader.upload(
|
|
268
|
+
uploading_options.merge(bucket: bucket_name, key: key),
|
|
269
|
+
&block
|
|
268
270
|
)
|
|
269
|
-
uploader.upload(uploading_options.merge(bucket: bucket_name, key: key), &block)
|
|
270
271
|
true
|
|
271
272
|
end
|
|
272
273
|
|
|
@@ -282,15 +283,29 @@ module Aws
|
|
|
282
283
|
# # and the parts are uploaded in parallel
|
|
283
284
|
# obj.upload_file('/path/to/very_large_file')
|
|
284
285
|
#
|
|
285
|
-
#
|
|
286
|
-
#
|
|
287
|
-
#
|
|
288
|
-
#
|
|
286
|
+
# The response of the S3 upload API is yielded if a block given.
|
|
287
|
+
#
|
|
288
|
+
# # API response will have etag value of the file
|
|
289
|
+
# obj.upload_file('/path/to/file') do |response|
|
|
290
|
+
# etag = response.etag
|
|
291
|
+
# end
|
|
292
|
+
#
|
|
293
|
+
# @param [String, Pathname, File, Tempfile] source A file on the local
|
|
294
|
+
# file system that will be uploaded as this object. This can either be
|
|
295
|
+
# a String or Pathname to the file, an open File object, or an open
|
|
296
|
+
# Tempfile object. If you pass an open File or Tempfile object, then
|
|
297
|
+
# you are responsible for closing it after the upload completes. When
|
|
298
|
+
# using an open Tempfile, rewind it before uploading or else the object
|
|
299
|
+
# will be empty.
|
|
289
300
|
#
|
|
290
301
|
# @option options [Integer] :multipart_threshold (15728640) Files larger
|
|
291
302
|
# than `:multipart_threshold` are uploaded using the S3 multipart APIs.
|
|
292
303
|
# Default threshold is 15MB.
|
|
293
304
|
#
|
|
305
|
+
# @option options [Integer] :thread_count (10) The number of parallel
|
|
306
|
+
# multipart uploads. This option is not used if the file is smaller than
|
|
307
|
+
# `:multipart_threshold`.
|
|
308
|
+
#
|
|
294
309
|
# @raise [MultipartUploadError] If an object is being uploaded in
|
|
295
310
|
# parts, and the upload can not be completed, then the upload is
|
|
296
311
|
# aborted and this error is raised. The raised error has a `#errors`
|
|
@@ -304,8 +319,13 @@ module Aws
|
|
|
304
319
|
uploading_options = options.dup
|
|
305
320
|
uploader = FileUploader.new(
|
|
306
321
|
multipart_threshold: uploading_options.delete(:multipart_threshold),
|
|
307
|
-
client: client
|
|
308
|
-
|
|
322
|
+
client: client
|
|
323
|
+
)
|
|
324
|
+
response = uploader.upload(
|
|
325
|
+
source,
|
|
326
|
+
uploading_options.merge(bucket: bucket_name, key: key)
|
|
327
|
+
)
|
|
328
|
+
yield response if block_given?
|
|
309
329
|
true
|
|
310
330
|
end
|
|
311
331
|
|
|
@@ -320,7 +340,7 @@ module Aws
|
|
|
320
340
|
# # and the parts are downloaded in parallel
|
|
321
341
|
# obj.download_file('/path/to/very_large_file')
|
|
322
342
|
#
|
|
323
|
-
# @param [String] destination Where to download the file to
|
|
343
|
+
# @param [String] destination Where to download the file to.
|
|
324
344
|
#
|
|
325
345
|
# @option options [String] mode `auto`, `single_request`, `get_range`
|
|
326
346
|
# `single_request` mode forces only 1 GET request is made in download,
|
|
@@ -328,21 +348,23 @@ module Aws
|
|
|
328
348
|
# customizing each range size in multipart_download,
|
|
329
349
|
# By default, `auto` mode is enabled, which performs multipart_download
|
|
330
350
|
#
|
|
331
|
-
# @option options [String] chunk_size required in get_range mode
|
|
351
|
+
# @option options [String] chunk_size required in get_range mode.
|
|
332
352
|
#
|
|
333
|
-
# @option options [
|
|
334
|
-
#
|
|
353
|
+
# @option options [Integer] thread_count (10) Customize threads used in
|
|
354
|
+
# the multipart download.
|
|
335
355
|
#
|
|
336
|
-
# @option options [String] version_id The object version id used to
|
|
337
|
-
# the object
|
|
356
|
+
# @option options [String] version_id The object version id used to
|
|
357
|
+
# retrieve the object. For more about object versioning, see:
|
|
338
358
|
# https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectVersioning.html
|
|
339
359
|
#
|
|
340
|
-
# @return [Boolean] Returns `true` when the file is downloaded
|
|
341
|
-
#
|
|
360
|
+
# @return [Boolean] Returns `true` when the file is downloaded without
|
|
361
|
+
# any errors.
|
|
342
362
|
def download_file(destination, options = {})
|
|
343
363
|
downloader = FileDownloader.new(client: client)
|
|
344
364
|
downloader.download(
|
|
345
|
-
destination,
|
|
365
|
+
destination,
|
|
366
|
+
options.merge(bucket: bucket_name, key: key)
|
|
367
|
+
)
|
|
346
368
|
true
|
|
347
369
|
end
|
|
348
370
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require 'forwardable'
|
|
2
|
+
|
|
1
3
|
module Aws
|
|
2
4
|
module S3
|
|
3
5
|
|
|
@@ -178,6 +180,8 @@ module Aws
|
|
|
178
180
|
class Client
|
|
179
181
|
|
|
180
182
|
extend Deprecations
|
|
183
|
+
extend Forwardable
|
|
184
|
+
def_delegators :@client, :delete_object, :head_object
|
|
181
185
|
|
|
182
186
|
# Creates a new encryption client. You must provide one of the following
|
|
183
187
|
# options:
|
data/lib/aws-sdk-s3/file_part.rb
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
module Aws
|
|
2
2
|
module S3
|
|
3
3
|
|
|
4
|
-
# A utility class that provides an IO-like interface to a portion of
|
|
5
|
-
#
|
|
4
|
+
# A utility class that provides an IO-like interface to a portion of a file
|
|
5
|
+
# on disk.
|
|
6
6
|
# @api private
|
|
7
7
|
class FilePart
|
|
8
8
|
|
|
9
|
-
# @option options [required,String,Pathname,File,Tempfile] :source
|
|
10
|
-
#
|
|
9
|
+
# @option options [required, String, Pathname, File, Tempfile] :source
|
|
10
|
+
# The file to upload.
|
|
11
|
+
#
|
|
12
|
+
# @option options [required, Integer] :offset The file part will read
|
|
11
13
|
# starting at this byte offset.
|
|
12
|
-
#
|
|
14
|
+
#
|
|
15
|
+
# @option options [required, Integer] :size The maximum number of bytes to
|
|
13
16
|
# read from the `:offset`.
|
|
14
17
|
def initialize(options = {})
|
|
15
18
|
@source = options[:source]
|
|
@@ -19,7 +22,7 @@ module Aws
|
|
|
19
22
|
@file = nil
|
|
20
23
|
end
|
|
21
24
|
|
|
22
|
-
# @return [String,Pathname,File,Tempfile]
|
|
25
|
+
# @return [String, Pathname, File, Tempfile]
|
|
23
26
|
attr_reader :source
|
|
24
27
|
|
|
25
28
|
# @return [Integer]
|
|
@@ -7,13 +7,14 @@ module Aws
|
|
|
7
7
|
|
|
8
8
|
FIFTEEN_MEGABYTES = 15 * 1024 * 1024
|
|
9
9
|
|
|
10
|
+
# @param [Hash] options
|
|
10
11
|
# @option options [Client] :client
|
|
11
|
-
# @option options [Integer] :multipart_threshold
|
|
12
|
-
# `:multipart_threshold` bytes are uploaded using S3 multipart APIs.
|
|
12
|
+
# @option options [Integer] :multipart_threshold (15728640)
|
|
13
13
|
def initialize(options = {})
|
|
14
14
|
@options = options
|
|
15
15
|
@client = options[:client] || Client.new
|
|
16
|
-
@multipart_threshold = options[:multipart_threshold] ||
|
|
16
|
+
@multipart_threshold = options[:multipart_threshold] ||
|
|
17
|
+
FIFTEEN_MEGABYTES
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
# @return [Client]
|
|
@@ -23,9 +24,9 @@ module Aws
|
|
|
23
24
|
# using a {MultipartFileUploader}.
|
|
24
25
|
attr_reader :multipart_threshold
|
|
25
26
|
|
|
26
|
-
# @param [String,Pathname,File,Tempfile] source
|
|
27
|
-
# @option options [required,String] :bucket
|
|
28
|
-
# @option options [required,String] :key
|
|
27
|
+
# @param [String, Pathname, File, Tempfile] source The file to upload.
|
|
28
|
+
# @option options [required, String] :bucket The bucket to upload to.
|
|
29
|
+
# @option options [required, String] :key The key for the object.
|
|
29
30
|
# @return [void]
|
|
30
31
|
def upload(source, options = {})
|
|
31
32
|
if File.size(source) >= multipart_threshold
|
|
@@ -37,12 +38,6 @@ module Aws
|
|
|
37
38
|
|
|
38
39
|
private
|
|
39
40
|
|
|
40
|
-
def put_object(source, options)
|
|
41
|
-
open_file(source) do |file|
|
|
42
|
-
@client.put_object(options.merge(body: file))
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
41
|
def open_file(source)
|
|
47
42
|
if String === source || Pathname === source
|
|
48
43
|
File.open(source, 'rb') { |file| yield(file) }
|
|
@@ -51,6 +46,12 @@ module Aws
|
|
|
51
46
|
end
|
|
52
47
|
end
|
|
53
48
|
|
|
49
|
+
def put_object(source, options)
|
|
50
|
+
open_file(source) do |file|
|
|
51
|
+
@client.put_object(options.merge(body: file))
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
54
55
|
end
|
|
55
56
|
end
|
|
56
57
|
end
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
require 'pathname'
|
|
2
|
-
require 'thread'
|
|
3
2
|
require 'set'
|
|
4
3
|
|
|
5
4
|
module Aws
|
|
@@ -16,14 +15,17 @@ module Aws
|
|
|
16
15
|
THREAD_COUNT = 10
|
|
17
16
|
|
|
18
17
|
# @api private
|
|
19
|
-
CREATE_OPTIONS =
|
|
20
|
-
|
|
18
|
+
CREATE_OPTIONS = Set.new(
|
|
19
|
+
Client.api.operation(:create_multipart_upload).input.shape.member_names
|
|
20
|
+
)
|
|
21
21
|
|
|
22
22
|
# @api private
|
|
23
|
-
UPLOAD_PART_OPTIONS =
|
|
24
|
-
|
|
23
|
+
UPLOAD_PART_OPTIONS = Set.new(
|
|
24
|
+
Client.api.operation(:upload_part).input.shape.member_names
|
|
25
|
+
)
|
|
25
26
|
|
|
26
27
|
# @option options [Client] :client
|
|
28
|
+
# @option options [Integer] :thread_count (THREAD_COUNT)
|
|
27
29
|
def initialize(options = {})
|
|
28
30
|
@client = options[:client] || Client.new
|
|
29
31
|
@thread_count = options[:thread_count] || THREAD_COUNT
|
|
@@ -32,9 +34,9 @@ module Aws
|
|
|
32
34
|
# @return [Client]
|
|
33
35
|
attr_reader :client
|
|
34
36
|
|
|
35
|
-
# @param [String,Pathname,File,Tempfile] source
|
|
36
|
-
# @option options [required,String] :bucket
|
|
37
|
-
# @option options [required,String] :key
|
|
37
|
+
# @param [String, Pathname, File, Tempfile] source The file to upload.
|
|
38
|
+
# @option options [required, String] :bucket The bucket to upload to.
|
|
39
|
+
# @option options [required, String] :key The key for the object.
|
|
38
40
|
# @return [void]
|
|
39
41
|
def upload(source, options = {})
|
|
40
42
|
if File.size(source) < MIN_PART_SIZE
|
|
@@ -57,7 +59,8 @@ module Aws
|
|
|
57
59
|
bucket: options[:bucket],
|
|
58
60
|
key: options[:key],
|
|
59
61
|
upload_id: upload_id,
|
|
60
|
-
multipart_upload: { parts: parts }
|
|
62
|
+
multipart_upload: { parts: parts }
|
|
63
|
+
)
|
|
61
64
|
end
|
|
62
65
|
|
|
63
66
|
def upload_parts(upload_id, source, options)
|
|
@@ -93,7 +96,7 @@ module Aws
|
|
|
93
96
|
part_number = 1
|
|
94
97
|
parts = []
|
|
95
98
|
while offset < size
|
|
96
|
-
parts << upload_part_opts(options).merge(
|
|
99
|
+
parts << upload_part_opts(options).merge(
|
|
97
100
|
upload_id: upload_id,
|
|
98
101
|
part_number: part_number,
|
|
99
102
|
body: FilePart.new(
|
|
@@ -101,7 +104,7 @@ module Aws
|
|
|
101
104
|
offset: offset,
|
|
102
105
|
size: part_size(size, default_part_size, offset)
|
|
103
106
|
)
|
|
104
|
-
|
|
107
|
+
)
|
|
105
108
|
part_number += 1
|
|
106
109
|
offset += default_part_size
|
|
107
110
|
end
|