aws-sdk-s3 1.80.0 → 1.114.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/CHANGELOG.md +903 -0
- data/LICENSE.txt +202 -0
- data/VERSION +1 -0
- data/lib/aws-sdk-s3/arn/access_point_arn.rb +69 -0
- data/lib/aws-sdk-s3/arn/multi_region_access_point_arn.rb +68 -0
- data/lib/aws-sdk-s3/arn/object_lambda_arn.rb +69 -0
- data/lib/aws-sdk-s3/arn/outpost_access_point_arn.rb +74 -0
- data/lib/aws-sdk-s3/bucket.rb +172 -46
- data/lib/aws-sdk-s3/bucket_acl.rb +28 -6
- data/lib/aws-sdk-s3/bucket_cors.rb +29 -9
- data/lib/aws-sdk-s3/bucket_lifecycle.rb +30 -9
- data/lib/aws-sdk-s3/bucket_lifecycle_configuration.rb +31 -9
- data/lib/aws-sdk-s3/bucket_logging.rb +25 -6
- data/lib/aws-sdk-s3/bucket_notification.rb +21 -9
- data/lib/aws-sdk-s3/bucket_policy.rb +27 -7
- data/lib/aws-sdk-s3/bucket_request_payment.rb +27 -8
- data/lib/aws-sdk-s3/bucket_tagging.rb +27 -7
- data/lib/aws-sdk-s3/bucket_versioning.rb +70 -10
- data/lib/aws-sdk-s3/bucket_website.rb +27 -7
- data/lib/aws-sdk-s3/client.rb +4415 -1650
- data/lib/aws-sdk-s3/client_api.rb +661 -41
- data/lib/aws-sdk-s3/customizations/bucket.rb +15 -7
- data/lib/aws-sdk-s3/customizations/object.rb +120 -21
- data/lib/aws-sdk-s3/customizations.rb +1 -1
- data/lib/aws-sdk-s3/encryption/client.rb +1 -1
- data/lib/aws-sdk-s3/encryption/decrypt_handler.rb +0 -4
- data/lib/aws-sdk-s3/encryptionV2/client.rb +1 -1
- data/lib/aws-sdk-s3/encryptionV2/decrypt_handler.rb +0 -4
- data/lib/aws-sdk-s3/encryptionV2/default_cipher_provider.rb +3 -3
- data/lib/aws-sdk-s3/encryptionV2/encrypt_handler.rb +0 -4
- data/lib/aws-sdk-s3/errors.rb +22 -1
- data/lib/aws-sdk-s3/event_streams.rb +1 -1
- data/lib/aws-sdk-s3/file_downloader.rb +7 -2
- data/lib/aws-sdk-s3/file_uploader.rb +9 -4
- data/lib/aws-sdk-s3/legacy_signer.rb +15 -25
- data/lib/aws-sdk-s3/multipart_file_uploader.rb +26 -7
- data/lib/aws-sdk-s3/multipart_upload.rb +133 -19
- data/lib/aws-sdk-s3/multipart_upload_part.rb +152 -23
- data/lib/aws-sdk-s3/object.rb +501 -126
- data/lib/aws-sdk-s3/object_acl.rb +39 -9
- data/lib/aws-sdk-s3/object_summary.rb +330 -110
- data/lib/aws-sdk-s3/object_version.rb +80 -49
- data/lib/aws-sdk-s3/plugins/accelerate.rb +13 -4
- data/lib/aws-sdk-s3/plugins/arn.rb +254 -0
- data/lib/aws-sdk-s3/plugins/bucket_dns.rb +1 -3
- data/lib/aws-sdk-s3/plugins/bucket_name_restrictions.rb +1 -1
- data/lib/aws-sdk-s3/plugins/dualstack.rb +33 -32
- data/lib/aws-sdk-s3/plugins/expect_100_continue.rb +2 -1
- data/lib/aws-sdk-s3/plugins/get_bucket_location_fix.rb +1 -1
- data/lib/aws-sdk-s3/plugins/iad_regional_endpoint.rb +18 -7
- data/lib/aws-sdk-s3/plugins/md5s.rb +5 -3
- data/lib/aws-sdk-s3/plugins/object_lambda_endpoint.rb +25 -0
- data/lib/aws-sdk-s3/plugins/s3_signer.rb +66 -17
- data/lib/aws-sdk-s3/plugins/skip_whole_multipart_get_checksums.rb +31 -0
- data/lib/aws-sdk-s3/plugins/streaming_retry.rb +23 -2
- data/lib/aws-sdk-s3/presigned_post.rb +38 -19
- data/lib/aws-sdk-s3/presigner.rb +34 -17
- data/lib/aws-sdk-s3/resource.rb +23 -3
- data/lib/aws-sdk-s3/types.rb +4792 -1089
- data/lib/aws-sdk-s3/waiters.rb +1 -1
- data/lib/aws-sdk-s3.rb +3 -2
- metadata +21 -13
- data/lib/aws-sdk-s3/plugins/bucket_arn.rb +0 -212
@@ -3,7 +3,7 @@
|
|
3
3
|
# WARNING ABOUT GENERATED CODE
|
4
4
|
#
|
5
5
|
# This file is generated. See the contributing guide for more information:
|
6
|
-
# https://github.com/aws/aws-sdk-ruby/blob/
|
6
|
+
# https://github.com/aws/aws-sdk-ruby/blob/version-3/CONTRIBUTING.md
|
7
7
|
#
|
8
8
|
# WARNING ABOUT GENERATED CODE
|
9
9
|
|
@@ -56,6 +56,12 @@ module Aws::S3
|
|
56
56
|
data[:etag]
|
57
57
|
end
|
58
58
|
|
59
|
+
# The algorithm that was used to create a checksum of the object.
|
60
|
+
# @return [Array<String>]
|
61
|
+
def checksum_algorithm
|
62
|
+
data[:checksum_algorithm]
|
63
|
+
end
|
64
|
+
|
59
65
|
# Size in bytes of the object.
|
60
66
|
# @return [Integer]
|
61
67
|
def size
|
@@ -245,20 +251,21 @@ module Aws::S3
|
|
245
251
|
# @option options [String] :request_payer
|
246
252
|
# Confirms that the requester knows that they will be charged for the
|
247
253
|
# request. Bucket owners need not specify this parameter in their
|
248
|
-
# requests. For information about downloading objects from
|
249
|
-
#
|
250
|
-
# in the *Amazon S3
|
254
|
+
# requests. For information about downloading objects from Requester
|
255
|
+
# Pays buckets, see [Downloading Objects in Requester Pays Buckets][1]
|
256
|
+
# in the *Amazon S3 User Guide*.
|
251
257
|
#
|
252
258
|
#
|
253
259
|
#
|
254
260
|
# [1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
|
255
261
|
# @option options [Boolean] :bypass_governance_retention
|
256
262
|
# Indicates whether S3 Object Lock should bypass Governance-mode
|
257
|
-
# restrictions to process this operation.
|
263
|
+
# restrictions to process this operation. To use this header, you must
|
264
|
+
# have the `s3:BypassGovernanceRetention` permission.
|
258
265
|
# @option options [String] :expected_bucket_owner
|
259
|
-
# The account
|
260
|
-
# a different account, the request
|
261
|
-
#
|
266
|
+
# The account ID of the expected bucket owner. If the bucket is owned by
|
267
|
+
# a different account, the request fails with the HTTP status code `403
|
268
|
+
# Forbidden` (access denied).
|
262
269
|
# @return [Types::DeleteObjectOutput]
|
263
270
|
def delete(options = {})
|
264
271
|
options = options.merge(
|
@@ -290,20 +297,21 @@ module Aws::S3
|
|
290
297
|
# request_payer: "requester", # accepts requester
|
291
298
|
# part_number: 1,
|
292
299
|
# expected_bucket_owner: "AccountId",
|
300
|
+
# checksum_mode: "ENABLED", # accepts ENABLED
|
293
301
|
# })
|
294
302
|
# @param [Hash] options ({})
|
295
303
|
# @option options [String] :if_match
|
296
304
|
# Return the object only if its entity tag (ETag) is the same as the one
|
297
|
-
# specified
|
305
|
+
# specified; otherwise, return a 412 (precondition failed) error.
|
298
306
|
# @option options [Time,DateTime,Date,Integer,String] :if_modified_since
|
299
307
|
# Return the object only if it has been modified since the specified
|
300
|
-
# time
|
308
|
+
# time; otherwise, return a 304 (not modified) error.
|
301
309
|
# @option options [String] :if_none_match
|
302
310
|
# Return the object only if its entity tag (ETag) is different from the
|
303
|
-
# one specified
|
311
|
+
# one specified; otherwise, return a 304 (not modified) error.
|
304
312
|
# @option options [Time,DateTime,Date,Integer,String] :if_unmodified_since
|
305
313
|
# Return the object only if it has not been modified since the specified
|
306
|
-
# time
|
314
|
+
# time; otherwise, return a 412 (precondition failed) error.
|
307
315
|
# @option options [String] :range
|
308
316
|
# Downloads the specified range bytes of an object. For more information
|
309
317
|
# about the HTTP Range header, see
|
@@ -330,13 +338,13 @@ module Aws::S3
|
|
330
338
|
# @option options [Time,DateTime,Date,Integer,String] :response_expires
|
331
339
|
# Sets the `Expires` header of the response.
|
332
340
|
# @option options [String] :sse_customer_algorithm
|
333
|
-
# Specifies the algorithm to use to when
|
341
|
+
# Specifies the algorithm to use to when decrypting the object (for
|
334
342
|
# example, AES256).
|
335
343
|
# @option options [String] :sse_customer_key
|
336
|
-
# Specifies the customer-provided encryption key for Amazon S3 to
|
337
|
-
#
|
338
|
-
#
|
339
|
-
# be appropriate for use with the algorithm specified in the
|
344
|
+
# Specifies the customer-provided encryption key for Amazon S3 used to
|
345
|
+
# encrypt the data. This value is used to decrypt the object when
|
346
|
+
# recovering it and must match the one used when storing the data. The
|
347
|
+
# key must be appropriate for use with the algorithm specified in the
|
340
348
|
# `x-amz-server-side-encryption-customer-algorithm` header.
|
341
349
|
# @option options [String] :sse_customer_key_md5
|
342
350
|
# Specifies the 128-bit MD5 digest of the encryption key according to
|
@@ -345,9 +353,9 @@ module Aws::S3
|
|
345
353
|
# @option options [String] :request_payer
|
346
354
|
# Confirms that the requester knows that they will be charged for the
|
347
355
|
# request. Bucket owners need not specify this parameter in their
|
348
|
-
# requests. For information about downloading objects from
|
349
|
-
#
|
350
|
-
# in the *Amazon S3
|
356
|
+
# requests. For information about downloading objects from Requester
|
357
|
+
# Pays buckets, see [Downloading Objects in Requester Pays Buckets][1]
|
358
|
+
# in the *Amazon S3 User Guide*.
|
351
359
|
#
|
352
360
|
#
|
353
361
|
#
|
@@ -358,9 +366,11 @@ module Aws::S3
|
|
358
366
|
# for the part specified. Useful for downloading just a part of an
|
359
367
|
# object.
|
360
368
|
# @option options [String] :expected_bucket_owner
|
361
|
-
# The account
|
362
|
-
# a different account, the request
|
363
|
-
#
|
369
|
+
# The account ID of the expected bucket owner. If the bucket is owned by
|
370
|
+
# a different account, the request fails with the HTTP status code `403
|
371
|
+
# Forbidden` (access denied).
|
372
|
+
# @option options [String] :checksum_mode
|
373
|
+
# To retrieve the checksum, this mode must be enabled.
|
364
374
|
# @return [Types::GetObjectOutput]
|
365
375
|
def get(options = {}, &block)
|
366
376
|
options = options.merge(
|
@@ -386,29 +396,24 @@ module Aws::S3
|
|
386
396
|
# request_payer: "requester", # accepts requester
|
387
397
|
# part_number: 1,
|
388
398
|
# expected_bucket_owner: "AccountId",
|
399
|
+
# checksum_mode: "ENABLED", # accepts ENABLED
|
389
400
|
# })
|
390
401
|
# @param [Hash] options ({})
|
391
402
|
# @option options [String] :if_match
|
392
403
|
# Return the object only if its entity tag (ETag) is the same as the one
|
393
|
-
# specified
|
404
|
+
# specified; otherwise, return a 412 (precondition failed) error.
|
394
405
|
# @option options [Time,DateTime,Date,Integer,String] :if_modified_since
|
395
406
|
# Return the object only if it has been modified since the specified
|
396
|
-
# time
|
407
|
+
# time; otherwise, return a 304 (not modified) error.
|
397
408
|
# @option options [String] :if_none_match
|
398
409
|
# Return the object only if its entity tag (ETag) is different from the
|
399
|
-
# one specified
|
410
|
+
# one specified; otherwise, return a 304 (not modified) error.
|
400
411
|
# @option options [Time,DateTime,Date,Integer,String] :if_unmodified_since
|
401
412
|
# Return the object only if it has not been modified since the specified
|
402
|
-
# time
|
413
|
+
# time; otherwise, return a 412 (precondition failed) error.
|
403
414
|
# @option options [String] :range
|
404
|
-
#
|
405
|
-
#
|
406
|
-
# [http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35]().
|
407
|
-
#
|
408
|
-
# <note markdown="1"> Amazon S3 doesn't support retrieving multiple ranges of data per
|
409
|
-
# `GET` request.
|
410
|
-
#
|
411
|
-
# </note>
|
415
|
+
# Because `HeadObject` returns only the metadata for an object, this
|
416
|
+
# parameter has no effect.
|
412
417
|
# @option options [String] :sse_customer_algorithm
|
413
418
|
# Specifies the algorithm to use to when encrypting the object (for
|
414
419
|
# example, AES256).
|
@@ -425,9 +430,9 @@ module Aws::S3
|
|
425
430
|
# @option options [String] :request_payer
|
426
431
|
# Confirms that the requester knows that they will be charged for the
|
427
432
|
# request. Bucket owners need not specify this parameter in their
|
428
|
-
# requests. For information about downloading objects from
|
429
|
-
#
|
430
|
-
# in the *Amazon S3
|
433
|
+
# requests. For information about downloading objects from Requester
|
434
|
+
# Pays buckets, see [Downloading Objects in Requester Pays Buckets][1]
|
435
|
+
# in the *Amazon S3 User Guide*.
|
431
436
|
#
|
432
437
|
#
|
433
438
|
#
|
@@ -438,9 +443,16 @@ module Aws::S3
|
|
438
443
|
# for the part specified. Useful querying about the size of the part and
|
439
444
|
# the number of parts in this object.
|
440
445
|
# @option options [String] :expected_bucket_owner
|
441
|
-
# The account
|
442
|
-
# a different account, the request
|
443
|
-
#
|
446
|
+
# The account ID of the expected bucket owner. If the bucket is owned by
|
447
|
+
# a different account, the request fails with the HTTP status code `403
|
448
|
+
# Forbidden` (access denied).
|
449
|
+
# @option options [String] :checksum_mode
|
450
|
+
# To retrieve the checksum, this parameter must be enabled.
|
451
|
+
#
|
452
|
+
# In addition, if you enable `ChecksumMode` and the object is encrypted
|
453
|
+
# with Amazon Web Services Key Management Service (Amazon Web Services
|
454
|
+
# KMS), you must have permission to use the `kms:Decrypt` action for the
|
455
|
+
# request to succeed.
|
444
456
|
# @return [Types::HeadObjectOutput]
|
445
457
|
def head(options = {})
|
446
458
|
options = options.merge(
|
@@ -520,6 +532,7 @@ module Aws::S3
|
|
520
532
|
# request_payer: "requester", # accepts requester
|
521
533
|
# bypass_governance_retention: false,
|
522
534
|
# expected_bucket_owner: "AccountId",
|
535
|
+
# checksum_algorithm: "CRC32", # accepts CRC32, CRC32C, SHA1, SHA256
|
523
536
|
# })
|
524
537
|
# @param options ({})
|
525
538
|
# @option options [String] :mfa
|
@@ -530,21 +543,39 @@ module Aws::S3
|
|
530
543
|
# @option options [String] :request_payer
|
531
544
|
# Confirms that the requester knows that they will be charged for the
|
532
545
|
# request. Bucket owners need not specify this parameter in their
|
533
|
-
# requests. For information about downloading objects from
|
534
|
-
#
|
535
|
-
# in the *Amazon S3
|
546
|
+
# requests. For information about downloading objects from Requester
|
547
|
+
# Pays buckets, see [Downloading Objects in Requester Pays Buckets][1]
|
548
|
+
# in the *Amazon S3 User Guide*.
|
536
549
|
#
|
537
550
|
#
|
538
551
|
#
|
539
552
|
# [1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
|
540
553
|
# @option options [Boolean] :bypass_governance_retention
|
541
554
|
# Specifies whether you want to delete this object even if it has a
|
542
|
-
# Governance-type Object Lock in place.
|
543
|
-
#
|
555
|
+
# Governance-type Object Lock in place. To use this header, you must
|
556
|
+
# have the `s3:BypassGovernanceRetention` permission.
|
544
557
|
# @option options [String] :expected_bucket_owner
|
545
|
-
# The account
|
546
|
-
# a different account, the request
|
547
|
-
#
|
558
|
+
# The account ID of the expected bucket owner. If the bucket is owned by
|
559
|
+
# a different account, the request fails with the HTTP status code `403
|
560
|
+
# Forbidden` (access denied).
|
561
|
+
# @option options [String] :checksum_algorithm
|
562
|
+
# Indicates the algorithm used to create the checksum for the object
|
563
|
+
# when using the SDK. This header will not provide any additional
|
564
|
+
# functionality if not using the SDK. When sending this header, there
|
565
|
+
# must be a corresponding `x-amz-checksum` or `x-amz-trailer` header
|
566
|
+
# sent. Otherwise, Amazon S3 fails the request with the HTTP status code
|
567
|
+
# `400 Bad Request`. For more information, see [Checking object
|
568
|
+
# integrity][1] in the *Amazon S3 User Guide*.
|
569
|
+
#
|
570
|
+
# If you provide an individual checksum, Amazon S3 ignores any provided
|
571
|
+
# `ChecksumAlgorithm` parameter.
|
572
|
+
#
|
573
|
+
# This checksum algorithm must be the same for all parts and it match
|
574
|
+
# the checksum value supplied in the `CreateMultipartUpload` request.
|
575
|
+
#
|
576
|
+
#
|
577
|
+
#
|
578
|
+
# [1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html
|
548
579
|
# @return [void]
|
549
580
|
def batch_delete!(options = {})
|
550
581
|
batch_enum.each do |batch|
|
@@ -29,7 +29,7 @@ each bucket. [Go here for more information](http://docs.aws.amazon.com/AmazonS3/
|
|
29
29
|
OptionHandler, step: :initialize, operations: operations
|
30
30
|
)
|
31
31
|
handlers.add(
|
32
|
-
AccelerateHandler, step: :build, priority:
|
32
|
+
AccelerateHandler, step: :build, priority: 11, operations: operations
|
33
33
|
)
|
34
34
|
end
|
35
35
|
|
@@ -40,8 +40,17 @@ each bucket. [Go here for more information](http://docs.aws.amazon.com/AmazonS3/
|
|
40
40
|
if context.params.is_a?(Hash)
|
41
41
|
accelerate = context.params.delete(:use_accelerate_endpoint)
|
42
42
|
end
|
43
|
-
if accelerate.nil?
|
44
|
-
|
43
|
+
accelerate = context.config.use_accelerate_endpoint if accelerate.nil?
|
44
|
+
# Raise if :endpoint and accelerate are both provided
|
45
|
+
if accelerate && !context.config.regional_endpoint
|
46
|
+
raise ArgumentError,
|
47
|
+
'Cannot use both :use_accelerate_endpoint and :endpoint'
|
48
|
+
end
|
49
|
+
# Raise if :use_fips_endpoint and accelerate are both provided
|
50
|
+
if accelerate && context.config.use_fips_endpoint
|
51
|
+
raise ArgumentError,
|
52
|
+
'Cannot use both :use_accelerate_endpoint and '\
|
53
|
+
':use_fips_endpoint'
|
45
54
|
end
|
46
55
|
context[:use_accelerate_endpoint] = accelerate
|
47
56
|
@handler.call(context)
|
@@ -51,7 +60,7 @@ each bucket. [Go here for more information](http://docs.aws.amazon.com/AmazonS3/
|
|
51
60
|
# @api private
|
52
61
|
class AccelerateHandler < Seahorse::Client::Handler
|
53
62
|
def call(context)
|
54
|
-
if context[:use_accelerate_endpoint]
|
63
|
+
if context.config.regional_endpoint && context[:use_accelerate_endpoint]
|
55
64
|
dualstack = !!context[:use_dualstack_endpoint]
|
56
65
|
use_accelerate_endpoint(context, dualstack)
|
57
66
|
end
|
@@ -0,0 +1,254 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../arn/access_point_arn'
|
4
|
+
require_relative '../arn/object_lambda_arn'
|
5
|
+
require_relative '../arn/outpost_access_point_arn'
|
6
|
+
require_relative '../arn/multi_region_access_point_arn'
|
7
|
+
|
8
|
+
module Aws
|
9
|
+
module S3
|
10
|
+
module Plugins
|
11
|
+
# When an accesspoint ARN is provided for :bucket in S3 operations, this
|
12
|
+
# plugin resolves the request endpoint from the ARN when possible.
|
13
|
+
# @api private
|
14
|
+
class ARN < Seahorse::Client::Plugin
|
15
|
+
option(
|
16
|
+
:s3_use_arn_region,
|
17
|
+
default: true,
|
18
|
+
doc_type: 'Boolean',
|
19
|
+
docstring: <<-DOCS) do |cfg|
|
20
|
+
For S3 ARNs passed into the `:bucket` parameter, this option will
|
21
|
+
use the region in the ARN, allowing for cross-region requests to
|
22
|
+
be made. Set to `false` to use the client's region instead.
|
23
|
+
DOCS
|
24
|
+
resolve_s3_use_arn_region(cfg)
|
25
|
+
end
|
26
|
+
|
27
|
+
option(
|
28
|
+
:s3_disable_multiregion_access_points,
|
29
|
+
default: false,
|
30
|
+
doc_type: 'Boolean',
|
31
|
+
docstring: <<-DOCS) do |cfg|
|
32
|
+
When set to `false` this will option will raise errors when multi-region
|
33
|
+
access point ARNs are used. Multi-region access points can potentially
|
34
|
+
result in cross region requests.
|
35
|
+
DOCS
|
36
|
+
resolve_s3_disable_multiregion_access_points(cfg)
|
37
|
+
end
|
38
|
+
|
39
|
+
# param validator is validate:50
|
40
|
+
# endpoint is build:90 (populates the URI for the first time)
|
41
|
+
# endpoint pattern is build:10
|
42
|
+
def add_handlers(handlers, _config)
|
43
|
+
handlers.add(ARNHandler, step: :validate, priority: 75)
|
44
|
+
handlers.add(UrlHandler)
|
45
|
+
end
|
46
|
+
|
47
|
+
# After extracting out any ARN input, resolve a new URL with it.
|
48
|
+
class UrlHandler < Seahorse::Client::Handler
|
49
|
+
def call(context)
|
50
|
+
if context.metadata[:s3_arn]
|
51
|
+
ARN.resolve_url!(
|
52
|
+
context.http_request.endpoint,
|
53
|
+
context.metadata[:s3_arn][:arn],
|
54
|
+
context.metadata[:s3_arn][:resolved_region],
|
55
|
+
context.metadata[:s3_arn][:fips],
|
56
|
+
context.metadata[:s3_arn][:dualstack],
|
57
|
+
# if regional_endpoint is false, a custom endpoint was provided
|
58
|
+
# in this case, we want to prefix the endpoint using the ARN
|
59
|
+
!context.config.regional_endpoint
|
60
|
+
)
|
61
|
+
end
|
62
|
+
@handler.call(context)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# This plugin will extract out any ARN input and set context for other
|
67
|
+
# plugins to use without having to translate the ARN again.
|
68
|
+
class ARNHandler < Seahorse::Client::Handler
|
69
|
+
def call(context)
|
70
|
+
bucket_member = _bucket_member(context.operation.input.shape)
|
71
|
+
if bucket_member && (bucket = context.params[bucket_member])
|
72
|
+
resolved_region, arn = ARN.resolve_arn!(
|
73
|
+
bucket,
|
74
|
+
context.config.region,
|
75
|
+
context.config.s3_use_arn_region
|
76
|
+
)
|
77
|
+
if arn
|
78
|
+
validate_config!(context, arn)
|
79
|
+
|
80
|
+
context.metadata[:s3_arn] = {
|
81
|
+
arn: arn,
|
82
|
+
resolved_region: resolved_region,
|
83
|
+
fips: context.config.use_fips_endpoint,
|
84
|
+
dualstack: extract_dualstack_config!(context)
|
85
|
+
}
|
86
|
+
end
|
87
|
+
end
|
88
|
+
@handler.call(context)
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def _bucket_member(input)
|
94
|
+
input.members.each do |member, ref|
|
95
|
+
return member if ref.shape.name == 'BucketName'
|
96
|
+
end
|
97
|
+
nil
|
98
|
+
end
|
99
|
+
|
100
|
+
# other plugins use dualstack so disable it when we're done
|
101
|
+
def extract_dualstack_config!(context)
|
102
|
+
dualstack = context[:use_dualstack_endpoint]
|
103
|
+
context[:use_dualstack_endpoint] = false if dualstack
|
104
|
+
dualstack
|
105
|
+
end
|
106
|
+
|
107
|
+
def validate_config!(context, arn)
|
108
|
+
if context.config.force_path_style
|
109
|
+
raise ArgumentError,
|
110
|
+
'Cannot provide an Access Point ARN when '\
|
111
|
+
'`:force_path_style` is set to true.'
|
112
|
+
end
|
113
|
+
|
114
|
+
if context.config.use_accelerate_endpoint
|
115
|
+
raise ArgumentError,
|
116
|
+
'Cannot provide an Access Point ARN when '\
|
117
|
+
'`:use_accelerate_endpoint` is set to true.'
|
118
|
+
end
|
119
|
+
|
120
|
+
if !arn.support_dualstack? && context[:use_dualstack_endpoint]
|
121
|
+
raise ArgumentError,
|
122
|
+
'Cannot provide an Outpost Access Point, Object Lambda, '\
|
123
|
+
'or Multi-region Access Point ARN'\
|
124
|
+
' when `:use_dualstack_endpoint` is set to true.'
|
125
|
+
end
|
126
|
+
|
127
|
+
if arn.region.empty? && context.config.s3_disable_multiregion_access_points
|
128
|
+
raise ArgumentError,
|
129
|
+
'Cannot provide a Multi-region Access Point ARN with '\
|
130
|
+
'`:s3_disable_multiregion_access_points` set to true'
|
131
|
+
end
|
132
|
+
|
133
|
+
if context.config.use_fips_endpoint && !arn.support_fips?
|
134
|
+
raise ArgumentError,
|
135
|
+
'FIPS client regions are not supported for this type '\
|
136
|
+
'of ARN.'
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
class << self
|
142
|
+
# @api private
|
143
|
+
def resolve_arn!(member_value, region, use_arn_region)
|
144
|
+
if Aws::ARNParser.arn?(member_value)
|
145
|
+
arn = Aws::ARNParser.parse(member_value)
|
146
|
+
s3_arn = resolve_arn_type!(arn)
|
147
|
+
s3_arn.validate_arn!
|
148
|
+
validate_region_config!(s3_arn, region, use_arn_region)
|
149
|
+
region = s3_arn.region if use_arn_region
|
150
|
+
[region, s3_arn]
|
151
|
+
else
|
152
|
+
[region]
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
# @api private
|
157
|
+
def resolve_url!(url, arn, region, fips = false, dualstack = false, has_custom_endpoint = false)
|
158
|
+
custom_endpoint = url.host if has_custom_endpoint
|
159
|
+
url.host = arn.host_url(region, fips, dualstack, custom_endpoint)
|
160
|
+
url.path = url_path(url.path, arn)
|
161
|
+
url
|
162
|
+
end
|
163
|
+
|
164
|
+
private
|
165
|
+
|
166
|
+
def resolve_arn_type!(arn)
|
167
|
+
case arn.service
|
168
|
+
when 's3'
|
169
|
+
arn.region.empty? ?
|
170
|
+
Aws::S3::MultiRegionAccessPointARN.new(arn.to_h) :
|
171
|
+
Aws::S3::AccessPointARN.new(arn.to_h)
|
172
|
+
when 's3-outposts'
|
173
|
+
Aws::S3::OutpostAccessPointARN.new(arn.to_h)
|
174
|
+
when 's3-object-lambda'
|
175
|
+
Aws::S3::ObjectLambdaARN.new(arn.to_h)
|
176
|
+
else
|
177
|
+
raise ArgumentError,
|
178
|
+
'Only Access Point, Outposts, and Object Lambdas ARNs '\
|
179
|
+
'are currently supported.'
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def resolve_s3_use_arn_region(cfg)
|
184
|
+
value = ENV['AWS_S3_USE_ARN_REGION'] ||
|
185
|
+
Aws.shared_config.s3_use_arn_region(profile: cfg.profile) ||
|
186
|
+
'true'
|
187
|
+
value = Aws::Util.str_2_bool(value)
|
188
|
+
# Raise if provided value is not true or false
|
189
|
+
if value.nil?
|
190
|
+
raise ArgumentError,
|
191
|
+
'Must provide either `true` or `false` for the '\
|
192
|
+
'`s3_use_arn_region` profile option or for '\
|
193
|
+
"ENV['AWS_S3_USE_ARN_REGION']."
|
194
|
+
end
|
195
|
+
value
|
196
|
+
end
|
197
|
+
|
198
|
+
def resolve_s3_disable_multiregion_access_points(cfg)
|
199
|
+
value = ENV['AWS_S3_DISABLE_MULTIREGION_ACCESS_POINTS'] ||
|
200
|
+
Aws.shared_config.s3_disable_multiregion_access_points(profile: cfg.profile) ||
|
201
|
+
'false'
|
202
|
+
value = Aws::Util.str_2_bool(value)
|
203
|
+
# Raise if provided value is not true or false
|
204
|
+
if value.nil?
|
205
|
+
raise ArgumentError,
|
206
|
+
'Must provide either `true` or `false` for '\
|
207
|
+
's3_use_arn_region profile option or for '\
|
208
|
+
"ENV['AWS_S3_USE_ARN_REGION']"
|
209
|
+
end
|
210
|
+
value
|
211
|
+
end
|
212
|
+
|
213
|
+
# Remove ARN from the path because we've already set the new host
|
214
|
+
def url_path(path, arn)
|
215
|
+
path = path.sub("/#{Seahorse::Util.uri_escape(arn.to_s)}", '')
|
216
|
+
.sub("/#{arn}", '')
|
217
|
+
"/#{path}" unless path =~ /^\//
|
218
|
+
path
|
219
|
+
end
|
220
|
+
|
221
|
+
def validate_region_config!(arn, region, use_arn_region)
|
222
|
+
if ['s3-external-1', 'aws-global'].include?(region)
|
223
|
+
# These "regions" are not regional endpoints
|
224
|
+
unless use_arn_region
|
225
|
+
raise Aws::Errors::InvalidARNRegionError,
|
226
|
+
'Configured client region is not a regional endpoint.'
|
227
|
+
end
|
228
|
+
# These "regions" are in the AWS partition
|
229
|
+
# Cannot use ARN region unless it's the same partition
|
230
|
+
unless arn.partition == 'aws'
|
231
|
+
raise Aws::Errors::InvalidARNPartitionError
|
232
|
+
end
|
233
|
+
else
|
234
|
+
# use_arn_region does not apply to MRAP (global) arns
|
235
|
+
unless arn.region.empty?
|
236
|
+
# Raise if the ARN and client regions are in different partitions
|
237
|
+
if use_arn_region &&
|
238
|
+
!Aws::Partitions.partition(arn.partition).region?(region)
|
239
|
+
raise Aws::Errors::InvalidARNPartitionError
|
240
|
+
end
|
241
|
+
|
242
|
+
# Raise if regions mismatch
|
243
|
+
# Either when it's a fips client or not using the ARN region
|
244
|
+
if !use_arn_region && region != arn.region
|
245
|
+
raise Aws::Errors::InvalidARNRegionError
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
@@ -24,7 +24,7 @@ request URI and never moved to the host as a sub-domain.
|
|
24
24
|
DOCS
|
25
25
|
|
26
26
|
def add_handlers(handlers, config)
|
27
|
-
handlers.add(Handler) unless config.force_path_style
|
27
|
+
handlers.add(Handler, priority: 48) unless config.force_path_style
|
28
28
|
end
|
29
29
|
|
30
30
|
# @api private
|
@@ -73,8 +73,6 @@ request URI and never moved to the host as a sub-domain.
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
|
-
# Checks for a valid RFC-3986 host name
|
77
|
-
# @see https://tools.ietf.org/html/rfc3986#section-3.2.2
|
78
76
|
# @param [String] bucket_name
|
79
77
|
# @return [Boolean]
|
80
78
|
def valid_subdomain?(bucket_name)
|
@@ -13,7 +13,7 @@ module Aws
|
|
13
13
|
def call(context)
|
14
14
|
bucket_member = _bucket_member(context.operation.input.shape)
|
15
15
|
if bucket_member && (bucket = context.params[bucket_member])
|
16
|
-
|
16
|
+
_resolved_region, arn = ARN.resolve_arn!(
|
17
17
|
bucket,
|
18
18
|
context.config.region,
|
19
19
|
context.config.s3_use_arn_region
|
@@ -5,27 +5,24 @@ module Aws
|
|
5
5
|
module Plugins
|
6
6
|
# @api private
|
7
7
|
class Dualstack < Seahorse::Client::Plugin
|
8
|
-
|
9
|
-
option(:use_dualstack_endpoint,
|
10
|
-
default: false,
|
11
|
-
doc_type: 'Boolean',
|
12
|
-
docstring: <<-DOCS)
|
13
|
-
When set to `true`, IPv6-compatible bucket endpoints will be used
|
14
|
-
for all operations.
|
15
|
-
DOCS
|
16
|
-
|
17
8
|
def add_handlers(handlers, config)
|
18
9
|
handlers.add(OptionHandler, step: :initialize)
|
19
|
-
handlers.add(DualstackHandler, step: :build, priority:
|
10
|
+
handlers.add(DualstackHandler, step: :build, priority: 49)
|
20
11
|
end
|
21
12
|
|
22
13
|
# @api private
|
23
14
|
class OptionHandler < Seahorse::Client::Handler
|
24
15
|
def call(context)
|
16
|
+
# Support client configuration and per-operation configuration
|
25
17
|
if context.params.is_a?(Hash)
|
26
18
|
dualstack = context.params.delete(:use_dualstack_endpoint)
|
27
19
|
end
|
28
20
|
dualstack = context.config.use_dualstack_endpoint if dualstack.nil?
|
21
|
+
# Raise if :endpoint and dualstack are both provided
|
22
|
+
if dualstack && !context.config.regional_endpoint
|
23
|
+
raise ArgumentError,
|
24
|
+
'Cannot use both :use_dualstack_endpoint and :endpoint'
|
25
|
+
end
|
29
26
|
context[:use_dualstack_endpoint] = dualstack
|
30
27
|
@handler.call(context)
|
31
28
|
end
|
@@ -34,37 +31,41 @@ for all operations.
|
|
34
31
|
# @api private
|
35
32
|
class DualstackHandler < Seahorse::Client::Handler
|
36
33
|
def call(context)
|
37
|
-
|
34
|
+
# only rewrite the endpoint if it's not a custom endpoint
|
35
|
+
# accelerate/ARN already handle dualstack cases, so ignore these
|
36
|
+
# check to see if dualstack is on but configured off via operation
|
37
|
+
if context.config.regional_endpoint &&
|
38
|
+
use_dualstack_endpoint?(context)
|
39
|
+
apply_dualstack_endpoint(context)
|
40
|
+
end
|
38
41
|
@handler.call(context)
|
39
42
|
end
|
40
43
|
|
41
44
|
private
|
42
|
-
def apply_dualstack_endpoint(context)
|
43
|
-
bucket_name = context.params[:bucket]
|
44
|
-
region = context.config.region
|
45
|
-
context.config.force_path_style
|
46
|
-
dns_suffix = Aws::Partitions::EndpointProvider.dns_suffix_for(region)
|
47
45
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
46
|
+
def apply_dualstack_endpoint(context)
|
47
|
+
new_endpoint = Aws::Partitions::EndpointProvider.resolve(
|
48
|
+
context.config.region,
|
49
|
+
's3',
|
50
|
+
'regional',
|
51
|
+
{
|
52
|
+
dualstack: context[:use_dualstack_endpoint],
|
53
|
+
fips: context.config.use_fips_endpoint
|
54
|
+
}
|
55
|
+
)
|
53
56
|
endpoint = URI.parse(context.http_request.endpoint.to_s)
|
54
|
-
endpoint.
|
55
|
-
|
56
|
-
endpoint.host = host
|
57
|
-
context.http_request.endpoint = endpoint.to_s
|
58
|
-
end
|
59
|
-
|
60
|
-
def use_bucket_dns?(bucket_name, context)
|
61
|
-
ssl = context.http_request.endpoint.scheme == "https"
|
62
|
-
bucket_name && BucketDns.dns_compatible?(bucket_name, ssl) &&
|
63
|
-
!context.config.force_path_style
|
57
|
+
endpoint.host = URI.parse(new_endpoint).host
|
58
|
+
context.http_request.endpoint = endpoint
|
64
59
|
end
|
65
60
|
|
66
61
|
def use_dualstack_endpoint?(context)
|
67
|
-
|
62
|
+
# case when dualstack is turned off via operation
|
63
|
+
(context[:use_dualstack_endpoint] ||
|
64
|
+
context.config.use_dualstack_endpoint) &&
|
65
|
+
# accelerate plugin already applies dualstack
|
66
|
+
!context[:use_accelerate_endpoint] &&
|
67
|
+
# arns handle dualstack
|
68
|
+
!context.metadata[:s3_arn]
|
68
69
|
end
|
69
70
|
end
|
70
71
|
|