aws-sdk-s3 1.69.1 → 1.74.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/lib/aws-sdk-s3.rb +1 -1
- data/lib/aws-sdk-s3/client.rb +4 -2
- data/lib/aws-sdk-s3/encryptionV2/io_decrypter.rb +6 -1
- data/lib/aws-sdk-s3/encryptionV2/io_encrypter.rb +6 -2
- data/lib/aws-sdk-s3/plugins/accelerate.rb +24 -37
- data/lib/aws-sdk-s3/plugins/http_200_errors.rb +2 -1
- data/lib/aws-sdk-s3/plugins/streaming_retry.rb +118 -0
- data/lib/aws-sdk-s3/presigned_post.rb +61 -28
- data/lib/aws-sdk-s3/types.rb +263 -0
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 626495d85d0f33f1a04615e2c65aca4331f8ac04b35306d2e68668eb1cbad727
|
4
|
+
data.tar.gz: 324b43984913dedda5bd63af0608eb9ba01feab28e8ff15ee5ceb7b1cb5d5578
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f4958752f8508e3d4ecdb0ad22bc5184f3c9e8c9c6e035bfcb5cabda3897fb8fec2b3da206499689f400c001e83e1d364daeea687bff71cbcc1b910779936058
|
7
|
+
data.tar.gz: ef54aeb2dc6373afe0b806a4e88ca85ed81eedba190da89c7370d10eea5535f6f608ba80539b7c5b31f3198ab64767afda81c8560475c9268155af373e1d23ff
|
data/lib/aws-sdk-s3.rb
CHANGED
data/lib/aws-sdk-s3/client.rb
CHANGED
@@ -44,6 +44,7 @@ require 'aws-sdk-s3/plugins/sse_cpk.rb'
|
|
44
44
|
require 'aws-sdk-s3/plugins/url_encoded_keys.rb'
|
45
45
|
require 'aws-sdk-s3/plugins/s3_signer.rb'
|
46
46
|
require 'aws-sdk-s3/plugins/bucket_name_restrictions.rb'
|
47
|
+
require 'aws-sdk-s3/plugins/streaming_retry.rb'
|
47
48
|
require 'aws-sdk-core/plugins/event_stream_configuration.rb'
|
48
49
|
|
49
50
|
Aws::Plugins::GlobalConfiguration.add_identifier(:s3)
|
@@ -106,6 +107,7 @@ module Aws::S3
|
|
106
107
|
add_plugin(Aws::S3::Plugins::UrlEncodedKeys)
|
107
108
|
add_plugin(Aws::S3::Plugins::S3Signer)
|
108
109
|
add_plugin(Aws::S3::Plugins::BucketNameRestrictions)
|
110
|
+
add_plugin(Aws::S3::Plugins::StreamingRetry)
|
109
111
|
add_plugin(Aws::Plugins::EventStreamConfiguration)
|
110
112
|
|
111
113
|
# @overload initialize(options)
|
@@ -333,7 +335,7 @@ module Aws::S3
|
|
333
335
|
# @option options [Boolean] :use_accelerate_endpoint (false)
|
334
336
|
# When set to `true`, accelerated bucket endpoints will be used
|
335
337
|
# for all object operations. You must first enable accelerate for
|
336
|
-
# each bucket.
|
338
|
+
# each bucket. [Go here for more information](http://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html).
|
337
339
|
#
|
338
340
|
# @option options [Boolean] :use_dualstack_endpoint (false)
|
339
341
|
# When set to `true`, IPv6-compatible bucket endpoints will be used
|
@@ -11670,7 +11672,7 @@ module Aws::S3
|
|
11670
11672
|
params: params,
|
11671
11673
|
config: config)
|
11672
11674
|
context[:gem_name] = 'aws-sdk-s3'
|
11673
|
-
context[:gem_version] = '1.
|
11675
|
+
context[:gem_version] = '1.74.0'
|
11674
11676
|
Seahorse::Client::Request.new(handlers, context)
|
11675
11677
|
end
|
11676
11678
|
|
@@ -10,6 +10,7 @@ module Aws
|
|
10
10
|
@cipher = cipher
|
11
11
|
# Ensure that IO is reset between retries
|
12
12
|
@io = io.tap { |io| io.truncate(0) if io.respond_to?(:truncate) }
|
13
|
+
@cipher_buffer = String.new
|
13
14
|
end
|
14
15
|
|
15
16
|
# @return [#write]
|
@@ -17,7 +18,11 @@ module Aws
|
|
17
18
|
|
18
19
|
def write(chunk)
|
19
20
|
# decrypt and write
|
20
|
-
@
|
21
|
+
if @cipher.method(:update).arity == 1
|
22
|
+
@io.write(@cipher.update(chunk))
|
23
|
+
else
|
24
|
+
@io.write(@cipher.update(chunk, @cipher_buffer))
|
25
|
+
end
|
21
26
|
end
|
22
27
|
|
23
28
|
def finalize
|
@@ -52,8 +52,12 @@ module Aws
|
|
52
52
|
def encrypt_to_tempfile(cipher, io)
|
53
53
|
encrypted = Tempfile.new(self.object_id.to_s)
|
54
54
|
encrypted.binmode
|
55
|
-
while chunk = io.read(ONE_MEGABYTE)
|
56
|
-
|
55
|
+
while chunk = io.read(ONE_MEGABYTE, read_buffer ||= String.new)
|
56
|
+
if cipher.method(:update).arity == 1
|
57
|
+
encrypted.write(cipher.update(chunk))
|
58
|
+
else
|
59
|
+
encrypted.write(cipher.update(chunk, cipher_buffer ||= String.new))
|
60
|
+
end
|
57
61
|
end
|
58
62
|
encrypted.write(cipher.final)
|
59
63
|
encrypted.write(cipher.auth_tag)
|
@@ -3,36 +3,44 @@
|
|
3
3
|
module Aws
|
4
4
|
module S3
|
5
5
|
module Plugins
|
6
|
-
|
7
6
|
# Provides support for using `Aws::S3::Client` with Amazon S3 Transfer
|
8
7
|
# Acceleration.
|
9
8
|
#
|
10
9
|
# Go here for more information about transfer acceleration:
|
11
10
|
# [http://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html](http://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html)
|
12
11
|
class Accelerate < Seahorse::Client::Plugin
|
13
|
-
|
14
|
-
|
12
|
+
option(
|
13
|
+
:use_accelerate_endpoint,
|
15
14
|
default: false,
|
16
15
|
doc_type: 'Boolean',
|
17
16
|
docstring: <<-DOCS)
|
18
17
|
When set to `true`, accelerated bucket endpoints will be used
|
19
18
|
for all object operations. You must first enable accelerate for
|
20
|
-
each bucket.
|
19
|
+
each bucket. [Go here for more information](http://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html).
|
21
20
|
DOCS
|
22
21
|
|
23
22
|
def add_handlers(handlers, config)
|
24
23
|
operations = config.api.operation_names - [
|
25
|
-
:create_bucket, :list_buckets, :delete_bucket
|
24
|
+
:create_bucket, :list_buckets, :delete_bucket
|
26
25
|
]
|
27
|
-
handlers
|
28
|
-
|
26
|
+
# Need 2 handlers so that the context can be set for other plugins
|
27
|
+
# and to remove :use_accelerate_endpoint from the params.
|
28
|
+
handlers.add(
|
29
|
+
OptionHandler, step: :initialize, operations: operations
|
30
|
+
)
|
31
|
+
handlers.add(
|
32
|
+
AccelerateHandler, step: :build, priority: 0, operations: operations
|
33
|
+
)
|
29
34
|
end
|
30
35
|
|
31
36
|
# @api private
|
32
37
|
class OptionHandler < Seahorse::Client::Handler
|
33
38
|
def call(context)
|
39
|
+
# Support client configuration and per-operation configuration
|
34
40
|
accelerate = context.params.delete(:use_accelerate_endpoint)
|
35
|
-
|
41
|
+
if accelerate.nil?
|
42
|
+
accelerate = context.config.use_accelerate_endpoint
|
43
|
+
end
|
36
44
|
context[:use_accelerate_endpoint] = accelerate
|
37
45
|
@handler.call(context)
|
38
46
|
end
|
@@ -40,39 +48,24 @@ each bucket. [Go here for more information](http://docs.aws.amazon.com/AmazonS3
|
|
40
48
|
|
41
49
|
# @api private
|
42
50
|
class AccelerateHandler < Seahorse::Client::Handler
|
43
|
-
|
44
51
|
def call(context)
|
45
52
|
if context[:use_accelerate_endpoint]
|
46
|
-
|
47
|
-
|
48
|
-
else
|
49
|
-
use_accelerate_endpoint(context)
|
50
|
-
end
|
53
|
+
dualstack = !!context[:use_dualstack_endpoint]
|
54
|
+
use_accelerate_endpoint(context, dualstack)
|
51
55
|
end
|
52
56
|
@handler.call(context)
|
53
57
|
end
|
54
58
|
|
55
59
|
private
|
56
60
|
|
57
|
-
def use_accelerate_endpoint(context)
|
58
|
-
bucket_name = context.params[:bucket]
|
59
|
-
validate_bucket_name!(bucket_name)
|
60
|
-
endpoint = URI.parse(context.http_request.endpoint.to_s)
|
61
|
-
endpoint.scheme = 'https'
|
62
|
-
endpoint.port = 443
|
63
|
-
endpoint.host = "#{bucket_name}.s3-accelerate.amazonaws.com"
|
64
|
-
context.http_request.endpoint = endpoint.to_s
|
65
|
-
# s3 accelerate endpoint doesn't work with 'expect' header
|
66
|
-
context.http_request.headers.delete('expect')
|
67
|
-
end
|
68
|
-
|
69
|
-
def use_combined_accelerate_dualstack_endpoint(context)
|
61
|
+
def use_accelerate_endpoint(context, dualstack)
|
70
62
|
bucket_name = context.params[:bucket]
|
71
63
|
validate_bucket_name!(bucket_name)
|
72
64
|
endpoint = URI.parse(context.http_request.endpoint.to_s)
|
73
65
|
endpoint.scheme = 'https'
|
74
66
|
endpoint.port = 443
|
75
|
-
endpoint.host = "#{bucket_name}.s3-accelerate
|
67
|
+
endpoint.host = "#{bucket_name}.s3-accelerate"\
|
68
|
+
"#{'.dualstack' if dualstack}.amazonaws.com"
|
76
69
|
context.http_request.endpoint = endpoint.to_s
|
77
70
|
# s3 accelerate endpoint doesn't work with 'expect' header
|
78
71
|
context.http_request.headers.delete('expect')
|
@@ -80,17 +73,11 @@ each bucket. [Go here for more information](http://docs.aws.amazon.com/AmazonS3
|
|
80
73
|
|
81
74
|
def validate_bucket_name!(bucket_name)
|
82
75
|
unless BucketDns.dns_compatible?(bucket_name, _ssl = true)
|
83
|
-
|
84
|
-
'
|
85
|
-
|
86
|
-
end
|
87
|
-
if bucket_name.include?('.')
|
88
|
-
msg = 'unable to use `accelerate: true` on buckets with dots'\
|
89
|
-
"in their name: #{bucket_name.inspect}"
|
90
|
-
raise ArgumentError, msg
|
76
|
+
raise ArgumentError,
|
77
|
+
'Unable to use `use_accelerate_endpoint: true` on buckets '\
|
78
|
+
'with non-DNS compatible names.'
|
91
79
|
end
|
92
80
|
end
|
93
|
-
|
94
81
|
end
|
95
82
|
end
|
96
83
|
end
|
@@ -0,0 +1,118 @@
|
|
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
|
+
# This handler works with the ResponseTarget plugin to provide smart
|
40
|
+
# retries of S3 streaming operations that support the range parameter
|
41
|
+
# (currently only: get_object). When a 200 OK with a TruncatedBodyError
|
42
|
+
# is received this handler will add a range header that excludes the
|
43
|
+
# data that has already been processed (written to file or sent to
|
44
|
+
# the target Proc).
|
45
|
+
# It is important to not write data to the custom target in the case of
|
46
|
+
# a non-success response. We do not want to write an XML error
|
47
|
+
# message to someone's file or pass it to a user's Proc.
|
48
|
+
# @api private
|
49
|
+
class StreamingRetry < Seahorse::Client::Plugin
|
50
|
+
|
51
|
+
class Handler < Seahorse::Client::Handler
|
52
|
+
|
53
|
+
def call(context)
|
54
|
+
target = context.params[:response_target] || context[:response_target]
|
55
|
+
|
56
|
+
# retry is only supported when range is NOT set on the initial request
|
57
|
+
if supported_target?(target) && !context.params[:range]
|
58
|
+
add_event_listeners(context, target)
|
59
|
+
end
|
60
|
+
@handler.call(context)
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def add_event_listeners(context, target)
|
66
|
+
context.http_response.on_headers(200..299) do
|
67
|
+
case context.http_response.body
|
68
|
+
when Seahorse::Client::BlockIO then
|
69
|
+
context.http_response.body = RetryableBlockIO.new(context.http_response.body)
|
70
|
+
when Seahorse::Client::ManagedFile then
|
71
|
+
context.http_response.body = RetryableManagedFile.new(context.http_response.body)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context.http_response.on_headers(400..599) do
|
76
|
+
context.http_response.body = StringIO.new # something to write the error to
|
77
|
+
end
|
78
|
+
|
79
|
+
context.http_response.on_success(200..299) do
|
80
|
+
body = context.http_response.body
|
81
|
+
if body.is_a?(RetryableManagedFile) && body.open?
|
82
|
+
body.close
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context.http_response.on_error do |error|
|
87
|
+
if retryable_body?(context) && truncated_body?(error)
|
88
|
+
context.http_request.headers[:range] = "bytes=#{context.http_response.body.size}-"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def truncated_body?(error)
|
94
|
+
error.is_a?(Seahorse::Client::NetworkingError) &&
|
95
|
+
error.original_error.is_a?(
|
96
|
+
Seahorse::Client::NetHttp::Handler::TruncatedBodyError
|
97
|
+
)
|
98
|
+
end
|
99
|
+
|
100
|
+
def retryable_body?(context)
|
101
|
+
context.http_response.body.is_a?(RetryableBlockIO) ||
|
102
|
+
context.http_response.body.is_a?(RetryableManagedFile)
|
103
|
+
end
|
104
|
+
|
105
|
+
def supported_target?(target)
|
106
|
+
case target
|
107
|
+
when Proc, String, Pathname then true
|
108
|
+
else false
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
handler(Handler, step: :sign, operations: [:get_object], priority: 10)
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -185,35 +185,58 @@ module Aws
|
|
185
185
|
# the post will expire. Defaults to one hour from creation of the
|
186
186
|
# presigned post. May not exceed one week from creation time.
|
187
187
|
# @option options [String] :key See {PresignedPost#key}.
|
188
|
-
# @option options [String] :key_starts_with
|
188
|
+
# @option options [String] :key_starts_with
|
189
|
+
# See {PresignedPost#key_starts_with}.
|
189
190
|
# @option options [String] :acl See {PresignedPost#acl}.
|
190
|
-
# @option options [String] :acl_starts_with
|
191
|
-
#
|
192
|
-
# @option options [String] :
|
191
|
+
# @option options [String] :acl_starts_with
|
192
|
+
# See {PresignedPost#acl_starts_with}.
|
193
|
+
# @option options [String] :cache_control
|
194
|
+
# See {PresignedPost#cache_control}.
|
195
|
+
# @option options [String] :cache_control_starts_with
|
196
|
+
# See {PresignedPost#cache_control_starts_with}.
|
193
197
|
# @option options [String] :content_type See {PresignedPost#content_type}.
|
194
|
-
# @option options [String] :content_type_starts_with
|
195
|
-
#
|
196
|
-
# @option options [String] :
|
197
|
-
#
|
198
|
-
# @option options [String] :
|
198
|
+
# @option options [String] :content_type_starts_with
|
199
|
+
# See {PresignedPost#content_type_starts_with}.
|
200
|
+
# @option options [String] :content_disposition
|
201
|
+
# See {PresignedPost#content_disposition}.
|
202
|
+
# @option options [String] :content_disposition_starts_with
|
203
|
+
# See {PresignedPost#content_disposition_starts_with}.
|
204
|
+
# @option options [String] :content_encoding
|
205
|
+
# See {PresignedPost#content_encoding}.
|
206
|
+
# @option options [String] :content_encoding_starts_with
|
207
|
+
# See {PresignedPost#content_encoding_starts_with}.
|
199
208
|
# @option options [String] :expires See {PresignedPost#expires}.
|
200
|
-
# @option options [String] :expires_starts_with
|
201
|
-
#
|
202
|
-
# @option options [
|
203
|
-
#
|
204
|
-
# @option options [String] :
|
205
|
-
#
|
206
|
-
# @option options [String] :
|
207
|
-
#
|
208
|
-
# @option options [
|
209
|
-
#
|
210
|
-
# @option options [String] :
|
211
|
-
#
|
212
|
-
# @option options [String] :
|
209
|
+
# @option options [String] :expires_starts_with
|
210
|
+
# See {PresignedPost#expires_starts_with}.
|
211
|
+
# @option options [Range<Integer>] :content_length_range
|
212
|
+
# See {PresignedPost#content_length_range}.
|
213
|
+
# @option options [String] :success_action_redirect
|
214
|
+
# See {PresignedPost#success_action_redirect}.
|
215
|
+
# @option options [String] :success_action_redirect_starts_with
|
216
|
+
# See {PresignedPost#success_action_redirect_starts_with}.
|
217
|
+
# @option options [String] :success_action_status
|
218
|
+
# See {PresignedPost#success_action_status}.
|
219
|
+
# @option options [String] :storage_class
|
220
|
+
# See {PresignedPost#storage_class}.
|
221
|
+
# @option options [String] :website_redirect_location
|
222
|
+
# See {PresignedPost#website_redirect_location}.
|
223
|
+
# @option options [Hash<String,String>] :metadata
|
224
|
+
# See {PresignedPost#metadata}.
|
225
|
+
# @option options [Hash<String,String>] :metadata_starts_with
|
226
|
+
# See {PresignedPost#metadata_starts_with}.
|
227
|
+
# @option options [String] :server_side_encryption
|
228
|
+
# See {PresignedPost#server_side_encryption}.
|
229
|
+
# @option options [String] :server_side_encryption_aws_kms_key_id
|
230
|
+
# See {PresignedPost#server_side_encryption_aws_kms_key_id}.
|
231
|
+
# @option options [String] :server_side_encryption_customer_algorithm
|
232
|
+
# See {PresignedPost#server_side_encryption_customer_algorithm}.
|
233
|
+
# @option options [String] :server_side_encryption_customer_key
|
234
|
+
# See {PresignedPost#server_side_encryption_customer_key}.
|
213
235
|
def initialize(credentials, bucket_region, bucket_name, options = {})
|
214
236
|
@credentials = credentials.credentials
|
215
237
|
@bucket_region = bucket_region
|
216
238
|
@bucket_name = bucket_name
|
239
|
+
@accelerate = !!options.delete(:use_accelerate_endpoint)
|
217
240
|
@url = options.delete(:url) || bucket_url
|
218
241
|
@fields = {}
|
219
242
|
@key_set = false
|
@@ -272,7 +295,7 @@ module Aws
|
|
272
295
|
|
273
296
|
# @!group Fields
|
274
297
|
|
275
|
-
# The key to use for the uploaded object.
|
298
|
+
# The key to use for the uploaded object. You can use `${filename}`
|
276
299
|
# as a variable in the key. This will be replaced with the name
|
277
300
|
# of the file as provided by the user.
|
278
301
|
#
|
@@ -507,7 +530,10 @@ module Aws
|
|
507
530
|
# (KMS) master encryption key to use for the object.
|
508
531
|
# @param [String] value
|
509
532
|
# @return [self]
|
510
|
-
define_field(
|
533
|
+
define_field(
|
534
|
+
:server_side_encryption_aws_kms_key_id,
|
535
|
+
'x-amz-server-side-encryption-aws-kms-key-id'
|
536
|
+
)
|
511
537
|
|
512
538
|
# @!endgroup
|
513
539
|
|
@@ -520,7 +546,10 @@ module Aws
|
|
520
546
|
# @param [String] value
|
521
547
|
# @see #server_side_encryption_customer_key
|
522
548
|
# @return [self]
|
523
|
-
define_field(
|
549
|
+
define_field(
|
550
|
+
:server_side_encryption_customer_algorithm,
|
551
|
+
'x-amz-server-side-encryption-customer-algorithm'
|
552
|
+
)
|
524
553
|
|
525
554
|
# Specifies the customer-provided encryption key for Amazon S3 to use
|
526
555
|
# in encrypting data. This value is used to store the object and then
|
@@ -582,10 +611,14 @@ module Aws
|
|
582
611
|
def bucket_url
|
583
612
|
url = Aws::Partitions::EndpointProvider.resolve(@bucket_region, 's3')
|
584
613
|
url = URI.parse(url)
|
585
|
-
if Plugins::BucketDns.dns_compatible?(@bucket_name, true)
|
586
|
-
|
614
|
+
if Plugins::BucketDns.dns_compatible?(@bucket_name, _ssl = true)
|
615
|
+
if @accelerate
|
616
|
+
url.host = "#{@bucket_name}.s3-accelerate.amazonaws.com"
|
617
|
+
else
|
618
|
+
url.host = "#{@bucket_name}.#{url.host}"
|
619
|
+
end
|
587
620
|
else
|
588
|
-
url.path =
|
621
|
+
url.path = "/#{@bucket_name}"
|
589
622
|
end
|
590
623
|
if @bucket_region == 'us-east-1'
|
591
624
|
# keep legacy behavior by default
|