aws-sdk-s3 1.136.0 → 1.176.1

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 (86) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +250 -1
  3. data/VERSION +1 -1
  4. data/lib/aws-sdk-s3/access_grants_credentials.rb +57 -0
  5. data/lib/aws-sdk-s3/access_grants_credentials_provider.rb +250 -0
  6. data/lib/aws-sdk-s3/bucket.rb +671 -139
  7. data/lib/aws-sdk-s3/bucket_acl.rb +12 -12
  8. data/lib/aws-sdk-s3/bucket_cors.rb +16 -16
  9. data/lib/aws-sdk-s3/bucket_lifecycle.rb +21 -16
  10. data/lib/aws-sdk-s3/bucket_lifecycle_configuration.rb +74 -17
  11. data/lib/aws-sdk-s3/bucket_logging.rb +19 -12
  12. data/lib/aws-sdk-s3/bucket_notification.rb +6 -6
  13. data/lib/aws-sdk-s3/bucket_policy.rb +62 -18
  14. data/lib/aws-sdk-s3/bucket_region_cache.rb +9 -5
  15. data/lib/aws-sdk-s3/bucket_request_payment.rb +12 -12
  16. data/lib/aws-sdk-s3/bucket_tagging.rb +16 -16
  17. data/lib/aws-sdk-s3/bucket_versioning.rb +32 -32
  18. data/lib/aws-sdk-s3/bucket_website.rb +16 -16
  19. data/lib/aws-sdk-s3/client.rb +7597 -2823
  20. data/lib/aws-sdk-s3/client_api.rb +288 -22
  21. data/lib/aws-sdk-s3/customizations/bucket.rb +1 -1
  22. data/lib/aws-sdk-s3/customizations/errors.rb +15 -2
  23. data/lib/aws-sdk-s3/customizations/object.rb +11 -5
  24. data/lib/aws-sdk-s3/customizations/object_summary.rb +5 -0
  25. data/lib/aws-sdk-s3/customizations/object_version.rb +13 -0
  26. data/lib/aws-sdk-s3/customizations.rb +25 -31
  27. data/lib/aws-sdk-s3/encryption/client.rb +2 -2
  28. data/lib/aws-sdk-s3/encryption/kms_cipher_provider.rb +2 -2
  29. data/lib/aws-sdk-s3/encryptionV2/client.rb +2 -2
  30. data/lib/aws-sdk-s3/encryptionV2/kms_cipher_provider.rb +2 -2
  31. data/lib/aws-sdk-s3/endpoint_parameters.rb +53 -18
  32. data/lib/aws-sdk-s3/endpoint_provider.rb +125 -6
  33. data/lib/aws-sdk-s3/endpoints.rb +545 -1261
  34. data/lib/aws-sdk-s3/errors.rb +47 -0
  35. data/lib/aws-sdk-s3/express_credentials.rb +55 -0
  36. data/lib/aws-sdk-s3/express_credentials_provider.rb +59 -0
  37. data/lib/aws-sdk-s3/file_downloader.rb +1 -2
  38. data/lib/aws-sdk-s3/file_uploader.rb +1 -1
  39. data/lib/aws-sdk-s3/multipart_file_uploader.rb +4 -4
  40. data/lib/aws-sdk-s3/multipart_stream_uploader.rb +6 -5
  41. data/lib/aws-sdk-s3/multipart_upload.rb +139 -36
  42. data/lib/aws-sdk-s3/multipart_upload_part.rb +175 -54
  43. data/lib/aws-sdk-s3/object.rb +1923 -313
  44. data/lib/aws-sdk-s3/object_acl.rb +34 -22
  45. data/lib/aws-sdk-s3/object_copier.rb +1 -1
  46. data/lib/aws-sdk-s3/object_multipart_copier.rb +10 -8
  47. data/lib/aws-sdk-s3/object_summary.rb +1690 -250
  48. data/lib/aws-sdk-s3/object_version.rb +397 -67
  49. data/lib/aws-sdk-s3/plugins/access_grants.rb +178 -0
  50. data/lib/aws-sdk-s3/plugins/endpoints.rb +32 -208
  51. data/lib/aws-sdk-s3/plugins/express_session_auth.rb +97 -0
  52. data/lib/aws-sdk-s3/plugins/http_200_errors.rb +55 -18
  53. data/lib/aws-sdk-s3/plugins/location_constraint.rb +3 -1
  54. data/lib/aws-sdk-s3/plugins/md5s.rb +2 -1
  55. data/lib/aws-sdk-s3/plugins/s3_signer.rb +7 -2
  56. data/lib/aws-sdk-s3/presigner.rb +5 -2
  57. data/lib/aws-sdk-s3/resource.rb +121 -22
  58. data/lib/aws-sdk-s3/types.rb +5960 -1526
  59. data/lib/aws-sdk-s3.rb +35 -31
  60. data/sig/bucket.rbs +221 -0
  61. data/sig/bucket_acl.rbs +78 -0
  62. data/sig/bucket_cors.rbs +69 -0
  63. data/sig/bucket_lifecycle.rbs +88 -0
  64. data/sig/bucket_lifecycle_configuration.rbs +115 -0
  65. data/sig/bucket_logging.rbs +76 -0
  66. data/sig/bucket_notification.rbs +114 -0
  67. data/sig/bucket_policy.rbs +59 -0
  68. data/sig/bucket_request_payment.rbs +54 -0
  69. data/sig/bucket_tagging.rbs +65 -0
  70. data/sig/bucket_versioning.rbs +77 -0
  71. data/sig/bucket_website.rbs +93 -0
  72. data/sig/client.rbs +2450 -0
  73. data/sig/customizations/bucket.rbs +19 -0
  74. data/sig/customizations/object.rbs +38 -0
  75. data/sig/customizations/object_summary.rbs +35 -0
  76. data/sig/errors.rbs +42 -0
  77. data/sig/multipart_upload.rbs +113 -0
  78. data/sig/multipart_upload_part.rbs +105 -0
  79. data/sig/object.rbs +448 -0
  80. data/sig/object_acl.rbs +86 -0
  81. data/sig/object_summary.rbs +340 -0
  82. data/sig/object_version.rbs +140 -0
  83. data/sig/resource.rbs +132 -0
  84. data/sig/types.rbs +2682 -0
  85. data/sig/waiters.rbs +95 -0
  86. metadata +44 -11
