aws-sdk-s3 1.96.2 → 1.113.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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +105 -0
  3. data/VERSION +1 -1
  4. data/lib/aws-sdk-s3/arn/access_point_arn.rb +6 -6
  5. data/lib/aws-sdk-s3/arn/multi_region_access_point_arn.rb +68 -0
  6. data/lib/aws-sdk-s3/arn/object_lambda_arn.rb +6 -6
  7. data/lib/aws-sdk-s3/arn/outpost_access_point_arn.rb +7 -6
  8. data/lib/aws-sdk-s3/bucket.rb +126 -29
  9. data/lib/aws-sdk-s3/bucket_acl.rb +21 -4
  10. data/lib/aws-sdk-s3/bucket_cors.rb +23 -6
  11. data/lib/aws-sdk-s3/bucket_lifecycle.rb +27 -8
  12. data/lib/aws-sdk-s3/bucket_lifecycle_configuration.rb +28 -6
  13. data/lib/aws-sdk-s3/bucket_logging.rb +21 -4
  14. data/lib/aws-sdk-s3/bucket_notification.rb +19 -7
  15. data/lib/aws-sdk-s3/bucket_policy.rb +23 -6
  16. data/lib/aws-sdk-s3/bucket_request_payment.rb +21 -4
  17. data/lib/aws-sdk-s3/bucket_tagging.rb +23 -6
  18. data/lib/aws-sdk-s3/bucket_versioning.rb +63 -12
  19. data/lib/aws-sdk-s3/bucket_website.rb +23 -6
  20. data/lib/aws-sdk-s3/client.rb +2691 -1278
  21. data/lib/aws-sdk-s3/client_api.rb +390 -21
  22. data/lib/aws-sdk-s3/customizations/object.rb +78 -5
  23. data/lib/aws-sdk-s3/encryption/client.rb +1 -1
  24. data/lib/aws-sdk-s3/encryption/decrypt_handler.rb +0 -4
  25. data/lib/aws-sdk-s3/encryptionV2/client.rb +1 -1
  26. data/lib/aws-sdk-s3/encryptionV2/decrypt_handler.rb +0 -4
  27. data/lib/aws-sdk-s3/encryptionV2/encrypt_handler.rb +0 -4
  28. data/lib/aws-sdk-s3/file_downloader.rb +1 -1
  29. data/lib/aws-sdk-s3/file_uploader.rb +6 -1
  30. data/lib/aws-sdk-s3/multipart_file_uploader.rb +26 -7
  31. data/lib/aws-sdk-s3/multipart_upload.rb +126 -12
  32. data/lib/aws-sdk-s3/multipart_upload_part.rb +134 -14
  33. data/lib/aws-sdk-s3/object.rb +291 -115
  34. data/lib/aws-sdk-s3/object_acl.rb +23 -6
  35. data/lib/aws-sdk-s3/object_summary.rb +207 -80
  36. data/lib/aws-sdk-s3/object_version.rb +66 -39
  37. data/lib/aws-sdk-s3/plugins/accelerate.rb +7 -1
  38. data/lib/aws-sdk-s3/plugins/arn.rb +59 -33
  39. data/lib/aws-sdk-s3/plugins/bucket_dns.rb +1 -1
  40. data/lib/aws-sdk-s3/plugins/dualstack.rb +25 -31
  41. data/lib/aws-sdk-s3/plugins/iad_regional_endpoint.rb +6 -0
  42. data/lib/aws-sdk-s3/plugins/md5s.rb +5 -3
  43. data/lib/aws-sdk-s3/plugins/s3_signer.rb +29 -5
  44. data/lib/aws-sdk-s3/plugins/skip_whole_multipart_get_checksums.rb +31 -0
  45. data/lib/aws-sdk-s3/presigned_post.rb +38 -19
  46. data/lib/aws-sdk-s3/presigner.rb +6 -0
  47. data/lib/aws-sdk-s3/resource.rb +18 -0
  48. data/lib/aws-sdk-s3/types.rb +2928 -920
  49. data/lib/aws-sdk-s3.rb +1 -1
  50. metadata +9 -7
@@ -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,8 +251,8 @@ 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 requester
249
- # pays buckets, see [Downloading Objects in Requestor Pays Buckets][1]
254
+ # requests. For information about downloading objects from Requester
255
+ # Pays buckets, see [Downloading Objects in Requester Pays Buckets][1]
250
256
  # in the *Amazon S3 User Guide*.
251
257
  #
