aws-sdk-s3 1.79.1 → 1.212.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 (133) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1548 -0
  3. data/LICENSE.txt +202 -0
  4. data/VERSION +1 -0
  5. data/lib/aws-sdk-s3/access_grants_credentials.rb +57 -0
  6. data/lib/aws-sdk-s3/access_grants_credentials_provider.rb +250 -0
  7. data/lib/aws-sdk-s3/bucket.rb +900 -98
  8. data/lib/aws-sdk-s3/bucket_acl.rb +44 -10
  9. data/lib/aws-sdk-s3/bucket_cors.rb +51 -11
  10. data/lib/aws-sdk-s3/bucket_lifecycle.rb +53 -8
  11. data/lib/aws-sdk-s3/bucket_lifecycle_configuration.rb +107 -9
  12. data/lib/aws-sdk-s3/bucket_logging.rb +43 -6
  13. data/lib/aws-sdk-s3/bucket_notification.rb +32 -9
  14. data/lib/aws-sdk-s3/bucket_policy.rb +90 -6
  15. data/lib/aws-sdk-s3/bucket_region_cache.rb +9 -5
  16. data/lib/aws-sdk-s3/bucket_request_payment.rb +38 -8
  17. data/lib/aws-sdk-s3/bucket_tagging.rb +46 -7
  18. data/lib/aws-sdk-s3/bucket_versioning.rb +127 -9
  19. data/lib/aws-sdk-s3/bucket_website.rb +46 -7
  20. data/lib/aws-sdk-s3/client.rb +13729 -3146
  21. data/lib/aws-sdk-s3/client_api.rb +1604 -277
  22. data/lib/aws-sdk-s3/customizations/bucket.rb +31 -47
  23. data/lib/aws-sdk-s3/customizations/errors.rb +40 -0
  24. data/lib/aws-sdk-s3/customizations/object.rb +253 -82
  25. data/lib/aws-sdk-s3/customizations/object_summary.rb +5 -0
  26. data/lib/aws-sdk-s3/customizations/object_version.rb +13 -0
  27. data/lib/aws-sdk-s3/customizations/types/permanent_redirect.rb +26 -0
  28. data/lib/aws-sdk-s3/customizations.rb +28 -29
  29. data/lib/aws-sdk-s3/default_executor.rb +103 -0
  30. data/lib/aws-sdk-s3/encryption/client.rb +9 -5
  31. data/lib/aws-sdk-s3/encryption/decrypt_handler.rb +0 -4
  32. data/lib/aws-sdk-s3/encryption/default_cipher_provider.rb +2 -0
  33. data/lib/aws-sdk-s3/encryption/encrypt_handler.rb +2 -0
  34. data/lib/aws-sdk-s3/encryption/kms_cipher_provider.rb +15 -9
  35. data/lib/aws-sdk-s3/encryptionV2/client.rb +105 -26
  36. data/lib/aws-sdk-s3/encryptionV2/decrypt_handler.rb +7 -165
  37. data/lib/aws-sdk-s3/encryptionV2/decryption.rb +205 -0
  38. data/lib/aws-sdk-s3/encryptionV2/default_cipher_provider.rb +20 -3
  39. data/lib/aws-sdk-s3/encryptionV2/encrypt_handler.rb +2 -4
  40. data/lib/aws-sdk-s3/encryptionV2/io_encrypter.rb +2 -0
  41. data/lib/aws-sdk-s3/encryptionV2/kms_cipher_provider.rb +18 -6
  42. data/lib/aws-sdk-s3/encryptionV2/utils.rb +5 -0
  43. data/lib/aws-sdk-s3/encryptionV3/client.rb +885 -0
  44. data/lib/aws-sdk-s3/encryptionV3/decrypt_handler.rb +98 -0
  45. data/lib/aws-sdk-s3/encryptionV3/decryption.rb +244 -0
  46. data/lib/aws-sdk-s3/encryptionV3/default_cipher_provider.rb +159 -0
  47. data/lib/aws-sdk-s3/encryptionV3/default_key_provider.rb +35 -0
  48. data/lib/aws-sdk-s3/encryptionV3/encrypt_handler.rb +98 -0
  49. data/lib/aws-sdk-s3/encryptionV3/errors.rb +47 -0
  50. data/lib/aws-sdk-s3/encryptionV3/io_auth_decrypter.rb +60 -0
  51. data/lib/aws-sdk-s3/encryptionV3/io_decrypter.rb +35 -0
  52. data/lib/aws-sdk-s3/encryptionV3/io_encrypter.rb +84 -0
  53. data/lib/aws-sdk-s3/encryptionV3/key_provider.rb +28 -0
  54. data/lib/aws-sdk-s3/encryptionV3/kms_cipher_provider.rb +159 -0
  55. data/lib/aws-sdk-s3/encryptionV3/materials.rb +58 -0
  56. data/lib/aws-sdk-s3/encryptionV3/utils.rb +321 -0
  57. data/lib/aws-sdk-s3/encryption_v2.rb +1 -0
  58. data/lib/aws-sdk-s3/encryption_v3.rb +24 -0
  59. data/lib/aws-sdk-s3/endpoint_parameters.rb +181 -0
  60. data/lib/aws-sdk-s3/endpoint_provider.rb +889 -0
  61. data/lib/aws-sdk-s3/endpoints.rb +1544 -0
  62. data/lib/aws-sdk-s3/errors.rb +80 -1
  63. data/lib/aws-sdk-s3/event_streams.rb +1 -1
  64. data/lib/aws-sdk-s3/express_credentials.rb +55 -0
  65. data/lib/aws-sdk-s3/express_credentials_provider.rb +59 -0
  66. data/lib/aws-sdk-s3/file_downloader.rb +258 -82
  67. data/lib/aws-sdk-s3/file_uploader.rb +25 -14
  68. data/lib/aws-sdk-s3/legacy_signer.rb +17 -26
  69. data/lib/aws-sdk-s3/multipart_download_error.rb +8 -0
  70. data/lib/aws-sdk-s3/multipart_file_uploader.rb +111 -86
  71. data/lib/aws-sdk-s3/multipart_stream_uploader.rb +110 -92
  72. data/lib/aws-sdk-s3/multipart_upload.rb +304 -14
  73. data/lib/aws-sdk-s3/multipart_upload_error.rb +3 -4
  74. data/lib/aws-sdk-s3/multipart_upload_part.rb +344 -20
  75. data/lib/aws-sdk-s3/object.rb +2457 -225
  76. data/lib/aws-sdk-s3/object_acl.rb +76 -15
  77. data/lib/aws-sdk-s3/object_copier.rb +7 -5
  78. data/lib/aws-sdk-s3/object_multipart_copier.rb +48 -23
  79. data/lib/aws-sdk-s3/object_summary.rb +2033 -169
  80. data/lib/aws-sdk-s3/object_version.rb +470 -53
  81. data/lib/aws-sdk-s3/plugins/accelerate.rb +1 -39
  82. data/lib/aws-sdk-s3/plugins/access_grants.rb +178 -0
  83. data/lib/aws-sdk-s3/plugins/arn.rb +70 -0
  84. data/lib/aws-sdk-s3/plugins/bucket_dns.rb +3 -41
  85. data/lib/aws-sdk-s3/plugins/bucket_name_restrictions.rb +1 -6
  86. data/lib/aws-sdk-s3/plugins/checksum_algorithm.rb +44 -0
  87. data/lib/aws-sdk-s3/plugins/dualstack.rb +2 -49
  88. data/lib/aws-sdk-s3/plugins/endpoints.rb +86 -0
  89. data/lib/aws-sdk-s3/plugins/expect_100_continue.rb +3 -1
  90. data/lib/aws-sdk-s3/plugins/express_session_auth.rb +88 -0
  91. data/lib/aws-sdk-s3/plugins/get_bucket_location_fix.rb +1 -1
  92. data/lib/aws-sdk-s3/plugins/http_200_errors.rb +87 -26
  93. data/lib/aws-sdk-s3/plugins/iad_regional_endpoint.rb +8 -26
  94. data/lib/aws-sdk-s3/plugins/location_constraint.rb +3 -1
  95. data/lib/aws-sdk-s3/plugins/md5s.rb +10 -68
  96. data/lib/aws-sdk-s3/plugins/s3_signer.rb +48 -88
  97. data/lib/aws-sdk-s3/plugins/streaming_retry.rb +28 -9
  98. data/lib/aws-sdk-s3/plugins/url_encoded_keys.rb +2 -1
  99. data/lib/aws-sdk-s3/presigned_post.rb +99 -78
  100. data/lib/aws-sdk-s3/presigner.rb +50 -42
  101. data/lib/aws-sdk-s3/resource.rb +144 -15
  102. data/lib/aws-sdk-s3/transfer_manager.rb +321 -0
  103. data/lib/aws-sdk-s3/types.rb +12223 -4723
  104. data/lib/aws-sdk-s3/waiters.rb +1 -1
  105. data/lib/aws-sdk-s3.rb +37 -28
  106. data/sig/bucket.rbs +231 -0
  107. data/sig/bucket_acl.rbs +78 -0
  108. data/sig/bucket_cors.rbs +69 -0
  109. data/sig/bucket_lifecycle.rbs +88 -0
  110. data/sig/bucket_lifecycle_configuration.rbs +115 -0
  111. data/sig/bucket_logging.rbs +76 -0
  112. data/sig/bucket_notification.rbs +114 -0
  113. data/sig/bucket_policy.rbs +59 -0
  114. data/sig/bucket_request_payment.rbs +54 -0
  115. data/sig/bucket_tagging.rbs +65 -0
  116. data/sig/bucket_versioning.rbs +77 -0
  117. data/sig/bucket_website.rbs +93 -0
  118. data/sig/client.rbs +2612 -0
  119. data/sig/customizations/bucket.rbs +19 -0
  120. data/sig/customizations/object.rbs +38 -0
  121. data/sig/customizations/object_summary.rbs +35 -0
  122. data/sig/errors.rbs +44 -0
  123. data/sig/multipart_upload.rbs +120 -0
  124. data/sig/multipart_upload_part.rbs +109 -0
  125. data/sig/object.rbs +464 -0
  126. data/sig/object_acl.rbs +86 -0
  127. data/sig/object_summary.rbs +347 -0
  128. data/sig/object_version.rbs +143 -0
  129. data/sig/resource.rbs +141 -0
  130. data/sig/types.rbs +2899 -0
  131. data/sig/waiters.rbs +95 -0
  132. metadata +74 -16
  133. data/lib/aws-sdk-s3/plugins/bucket_arn.rb +0 -212
