aws-sdk-s3 1.86.2 → 1.89.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -480,7 +480,7 @@ module Aws::S3
480
480
  ResponseContentEncoding = Shapes::StringShape.new(name: 'ResponseContentEncoding')
481
481
  ResponseContentLanguage = Shapes::StringShape.new(name: 'ResponseContentLanguage')
482
482
  ResponseContentType = Shapes::StringShape.new(name: 'ResponseContentType')
483
- ResponseExpires = Shapes::TimestampShape.new(name: 'ResponseExpires')
483
+ ResponseExpires = Shapes::TimestampShape.new(name: 'ResponseExpires', timestampFormat: "rfc822")
484
484
  Restore = Shapes::StringShape.new(name: 'Restore')
485
485
  RestoreObjectOutput = Shapes::StructureShape.new(name: 'RestoreObjectOutput')
486
486
  RestoreObjectRequest = Shapes::StructureShape.new(name: 'RestoreObjectRequest')
@@ -1288,6 +1288,7 @@ module Aws::S3
1288
1288
  GetObjectTaggingRequest.add_member(:key, Shapes::ShapeRef.new(shape: ObjectKey, required: true, location: "uri", location_name: "Key"))
1289
1289
  GetObjectTaggingRequest.add_member(:version_id, Shapes::ShapeRef.new(shape: ObjectVersionId, location: "querystring", location_name: "versionId"))
1290
1290
  GetObjectTaggingRequest.add_member(:expected_bucket_owner, Shapes::ShapeRef.new(shape: AccountId, location: "header", location_name: "x-amz-expected-bucket-owner"))
1291
+ GetObjectTaggingRequest.add_member(:request_payer, Shapes::ShapeRef.new(shape: RequestPayer, location: "header", location_name: "x-amz-request-payer"))
1291
1292
  GetObjectTaggingRequest.struct_class = Types::GetObjectTaggingRequest
1292
1293
 
1293
1294
  GetObjectTorrentOutput.add_member(:body, Shapes::ShapeRef.new(shape: Body, location_name: "Body", metadata: {"streaming"=>true}))
@@ -2105,6 +2106,7 @@ module Aws::S3
2105
2106
  PutObjectTaggingRequest.add_member(:content_md5, Shapes::ShapeRef.new(shape: ContentMD5, location: "header", location_name: "Content-MD5"))
2106
2107
  PutObjectTaggingRequest.add_member(:tagging, Shapes::ShapeRef.new(shape: Tagging, required: true, location_name: "Tagging", metadata: {"xmlNamespace"=>{"uri"=>"http://s3.amazonaws.com/doc/2006-03-01/"}}))
2107
2108
  PutObjectTaggingRequest.add_member(:expected_bucket_owner, Shapes::ShapeRef.new(shape: AccountId, location: "header", location_name: "x-amz-expected-bucket-owner"))
2109
+ PutObjectTaggingRequest.add_member(:request_payer, Shapes::ShapeRef.new(shape: RequestPayer, location: "header", location_name: "x-amz-request-payer"))
2108
2110
  PutObjectTaggingRequest.struct_class = Types::PutObjectTaggingRequest
2109
2111
  PutObjectTaggingRequest[:payload] = :tagging
2110
2112
  PutObjectTaggingRequest[:payload_member] = PutObjectTaggingRequest.member(:tagging)
@@ -88,18 +88,23 @@ module Aws
88
88
  # You can pass `virtual_host: true` to use the bucket name as the
89
89
  # host name.
90
90
  #
91
- # bucket = s3.bucket('my.bucket.com')
91
+ # bucket = s3.bucket('my-bucket.com')
92
92
  # bucket.url(virtual_host: true)
93
- # #=> "http://my.bucket.com"
93
+ # #=> "http://my-bucket.com"
94
94
  #
95
95
  # @option options [Boolean] :virtual_host (false) When `true`,
96
96
  # the bucket name will be used as the host name. This is useful
97
97
  # when you have a CNAME configured for this bucket.
98
98
  #
99
+ # @option options [Boolean] :secure (true) When `false`, http
100
+ # will be used with virtual_host. This is required when
101
+ # the bucket name has a dot (.) in it.
102
+ #
99
103
  # @return [String] the URL for this bucket.