252
258
  #
@@ -254,11 +260,12 @@ module Aws::S3
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
266
  # The account ID of the expected bucket owner. If the bucket is owned by
260
- # a different account, the request will fail with an HTTP `403 (Access
261
- # Denied)` error.
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, otherwise return a 412 (precondition failed).
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, otherwise return a 304 (not modified).
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, otherwise return a 304 (not modified).
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, otherwise return a 412 (precondition failed).
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
@@ -345,8 +353,8 @@ 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 requester
349
- # pays buckets, see [Downloading Objects in Requestor Pays Buckets][1]
356
+ # requests. For information about downloading objects from Requester
357
+ # Pays buckets, see [Downloading Objects in Requester Pays Buckets][1]
350
358
  # in the *Amazon S3 User Guide*.
351
359
  #
352
360
  #
@@ -359,8 +367,10 @@ module Aws::S3
359
367
  # object.
360
368
  # @option options [String] :expected_bucket_owner
361
369
  # The account ID of the expected bucket owner. If the bucket is owned by
362
- # a different account, the request will fail with an HTTP `403 (Access
363
- # Denied)` error.
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,33 +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, otherwise return a 412 (precondition failed).
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, otherwise return a 304 (not modified).
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, otherwise return a 304 (not modified).
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, otherwise return a 412 (precondition failed).
413
+ # time; otherwise, return a 412 (precondition failed) error.
403
414
  # @option options [String] :range
404
- # Downloads the specified range bytes of an object. For more information
405
- # about the HTTP Range header, see
406
- # [http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35][1].
407
- #
408
- # <note markdown="1"> Amazon S3 doesn't support retrieving multiple ranges of data per
409
- # `GET` request.
410
- #
411
- # </note>
412
- #
413
- #
414
- #
415
- # [1]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35
415
+ # Because `HeadObject` returns only the metadata for an object, this
416
+ # parameter has no effect.
416
417
  # @option options [String] :sse_customer_algorithm
417
418
  # Specifies the algorithm to use to when encrypting the object (for
418
419
  # example, AES256).
@@ -429,8 +430,8 @@ module Aws::S3
429
430
  # @option options [String] :request_payer
430
431
  # Confirms that the requester knows that they will be charged for the
431
432
  # request. Bucket owners need not specify this parameter in their
432
- # requests. For information about downloading objects from requester
433
- # pays buckets, see [Downloading Objects in Requestor Pays Buckets][1]
433
+ # requests. For information about downloading objects from Requester
434
+ # Pays buckets, see [Downloading Objects in Requester Pays Buckets][1]
434
435
  # in the *Amazon S3 User Guide*.
435
436
  #
436
437
  #
@@ -443,8 +444,15 @@ module Aws::S3
443
444
  # the number of parts in this object.
444
445
  # @option options [String] :expected_bucket_owner
445
446
  # The account ID of the expected bucket owner. If the bucket is owned by
446
- # a different account, the request will fail with an HTTP `403 (Access
447
- # Denied)` error.
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.
448
456
  # @return [Types::HeadObjectOutput]
449
457
  def head(options = {})