@@ -23,20 +23,16 @@ each bucket. [Go here for more information](http://docs.aws.amazon.com/AmazonS3/
23
23
  operations = config.api.operation_names - [
24
24
  :create_bucket, :list_buckets, :delete_bucket
25
25
  ]
26
- # Need 2 handlers so that the context can be set for other plugins
27
- # and to remove :use_accelerate_endpoint from the params.
28
26
  handlers.add(
29
27
  OptionHandler, step: :initialize, operations: operations
30
28
  )
31
- handlers.add(
32
- AccelerateHandler, step: :build, priority: 0, operations: operations
33
- )
34
29
  end
35
30
 
36
31
  # @api private
37
32
  class OptionHandler < Seahorse::Client::Handler
38
33
  def call(context)
39
34
  # Support client configuration and per-operation configuration
35
+ # TODO: move this to an options hash and warn here.
40
36
  if context.params.is_a?(Hash)
41
37
  accelerate = context.params.delete(:use_accelerate_endpoint)
42
38
  end
@@ -47,40 +43,6 @@ each bucket. [Go here for more information](http://docs.aws.amazon.com/AmazonS3/
47
43
  @handler.call(context)
48
44
  end
49
45
  end
50
-
51
- # @api private
52
- class AccelerateHandler < Seahorse::Client::Handler
53
- def call(context)
54
- if context[:use_accelerate_endpoint]
55
- dualstack = !!context[:use_dualstack_endpoint]
56
- use_accelerate_endpoint(context, dualstack)
57
- end
58
- @handler.call(context)
59
- end
60
-
61
- private
62
-
63
- def use_accelerate_endpoint(context, dualstack)
64
- bucket_name = context.params[:bucket]
65
- validate_bucket_name!(bucket_name)
66
- endpoint = URI.parse(context.http_request.endpoint.to_s)
67
- endpoint.scheme = 'https'
68
- endpoint.port = 443
69
- endpoint.host = "#{bucket_name}.s3-accelerate"\
70
- "#{'.dualstack' if dualstack}.amazonaws.com"
71
- context.http_request.endpoint = endpoint.to_s
72
- # s3 accelerate endpoint doesn't work with 'expect' header
73
- context.http_request.headers.delete('expect')
74
- end
75
-
76
- def validate_bucket_name!(bucket_name)
77
- unless BucketDns.dns_compatible?(bucket_name, _ssl = true)
78
- raise ArgumentError,
79
- 'Unable to use `use_accelerate_endpoint: true` on buckets '\
80
- 'with non-DNS compatible names.'
81
- end
82
- end
83
- end
84
46
  end
85
47
  end
86
48
  end
@@ -0,0 +1,178 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module S3
5
+ module Plugins
6
+ # @api private
7
+ class AccessGrants < Seahorse::Client::Plugin
8
+ @s3control =
9
+ begin
10
+ require 'aws-sdk-s3control'
11
+ true
12
+ rescue LoadError
13
+ false
14
+ end
15
+
16
+ option(
17
+ :access_grants,
18
+ default: false,
19
+ doc_type: 'Boolean',
20
+ docstring: <<-DOCS)
21
+ When `true`, the S3 client will use the S3 Access Grants feature to
22
+ authenticate requests. Bucket credentials will be fetched from S3
23
+ Control using the `get_data_access` API.
24
+ DOCS
25
+
26
+ option(:access_grants_credentials_provider,
27
+ doc_type: 'Aws::S3::AccessGrantsCredentialsProvider',
28
+ rbs_type: 'untyped',
29
+ docstring: <<-DOCS) do |_cfg|
30
+ When `access_grants` is `true`, this option can be used to provide
31
+ additional options to the credentials provider, including a privilege
32
+ setting, caching, and fallback behavior.
33
+ DOCS
34
+ Aws::S3::AccessGrantsCredentialsProvider.new
35
+ end
36
+
37
+ # @api private
38
+ class Handler < Seahorse::Client::Handler
39
+ PERMISSION_MAP = {
40
+ head_object: 'READ',
41
+ get_object: 'READ',
42
+ get_object_acl: 'READ',
43
+ list_multipart_uploads: 'READ',
44
+ list_objects_v2: 'READ',
45
+ list_object_versions: 'READ',
46
+ list_parts: 'READ',
47
+ head_bucket: 'READ',
48
+ get_object_attributes: 'READ',
49
+ put_object: 'WRITE',
50
+ put_object_acl: 'WRITE',
51
+ delete_object: 'WRITE',
52
+ abort_multipart_upload: 'WRITE',
53
+ create_multipart_upload: 'WRITE',
54
+ upload_part: 'WRITE',
55
+ complete_multipart_upload: 'WRITE',
56
+ delete_objects: 'WRITE',
57
+ copy_object: 'READWRITE'
58
+ }.freeze
59
+
60
+ def call(context)
61
+ provider = context.config.access_grants_credentials_provider
62
+
63
+ if access_grants_operation?(context) &&
64
+ !s3_express_endpoint?(context) &&
65
+ !credentials_head_bucket_call?(provider)
66
+ params = context[:endpoint_params]
67
+ permission = PERMISSION_MAP[context.operation_name]
68
+
69
+ key =
70
+ case context.operation_name
71
+ when :delete_objects
72
+ delete_params = context.params[:delete]
73
+ common_prefixes(delete_params[:objects].map { |o| o[:key] })
74
+ when :copy_object
75
+ source_bucket, source_key = params[:copy_source].split('/', 2)
76
+ if params[:bucket] != source_bucket
77
+ raise ArgumentError,
78
+ 'source and destination bucket must be the same'
79
+ end
80
+ common_prefixes([params[:key], source_key])
81
+ else
82
+ params[:key]
83
+ end
84
+
85
+ credentials = provider.access_grants_credentials_for(
86
+ bucket: params[:bucket],
87
+ key: key,
88
+ prefix: params[:prefix],
89
+ permission: permission
90
+ )
91
+ context[:sigv4_credentials] = credentials # Sign will use this
92
+ end
93
+
94
+ with_metric(credentials) { @handler.call(context) }
95
+ end
96
+
97
+ private
98
+
99
+ def with_metric(credentials, &block)
100
+ return block.call unless credentials
101
+
102
+ Aws::Plugins::UserAgent.metric('S3_ACCESS_GRANTS', &block)
103
+ end
104
+
105
+ # HeadBucket is a supported call. When fetching credentials,
106
+ # this plugin is executed again, and becomes recursive.
107
+ def credentials_head_bucket_call?(provider)
108
+ provider.instance_variable_get(:@head_bucket_call)
109
+ end
110
+
111
+ def access_grants_operation?(context)
112
+ params = context[:endpoint_params]
113
+ params[:bucket] && PERMISSION_MAP[context.operation_name]
114
+ end
115
+
116
+ def s3_express_endpoint?(context)
117
+ context[:endpoint_properties]['backend'] == 'S3Express'
118
+ end
119
+
120
+ # Return the common prefix of the keys, regardless of the delimiter.
121
+ # For example, given keys ['foo/bar', 'foo/baz'], the common prefix
122
+ # is 'foo/ba'.
123
+ def common_prefixes(keys)
124
+ return '' if keys.empty?
125
+
126
+ first_key = keys[0]
127
+ common_ancestor = first_key
128
+ last_prefix = ''
129
+ keys.each do |k|
130
+ until common_ancestor.empty?
131
+ break if k.start_with?(common_ancestor)
132
+
133
+ last_index = common_ancestor.rindex('/')
134
+ return '' if last_index.nil?
135
+
136
+ last_prefix = common_ancestor[(last_index + 1)..-1]
137
+ common_ancestor = common_ancestor[0...last_index]
138
+ end
139
+ end
140
+ new_common_ancestor = "#{common_ancestor}/#{last_prefix}"
141
+ keys.each do |k|
142
+ until last_prefix.empty?
143
+ break if k.start_with?(new_common_ancestor)
144
+
145
+ last_prefix = last_prefix[0...-1]
146
+ new_common_ancestor = "#{common_ancestor}/#{last_prefix}"
147
+ end
148
+ end
149
+ if new_common_ancestor == "#{first_key}/"
150
+ first_key
151
+ else
152
+ new_common_ancestor
153
+ end
154
+ end
155
+ end
156
+
157
+ def add_handlers(handlers, config)
158
+ return unless AccessGrants.s3control? && config.access_grants
159
+
160
+ handlers.add(Handler)
161
+ end
162
+
163
+ def after_initialize(client)
164
+ return unless AccessGrants.s3control? && client.config.access_grants
165
+
166
+ provider = client.config.access_grants_credentials_provider
167
+ provider.s3_client = client unless provider.s3_client
168
+ end
169
+
170
+ class << self
171
+ def s3control?
172
+ @s3control
173
+ end
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module S3
5
+ module Plugins
6
+ # When an accesspoint ARN is provided for :bucket in S3 operations, this
7
+ # plugin resolves the request endpoint from the ARN when possible.
8
+ # @api private
9
+ class ARN < Seahorse::Client::Plugin
10
+ option(
11
+ :s3_use_arn_region,
12
+ default: true,
13
+ doc_type: 'Boolean',
14
+ docstring: <<-DOCS) do |cfg|
15
+ For S3 ARNs passed into the `:bucket` parameter, this option will
16
+ use the region in the ARN, allowing for cross-region requests to
17
+ be made. Set to `false` to use the client's region instead.
18
+ DOCS
19
+ resolve_s3_use_arn_region(cfg)
20
+ end
21
+
22
+ option(
23
+ :s3_disable_multiregion_access_points,
24
+ default: false,
25
+ doc_type: 'Boolean',
26
+ docstring: <<-DOCS) do |cfg|
27
+ When set to `false` this will option will raise errors when multi-region
28
+ access point ARNs are used. Multi-region access points can potentially
29
+ result in cross region requests.
30
+ DOCS
31
+ resolve_s3_disable_multiregion_access_points(cfg)
32
+ end
33
+
34
+ class << self
35
+ private
36
+
37
+ def resolve_s3_use_arn_region(cfg)
38
+ value = ENV['AWS_S3_USE_ARN_REGION'] ||
39
+ Aws.shared_config.s3_use_arn_region(profile: cfg.profile) ||
40
+ 'true'
41
+ value = Aws::Util.str_2_bool(value)
42
+ # Raise if provided value is not true or false
43
+ if value.nil?
44
+ raise ArgumentError,
45
+ 'Must provide either `true` or `false` for the '\
46
+ '`s3_use_arn_region` profile option or for '\
47
+ "ENV['AWS_S3_USE_ARN_REGION']."
48
+ end
49
+ value
50
+ end
51
+
52
+ def resolve_s3_disable_multiregion_access_points(cfg)
53
+ value = ENV['AWS_S3_DISABLE_MULTIREGION_ACCESS_POINTS'] ||
54
+ Aws.shared_config.s3_disable_multiregion_access_points(profile: cfg.profile) ||
55
+ 'false'
56
+ value = Aws::Util.str_2_bool(value)
57
+ # Raise if provided value is not true or false
58
+ if value.nil?
59
+ raise ArgumentError,
60
+ 'Must provide either `true` or `false` for '\
61
+ 's3_use_arn_region profile option or for '\
62
+ "ENV['AWS_S3_USE_ARN_REGION']"
63
+ end
64
+ value
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -23,45 +23,10 @@ When set to `true`, the bucket name is always left in the
23
23
  request URI and never moved to the host as a sub-domain.
24
24
  DOCS
25
25
 
26
- def add_handlers(handlers, config)
27
- handlers.add(Handler) unless config.force_path_style
28
- end
29
-
30
- # @api private
31
- class Handler < Seahorse::Client::Handler
32
-
33
- def call(context)
34
- move_dns_compat_bucket_to_subdomain(context)
35
- @handler.call(context)
36
- end
37
-
38
- private
39
-
40
- def move_dns_compat_bucket_to_subdomain(context)
41
- bucket_name = context.params[:bucket]
42
- endpoint = context.http_request.endpoint
43
- if bucket_name &&
44
- BucketDns.dns_compatible?(bucket_name, https?(endpoint)) &&
45
- context.operation_name.to_s != 'get_bucket_location'
46
- move_bucket_to_subdomain(bucket_name, endpoint)
47
- end
48
- end
49
-
50
- def move_bucket_to_subdomain(bucket_name, endpoint)
51
- endpoint.host = "#{bucket_name}.#{endpoint.host}"
52
- path = endpoint.path.sub("/#{bucket_name}", '')
53
- path = "/#{path}" unless path.match(/^\//)
54
- endpoint.path = path
55
- end
56
-
57
- def https?(uri)
58
- uri.scheme == 'https'
59
- end
60
-
61
- end
62
-
26
+ # These class methods were originally used in a handler in this plugin.
27
+ # SigV2 legacy signer needs this logic so we keep it here as utility.
28
+ # New endpoint resolution will check this as a matcher.
63
29
  class << self
64
-
65
30
  # @param [String] bucket_name
66
31
  # @param [Boolean] ssl
67
32
  # @return [Boolean]
@@ -73,8 +38,6 @@ request URI and never moved to the host as a sub-domain.
73
38
  end
74
39
  end
75
40
 
76
- # Checks for a valid RFC-3986 host name
77
- # @see https://tools.ietf.org/html/rfc3986#section-3.2.2
78
41
  # @param [String] bucket_name
79
42
  # @return [Boolean]
80
43
  def valid_subdomain?(bucket_name)
@@ -83,7 +46,6 @@ request URI and never moved to the host as a sub-domain.
83
46
  bucket_name !~ /(\d+\.){3}\d+/ &&
84
47
  bucket_name !~ /[.-]{2}/
85
48
  end
86
-
87
49
  end
88
50
  end
89
51
  end
@@ -13,12 +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
- _resolved_bucket, _resolved_region, arn = BucketARN.resolve_arn!(
17
- bucket,
18
- context.config.region,
19
- context.config.s3_use_arn_region
20
- )
21
- if !arn && bucket.include?('/')
16
+ if !Aws::ARNParser.arn?(bucket) && bucket.include?('/')
22
17
  raise ArgumentError,
23
18
  'bucket name must not contain a forward-slash (/)'
24
19
  end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module S3
5
+ module Plugins
6
+ # @api private
7
+ class ChecksumAlgorithm < Seahorse::Client::Plugin
8
+
9
+ # S3 GetObject results for whole Multipart Objects contain a checksum
10
+ # that cannot be validated. These should be skipped by the
11
+ # ChecksumAlgorithm plugin.
12
+ class SkipWholeMultipartGetChecksumsHandler < Seahorse::Client::Handler
13
+ def call(context)
14
+ context[:http_checksum] ||= {}
15
+ context[:http_checksum][:skip_on_suffix] = true
16
+
17
+ @handler.call(context)
18
+ end
19
+ end
20
+
21
+ # Handler to disable trailer checksums for S3-compatible services
22
+ # that don't support STREAMING-UNSIGNED-PAYLOAD-TRAILER
23
+ # See: https://github.com/aws/aws-sdk-ruby/issues/3338
24
+ class SkipTrailerChecksumsHandler < Seahorse::Client::Handler
25
+ def call(context)
26
+ context[:skip_trailer_checksums] = true if custom_endpoint?(context.config)
27
+ @handler.call(context)
28
+ end
29
+
30
+ private
31
+
32
+ def custom_endpoint?(config)
33
+ !config.regional_endpoint || !config.endpoint_provider.instance_of?(Aws::S3::EndpointProvider)
34
+ end
35
+ end
36
+
37
+ def add_handlers(handlers, _config)
38
+ handlers.add(SkipWholeMultipartGetChecksumsHandler, step: :initialize, operations: [:get_object])
39
+ handlers.add(SkipTrailerChecksumsHandler, step: :build, priority: 16, operations: %i[put_object upload_part])
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -5,23 +5,14 @@ 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
- def add_handlers(handlers, config)
8
+ def add_handlers(handlers, _config)
18
9
  handlers.add(OptionHandler, step: :initialize)
19
- handlers.add(DualstackHandler, step: :build, priority: 0)
20
10
  end
21
11
 
22
12
  # @api private
23
13
  class OptionHandler < Seahorse::Client::Handler
24
14
  def call(context)
15
+ # Support client configuration and per-operation configuration
25
16
  if context.params.is_a?(Hash)
26
17
  dualstack = context.params.delete(:use_dualstack_endpoint)
27
18
  end
@@ -30,44 +21,6 @@ for all operations.
30
21
  @handler.call(context)
31
22
  end
32
23
  end
33
-
34
- # @api private
35
- class DualstackHandler < Seahorse::Client::Handler
36
- def call(context)
37
- apply_dualstack_endpoint(context) if use_dualstack_endpoint?(context)
38
- @handler.call(context)
39
- end
40
-
41
- 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
-
48
- if use_bucket_dns?(bucket_name, context)
49
- host = "#{bucket_name}.s3.dualstack.#{region}.#{dns_suffix}"
50
- else
51
- host = "s3.dualstack.#{region}.#{dns_suffix}"
52
- end
53
- endpoint = URI.parse(context.http_request.endpoint.to_s)
54
- endpoint.scheme = context.http_request.endpoint.scheme
55
- endpoint.port = context.http_request.endpoint.port
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
64
- end
65
-
66
- def use_dualstack_endpoint?(context)
67
- context[:use_dualstack_endpoint] && !context[:use_accelerate_endpoint]
68
- end
69
- end
70
-
71
24
  end
72
25
  end
73
26
  end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ # WARNING ABOUT GENERATED CODE
4
+ #
5
+ # This file is generated. See the contributing guide for more information:
6
+ # https://github.com/aws/aws-sdk-ruby/blob/version-3/CONTRIBUTING.md
7
+ #
8
+ # WARNING ABOUT GENERATED CODE
9
+
10
+
11
+ module Aws::S3
12
+ module Plugins
13
+ class Endpoints < Seahorse::Client::Plugin
14
+ option(
15
+ :endpoint_provider,
16
+ doc_type: 'Aws::S3::EndpointProvider',
17
+ rbs_type: 'untyped',
18
+ docstring: <<~DOCS) do |_cfg|
19
+ The endpoint provider used to resolve endpoints. Any object that responds to
20
+ `#resolve_endpoint(parameters)` where `parameters` is a Struct similar to
21
+ `Aws::S3::EndpointParameters`.
22
+ DOCS
23
+ Aws::S3::EndpointProvider.new
24
+ end
25
+
26
+ option(
27
+ :disable_s3_express_session_auth,
28
+ doc_type: 'boolean',
29
+ docstring: <<~DOCS) do |cfg|
30
+ Parameter to indicate whether S3Express session auth should be disabled
31
+ DOCS
32
+ nil
33
+ end
34
+
35
+ # @api private
36
+ class Handler < Seahorse::Client::Handler
37
+ def call(context)
38
+ unless context[:discovered_endpoint]
39
+ params = Aws::S3::Endpoints.parameters_for_operation(context)
40
+ endpoint = context.config.endpoint_provider.resolve_endpoint(params)
41
+
42
+ context.http_request.endpoint = endpoint.url
43
+ apply_endpoint_headers(context, endpoint.headers)
44
+
45
+ context[:endpoint_params] = params
46
+ context[:endpoint_properties] = endpoint.properties
47
+ end
48
+
49
+ context[:auth_scheme] =
50
+ Aws::Endpoints.resolve_auth_scheme(context, endpoint)
51
+
52
+ with_metrics(context) { @handler.call(context) }
53
+ end
54
+
55
+ private
56
+
57
+ def with_metrics(context, &block)
58
+ metrics = []
59
+ metrics << 'ENDPOINT_OVERRIDE' unless context.config.regional_endpoint
60
+ if context[:auth_scheme] && context[:auth_scheme]['name'] == 'sigv4a'
61
+ metrics << 'SIGV4A_SIGNING'
62
+ end
63
+ if context.config.credentials&.credentials&.account_id
64
+ metrics << 'RESOLVED_ACCOUNT_ID'
65
+ end
66
+ Aws::Plugins::UserAgent.metric(*metrics, &block)
67
+ end
68
+
69
+ def apply_endpoint_headers(context, headers)
70
+ headers.each do |key, values|
71
+ value = values
72
+ .compact
73
+ .map { |s| Seahorse::Util.escape_header_list_string(s.to_s) }
74
+ .join(',')
75
+
76
+ context.http_request.headers[key] = value
77
+ end
78
+ end
79
+ end
80
+
81
+ def add_handlers(handlers, _config)
82
+ handlers.add(Handler, step: :build, priority: 75)
83
+ end
84
+ end
85
+ end
86
+ end
@@ -15,7 +15,9 @@ module Aws
15
15
  class Handler < Seahorse::Client::Handler
16
16
 
17
17
  def call(context)
18
- if context.http_request.body && context.http_request.body.size > 0
18
+ body = context.http_request.body
19
+ if body.respond_to?(:size) && body.size > 0 &&
20
+ !context[:use_accelerate_endpoint]
19
21
  context.http_request.headers['expect'] = '100-continue'
20
22
  end
21
23
  @handler.call(context)
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module S3
5
+ module Plugins
6
+ # @api private
7
+ class ExpressSessionAuth < Seahorse::Client::Plugin
8
+ # This should be s3_disable_express_auth instead
9
+ # But this is not a built in. We're overwriting the generated value
10
+ option(:disable_s3_express_session_auth,
11
+ default: false,
12
+ doc_type: 'Boolean',
13
+ docstring: <<-DOCS) do |cfg|
14
+ When `true`, S3 Express session authentication is disabled.
15
+ DOCS
16
+ resolve_disable_s3_express_session_auth(cfg)
17
+ end
18
+
19
+ option(:express_credentials_provider,
20
+ doc_type: 'Aws::S3::ExpressCredentialsProvider',
21
+ rbs_type: 'untyped',
22
+ docstring: <<-DOCS) do |_cfg|
23
+ Credential Provider for S3 Express endpoints. Manages credentials
24
+ for different buckets.
25
+ DOCS
26
+ Aws::S3::ExpressCredentialsProvider.new
27
+ end
28
+
29
+ # @api private
30
+ class Handler < Seahorse::Client::Handler
31
+ def call(context)
32
+ context[:s3_express_endpoint] = true if s3_express_endpoint?(context)
33
+
34
+ # if s3 express auth, use new credentials and sign additional header
35
+ if context[:auth_scheme]['name'] == 'sigv4-s3express' &&
36
+ !context.config.disable_s3_express_session_auth
37
+ bucket = context.params[:bucket]
38
+ credentials_provider = context.config.express_credentials_provider
39
+ credentials = credentials_provider.express_credentials_for(bucket)
40
+ context[:sigv4_credentials] = credentials # Sign will use this
41
+ end
42
+
43
+ with_metric(credentials) { @handler.call(context) }
44
+ end
45
+
46
+ private
47
+
48
+ def with_metric(credentials, &block)
49
+ return block.call unless credentials
50
+
51
+ Aws::Plugins::UserAgent.metric('S3_EXPRESS_BUCKET', &block)
52
+ end
53
+
54
+ def s3_express_endpoint?(context)
55
+ context[:endpoint_properties]['backend'] == 'S3Express'
56
+ end
57
+ end
58
+
59
+ handler(Handler)
60
+
61
+ # Optimization - sets this client as the client to create sessions.
62
+ def after_initialize(client)
63
+ provider = client.config.express_credentials_provider
64
+ provider.client = client unless provider.client
65
+ end
66
+
67
+ class << self
68
+ private
69
+
70
+ def resolve_disable_s3_express_session_auth(cfg)
71
+ value = ENV['AWS_S3_DISABLE_EXPRESS_SESSION_AUTH'] ||
72
+ Aws.shared_config.s3_disable_express_session_auth(profile: cfg.profile) ||
73
+ 'false'
74
+ value = Aws::Util.str_2_bool(value)
75
+ # Raise if provided value is not true or false
76
+ if value.nil?
77
+ raise ArgumentError,
78
+ 'Must provide either `true` or `false` for the '\
79
+ '`s3_disable_express_session_auth` profile option or for '\
80
+ "ENV['AWS_S3_DISABLE_EXPRESS_SESSION_AUTH']."
81
+ end
82
+ value
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end