aws-sdk-s3 1.61.1 → 1.166.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1255 -0
- data/LICENSE.txt +202 -0
- data/VERSION +1 -0
- 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 +814 -112
- data/lib/aws-sdk-s3/bucket_acl.rb +54 -17
- data/lib/aws-sdk-s3/bucket_cors.rb +63 -20
- data/lib/aws-sdk-s3/bucket_lifecycle.rb +63 -19
- data/lib/aws-sdk-s3/bucket_lifecycle_configuration.rb +64 -19
- data/lib/aws-sdk-s3/bucket_logging.rb +58 -17
- data/lib/aws-sdk-s3/bucket_notification.rb +47 -20
- data/lib/aws-sdk-s3/bucket_policy.rb +104 -17
- data/lib/aws-sdk-s3/bucket_region_cache.rb +11 -5
- data/lib/aws-sdk-s3/bucket_request_payment.rb +53 -19
- data/lib/aws-sdk-s3/bucket_tagging.rb +60 -17
- data/lib/aws-sdk-s3/bucket_versioning.rb +106 -17
- data/lib/aws-sdk-s3/bucket_website.rb +64 -19
- data/lib/aws-sdk-s3/client.rb +11280 -3232
- data/lib/aws-sdk-s3/client_api.rb +1078 -197
- data/lib/aws-sdk-s3/customizations/bucket.rb +33 -45
- data/lib/aws-sdk-s3/customizations/errors.rb +40 -0
- data/lib/aws-sdk-s3/customizations/multipart_upload.rb +2 -0
- data/lib/aws-sdk-s3/customizations/object.rb +237 -39
- data/lib/aws-sdk-s3/customizations/object_summary.rb +10 -0
- data/lib/aws-sdk-s3/customizations/object_version.rb +13 -0
- data/lib/aws-sdk-s3/customizations/types/list_object_versions_output.rb +2 -0
- data/lib/aws-sdk-s3/customizations/types/permanent_redirect.rb +26 -0
- data/lib/aws-sdk-s3/customizations.rb +27 -28
- data/lib/aws-sdk-s3/encryption/client.rb +25 -8
- data/lib/aws-sdk-s3/encryption/decrypt_handler.rb +71 -29
- data/lib/aws-sdk-s3/encryption/default_cipher_provider.rb +43 -5
- data/lib/aws-sdk-s3/encryption/default_key_provider.rb +2 -0
- data/lib/aws-sdk-s3/encryption/encrypt_handler.rb +13 -2
- data/lib/aws-sdk-s3/encryption/errors.rb +2 -0
- data/lib/aws-sdk-s3/encryption/io_auth_decrypter.rb +2 -0
- data/lib/aws-sdk-s3/encryption/io_decrypter.rb +11 -3
- data/lib/aws-sdk-s3/encryption/io_encrypter.rb +2 -0
- data/lib/aws-sdk-s3/encryption/key_provider.rb +2 -0
- data/lib/aws-sdk-s3/encryption/kms_cipher_provider.rb +46 -11
- data/lib/aws-sdk-s3/encryption/materials.rb +8 -6
- data/lib/aws-sdk-s3/encryption/utils.rb +25 -0
- data/lib/aws-sdk-s3/encryption.rb +4 -0
- data/lib/aws-sdk-s3/encryptionV2/client.rb +570 -0
- data/lib/aws-sdk-s3/encryptionV2/decrypt_handler.rb +223 -0
- data/lib/aws-sdk-s3/encryptionV2/default_cipher_provider.rb +170 -0
- data/lib/aws-sdk-s3/encryptionV2/default_key_provider.rb +40 -0
- data/lib/aws-sdk-s3/encryptionV2/encrypt_handler.rb +65 -0
- data/lib/aws-sdk-s3/encryptionV2/errors.rb +37 -0
- data/lib/aws-sdk-s3/encryptionV2/io_auth_decrypter.rb +58 -0
- data/lib/aws-sdk-s3/encryptionV2/io_decrypter.rb +37 -0
- data/lib/aws-sdk-s3/encryptionV2/io_encrypter.rb +73 -0
- data/lib/aws-sdk-s3/encryptionV2/key_provider.rb +31 -0
- data/lib/aws-sdk-s3/encryptionV2/kms_cipher_provider.rb +173 -0
- data/lib/aws-sdk-s3/encryptionV2/materials.rb +60 -0
- data/lib/aws-sdk-s3/encryptionV2/utils.rb +103 -0
- data/lib/aws-sdk-s3/encryption_v2.rb +23 -0
- data/lib/aws-sdk-s3/endpoint_parameters.rb +186 -0
- data/lib/aws-sdk-s3/endpoint_provider.rb +592 -0
- data/lib/aws-sdk-s3/endpoints.rb +2392 -0
- data/lib/aws-sdk-s3/errors.rb +27 -1
- data/lib/aws-sdk-s3/event_streams.rb +8 -1
- 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 +176 -44
- data/lib/aws-sdk-s3/file_part.rb +2 -0
- data/lib/aws-sdk-s3/file_uploader.rb +28 -8
- data/lib/aws-sdk-s3/legacy_signer.rb +17 -25
- data/lib/aws-sdk-s3/multipart_file_uploader.rb +69 -13
- data/lib/aws-sdk-s3/multipart_stream_uploader.rb +49 -18
- data/lib/aws-sdk-s3/multipart_upload.rb +242 -25
- data/lib/aws-sdk-s3/multipart_upload_error.rb +2 -0
- data/lib/aws-sdk-s3/multipart_upload_part.rb +343 -31
- data/lib/aws-sdk-s3/object.rb +2240 -218
- data/lib/aws-sdk-s3/object_acl.rb +80 -21
- data/lib/aws-sdk-s3/object_copier.rb +9 -5
- data/lib/aws-sdk-s3/object_multipart_copier.rb +48 -22
- data/lib/aws-sdk-s3/object_summary.rb +1900 -178
- data/lib/aws-sdk-s3/object_version.rb +449 -59
- data/lib/aws-sdk-s3/plugins/accelerate.rb +17 -64
- data/lib/aws-sdk-s3/plugins/access_grants.rb +178 -0
- data/lib/aws-sdk-s3/plugins/arn.rb +70 -0
- data/lib/aws-sdk-s3/plugins/bucket_dns.rb +5 -41
- data/lib/aws-sdk-s3/plugins/bucket_name_restrictions.rb +3 -6
- data/lib/aws-sdk-s3/plugins/dualstack.rb +7 -50
- data/lib/aws-sdk-s3/plugins/endpoints.rb +289 -0
- data/lib/aws-sdk-s3/plugins/expect_100_continue.rb +5 -4
- data/lib/aws-sdk-s3/plugins/express_session_auth.rb +97 -0
- data/lib/aws-sdk-s3/plugins/get_bucket_location_fix.rb +3 -1
- data/lib/aws-sdk-s3/plugins/http_200_errors.rb +60 -15
- data/lib/aws-sdk-s3/plugins/iad_regional_endpoint.rb +11 -27
- data/lib/aws-sdk-s3/plugins/location_constraint.rb +5 -1
- data/lib/aws-sdk-s3/plugins/md5s.rb +32 -26
- data/lib/aws-sdk-s3/plugins/redirects.rb +2 -0
- data/lib/aws-sdk-s3/plugins/s3_host_id.rb +2 -0
- data/lib/aws-sdk-s3/plugins/s3_signer.rb +50 -88
- data/lib/aws-sdk-s3/plugins/skip_whole_multipart_get_checksums.rb +31 -0
- data/lib/aws-sdk-s3/plugins/sse_cpk.rb +3 -1
- data/lib/aws-sdk-s3/plugins/streaming_retry.rb +139 -0
- data/lib/aws-sdk-s3/plugins/url_encoded_keys.rb +2 -0
- data/lib/aws-sdk-s3/presigned_post.rb +160 -103
- data/lib/aws-sdk-s3/presigner.rb +136 -61
- data/lib/aws-sdk-s3/resource.rb +120 -15
- data/lib/aws-sdk-s3/types.rb +9683 -4358
- data/lib/aws-sdk-s3/waiters.rb +67 -1
- data/lib/aws-sdk-s3.rb +40 -29
- data/sig/bucket.rbs +213 -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 +111 -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 +2397 -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 +34 -0
- data/sig/multipart_upload.rbs +111 -0
- data/sig/multipart_upload_part.rbs +105 -0
- data/sig/object.rbs +443 -0
- data/sig/object_acl.rbs +86 -0
- data/sig/object_summary.rbs +335 -0
- data/sig/object_version.rbs +137 -0
- data/sig/resource.rbs +130 -0
- data/sig/types.rbs +2585 -0
- data/sig/waiters.rbs +95 -0
- metadata +73 -15
- data/lib/aws-sdk-s3/plugins/bucket_arn.rb +0 -211
|
@@ -1,20 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'openssl'
|
|
2
4
|
|
|
3
5
|
module Aws
|
|
4
6
|
module S3
|
|
5
7
|
module Plugins
|
|
8
|
+
# @api private
|
|
9
|
+
# This plugin is effectively deprecated in favor of modeled
|
|
10
|
+
# httpChecksumRequired traits.
|
|
6
11
|
class Md5s < Seahorse::Client::Plugin
|
|
7
|
-
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
:
|
|
11
|
-
:
|
|
12
|
-
:put_bucket_lifecycle,
|
|
13
|
-
:put_bucket_policy,
|
|
14
|
-
:put_bucket_tagging,
|
|
15
|
-
:put_object_legal_hold,
|
|
16
|
-
:put_object_lock_configuration,
|
|
17
|
-
:put_object_retention
|
|
12
|
+
# These operations allow Content MD5 but are not required by
|
|
13
|
+
# httpChecksumRequired. This list should not grow.
|
|
14
|
+
OPTIONAL_OPERATIONS = [
|
|
15
|
+
:put_object,
|
|
16
|
+
:upload_part
|
|
18
17
|
]
|
|
19
18
|
|
|
20
19
|
# @api private
|
|
@@ -23,9 +22,12 @@ module Aws
|
|
|
23
22
|
CHUNK_SIZE = 1 * 1024 * 1024 # one MB
|
|
24
23
|
|
|
25
24
|
def call(context)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
context.http_request.
|
|
25
|
+
if !context[:checksum_algorithms] && # skip in favor of flexible checksum
|
|
26
|
+
!context[:s3_express_endpoint] # s3 express endpoints do not support md5
|
|
27
|
+
body = context.http_request.body
|
|
28
|
+
if body.respond_to?(:size) && body.size > 0
|
|
29
|
+
context.http_request.headers['Content-Md5'] ||= md5(body)
|
|
30
|
+
end
|
|
29
31
|
end
|
|
30
32
|
@handler.call(context)
|
|
31
33
|
end
|
|
@@ -47,7 +49,9 @@ module Aws
|
|
|
47
49
|
end
|
|
48
50
|
|
|
49
51
|
def update_in_chunks(digest, io)
|
|
50
|
-
|
|
52
|
+
loop do
|
|
53
|
+
chunk = io.read(CHUNK_SIZE)
|
|
54
|
+
break unless chunk
|
|
51
55
|
digest.update(chunk)
|
|
52
56
|
end
|
|
53
57
|
io.rewind
|
|
@@ -59,20 +63,22 @@ module Aws
|
|
|
59
63
|
default: true,
|
|
60
64
|
doc_type: 'Boolean',
|
|
61
65
|
docstring: <<-DOCS)
|
|
62
|
-
When `true` a MD5 checksum will be computed
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
When `true` a MD5 checksum will be computed and sent in the Content Md5
|
|
67
|
+
header for :put_object and :upload_part. When `false`, MD5 checksums
|
|
68
|
+
will not be computed for these operations. Checksums are still computed
|
|
69
|
+
for operations requiring them. Checksum errors returned by Amazon S3 are
|
|
70
|
+
automatically retried up to `:retry_limit` times.
|
|
66
71
|
DOCS
|
|
67
72
|
|
|
68
73
|
def add_handlers(handlers, config)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
if config.compute_checksums
|
|
75
|
+
# priority set low to ensure md5 is computed AFTER the request is
|
|
76
|
+
# built but before it is signed
|
|
77
|
+
handlers.add(
|
|
78
|
+
Handler,
|
|
79
|
+
priority: 10, step: :build, operations: OPTIONAL_OPERATIONS
|
|
80
|
+
)
|
|
81
|
+
end
|
|
76
82
|
end
|
|
77
83
|
|
|
78
84
|
end
|
|
@@ -1,26 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'aws-sigv4'
|
|
2
4
|
|
|
3
5
|
module Aws
|
|
4
6
|
module S3
|
|
7
|
+
# @api private
|
|
8
|
+
def self.bucket_region_cache
|
|
9
|
+
@bucket_region_cache ||= BucketRegionCache.new
|
|
10
|
+
end
|
|
11
|
+
|
|
5
12
|
module Plugins
|
|
6
|
-
# This plugin
|
|
13
|
+
# This plugin used to have a V4 signer but it was removed in favor of
|
|
14
|
+
# generic Sign plugin that uses endpoint auth scheme.
|
|
15
|
+
#
|
|
7
16
|
# @api private
|
|
8
17
|
class S3Signer < Seahorse::Client::Plugin
|
|
9
18
|
option(:signature_version, 'v4')
|
|
10
19
|
|
|
11
|
-
option(:sigv4_signer) do |cfg|
|
|
12
|
-
S3Signer.build_v4_signer(
|
|
13
|
-
region: cfg.sigv4_region,
|
|
14
|
-
credentials: cfg.credentials
|
|
15
|
-
)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
option(:sigv4_region) do |cfg|
|
|
19
|
-
raise Aws::Errors::MissingRegionError if cfg.region.nil?
|
|
20
|
-
|
|
21
|
-
Aws::Partitions::EndpointProvider.signing_region(cfg.region, 's3')
|
|
22
|
-
end
|
|
23
|
-
|
|
24
20
|
def add_handlers(handlers, cfg)
|
|
25
21
|
case cfg.signature_version
|
|
26
22
|
when 'v4' then add_v4_handlers(handlers)
|
|
@@ -33,11 +29,11 @@ module Aws
|
|
|
33
29
|
|
|
34
30
|
def add_v4_handlers(handlers)
|
|
35
31
|
handlers.add(CachedBucketRegionHandler, step: :sign, priority: 60)
|
|
36
|
-
handlers.add(V4Handler, step: :sign)
|
|
37
32
|
handlers.add(BucketRegionErrorHandler, step: :sign, priority: 40)
|
|
38
33
|
end
|
|
39
34
|
|
|
40
35
|
def add_legacy_handler(handlers)
|
|
36
|
+
# generic Sign plugin will be skipped if it sees sigv2
|
|
41
37
|
handlers.add(LegacyHandler, step: :sign)
|
|
42
38
|
end
|
|
43
39
|
|
|
@@ -48,32 +44,6 @@ module Aws
|
|
|
48
44
|
end
|
|
49
45
|
end
|
|
50
46
|
|
|
51
|
-
class V4Handler < Seahorse::Client::Handler
|
|
52
|
-
def call(context)
|
|
53
|
-
Aws::Plugins::SignatureV4.apply_signature(
|
|
54
|
-
context: context,
|
|
55
|
-
signer: sigv4_signer(context)
|
|
56
|
-
)
|
|
57
|
-
@handler.call(context)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
private
|
|
61
|
-
|
|
62
|
-
def sigv4_signer(context)
|
|
63
|
-
# If the client was configured with the wrong region,
|
|
64
|
-
# we have to build a new signer.
|
|
65
|
-
if context[:cached_sigv4_region] &&
|
|
66
|
-
context[:cached_sigv4_region] != context.config.sigv4_signer.region
|
|
67
|
-
S3Signer.build_v4_signer(
|
|
68
|
-
region: context[:cached_sigv4_region],
|
|
69
|
-
credentials: context.config.credentials
|
|
70
|
-
)
|
|
71
|
-
else
|
|
72
|
-
context.config.sigv4_signer
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
47
|
# This handler will update the http endpoint when the bucket region
|
|
78
48
|
# is known/cached.
|
|
79
49
|
class CachedBucketRegionHandler < Seahorse::Client::Handler
|
|
@@ -86,10 +56,14 @@ module Aws
|
|
|
86
56
|
private
|
|
87
57
|
|
|
88
58
|
def check_for_cached_region(context, bucket)
|
|
89
|
-
cached_region = S3
|
|
90
|
-
if cached_region &&
|
|
91
|
-
|
|
92
|
-
|
|
59
|
+
cached_region = Aws::S3.bucket_region_cache[bucket]
|
|
60
|
+
if cached_region &&
|
|
61
|
+
cached_region != context.config.region &&
|
|
62
|
+
!S3Signer.custom_endpoint?(context)
|
|
63
|
+
context.http_request.endpoint.host = S3Signer.new_hostname(
|
|
64
|
+
context, cached_region
|
|
65
|
+
)
|
|
66
|
+
context[:sigv4_region] = cached_region # Sign plugin will use this
|
|
93
67
|
end
|
|
94
68
|
end
|
|
95
69
|
end
|
|
@@ -97,7 +71,8 @@ module Aws
|
|
|
97
71
|
# This handler detects when a request fails because of a mismatched bucket
|
|
98
72
|
# region. It follows up by making a request to determine the correct
|
|
99
73
|
# region, then finally a version 4 signed request against the correct
|
|
100
|
-
# regional endpoint.
|
|
74
|
+
# regional endpoint. This is intended for s3's global endpoint which
|
|
75
|
+
# will return 400 if the bucket is not in region.
|
|
101
76
|
class BucketRegionErrorHandler < Seahorse::Client::Handler
|
|
102
77
|
def call(context)
|
|
103
78
|
response = @handler.call(context)
|
|
@@ -109,7 +84,8 @@ module Aws
|
|
|
109
84
|
def handle_region_errors(response)
|
|
110
85
|
if wrong_sigv4_region?(response) &&
|
|
111
86
|
!fips_region?(response) &&
|
|
112
|
-
!custom_endpoint?(response)
|
|
87
|
+
!S3Signer.custom_endpoint?(response.context) &&
|
|
88
|
+
!expired_credentials?(response)
|
|
113
89
|
get_region_and_retry(response.context)
|
|
114
90
|
else
|
|
115
91
|
response
|
|
@@ -126,18 +102,15 @@ module Aws
|
|
|
126
102
|
end
|
|
127
103
|
|
|
128
104
|
def update_bucket_cache(context, actual_region)
|
|
129
|
-
S3
|
|
105
|
+
Aws::S3.bucket_region_cache[context.params[:bucket]] = actual_region
|
|
130
106
|
end
|
|
131
107
|
|
|
132
108
|
def fips_region?(resp)
|
|
133
|
-
resp.context.http_request.endpoint.host.include?('fips')
|
|
109
|
+
resp.context.http_request.endpoint.host.include?('s3-fips.')
|
|
134
110
|
end
|
|
135
111
|
|
|
136
|
-
def
|
|
137
|
-
|
|
138
|
-
resp.context.config.region
|
|
139
|
-
)
|
|
140
|
-
!resp.context.http_request.endpoint.hostname.include?(resolved_suffix)
|
|
112
|
+
def expired_credentials?(resp)
|
|
113
|
+
resp.context.http_response.body_contents.match(/<Code>ExpiredToken<\/Code>/)
|
|
141
114
|
end
|
|
142
115
|
|
|
143
116
|
def wrong_sigv4_region?(resp)
|
|
@@ -148,15 +121,18 @@ module Aws
|
|
|
148
121
|
|
|
149
122
|
def resign_with_new_region(context, actual_region)
|
|
150
123
|
context.http_response.body.truncate(0)
|
|
151
|
-
context.http_request.endpoint.host = S3Signer.new_hostname(
|
|
124
|
+
context.http_request.endpoint.host = S3Signer.new_hostname(
|
|
125
|
+
context, actual_region
|
|
126
|
+
)
|
|
152
127
|
context.metadata[:redirect_region] = actual_region
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
)
|
|
128
|
+
|
|
129
|
+
signer = Aws::Plugins::Sign.signer_for(
|
|
130
|
+
context[:auth_scheme],
|
|
131
|
+
context.config,
|
|
132
|
+
actual_region
|
|
159
133
|
)
|
|
134
|
+
|
|
135
|
+
signer.sign(context)
|
|
160
136
|
end
|
|
161
137
|
|
|
162
138
|
def region_from_body(body)
|
|
@@ -182,36 +158,22 @@ module Aws
|
|
|
182
158
|
end
|
|
183
159
|
|
|
184
160
|
class << self
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
credentials_provider: options[:credentials],
|
|
193
|
-
uri_escape_path: false,
|
|
194
|
-
unsigned_headers: ['content-length', 'x-amzn-trace-id']
|
|
195
|
-
)
|
|
161
|
+
def new_hostname(context, region)
|
|
162
|
+
endpoint_params = context[:endpoint_params].dup
|
|
163
|
+
endpoint_params.region = region
|
|
164
|
+
endpoint_params.endpoint = nil
|
|
165
|
+
endpoint =
|
|
166
|
+
context.config.endpoint_provider.resolve_endpoint(endpoint_params)
|
|
167
|
+
URI(endpoint.url).host
|
|
196
168
|
end
|
|
197
169
|
|
|
198
|
-
def
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
context.params[:bucket],
|
|
203
|
-
region,
|
|
204
|
-
context.config.s3_use_arn_region
|
|
205
|
-
)
|
|
206
|
-
uri = URI.parse(
|
|
207
|
-
Aws::Partitions::EndpointProvider.resolve(resolved_region, 's3')
|
|
208
|
-
)
|
|
170
|
+
def custom_endpoint?(context)
|
|
171
|
+
region = context.config.region
|
|
172
|
+
partition = Aws::Endpoints::Matchers.aws_partition(region)
|
|
173
|
+
endpoint = context.http_request.endpoint
|
|
209
174
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
else
|
|
213
|
-
resolved_bucket + '.' + uri.host
|
|
214
|
-
end
|
|
175
|
+
!endpoint.hostname.include?(partition['dnsSuffix']) &&
|
|
176
|
+
!endpoint.hostname.include?(partition['dualStackDnsSuffix'])
|
|
215
177
|
end
|
|
216
178
|
end
|
|
217
179
|
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Aws
|
|
4
|
+
module S3
|
|
5
|
+
module Plugins
|
|
6
|
+
|
|
7
|
+
# S3 GetObject results for whole Multipart Objects contain a checksum
|
|
8
|
+
# that cannot be validated. These should be skipped by the
|
|
9
|
+
# ChecksumAlgorithm plugin.
|
|
10
|
+
class SkipWholeMultipartGetChecksums < Seahorse::Client::Plugin
|
|
11
|
+
|
|
12
|
+
class Handler < Seahorse::Client::Handler
|
|
13
|
+
|
|
14
|
+
def call(context)
|
|
15
|
+
context[:http_checksum] ||= {}
|
|
16
|
+
context[:http_checksum][:skip_on_suffix] = true
|
|
17
|
+
|
|
18
|
+
@handler.call(context)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
handler(
|
|
24
|
+
Handler,
|
|
25
|
+
step: :initialize,
|
|
26
|
+
operations: [:get_object]
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'uri'
|
|
2
4
|
require 'openssl'
|
|
3
5
|
|
|
@@ -18,7 +20,7 @@ This should only be disabled for local testing.
|
|
|
18
20
|
class Handler < Seahorse::Client::Handler
|
|
19
21
|
|
|
20
22
|
def call(context)
|
|
21
|
-
compute_key_md5(context)
|
|
23
|
+
compute_key_md5(context) if context.params.is_a?(Hash)
|
|
22
24
|
@handler.call(context)
|
|
23
25
|
end
|
|
24
26
|
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'forwardable'
|
|
4
|
+
|
|
5
|
+
module Aws
|
|
6
|
+
module S3
|
|
7
|
+
module Plugins
|
|
8
|
+
|
|
9
|
+
# A wrapper around BlockIO that adds no-ops for truncate and rewind
|
|
10
|
+
# @api private
|
|
11
|
+
class RetryableBlockIO
|
|
12
|
+
extend Forwardable
|
|
13
|
+
def_delegators :@block_io, :write, :read, :size
|
|
14
|
+
|
|
15
|
+
def initialize(block_io)
|
|
16
|
+
@block_io = block_io
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def truncate(_integer); end
|
|
20
|
+
|
|
21
|
+
def rewind; end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# A wrapper around ManagedFile that adds no-ops for truncate and rewind
|
|
25
|
+
# @api private
|
|
26
|
+
class RetryableManagedFile
|
|
27
|
+
extend Forwardable
|
|
28
|
+
def_delegators :@file, :write, :read, :size, :open?, :close
|
|
29
|
+
|
|
30
|
+
def initialize(managed_file)
|
|
31
|
+
@file = managed_file
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def truncate(_integer); end
|
|
35
|
+
|
|
36
|
+
def rewind; end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
class NonRetryableStreamingError < StandardError
|
|
40
|
+
|
|
41
|
+
def initialize(error)
|
|
42
|
+
super('Unable to retry request - retry could result in processing duplicated chunks.')
|
|
43
|
+
set_backtrace(error.backtrace)
|
|
44
|
+
@original_error = error
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
attr_reader :original_error
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# This handler works with the ResponseTarget plugin to provide smart
|
|
51
|
+
# retries of S3 streaming operations that support the range parameter
|
|
52
|
+
# (currently only: get_object). When a 200 OK with a TruncatedBodyError
|
|
53
|
+
# is received this handler will add a range header that excludes the
|
|
54
|
+
# data that has already been processed (written to file or sent to
|
|
55
|
+
# the target Proc).
|
|
56
|
+
# It is important to not write data to the custom target in the case of
|
|
57
|
+
# a non-success response. We do not want to write an XML error
|
|
58
|
+
# message to someone's file or pass it to a user's Proc.
|
|
59
|
+
# @api private
|
|
60
|
+
class StreamingRetry < Seahorse::Client::Plugin
|
|
61
|
+
|
|
62
|
+
class Handler < Seahorse::Client::Handler
|
|
63
|
+
|
|
64
|
+
def call(context)
|
|
65
|
+
target = context.params[:response_target] || context[:response_target]
|
|
66
|
+
|
|
67
|
+
# retry is only supported when range is NOT set on the initial request
|
|
68
|
+
if supported_target?(target) && !context.params[:range]
|
|
69
|
+
add_event_listeners(context, target)
|
|
70
|
+
end
|
|
71
|
+
@handler.call(context)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def add_event_listeners(context, target)
|
|
77
|
+
context.http_response.on_headers(200..299) do
|
|
78
|
+
case context.http_response.body
|
|
79
|
+
when Seahorse::Client::BlockIO then
|
|
80
|
+
context.http_response.body = RetryableBlockIO.new(context.http_response.body)
|
|
81
|
+
when Seahorse::Client::ManagedFile then
|
|
82
|
+
context.http_response.body = RetryableManagedFile.new(context.http_response.body)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
context.http_response.on_headers(400..599) do
|
|
87
|
+
context.http_response.body = StringIO.new # something to write the error to
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
context.http_response.on_success(200..299) do
|
|
91
|
+
body = context.http_response.body
|
|
92
|
+
if body.is_a?(RetryableManagedFile) && body.open?
|
|
93
|
+
body.close
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
context.http_response.on_error do |error|
|
|
98
|
+
if retryable_body?(context)
|
|
99
|
+
if truncated_body?(error)
|
|
100
|
+
context.http_request.headers[:range] = "bytes=#{context.http_response.body.size}-"
|
|
101
|
+
else
|
|
102
|
+
case context.http_response.body
|
|
103
|
+
when RetryableManagedFile
|
|
104
|
+
# call rewind on the underlying file
|
|
105
|
+
context.http_response.body.instance_variable_get(:@file).rewind
|
|
106
|
+
else
|
|
107
|
+
raise NonRetryableStreamingError, error
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def truncated_body?(error)
|
|
115
|
+
error.is_a?(Seahorse::Client::NetworkingError) &&
|
|
116
|
+
error.original_error.is_a?(
|
|
117
|
+
Seahorse::Client::NetHttp::Handler::TruncatedBodyError
|
|
118
|
+
)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def retryable_body?(context)
|
|
122
|
+
context.http_response.body.is_a?(RetryableBlockIO) ||
|
|
123
|
+
context.http_response.body.is_a?(RetryableManagedFile)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def supported_target?(target)
|
|
127
|
+
case target
|
|
128
|
+
when Proc, String, Pathname then true
|
|
129
|
+
else false
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
handler(Handler, step: :sign, operations: [:get_object], priority: 10)
|
|
135
|
+
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|