450
458
  options = options.merge(
@@ -524,6 +532,7 @@ module Aws::S3
524
532
  # request_payer: "requester", # accepts requester
525
533
  # bypass_governance_retention: false,
526
534
  # expected_bucket_owner: "AccountId",
535
+ # checksum_algorithm: "CRC32", # accepts CRC32, CRC32C, SHA1, SHA256
527
536
  # })
528
537
  # @param options ({})
529
538
  # @option options [String] :mfa
@@ -534,8 +543,8 @@ module Aws::S3
534
543
  # @option options [String] :request_payer
535
544
  # Confirms that the requester knows that they will be charged for the
536
545
  # request. Bucket owners need not specify this parameter in their
537
- # requests. For information about downloading objects from requester
538
- # pays buckets, see [Downloading Objects in Requestor Pays Buckets][1]
546
+ # requests. For information about downloading objects from Requester
547
+ # Pays buckets, see [Downloading Objects in Requester Pays Buckets][1]
539
548
  # in the *Amazon S3 User Guide*.
540
549
  #
541
550
  #
@@ -543,12 +552,30 @@ module Aws::S3
543
552
  # [1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
544
553
  # @option options [Boolean] :bypass_governance_retention
545
554
  # Specifies whether you want to delete this object even if it has a
546
- # Governance-type Object Lock in place. You must have sufficient
547
- # permissions to perform this operation.
555
+ # Governance-type Object Lock in place. To use this header, you must
556
+ # have the `s3:BypassGovernanceRetention` permission.
548
557
  # @option options [String] :expected_bucket_owner
549
558
  # The account ID of the expected bucket owner. If the bucket is owned by
550
- # a different account, the request will fail with an HTTP `403 (Access
551
- # Denied)` error.
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
552
579
  # @return [void]
553
580
  def batch_delete!(options = {})
554
581
  batch_enum.each do |batch|
@@ -41,11 +41,17 @@ each bucket. [Go here for more information](http://docs.aws.amazon.com/AmazonS3/
41
41
  accelerate = context.params.delete(:use_accelerate_endpoint)
42
42
  end
43
43
  accelerate = context.config.use_accelerate_endpoint if accelerate.nil?
44
- # Raise if :endpoint and dualstack are both provided
44
+ # Raise if :endpoint and accelerate are both provided
45
45
  if accelerate && !context.config.regional_endpoint
46
46
  raise ArgumentError,
47
47
  'Cannot use both :use_accelerate_endpoint and :endpoint'
48
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'
54
+ end
49
55
  context[:use_accelerate_endpoint] = accelerate
50
56
  @handler.call(context)
51
57
  end
@@ -3,6 +3,7 @@
3
3
  require_relative '../arn/access_point_arn'
4
4
  require_relative '../arn/object_lambda_arn'
5
5
  require_relative '../arn/outpost_access_point_arn'
6
+ require_relative '../arn/multi_region_access_point_arn'
6
7
 
7
8
  module Aws
8
9
  module S3
@@ -23,6 +24,18 @@ be made. Set to `false` to use the client's region instead.
23
24
  resolve_s3_use_arn_region(cfg)
24
25
  end
25
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
+
26
39
  # param validator is validate:50
27
40
  # endpoint is build:90 (populates the URI for the first time)
28
41
  # endpoint pattern is build:10
@@ -64,17 +77,10 @@ be made. Set to `false` to use the client's region instead.
64
77
  if arn
65
78
  validate_config!(context, arn)
66
79
 
67
- fips = false
68
- if resolved_region.include?('fips')
69
- fips = true
70
- resolved_region = resolved_region.gsub('fips-', '')
71
- .gsub('-fips', '')
72
- end
73
-
74
80
  context.metadata[:s3_arn] = {
75
81
  arn: arn,
76
82
  resolved_region: resolved_region,
77
- fips: fips,
83
+ fips: context.config.use_fips_endpoint,
78
84
  dualstack: extract_dualstack_config!(context)
79
85
  }
80
86
  end
@@ -113,8 +119,21 @@ be made. Set to `false` to use the client's region instead.
113
119
 
114
120
  if !arn.support_dualstack? && context[:use_dualstack_endpoint]
115
121
  raise ArgumentError,
116
- 'Cannot provide an Outpost Access Point ARN when '\
117
- '`:use_dualstack_endpoint` is set to true.'
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.'
118
137
  end
119
138
  end
120
139
  end
@@ -127,7 +146,7 @@ be made. Set to `false` to use the client's region instead.
127
146
  s3_arn = resolve_arn_type!(arn)
128
147
  s3_arn.validate_arn!
129
148
  validate_region_config!(s3_arn, region, use_arn_region)
130
- region = s3_arn.region if use_arn_region && !region.include?('fips')
149
+ region = s3_arn.region if use_arn_region
131
150
  [region, s3_arn]
132
151
  else
133
152
  [region]
@@ -147,7 +166,9 @@ be made. Set to `false` to use the client's region instead.
147
166
  def resolve_arn_type!(arn)
148
167
  case arn.service
149
168
  when 's3'
150
- Aws::S3::AccessPointARN.new(arn.to_h)
169
+ arn.region.empty? ?
170
+ Aws::S3::MultiRegionAccessPointARN.new(arn.to_h) :
171
+ Aws::S3::AccessPointARN.new(arn.to_h)
151
172
  when 's3-outposts'
152
173
  Aws::S3::OutpostAccessPointARN.new(arn.to_h)
153
174
  when 's3-object-lambda'
@@ -174,6 +195,21 @@ be made. Set to `false` to use the client's region instead.
174
195
  value
175
196
  end
176
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
+
177
213
  # Remove ARN from the path because we've already set the new host
178
214
  def url_path(path, arn)
179
215
  path = path.sub("/#{Seahorse::Util.uri_escape(arn.to_s)}", '')
@@ -195,29 +231,19 @@ be made. Set to `false` to use the client's region instead.
195
231
  raise Aws::Errors::InvalidARNPartitionError
196
232
  end
197
233
  else
198
- if region.include?('fips')
199
- # If ARN type doesn't support FIPS but the client region is FIPS
200
- unless arn.support_fips?
201
- raise ArgumentError,
202
- 'FIPS client regions are not supported for this type '\
203
- 'of ARN.'
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
204
240
  end
205
241
 
206
- fips = true
207
- # Normalize the region so we can compare partition and regions
208
- region = region.gsub('fips-', '').gsub('-fips', '')
209
- end
210
-
211
- # Raise if the ARN and client regions are in different partitions
212
- if use_arn_region &&
213
- !Aws::Partitions.partition(arn.partition).region?(region)
214
- raise Aws::Errors::InvalidARNPartitionError
215
- end
216
-
217
- # Raise if regions mismatch
218
- # Either when it's a fips client or not using the ARN region
219
- if (!use_arn_region || fips) && region != arn.region
220
- raise Aws::Errors::InvalidARNRegionError
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
221
247
  end
222
248
  end
223
249
  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
@@ -5,18 +5,9 @@ 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: 11)
10
+ handlers.add(DualstackHandler, step: :build, priority: 49)
20
11
  end
21
12
 
22
13
  # @api private
@@ -40,38 +31,41 @@ for all operations.
40
31
  # @api private
41
32
  class DualstackHandler < Seahorse::Client::Handler
42
33
  def call(context)
43
- if context.config.regional_endpoint && use_dualstack_endpoint?(context)
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)
44
39
  apply_dualstack_endpoint(context)