@@ -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
@@ -14,35 +14,58 @@ module Aws::S3
14
14
  option(
15
15
  :endpoint_provider,
16
16
  doc_type: 'Aws::S3::EndpointProvider',
17
- docstring: 'The endpoint provider used to resolve endpoints. Any '\
18
- 'object that responds to `#resolve_endpoint(parameters)` '\
19
- 'where `parameters` is a Struct similar to '\
20
- '`Aws::S3::EndpointParameters`'
21
- ) do |cfg|
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
22
23
  Aws::S3::EndpointProvider.new
23
24
  end
24
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
+
25
35
  # @api private
26
36
  class Handler < Seahorse::Client::Handler
27
37
  def call(context)
28
- # If endpoint was discovered, do not resolve or apply the endpoint.
29
38
  unless context[:discovered_endpoint]
30
- params = parameters_for_operation(context)
39
+ params = Aws::S3::Endpoints.parameters_for_operation(context)
31
40
  endpoint = context.config.endpoint_provider.resolve_endpoint(params)
32
41
 
33
42
  context.http_request.endpoint = endpoint.url
34
43
  apply_endpoint_headers(context, endpoint.headers)
44
+
45
+ context[:endpoint_params] = params
46
+ context[:endpoint_properties] = endpoint.properties
35
47
  end
36
48
 
37
- context[:endpoint_params] = params
38
49
  context[:auth_scheme] =
39
50
  Aws::Endpoints.resolve_auth_scheme(context, endpoint)
40
51
 
41
- @handler.call(context)
52
+ with_metrics(context) { @handler.call(context) }
42
53
  end
43
54
 
44
55
  private
45
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
+
46
69
  def apply_endpoint_headers(context, headers)
47
70
  headers.each do |key, values|
48
71
  value = values
@@ -53,205 +76,6 @@ module Aws::S3
53
76
  context.http_request.headers[key] = value
54
77
  end
55
78
  end
