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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +250 -1
- data/VERSION +1 -1
- data/lib/aws-sdk-s3/access_grants_credentials.rb +57 -0
- data/lib/aws-sdk-s3/access_grants_credentials_provider.rb +250 -0
- data/lib/aws-sdk-s3/bucket.rb +671 -139
- data/lib/aws-sdk-s3/bucket_acl.rb +12 -12
- data/lib/aws-sdk-s3/bucket_cors.rb +16 -16
- data/lib/aws-sdk-s3/bucket_lifecycle.rb +21 -16
- data/lib/aws-sdk-s3/bucket_lifecycle_configuration.rb +74 -17
- data/lib/aws-sdk-s3/bucket_logging.rb +19 -12
- data/lib/aws-sdk-s3/bucket_notification.rb +6 -6
- data/lib/aws-sdk-s3/bucket_policy.rb +62 -18
- data/lib/aws-sdk-s3/bucket_region_cache.rb +9 -5
- data/lib/aws-sdk-s3/bucket_request_payment.rb +12 -12
- data/lib/aws-sdk-s3/bucket_tagging.rb +16 -16
- data/lib/aws-sdk-s3/bucket_versioning.rb +32 -32
- data/lib/aws-sdk-s3/bucket_website.rb +16 -16
- data/lib/aws-sdk-s3/client.rb +7597 -2823
- data/lib/aws-sdk-s3/client_api.rb +288 -22
- data/lib/aws-sdk-s3/customizations/bucket.rb +1 -1
- data/lib/aws-sdk-s3/customizations/errors.rb +15 -2
- data/lib/aws-sdk-s3/customizations/object.rb +11 -5
- data/lib/aws-sdk-s3/customizations/object_summary.rb +5 -0
- data/lib/aws-sdk-s3/customizations/object_version.rb +13 -0
- data/lib/aws-sdk-s3/customizations.rb +25 -31
- data/lib/aws-sdk-s3/encryption/client.rb +2 -2
- data/lib/aws-sdk-s3/encryption/kms_cipher_provider.rb +2 -2
- data/lib/aws-sdk-s3/encryptionV2/client.rb +2 -2
- data/lib/aws-sdk-s3/encryptionV2/kms_cipher_provider.rb +2 -2
- data/lib/aws-sdk-s3/endpoint_parameters.rb +53 -18
- data/lib/aws-sdk-s3/endpoint_provider.rb +125 -6
- data/lib/aws-sdk-s3/endpoints.rb +545 -1261
- data/lib/aws-sdk-s3/errors.rb +47 -0
- data/lib/aws-sdk-s3/express_credentials.rb +55 -0
- data/lib/aws-sdk-s3/express_credentials_provider.rb +59 -0
- data/lib/aws-sdk-s3/file_downloader.rb +1 -2
- data/lib/aws-sdk-s3/file_uploader.rb +1 -1
- data/lib/aws-sdk-s3/multipart_file_uploader.rb +4 -4
- data/lib/aws-sdk-s3/multipart_stream_uploader.rb +6 -5
- data/lib/aws-sdk-s3/multipart_upload.rb +139 -36
- data/lib/aws-sdk-s3/multipart_upload_part.rb +175 -54
- data/lib/aws-sdk-s3/object.rb +1923 -313
- data/lib/aws-sdk-s3/object_acl.rb +34 -22
- data/lib/aws-sdk-s3/object_copier.rb +1 -1
- data/lib/aws-sdk-s3/object_multipart_copier.rb +10 -8
- data/lib/aws-sdk-s3/object_summary.rb +1690 -250
- data/lib/aws-sdk-s3/object_version.rb +397 -67
- data/lib/aws-sdk-s3/plugins/access_grants.rb +178 -0
- data/lib/aws-sdk-s3/plugins/endpoints.rb +32 -208
- data/lib/aws-sdk-s3/plugins/express_session_auth.rb +97 -0
- data/lib/aws-sdk-s3/plugins/http_200_errors.rb +55 -18
- data/lib/aws-sdk-s3/plugins/location_constraint.rb +3 -1
- data/lib/aws-sdk-s3/plugins/md5s.rb +2 -1
- data/lib/aws-sdk-s3/plugins/s3_signer.rb +7 -2
- data/lib/aws-sdk-s3/presigner.rb +5 -2
- data/lib/aws-sdk-s3/resource.rb +121 -22
- data/lib/aws-sdk-s3/types.rb +5960 -1526
- data/lib/aws-sdk-s3.rb +35 -31
- data/sig/bucket.rbs +221 -0
- data/sig/bucket_acl.rbs +78 -0
- data/sig/bucket_cors.rbs +69 -0
- data/sig/bucket_lifecycle.rbs +88 -0
- data/sig/bucket_lifecycle_configuration.rbs +115 -0
- data/sig/bucket_logging.rbs +76 -0
- data/sig/bucket_notification.rbs +114 -0
- data/sig/bucket_policy.rbs +59 -0
- data/sig/bucket_request_payment.rbs +54 -0
- data/sig/bucket_tagging.rbs +65 -0
- data/sig/bucket_versioning.rbs +77 -0
- data/sig/bucket_website.rbs +93 -0
- data/sig/client.rbs +2450 -0
- data/sig/customizations/bucket.rbs +19 -0
- data/sig/customizations/object.rbs +38 -0
- data/sig/customizations/object_summary.rbs +35 -0
- data/sig/errors.rbs +42 -0
- data/sig/multipart_upload.rbs +113 -0
- data/sig/multipart_upload_part.rbs +105 -0
- data/sig/object.rbs +448 -0
- data/sig/object_acl.rbs +86 -0
- data/sig/object_summary.rbs +340 -0
- data/sig/object_version.rbs +140 -0
- data/sig/resource.rbs +132 -0
- data/sig/types.rbs +2682 -0
- data/sig/waiters.rbs +95 -0
- 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
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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(
|
29
|
-
error_code = xml.match(
|
30
|
-
error_message = xml.match(
|
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
|
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][:
|
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)
|