45
40
  end
46
41
  @handler.call(context)
47
42
  end
48
43
 
49
44
  private
50
- def apply_dualstack_endpoint(context)
51
- bucket_name = context.params[:bucket]
52
- region = context.config.region
53
- dns_suffix = Aws::Partitions::EndpointProvider.dns_suffix_for(region)
54
45
 
55
- if use_bucket_dns?(bucket_name, context)
56
- host = "#{bucket_name}.s3.dualstack.#{region}.#{dns_suffix}"
57
- else
58
- host = "s3.dualstack.#{region}.#{dns_suffix}"
59
- end
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
+ )
60
56
  endpoint = URI.parse(context.http_request.endpoint.to_s)
61
- endpoint.scheme = context.http_request.endpoint.scheme
62
- endpoint.port = context.http_request.endpoint.port
63
- endpoint.host = host
64
- context.http_request.endpoint = endpoint.to_s
65
- end
66
-
67
- def use_bucket_dns?(bucket_name, context)
68
- ssl = context.http_request.endpoint.scheme == "https"
69
- bucket_name && BucketDns.dns_compatible?(bucket_name, ssl) &&
70
- !context.config.force_path_style
57
+ endpoint.host = URI.parse(new_endpoint).host
58
+ context.http_request.endpoint = endpoint
71
59
  end
72
60
 
73
61
  def use_dualstack_endpoint?(context)
74
- context[:use_dualstack_endpoint] && !context[:use_accelerate_endpoint]
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]
75
69
  end
76
70
  end
77
71
 
@@ -48,8 +48,14 @@ Defaults to `legacy` mode which uses the global endpoint.
48
48
  private
49
49
 
50
50
  def self.resolve_iad_regional_endpoint(cfg)
51
+ default_mode_value =
52
+ if cfg.respond_to?(:defaults_mode_config_resolver)
53
+ cfg.defaults_mode_config_resolver.resolve(:s3_us_east_1_regional_endpoint)
54
+ end
55
+
51
56
  mode = ENV['AWS_S3_US_EAST_1_REGIONAL_ENDPOINT'] ||
52
57
  Aws.shared_config.s3_us_east_1_regional_endpoint(profile: cfg.profile) ||
58
+ default_mode_value ||
53
59
  'legacy'
54
60
  mode = mode.downcase
55
61
  unless %w(legacy regional).include?(mode)
@@ -22,9 +22,11 @@ module Aws
22
22
  CHUNK_SIZE = 1 * 1024 * 1024 # one MB
23
23
 
24
24
  def call(context)