56
-
57
- def parameters_for_operation(context)
58
- case context.operation_name
59
- when :abort_multipart_upload
60
- Aws::S3::Endpoints::AbortMultipartUpload.build(context)
61
- when :complete_multipart_upload
62
- Aws::S3::Endpoints::CompleteMultipartUpload.build(context)
63
- when :copy_object
64
- Aws::S3::Endpoints::CopyObject.build(context)
65
- when :create_bucket
66
- Aws::S3::Endpoints::CreateBucket.build(context)
67
- when :create_multipart_upload
68
- Aws::S3::Endpoints::CreateMultipartUpload.build(context)
69
- when :delete_bucket
70
- Aws::S3::Endpoints::DeleteBucket.build(context)
71
- when :delete_bucket_analytics_configuration
72
- Aws::S3::Endpoints::DeleteBucketAnalyticsConfiguration.build(context)
73
- when :delete_bucket_cors
74
- Aws::S3::Endpoints::DeleteBucketCors.build(context)
75
- when :delete_bucket_encryption
76
- Aws::S3::Endpoints::DeleteBucketEncryption.build(context)
77
- when :delete_bucket_intelligent_tiering_configuration
78
- Aws::S3::Endpoints::DeleteBucketIntelligentTieringConfiguration.build(context)
79
- when :delete_bucket_inventory_configuration
80
- Aws::S3::Endpoints::DeleteBucketInventoryConfiguration.build(context)
81
- when :delete_bucket_lifecycle
82
- Aws::S3::Endpoints::DeleteBucketLifecycle.build(context)
83
- when :delete_bucket_metrics_configuration
84
- Aws::S3::Endpoints::DeleteBucketMetricsConfiguration.build(context)
85
- when :delete_bucket_ownership_controls
86
- Aws::S3::Endpoints::DeleteBucketOwnershipControls.build(context)
87
- when :delete_bucket_policy
88
- Aws::S3::Endpoints::DeleteBucketPolicy.build(context)
89
- when :delete_bucket_replication
90
- Aws::S3::Endpoints::DeleteBucketReplication.build(context)
91
- when :delete_bucket_tagging
92
- Aws::S3::Endpoints::DeleteBucketTagging.build(context)
93
- when :delete_bucket_website
94
- Aws::S3::Endpoints::DeleteBucketWebsite.build(context)
95
- when :delete_object
96
- Aws::S3::Endpoints::DeleteObject.build(context)
97
- when :delete_object_tagging
98
- Aws::S3::Endpoints::DeleteObjectTagging.build(context)
99
- when :delete_objects
100
- Aws::S3::Endpoints::DeleteObjects.build(context)
101
- when :delete_public_access_block
102
- Aws::S3::Endpoints::DeletePublicAccessBlock.build(context)
103
- when :get_bucket_accelerate_configuration
104
- Aws::S3::Endpoints::GetBucketAccelerateConfiguration.build(context)
105
- when :get_bucket_acl
106
- Aws::S3::Endpoints::GetBucketAcl.build(context)
107
- when :get_bucket_analytics_configuration
108
- Aws::S3::Endpoints::GetBucketAnalyticsConfiguration.build(context)
109
- when :get_bucket_cors
110
- Aws::S3::Endpoints::GetBucketCors.build(context)
111
- when :get_bucket_encryption
112
- Aws::S3::Endpoints::GetBucketEncryption.build(context)
113
- when :get_bucket_intelligent_tiering_configuration
114
- Aws::S3::Endpoints::GetBucketIntelligentTieringConfiguration.build(context)
115
- when :get_bucket_inventory_configuration
116
- Aws::S3::Endpoints::GetBucketInventoryConfiguration.build(context)
117
- when :get_bucket_lifecycle
118
- Aws::S3::Endpoints::GetBucketLifecycle.build(context)
119
- when :get_bucket_lifecycle_configuration
120
- Aws::S3::Endpoints::GetBucketLifecycleConfiguration.build(context)
121
- when :get_bucket_location
122
- Aws::S3::Endpoints::GetBucketLocation.build(context)
123
- when :get_bucket_logging
124
- Aws::S3::Endpoints::GetBucketLogging.build(context)
125
- when :get_bucket_metrics_configuration
126
- Aws::S3::Endpoints::GetBucketMetricsConfiguration.build(context)
127
- when :get_bucket_notification
128
- Aws::S3::Endpoints::GetBucketNotification.build(context)
129
- when :get_bucket_notification_configuration
130
- Aws::S3::Endpoints::GetBucketNotificationConfiguration.build(context)
131
- when :get_bucket_ownership_controls
132
- Aws::S3::Endpoints::GetBucketOwnershipControls.build(context)
133
- when :get_bucket_policy
134
- Aws::S3::Endpoints::GetBucketPolicy.build(context)
135
- when :get_bucket_policy_status
136
- Aws::S3::Endpoints::GetBucketPolicyStatus.build(context)
137
- when :get_bucket_replication
138
- Aws::S3::Endpoints::GetBucketReplication.build(context)
139
- when :get_bucket_request_payment
140
- Aws::S3::Endpoints::GetBucketRequestPayment.build(context)
141
- when :get_bucket_tagging
142
- Aws::S3::Endpoints::GetBucketTagging.build(context)
143
- when :get_bucket_versioning
144
- Aws::S3::Endpoints::GetBucketVersioning.build(context)
145
- when :get_bucket_website
146
- Aws::S3::Endpoints::GetBucketWebsite.build(context)
147
- when :get_object
148
- Aws::S3::Endpoints::GetObject.build(context)
149
- when :get_object_acl
150
- Aws::S3::Endpoints::GetObjectAcl.build(context)
151
- when :get_object_attributes
152
- Aws::S3::Endpoints::GetObjectAttributes.build(context)
153
- when :get_object_legal_hold
154
- Aws::S3::Endpoints::GetObjectLegalHold.build(context)
155
- when :get_object_lock_configuration
156
- Aws::S3::Endpoints::GetObjectLockConfiguration.build(context)
157
- when :get_object_retention
158
- Aws::S3::Endpoints::GetObjectRetention.build(context)
159
- when :get_object_tagging
160
- Aws::S3::Endpoints::GetObjectTagging.build(context)
161
- when :get_object_torrent
162
- Aws::S3::Endpoints::GetObjectTorrent.build(context)
163
- when :get_public_access_block
164
- Aws::S3::Endpoints::GetPublicAccessBlock.build(context)
165
- when :head_bucket
166
- Aws::S3::Endpoints::HeadBucket.build(context)
167
- when :head_object
168
- Aws::S3::Endpoints::HeadObject.build(context)
169
- when :list_bucket_analytics_configurations
170
- Aws::S3::Endpoints::ListBucketAnalyticsConfigurations.build(context)
171
- when :list_bucket_intelligent_tiering_configurations
172
- Aws::S3::Endpoints::ListBucketIntelligentTieringConfigurations.build(context)
173
- when :list_bucket_inventory_configurations
174
- Aws::S3::Endpoints::ListBucketInventoryConfigurations.build(context)
175
- when :list_bucket_metrics_configurations
176
- Aws::S3::Endpoints::ListBucketMetricsConfigurations.build(context)
177
- when :list_buckets
178
- Aws::S3::Endpoints::ListBuckets.build(context)
179
- when :list_multipart_uploads
180
- Aws::S3::Endpoints::ListMultipartUploads.build(context)
181
- when :list_object_versions
182
- Aws::S3::Endpoints::ListObjectVersions.build(context)
183
- when :list_objects
184
- Aws::S3::Endpoints::ListObjects.build(context)
185
- when :list_objects_v2
186
- Aws::S3::Endpoints::ListObjectsV2.build(context)
187
- when :list_parts
188
- Aws::S3::Endpoints::ListParts.build(context)
189
- when :put_bucket_accelerate_configuration
190
- Aws::S3::Endpoints::PutBucketAccelerateConfiguration.build(context)
191
- when :put_bucket_acl
192
- Aws::S3::Endpoints::PutBucketAcl.build(context)
193
- when :put_bucket_analytics_configuration
194
- Aws::S3::Endpoints::PutBucketAnalyticsConfiguration.build(context)
195
- when :put_bucket_cors
196
- Aws::S3::Endpoints::PutBucketCors.build(context)
197
- when :put_bucket_encryption
198
- Aws::S3::Endpoints::PutBucketEncryption.build(context)
199
- when :put_bucket_intelligent_tiering_configuration
200
- Aws::S3::Endpoints::PutBucketIntelligentTieringConfiguration.build(context)
201
- when :put_bucket_inventory_configuration
202
- Aws::S3::Endpoints::PutBucketInventoryConfiguration.build(context)
203
- when :put_bucket_lifecycle
204
- Aws::S3::Endpoints::PutBucketLifecycle.build(context)
205
- when :put_bucket_lifecycle_configuration
206
- Aws::S3::Endpoints::PutBucketLifecycleConfiguration.build(context)
207
- when :put_bucket_logging
208
- Aws::S3::Endpoints::PutBucketLogging.build(context)
209
- when :put_bucket_metrics_configuration
210
- Aws::S3::Endpoints::PutBucketMetricsConfiguration.build(context)
211
- when :put_bucket_notification
212
- Aws::S3::Endpoints::PutBucketNotification.build(context)
213
- when :put_bucket_notification_configuration
214
- Aws::S3::Endpoints::PutBucketNotificationConfiguration.build(context)
215
- when :put_bucket_ownership_controls
216
- Aws::S3::Endpoints::PutBucketOwnershipControls.build(context)
217
- when :put_bucket_policy
218
- Aws::S3::Endpoints::PutBucketPolicy.build(context)
219
- when :put_bucket_replication
220
- Aws::S3::Endpoints::PutBucketReplication.build(context)
221
- when :put_bucket_request_payment
222
- Aws::S3::Endpoints::PutBucketRequestPayment.build(context)
223
- when :put_bucket_tagging
224
- Aws::S3::Endpoints::PutBucketTagging.build(context)
225
- when :put_bucket_versioning
226
- Aws::S3::Endpoints::PutBucketVersioning.build(context)
227
- when :put_bucket_website
228
- Aws::S3::Endpoints::PutBucketWebsite.build(context)
229
- when :put_object
230
- Aws::S3::Endpoints::PutObject.build(context)
231
- when :put_object_acl
232
- Aws::S3::Endpoints::PutObjectAcl.build(context)
233
- when :put_object_legal_hold
234
- Aws::S3::Endpoints::PutObjectLegalHold.build(context)
235
- when :put_object_lock_configuration
236
- Aws::S3::Endpoints::PutObjectLockConfiguration.build(context)
237
- when :put_object_retention
238
- Aws::S3::Endpoints::PutObjectRetention.build(context)
239
- when :put_object_tagging
240
- Aws::S3::Endpoints::PutObjectTagging.build(context)
241
- when :put_public_access_block
242
- Aws::S3::Endpoints::PutPublicAccessBlock.build(context)
243
- when :restore_object
244
- Aws::S3::Endpoints::RestoreObject.build(context)
245
- when :select_object_content
246
- Aws::S3::Endpoints::SelectObjectContent.build(context)
247
- when :upload_part
248
- Aws::S3::Endpoints::UploadPart.build(context)
249
- when :upload_part_copy
250
- Aws::S3::Endpoints::UploadPartCopy.build(context)
251
- when :write_get_object_response
252
- Aws::S3::Endpoints::WriteGetObjectResponse.build(context)
253
- end
254
- end
255
79
  end
