aws-sdk-s3 1.136.0 → 1.176.1

Sign up to get free protection for your applications and to get access to all the features.
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)