25
- body = context.http_request.body
26
- if body.respond_to?(:size) && body.size > 0
27
- context.http_request.headers['Content-Md5'] ||= md5(body)
25
+ if !context[:checksum_algorithms] # skip in favor of flexible checksum
26
+ body = context.http_request.body
27
+ if body.respond_to?(:size) && body.size > 0
28
+ context.http_request.headers['Content-Md5'] ||= md5(body)
29
+ end
28
30
  end
29
31
  @handler.call(context)
30
32
  end
@@ -22,7 +22,9 @@ module Aws
22
22
  # S3 removes core's signature_v4 plugin that checks for this
23
23
  raise Aws::Errors::MissingRegionError if cfg.region.nil?
24
24
 
25
- Aws::Partitions::EndpointProvider.signing_region(cfg.region, 's3')
25
+ Aws::Partitions::EndpointProvider.signing_region(
26
+ cfg.region, 's3'
27
+ )
26
28
  end
27
29
 
28
30
  def add_handlers(handlers, cfg)
@@ -74,9 +76,17 @@ module Aws
74
76
  credentials: context.config.credentials
75
77
  )
76
78
  elsif (arn = context.metadata[:s3_arn])
79
+ if arn[:arn].is_a?(MultiRegionAccessPointARN)
80
+ signing_region = '*'
81
+ signing_algorithm = :sigv4a
82
+ else
83
+ signing_region = arn[:resolved_region]
84
+ signing_algorithm = :sigv4
85
+ end
77
86
  S3Signer.build_v4_signer(
78
87
  service: arn[:arn].service,
79
- region: arn[:resolved_region],
88
+ signing_algorithm: signing_algorithm,
89
+ region: signing_region,
80
90
  credentials: context.config.credentials
81
91
  )
82
92
  elsif context.operation.name == 'WriteGetObjectResponse'
@@ -154,7 +164,12 @@ module Aws
154
164
 
155
165
  def custom_endpoint?(resp)
156
166
  resolved_suffix = Aws::Partitions::EndpointProvider.dns_suffix_for(
157
- resp.context.config.region
167
+ resp.context.config.region,
168
+ 's3',
169
+ {
170
+ dualstack: resp.context[:use_dualstack_endpoint],
171
+ fips: resp.context.config.use_fips_endpoint
172
+ }
158
173
  )
159
174
  !resp.context.http_request.endpoint.hostname.include?(resolved_suffix)
160
175
  end
@@ -216,6 +231,7 @@ module Aws
216
231
  service: options[:service],
217
232
  region: options[:region],
218
233
  credentials_provider: options[:credentials],
234
+ signing_algorithm: options.fetch(:signing_algorithm, :sigv4),
219
235
  uri_escape_path: false,
220
236
  unsigned_headers: ['content-length', 'x-amzn-trace-id']
221
237
  )
@@ -225,12 +241,20 @@ module Aws
225
241
  # Otherwise it will retry with the ARN as the bucket name.
226
242
  def new_hostname(context, region)
227
243
  uri = URI.parse(
228
- Aws::Partitions::EndpointProvider.resolve(region, 's3')
244
+ Aws::Partitions::EndpointProvider.resolve(
245
+ region, 's3', 'regional',
246
+ {
247
+ dualstack: context[:use_dualstack_endpoint],
248
+ fips: context.config.use_fips_endpoint
249
+ }
250
+ )
229
251
  )
230
252
 
231
253
  if (arn = context.metadata[:s3_arn])
232
254
  # Retry with the response region and not the ARN resolved one
233
- ARN.resolve_url!(uri, arn[:arn], region).host
255
+ ARN.resolve_url!(
256
+ uri, arn[:arn], region, arn[:fips], arn[:dualstack]
257
+ ).host
234
258
  else
235
259
  "#{context.params[:bucket]}.#{uri.host}"
236
260
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module S3
5
+ module Plugins
6
+
7
+ # S3 GetObject results for whole Multipart Objects contain a checksum
8
+ # that cannot be validated. These should be skipped by the
9
+ # ChecksumAlgorithm plugin.
10
+ class SkipWholeMultipartGetChecksums < Seahorse::Client::Plugin
11
+
12
+ class Handler < Seahorse::Client::Handler
13
+
14
+ def call(context)
15
+ context[:http_checksum] ||= {}
16
+ context[:http_checksum][:skip_on_suffix] = true
17
+
18
+ @handler.call(context)
19
+ end
20
+
21
+ end
22
+
23
+ handler(
24
+ Handler,
25
+ step: :initialize,
26
+ operations: [:get_object]
27
+ )
28
+ end
29
+ end
30
+ end
31
+ end