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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 71499a1c36cb061a8fb6b48a61fba9eec3985149a0e3effb810f8bf45e89f8db
4
- data.tar.gz: 05e2a7de980f2c579b09688d1301326ce8a5df60bb9f3487a0ff21486afb58e6
3
+ metadata.gz: 626495d85d0f33f1a04615e2c65aca4331f8ac04b35306d2e68668eb1cbad727
4
+ data.tar.gz: 324b43984913dedda5bd63af0608eb9ba01feab28e8ff15ee5ceb7b1cb5d5578
5
5
  SHA512:
6
- metadata.gz: 522caf62fdf5130b9e8f19da2c06841074ea7da04c15c9e2731992cadc9fcd7372a0705db07902bd672ea48d7b47703876f0f679c402330f13fb33120f6e4478
7
- data.tar.gz: 977b14327746226f9abb50cc7984f23abfa6526b6a3b10360c5e1827d4b38166c827290ca416e109a58bebf5debecdb4effc7dbc316c22e921a004720cad8e63
6
+ metadata.gz: f4958752f8508e3d4ecdb0ad22bc5184f3c9e8c9c6e035bfcb5cabda3897fb8fec2b3da206499689f400c001e83e1d364daeea687bff71cbcc1b910779936058
7
+ data.tar.gz: ef54aeb2dc6373afe0b806a4e88ca85ed81eedba190da89c7370d10eea5535f6f608ba80539b7c5b31f3198ab64767afda81c8560475c9268155af373e1d23ff
@@ -68,6 +68,6 @@ require_relative 'aws-sdk-s3/event_streams'
68
68
  # @service
69
69
  module Aws::S3
70
70
 
71
- GEM_VERSION = '1.69.1'
71
+ GEM_VERSION = '1.74.0'
72
72
 
73
73
  end
@@ -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. [Go here for more information](http://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html).
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.69.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
- @io.write(@cipher.update(chunk))
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
- encrypted.write(cipher.update(chunk))
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
- option(:use_accelerate_endpoint,
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. [Go here for more information](http://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html).
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.add(OptionHandler, step: :initialize, operations: operations)
28
- handlers.add(AccelerateHandler, step: :build, priority: 0, operations: operations)
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
- accelerate = context.config.use_accelerate_endpoint if accelerate.nil?
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
- if context[:use_dualstack_endpoint]
47
- use_combined_accelerate_dualstack_endpoint(context)
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.dualstack.amazonaws.com"
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
- msg = 'unable to use `accelerate: true` on buckets with '\
84
- 'non-DNS compatible names'
85
- raise ArgumentError, msg
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
@@ -40,7 +40,8 @@ module Aws
40
40
  end
41
41
  end
42
42
 
43
- handler(Handler,
43
+ handler(
44
+ Handler,
44
45
  step: :sign,
45
46
  operations: [
46
47
  :complete_multipart_upload,
@@ -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 See {PresignedPost#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 See {PresignedPost#acl_starts_with}.
191
- # @option options [String] :cache_control See {PresignedPost#cache_control}.
192
- # @option options [String] :cache_control_starts_with See {PresignedPost#cache_control_starts_with}.
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 See {PresignedPost#content_type_starts_with}.
195
- # @option options [String] :content_disposition See {PresignedPost#content_disposition}.
196
- # @option options [String] :content_disposition_starts_with See {PresignedPost#content_disposition_starts_with}.
197
- # @option options [String] :content_encoding See {PresignedPost#content_encoding}.
198
- # @option options [String] :content_encoding_starts_with See {PresignedPost#content_encoding_starts_with}.
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 See {PresignedPost#expires_starts_with}.
201
- # @option options [Range<Integer>] :content_length_range See {PresignedPost#content_length_range}.
202
- # @option options [String] :success_action_redirect See {PresignedPost#success_action_redirect}.
203
- # @option options [String] :success_action_redirect_starts_with See {PresignedPost#success_action_redirect_starts_with}.
204
- # @option options [String] :success_action_status See {PresignedPost#success_action_status}.
205
- # @option options [String] :storage_class See {PresignedPost#storage_class}.
206
- # @option options [String] :website_redirect_location See {PresignedPost#website_redirect_location}.
207
- # @option options [Hash<String,String>] :metadata See {PresignedPost#metadata}.
208
- # @option options [Hash<String,String>] :metadata_starts_with See {PresignedPost#metadata_starts_with}.
209
- # @option options [String] :server_side_encryption See {PresignedPost#server_side_encryption}.
210
- # @option options [String] :server_side_encryption_aws_kms_key_id See {PresignedPost#server_side_encryption_aws_kms_key_id}.
211
- # @option options [String] :server_side_encryption_customer_algorithm See {PresignedPost#server_side_encryption_customer_algorithm}.
212
- # @option options [String] :server_side_encryption_customer_key See {PresignedPost#server_side_encryption_customer_key}.
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. Use can use `${filename}`
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(:server_side_encryption_aws_kms_key_id, 'x-amz-server-side-encryption-aws-kms-key-id')
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(:server_side_encryption_customer_algorithm, 'x-amz-server-side-encryption-customer-algorithm')
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
- url.host = @bucket_name + '.' + url.host
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 = '/' + @bucket_name
621
+ url.path = "/#{@bucket_name}"
589
622
  end
590
623
  if @bucket_region == 'us-east-1'
591
624
  # keep legacy behavior by default