256
80
 
257
81
  def add_handlers(handlers, _config)
@@ -0,0 +1,97 @@
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
+ if (props = context[:endpoint_properties])
33
+ # S3 Express endpoint - turn off md5 and enable crc32 default
34
+ if props['backend'] == 'S3Express'
35
+ if context.operation_name == :put_object || checksum_required?(context)
36
+ context[:default_request_checksum_algorithm] = 'CRC32'
37
+ end
38
+ context[:s3_express_endpoint] = true
39
+ end
40
+
41
+ # if s3 express auth, use new credentials and sign additional header
42
+ if context[:auth_scheme]['name'] == 'sigv4-s3express' &&
43
+ !context.config.disable_s3_express_session_auth
44
+ bucket = context.params[:bucket]
45
+ credentials_provider = context.config.express_credentials_provider
46
+ credentials = credentials_provider.express_credentials_for(bucket)
47
+ context[:sigv4_credentials] = credentials # Sign will use this
48
+ end
49
+ end
50
+ with_metric(credentials) { @handler.call(context) }
51
+ end
52
+
53
+ private
54
+
55
+ def with_metric(credentials, &block)
56
+ return block.call unless credentials
57
+
58
+ Aws::Plugins::UserAgent.metric('S3_EXPRESS_BUCKET', &block)
59
+ end
60
+
61
+ def checksum_required?(context)
62
+ context.operation.http_checksum_required ||
63
+ (context.operation.http_checksum &&
64
+ context.operation.http_checksum['requestChecksumRequired'])
65
+ end
66
+ end
67
+
68
+ handler(Handler)
69
+
70
+ # Optimization - sets this client as the client to create sessions.
71
+ def after_initialize(client)
72
+ provider = client.config.express_credentials_provider
73
+ provider.client = client unless provider.client
74
+ end
75
+
76
+ class << self
77
+ private
78
+
79
+ def resolve_disable_s3_express_session_auth(cfg)
80
+ value = ENV['AWS_S3_DISABLE_EXPRESS_SESSION_AUTH'] ||
81
+ Aws.shared_config.s3_disable_express_session_auth(profile: cfg.profile) ||
82
+ 'false'
83
+ value = Aws::Util.str_2_bool(value)
84
+ # Raise if provided value is not true or false
85
+ if value.nil?
86
+ raise ArgumentError,
87
+ 'Must provide either `true` or `false` for the '\
88
+ '`s3_disable_express_session_auth` profile option or for '\
89
+ "ENV['AWS_S3_DISABLE_EXPRESS_SESSION_AUTH']."
90
+ end
91
+ value
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -15,22 +15,67 @@ module Aws
15
15
 