100
104
  def url(options = {})
101
105
  if options[:virtual_host]
102
- "http://#{name}"
106
+ scheme = options.fetch(:secure, true) ? 'https' : 'http'
107
+ "#{scheme}://#{name}"
103
108
  elsif @arn
104
109
  Plugins::ARN.resolve_url!(
105
110
  client.config.endpoint.dup,
@@ -201,16 +201,22 @@ module Aws
201
201
  # s3.bucket('bucket-name').object('obj-key').public_url
202
202
  # #=> "https://bucket-name.s3.amazonaws.com/obj-key"
203
203
  #
204
- # To use virtual hosted bucket url (disables https):
204
+ # To use virtual hosted bucket url.
205
+ # Uses https unless secure: false is set. If the bucket
206
+ # name contains dots (.) then you will need to set secure: false.
205
207
  #
206
- # s3.bucket('my.bucket.com').object('key')
208
+ # s3.bucket('my-bucket.com').object('key')
207
209
  # .public_url(virtual_host: true)
208
- # #=> "http://my.bucket.com/key"
210
+ # #=> "https://my-bucket.com/key"
209
211
  #
210
212
  # @option options [Boolean] :virtual_host (false) When `true`, the bucket
211
213
  # name will be used as the host name. This is useful when you have
212
214
  # a CNAME configured for the bucket.
213
215
  #
216
+ # @option options [Boolean] :secure (true) When `false`, http
217
+ # will be used with virtual_host. This is required when
218
+ # the bucket name has a dot (.) in it.
219
+ #
214
220
  # @return [String]
215
221
  def public_url(options = {})
216
222
  url = URI.parse(bucket.url(options))
@@ -87,9 +87,9 @@ module Aws
87
87
  ' kms+context. Please configure the client with the' \
88
88
  ' required kms_key_id'
89
89
  else
90
- raise ArgumentError, 'Unsupported wrap-alg: ' \
91
- "#{envelope['x-amz-wrap-alg']}"
92
- end
90
+ raise ArgumentError, 'Unsupported wrap-alg: ' \
91
+ "#{envelope['x-amz-wrap-alg']}"
92
+ end
93
93
  iv = decode64(envelope['x-amz-iv'])
94
94
  Utils.aes_decryption_cipher(:GCM, key, iv)
95
95
  end
@@ -97,7 +97,7 @@ module Aws::S3
97
97
  data[:archive_status]
98
98
  end
99
99
 
100
- # Last modified date of the object
100
+ # Creation date of the object.
101
101
  # @return [Time]
102
102
  def last_modified
103
103
  data[:last_modified]
@@ -881,13 +881,13 @@ module Aws::S3
881
881
  # @option options [String] :version_id
882
882
  # VersionId used to reference a specific version of the object.
883
883
  # @option options [String] :sse_customer_algorithm
884
- # Specifies the algorithm to use to when encrypting the object (for
884
+ # Specifies the algorithm to use to when decrypting the object (for
885
885
  # example, AES256).
886
886
  # @option options [String] :sse_customer_key
887
- # Specifies the customer-provided encryption key for Amazon S3 to use in
888
- # encrypting data. This value is used to store the object and then it is
889
- # discarded; Amazon S3 does not store the encryption key. The key must
890
- # be appropriate for use with the algorithm specified in the
887
+ # Specifies the customer-provided encryption key for Amazon S3 used to
888
+ # encrypt the data. This value is used to decrypt the object when
889
+ # recovering it and must match the one used when storing the data. The
890
+ # key must be appropriate for use with the algorithm specified in the
891
891
  # `x-amz-server-side-encryption-customer-algorithm` header.
892
892
  # @option options [String] :sse_customer_key_md5
893
893
  # Specifies the 128-bit MD5 digest of the encryption key according to
@@ -42,7 +42,7 @@ module Aws::S3
42
42
  @key
43
43
  end
44
44
 
45
- # The date the Object was Last Modified
45
+ # Creation date of the object.
46
46
  # @return [Time]
47
47
  def last_modified
48
48
  data[:last_modified]
@@ -624,13 +624,13 @@ module Aws::S3
624
624
  # @option options [String] :version_id
625
625
  # VersionId used to reference a specific version of the object.
626
626
  # @option options [String] :sse_customer_algorithm
627
- # Specifies the algorithm to use to when encrypting the object (for
627
+ # Specifies the algorithm to use to when decrypting the object (for
628
628
  # example, AES256).
629
629
  # @option options [String] :sse_customer_key
630
- # Specifies the customer-provided encryption key for Amazon S3 to use in
631
- # encrypting data. This value is used to store the object and then it is
632
- # discarded; Amazon S3 does not store the encryption key. The key must
633
- # be appropriate for use with the algorithm specified in the
630
+ # Specifies the customer-provided encryption key for Amazon S3 used to
631
+ # encrypt the data. This value is used to decrypt the object when
632
+ # recovering it and must match the one used when storing the data. The
633
+ # key must be appropriate for use with the algorithm specified in the
634
634
  # `x-amz-server-side-encryption-customer-algorithm` header.
635
635
  # @option options [String] :sse_customer_key_md5
636
636
  # Specifies the 128-bit MD5 digest of the encryption key according to
@@ -330,13 +330,13 @@ module Aws::S3
330
330
  # @option options [Time,DateTime,Date,Integer,String] :response_expires
331
331
  # Sets the `Expires` header of the response.
332
332
  # @option options [String] :sse_customer_algorithm
333
- # Specifies the algorithm to use to when encrypting the object (for
333
+ # Specifies the algorithm to use to when decrypting the object (for
334
334
  # example, AES256).
335
335
  # @option options [String] :sse_customer_key
336
- # Specifies the customer-provided encryption key for Amazon S3 to use in
337
- # encrypting data. This value is used to store the object and then it is
338
- # discarded; Amazon S3 does not store the encryption key. The key must
339
- # be appropriate for use with the algorithm specified in the
336
+ # Specifies the customer-provided encryption key for Amazon S3 used to
337
+ # encrypt the data. This value is used to decrypt the object when
338
+ # recovering it and must match the one used when storing the data. The
339
+ # key must be appropriate for use with the algorithm specified in the
340
340
  # `x-amz-server-side-encryption-customer-algorithm` header.
341
341
  # @option options [String] :sse_customer_key_md5
342
342
  # Specifies the 128-bit MD5 digest of the encryption key according to
@@ -29,7 +29,7 @@ each bucket. [Go here for more information](http://docs.aws.amazon.com/AmazonS3/
29
29
  OptionHandler, step: :initialize, operations: operations
30
30
  )
31
31
  handlers.add(
32
- AccelerateHandler, step: :build, priority: 0, operations: operations
32
+ AccelerateHandler, step: :build, priority: 11, operations: operations
33
33
  )
34
34
  end
35
35
 
@@ -40,8 +40,11 @@ each bucket. [Go here for more information](http://docs.aws.amazon.com/AmazonS3/
40
40
  if context.params.is_a?(Hash)
41
41
  accelerate = context.params.delete(:use_accelerate_endpoint)
42
42
  end
43
- if accelerate.nil?
44
- accelerate = context.config.use_accelerate_endpoint
43
+ accelerate = context.config.use_accelerate_endpoint if accelerate.nil?
44
+ # Raise if :endpoint and dualstack are both provided
45
+ if accelerate && !context.config.regional_endpoint
46
+ raise ArgumentError,
47
+ 'Cannot use both :use_accelerate_endpoint and :endpoint'
45
48
  end
46
49
  context[:use_accelerate_endpoint] = accelerate
47
50
  @handler.call(context)
@@ -51,7 +54,7 @@ each bucket. [Go here for more information](http://docs.aws.amazon.com/AmazonS3/
51
54
  # @api private
52
55
  class AccelerateHandler < Seahorse::Client::Handler
53
56
  def call(context)
54
- if context[:use_accelerate_endpoint]
57
+ if context.config.regional_endpoint && context[:use_accelerate_endpoint]
55
58
  dualstack = !!context[:use_dualstack_endpoint]
56
59
  use_accelerate_endpoint(context, dualstack)
57
60
  end
@@ -22,11 +22,35 @@ be made. Set to `false` to use the client's region instead.
22
22
  resolve_s3_use_arn_region(cfg)
23
23
  end
24
24
 
25
+ # param validator is validate:50 (required to add account_id from arn)
26
+ # endpoint is build:90 (populates the URI for the first time)
27
+ # endpoint pattern is build:10 (prefix account id to host)
25
28
  def add_handlers(handlers, _config)
26
- handlers.add(Handler)
29
+ handlers.add(ARNHandler, step: :validate, priority: 75)
30
+ handlers.add(UrlHandler)
27
31
  end
28
32
 
29
- class Handler < Seahorse::Client::Handler
33
+ # After extracting out any ARN input, resolve a new URL with it.
34
+ class UrlHandler < Seahorse::Client::Handler
35
+ def call(context)
36
+ if context.metadata[:s3_arn]
37
+ ARN.resolve_url!(
38
+ context.http_request.endpoint,
39
+ context.metadata[:s3_arn][:arn],
40
+ context.metadata[:s3_arn][:resolved_region],
41
+ context.metadata[:s3_arn][:dualstack],
42
+ # if regional_endpoint is false, a custom endpoint was provided
43
+ # in this case, we want to prefix the endpoint using the ARN
44
+ !context.config.regional_endpoint
45
+ )
46
+ end
47
+ @handler.call(context)
48
+ end
49
+ end
50
+
51
+ # This plugin will extract out any ARN input and set context for other
52
+ # plugins to use without having to translate the ARN again.
53
+ class ARNHandler < Seahorse::Client::Handler
30
54
  def call(context)
31
55
  bucket_member = _bucket_member(context.operation.input.shape)
32
56
  if bucket_member && (bucket = context.params[bucket_member])
@@ -38,12 +62,11 @@ be made. Set to `false` to use the client's region instead.
38
62
  if arn
39
63
  validate_config!(context, arn)
40
64
 
41
- ARN.resolve_url!(
42
- context.http_request.endpoint,
43
- arn,
44
- resolved_region,
45
- extract_dualstack_config!(context)
46
- )
65
+ context.metadata[:s3_arn] = {
66
+ arn: arn,
67
+ resolved_region: resolved_region,
68
+ dualstack: extract_dualstack_config!(context)
69
+ }
47
70
  end
48
71
  end
49
72
  @handler.call(context)
@@ -66,28 +89,22 @@ be made. Set to `false` to use the client's region instead.
66
89
  end
67
90
 
68
91
  def validate_config!(context, arn)
69
- unless context.config.regional_endpoint
70
- raise ArgumentError,
71
- 'Cannot provide both an Access Point ARN and setting '\
72
- ':endpoint.'
73
- end
74
-
75
92
  if context.config.force_path_style
76
93
  raise ArgumentError,
77
- 'Cannot provide both an Access Point ARN and setting '\
78
- ':force_path_style to true.'
94
+ 'Cannot provide an Access Point ARN when '\
95
+ '`:force_path_style` is set to true.'
79
96
  end
80
97
 
81
98
  if context.config.use_accelerate_endpoint
82
99
  raise ArgumentError,
83
- 'Cannot provide both an Access Point ARN and setting '\
84
- ':use_accelerate_endpoint to true.'
100
+ 'Cannot provide an Access Point ARN when '\
101
+ '`:use_accelerate_endpoint` is set to true.'
85
102
  end
86
103
 
87
104
  if !arn.support_dualstack? && context[:use_dualstack_endpoint]
88
105
  raise ArgumentError,
89
- 'Cannot provide both an Outpost Access Point ARN and '\
90
- 'setting :use_dualstack_endpoint to true.'
106
+ 'Cannot provide an Outpost Access Point ARN when '\
107
+ '`:use_dualstack_endpoint` is set to true.'
91
108
  end
92
109
  end
93
110
  end
@@ -116,8 +133,9 @@ be made. Set to `false` to use the client's region instead.
116
133
  end
117
134
 
118
135
  # @api private
119
- def resolve_url!(url, arn, region, dualstack = false)
120
- url.host = arn.host_url(region, dualstack)
136
+ def resolve_url!(url, arn, region, dualstack = false, has_custom_endpoint = false)
137
+ custom_endpoint = url.host if has_custom_endpoint
138
+ url.host = arn.host_url(region, dualstack, custom_endpoint)
121
139
  url.path = url_path(url.path, arn)
122
140
  url
123
141
  end
@@ -132,9 +150,9 @@ be made. Set to `false` to use the client's region instead.
132
150
  # Raise if provided value is not true or false
133
151
  if value.nil?
134
152
  raise ArgumentError,
135
- 'Must provide either `true` or `false` for '\
136
- 's3_use_arn_region profile option or for '\
137
- "ENV['AWS_S3_USE_ARN_REGION']"
153
+ 'Must provide either `true` or `false` for the '\
154
+ '`s3_use_arn_region` profile option or for '\
155
+ "ENV['AWS_S3_USE_ARN_REGION']."
138
156
  end
139
157
  value
140
158
  end
@@ -163,7 +181,7 @@ be made. Set to `false` to use the client's region instead.
163
181
  if !fips && !use_arn_region && region.include?('fips')
164
182
  raise ArgumentError,
165
183
  'FIPS client regions are not supported for this type of '\
166
- 'ARN without s3_use_arn_region.'
184
+ 'ARN without `:s3_use_arn_region`.'
167
185
  end
168
186
 
169
187
  # if it's a fips region, attempt to normalize it
@@ -16,16 +16,22 @@ for all operations.
16
16
 
17
17
  def add_handlers(handlers, config)
18
18
  handlers.add(OptionHandler, step: :initialize)
19
- handlers.add(DualstackHandler, step: :build, priority: 0)
19
+ handlers.add(DualstackHandler, step: :build, priority: 11)
20
20
  end
21
21
 
22
22
  # @api private
23
23
  class OptionHandler < Seahorse::Client::Handler
24
24
  def call(context)
25
+ # Support client configuration and per-operation configuration
25
26
  if context.params.is_a?(Hash)
26
27
  dualstack = context.params.delete(:use_dualstack_endpoint)
27
28
  end
28
29
  dualstack = context.config.use_dualstack_endpoint if dualstack.nil?
30
+ # Raise if :endpoint and dualstack are both provided
31
+ if dualstack && !context.config.regional_endpoint
32
+ raise ArgumentError,
33
+ 'Cannot use both :use_dualstack_endpoint and :endpoint'
34
+ end
29
35
  context[:use_dualstack_endpoint] = dualstack
30
36
  @handler.call(context)
31
37
  end
@@ -34,7 +40,9 @@ for all operations.
34
40
  # @api private
35
41
  class DualstackHandler < Seahorse::Client::Handler
36
42
  def call(context)
37
- apply_dualstack_endpoint(context) if use_dualstack_endpoint?(context)
43
+ if context.config.regional_endpoint && use_dualstack_endpoint?(context)
44
+ apply_dualstack_endpoint(context)
45
+ end
38
46
  @handler.call(context)
39
47
  end
40
48
 
@@ -42,7 +50,6 @@ for all operations.
42
50
  def apply_dualstack_endpoint(context)
43
51
  bucket_name = context.params[:bucket]
44
52
  region = context.config.region
45
- context.config.force_path_style
46
53
  dns_suffix = Aws::Partitions::EndpointProvider.dns_suffix_for(region)
47
54
 
48
55
  if use_bucket_dns?(bucket_name, context)
@@ -15,7 +15,8 @@ module Aws
15
15
  class Handler < Seahorse::Client::Handler
16
16
 
17
17
  def call(context)
18
- if context.http_request.body && context.http_request.body.size > 0
18
+ body = context.http_request.body
19
+ if body.respond_to?(:size) && body.size > 0
19
20
  context.http_request.headers['expect'] = '100-continue'
20
21
  end
21
22
  @handler.call(context)
@@ -17,7 +17,8 @@ region. Defaults to `legacy` mode using global endpoint.
17
17
  end
18
18
 
19
19
  def add_handlers(handlers, config)
20
- if config.region == 'us-east-1'
20
+ # only modify non-custom endpoints
21
+ if config.regional_endpoint && config.region == 'us-east-1'
21
22
  handlers.add(Handler)
22
23
  end
23
24
  end
@@ -29,9 +30,8 @@ region. Defaults to `legacy` mode using global endpoint.
29
30
  # keep legacy global endpoint pattern by default
30
31
  if context.config.s3_us_east_1_regional_endpoint == 'legacy'
31
32
  host = context.http_request.endpoint.host
32
- # if it's an ARN, don't touch the endpoint at all
33
- # TODO this should use context.metadata[:s3_arn] later
34
- unless host.include?('.s3-outposts.') || host.include?('.s3-accesspoint.')
33
+ # if it's an ARN then don't touch the endpoint at all
34
+ unless context.metadata[:s3_arn]
35
35
  legacy_host = IADRegionalEndpoint.legacy_host(host)
36
36
  context.http_request.endpoint.host = legacy_host
37
37
  end
@@ -23,7 +23,7 @@ module Aws
23
23
 
24
24
  def call(context)
25
25
  body = context.http_request.body
26
- if body.size > 0
26
+ if body.respond_to?(:size) && body.size > 0
27
27
  context.http_request.headers['Content-Md5'] ||= md5(body)
28
28
  end
29
29
  @handler.call(context)
@@ -73,22 +73,14 @@ module Aws
73
73
  region: context[:cached_sigv4_region],
74
74
  credentials: context.config.credentials
75
75
  )
76
- else
77
- resolved_region, arn = ARN.resolve_arn!(
78
- context.params[:bucket],
79
- context.config.sigv4_signer.region,
80
- context.config.s3_use_arn_region
76
+ elsif (arn = context.metadata[:s3_arn])
77
+ S3Signer.build_v4_signer(
78
+ service: arn[:arn].service,
79
+ region: arn[:resolved_region],
80
+ credentials: context.config.credentials
81
81
  )
82
-
83
- if arn
84
- S3Signer.build_v4_signer(
85
- service: arn.service,
86
- region: resolved_region,
87
- credentials: context.config.credentials
88
- )
89
- else
90
- context.config.sigv4_signer
91
- end
82
+ else
83
+ context.config.sigv4_signer
92
84
  end
93
85
  end
94
86
  end
@@ -173,10 +165,14 @@ module Aws
173
165
  context, actual_region
174
166
  )
175
167
  context.metadata[:redirect_region] = actual_region
168
+ # if it's an ARN, use the service in the ARN
169
+ if (arn = context.metadata[:s3_arn])
170
+ service = arn[:arn].service
171
+ end
176
172
  Aws::Plugins::SignatureV4.apply_signature(
177
173
  context: context,
178
174
  signer: S3Signer.build_v4_signer(
179
- service: 's3',
175
+ service: service || 's3',
180
176
  region: actual_region,
181
177
  credentials: context.config.credentials
182
178
  )
@@ -219,20 +215,16 @@ module Aws
219
215
  )
220
216
  end
221
217
 
218
+ # Check to see if the bucket is actually an ARN
219
+ # Otherwise it will retry with the ARN as the bucket name.
222
220
  def new_hostname(context, region)
223
- # Check to see if the bucket is actually an ARN and resolve it
224
- # Otherwise it will retry with the ARN as the bucket name.
225
- resolved_region, arn = ARN.resolve_arn!(
226
- context.params[:bucket],
227
- region,
228
- context.config.s3_use_arn_region
229
- )
230
221
  uri = URI.parse(
231
- Aws::Partitions::EndpointProvider.resolve(resolved_region, 's3')
222
+ Aws::Partitions::EndpointProvider.resolve(region, 's3')
232
223
  )
233
224
 
234
- if arn
235
- ARN.resolve_url!(uri, arn).host
225
+ if (arn = context.metadata[:s3_arn])
226
+ # Retry with the response region and not the ARN resolved one
227
+ ARN.resolve_url!(uri, arn[:arn], region).host
236
228
  else
237
229
  "#{context.params[:bucket]}.#{uri.host}"
238
230
  end