16
16
  def call(context)
17
17
  @handler.call(context).on(200) do |response|
18
- if error = check_for_error(context)
19
- context.http_response.status_code = 500
20
- response.data = nil
21
- response.error = error
18
+ return response if streaming_output?(context.operation.output)
19
+
20
+ error = check_for_error(context)
21
+ return response unless error
22
+
23
+ context.http_response.status_code = 500
24
+ response.data = nil
25
+ response.error = error
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ # Streaming outputs are not subject to 200 errors.
32
+ def streaming_output?(output)
33
+ if (payload = output[:payload_member])
34
+ # checking ref and shape
35
+ payload['streaming'] || payload.shape['streaming'] ||
36
+ payload.eventstream
37
+ else
38
+ false
39
+ end
40
+ end
41
+
42
+ # Checks if the output shape is a structure shape and has members that
43
+ # are in the body for the case of a payload and a normal structure. A
44
+ # non-structure shape will not have members in the body. In the case
45
+ # of a string or blob, the body contents would have been checked first
46
+ # before this method is called in incomplete_xml_body?.
47
+ def members_in_body?(output)
48
+ shape =
49
+ if output[:payload_member]
50
+ output[:payload_member].shape
51
+ else
52
+ output.shape
22
53
  end
54
+
55
+ if structure_shape?(shape)
56
+ shape.members.any? { |_, k| k.location.nil? }
57
+ else
58
+ false
23
59
  end
24
60
  end
25
61
 
62
+ def structure_shape?(shape)
63
+ shape.is_a?(Seahorse::Model::Shapes::StructureShape)
64
+ end
65
+
66
+ # Must have a member in the body and have the start of an XML Tag.
67
+ # Other incomplete xml bodies will result in an XML ParsingError.
68
+ def incomplete_xml_body?(xml, output)
69
+ members_in_body?(output) && !xml.match(/<\w/)
70
+ end
71
+
26
72
  def check_for_error(context)
27
73
  xml = context.http_response.body_contents
28
- if xml.match(/<Error>/)
29
- error_code = xml.match(/<Code>(.+?)<\/Code>/)[1]
30
- error_message = xml.match(/<Message>(.+?)<\/Message>/)[1]
74
+ if xml.match(/<\?xml\s[^>]*\?>\s*<Error>/)
75
+ error_code = xml.match(%r{<Code>(.+?)</Code>})[1]
76
+ error_message = xml.match(%r{<Message>(.+?)</Message>})[1]
31
77
  S3::Errors.error_class(error_code).new(context, error_message)
32
- elsif !xml.match(/<\w/) # Must have the start of an XML Tag
33
- # Other incomplete xml bodies will result in XML ParsingError
78
+ elsif incomplete_xml_body?(xml, context.operation.output)
34
79
  Seahorse::Client::NetworkingError.new(
35
80
  S3::Errors
36
81
  .error_class('InternalError')
@@ -40,15 +85,7 @@ module Aws
40
85
  end
41
86
  end
42
87
 
43
- handler(
44
- Handler,
45
- step: :sign,
46
- operations: [
47
- :complete_multipart_upload,
48
- :copy_object,
49
- :upload_part_copy,
50
- ]
51
- )
88
+ handler(Handler, step: :sign)
52
89
  end
53
90
  end
54
91
  end
@@ -22,7 +22,9 @@ module Aws
22
22
 
23
23
  def populate_location_constraint(params, region)
24
24
  params[:create_bucket_configuration] ||= {}
25
- params[:create_bucket_configuration][:location_constraint] ||= region
25
+ unless params[:create_bucket_configuration][:location]
26
+ params[:create_bucket_configuration][:location_constraint] ||= region
27
+ end
26
28
  end
27
29
 
28
30
  end
@@ -22,7 +22,8 @@ module Aws
22
22
  CHUNK_SIZE = 1 * 1024 * 1024 # one MB
23
23
 
24
24
  def call(context)
25
- if !context[:checksum_algorithms] # skip in favor of flexible checksum
25
+ if !context[:checksum_algorithms] && # skip in favor of flexible checksum
26
+ !context[:s3_express_endpoint] # s3 express endpoints do not support md5
26
27
  body = context.http_request.body
27
28
  if body.respond_to?(:size) && body.size > 0
28
29
  context.http_request.headers['Content-Md5'] ||= md5(body)