aws-sdk-s3 1.31.0 → 1.111.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +868 -0
  3. data/LICENSE.txt +202 -0
  4. data/VERSION +1 -0
  5. data/lib/aws-sdk-s3/arn/access_point_arn.rb +69 -0
  6. data/lib/aws-sdk-s3/arn/multi_region_access_point_arn.rb +68 -0
  7. data/lib/aws-sdk-s3/arn/object_lambda_arn.rb +69 -0
  8. data/lib/aws-sdk-s3/arn/outpost_access_point_arn.rb +74 -0
  9. data/lib/aws-sdk-s3/bucket.rb +298 -78
  10. data/lib/aws-sdk-s3/bucket_acl.rb +41 -15
  11. data/lib/aws-sdk-s3/bucket_cors.rb +51 -14
  12. data/lib/aws-sdk-s3/bucket_lifecycle.rb +38 -16
  13. data/lib/aws-sdk-s3/bucket_lifecycle_configuration.rb +40 -16
  14. data/lib/aws-sdk-s3/bucket_logging.rb +36 -15
  15. data/lib/aws-sdk-s3/bucket_notification.rb +44 -18
  16. data/lib/aws-sdk-s3/bucket_policy.rb +35 -13
  17. data/lib/aws-sdk-s3/bucket_region_cache.rb +2 -0
  18. data/lib/aws-sdk-s3/bucket_request_payment.rb +35 -12
  19. data/lib/aws-sdk-s3/bucket_tagging.rb +43 -14
  20. data/lib/aws-sdk-s3/bucket_versioning.rb +70 -12
  21. data/lib/aws-sdk-s3/bucket_website.rb +50 -17
  22. data/lib/aws-sdk-s3/client.rb +7851 -628
  23. data/lib/aws-sdk-s3/client_api.rb +436 -2
  24. data/lib/aws-sdk-s3/customizations/bucket.rb +59 -16
  25. data/lib/aws-sdk-s3/customizations/multipart_upload.rb +2 -0
  26. data/lib/aws-sdk-s3/customizations/object.rb +200 -62
  27. data/lib/aws-sdk-s3/customizations/object_summary.rb +5 -0
  28. data/lib/aws-sdk-s3/customizations/types/list_object_versions_output.rb +2 -0
  29. data/lib/aws-sdk-s3/customizations.rb +4 -1
  30. data/lib/aws-sdk-s3/encryption/client.rb +23 -6
  31. data/lib/aws-sdk-s3/encryption/decrypt_handler.rb +71 -29
  32. data/lib/aws-sdk-s3/encryption/default_cipher_provider.rb +43 -5
  33. data/lib/aws-sdk-s3/encryption/default_key_provider.rb +2 -0
  34. data/lib/aws-sdk-s3/encryption/encrypt_handler.rb +13 -2
  35. data/lib/aws-sdk-s3/encryption/errors.rb +2 -0
  36. data/lib/aws-sdk-s3/encryption/io_auth_decrypter.rb +2 -0
  37. data/lib/aws-sdk-s3/encryption/io_decrypter.rb +11 -3
  38. data/lib/aws-sdk-s3/encryption/io_encrypter.rb +2 -0
  39. data/lib/aws-sdk-s3/encryption/key_provider.rb +2 -0
  40. data/lib/aws-sdk-s3/encryption/kms_cipher_provider.rb +34 -3
  41. data/lib/aws-sdk-s3/encryption/materials.rb +8 -6
  42. data/lib/aws-sdk-s3/encryption/utils.rb +25 -0
  43. data/lib/aws-sdk-s3/encryption.rb +4 -0
  44. data/lib/aws-sdk-s3/encryptionV2/client.rb +566 -0
  45. data/lib/aws-sdk-s3/encryptionV2/decrypt_handler.rb +222 -0
  46. data/lib/aws-sdk-s3/encryptionV2/default_cipher_provider.rb +170 -0
  47. data/lib/aws-sdk-s3/encryptionV2/default_key_provider.rb +40 -0
  48. data/lib/aws-sdk-s3/encryptionV2/encrypt_handler.rb +65 -0
  49. data/lib/aws-sdk-s3/encryptionV2/errors.rb +37 -0
  50. data/lib/aws-sdk-s3/encryptionV2/io_auth_decrypter.rb +58 -0
  51. data/lib/aws-sdk-s3/encryptionV2/io_decrypter.rb +37 -0
  52. data/lib/aws-sdk-s3/encryptionV2/io_encrypter.rb +73 -0
  53. data/lib/aws-sdk-s3/encryptionV2/key_provider.rb +31 -0
  54. data/lib/aws-sdk-s3/encryptionV2/kms_cipher_provider.rb +169 -0
  55. data/lib/aws-sdk-s3/encryptionV2/materials.rb +60 -0
  56. data/lib/aws-sdk-s3/encryptionV2/utils.rb +103 -0
  57. data/lib/aws-sdk-s3/encryption_v2.rb +23 -0
  58. data/lib/aws-sdk-s3/errors.rb +123 -1
  59. data/lib/aws-sdk-s3/event_streams.rb +20 -7
  60. data/lib/aws-sdk-s3/file_downloader.rb +16 -9
  61. data/lib/aws-sdk-s3/file_part.rb +11 -6
  62. data/lib/aws-sdk-s3/file_uploader.rb +33 -14
  63. data/lib/aws-sdk-s3/legacy_signer.rb +17 -25
  64. data/lib/aws-sdk-s3/multipart_file_uploader.rb +53 -13
  65. data/lib/aws-sdk-s3/multipart_stream_uploader.rb +20 -7
  66. data/lib/aws-sdk-s3/multipart_upload.rb +64 -29
  67. data/lib/aws-sdk-s3/multipart_upload_error.rb +2 -0
  68. data/lib/aws-sdk-s3/multipart_upload_part.rb +116 -42
  69. data/lib/aws-sdk-s3/object.rb +656 -156
  70. data/lib/aws-sdk-s3/object_acl.rb +65 -21
  71. data/lib/aws-sdk-s3/object_copier.rb +2 -0
  72. data/lib/aws-sdk-s3/object_multipart_copier.rb +2 -0
  73. data/lib/aws-sdk-s3/object_summary.rb +485 -143
  74. data/lib/aws-sdk-s3/object_version.rb +117 -62
  75. data/lib/aws-sdk-s3/plugins/accelerate.rb +38 -38
  76. data/lib/aws-sdk-s3/plugins/arn.rb +254 -0
  77. data/lib/aws-sdk-s3/plugins/bucket_dns.rb +8 -8
  78. data/lib/aws-sdk-s3/plugins/bucket_name_restrictions.rb +25 -3
  79. data/lib/aws-sdk-s3/plugins/dualstack.rb +38 -33
  80. data/lib/aws-sdk-s3/plugins/expect_100_continue.rb +4 -4
  81. data/lib/aws-sdk-s3/plugins/get_bucket_location_fix.rb +3 -1
  82. data/lib/aws-sdk-s3/plugins/http_200_errors.rb +11 -3
  83. data/lib/aws-sdk-s3/plugins/iad_regional_endpoint.rb +73 -0
  84. data/lib/aws-sdk-s3/plugins/location_constraint.rb +2 -0
  85. data/lib/aws-sdk-s3/plugins/md5s.rb +30 -28
  86. data/lib/aws-sdk-s3/plugins/object_lambda_endpoint.rb +25 -0
  87. data/lib/aws-sdk-s3/plugins/redirects.rb +2 -0
  88. data/lib/aws-sdk-s3/plugins/s3_host_id.rb +2 -0
  89. data/lib/aws-sdk-s3/plugins/s3_signer.rb +89 -36
  90. data/lib/aws-sdk-s3/plugins/sse_cpk.rb +3 -1
  91. data/lib/aws-sdk-s3/plugins/streaming_retry.rb +118 -0
  92. data/lib/aws-sdk-s3/plugins/url_encoded_keys.rb +2 -0
  93. data/lib/aws-sdk-s3/presigned_post.rb +72 -32
  94. data/lib/aws-sdk-s3/presigner.rb +168 -66
  95. data/lib/aws-sdk-s3/resource.rb +41 -5
  96. data/lib/aws-sdk-s3/types.rb +6758 -1027
  97. data/lib/aws-sdk-s3/waiters.rb +67 -1
  98. data/lib/aws-sdk-s3.rb +12 -6
  99. metadata +37 -13
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'openssl'
2
4
  require 'base64'
3
5
 
@@ -183,35 +185,59 @@ module Aws
183
185
  # the post will expire. Defaults to one hour from creation of the
184
186
  # presigned post. May not exceed one week from creation time.
185
187
  # @option options [String] :key See {PresignedPost#key}.
186
- # @option options [String] :key_starts_with See {PresignedPost#key_starts_with}.
188
+ # @option options [String] :key_starts_with
189
+ # See {PresignedPost#key_starts_with}.
187
190
  # @option options [String] :acl See {PresignedPost#acl}.
188
- # @option options [String] :acl_starts_with See {PresignedPost#acl_starts_with}.
189
- # @option options [String] :cache_control See {PresignedPost#cache_control}.
190
- # @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}.
191
197
  # @option options [String] :content_type See {PresignedPost#content_type}.
192
- # @option options [String] :content_type_starts_with See {PresignedPost#content_type_starts_with}.
193
- # @option options [String] :content_disposition See {PresignedPost#content_disposition}.
194
- # @option options [String] :content_disposition_starts_with See {PresignedPost#content_disposition_starts_with}.
195
- # @option options [String] :content_encoding See {PresignedPost#content_encoding}.
196
- # @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}.
197
208
  # @option options [String] :expires See {PresignedPost#expires}.
198
- # @option options [String] :expires_starts_with See {PresignedPost#expires_starts_with}.
199
- # @option options [Range<Integer>] :content_length_range See {PresignedPost#content_length_range}.
200
- # @option options [String] :success_action_redirect See {PresignedPost#success_action_redirect}.
201
- # @option options [String] :success_action_redirect_starts_with See {PresignedPost#success_action_redirect_starts_with}.
202
- # @option options [String] :success_action_status See {PresignedPost#success_action_status}.
203
- # @option options [String] :storage_class See {PresignedPost#storage_class}.
204
- # @option options [String] :website_redirect_location See {PresignedPost#website_redirect_location}.
205
- # @option options [Hash<String,String>] :metadata See {PresignedPost#metadata}.
206
- # @option options [Hash<String,String>] :metadata_starts_with See {PresignedPost#metadata_starts_with}.
207
- # @option options [String] :server_side_encryption See {PresignedPost#server_side_encryption}.
208
- # @option options [String] :server_side_encryption_aws_kms_key_id See {PresignedPost#server_side_encryption_aws_kms_key_id}.
209
- # @option options [String] :server_side_encryption_customer_algorithm See {PresignedPost#server_side_encryption_customer_algorithm}.
210
- # @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}.
211
235
  def initialize(credentials, bucket_region, bucket_name, options = {})
212
236
  @credentials = credentials.credentials
213
237
  @bucket_region = bucket_region
214
238
  @bucket_name = bucket_name
239
+ @accelerate = !!options.delete(:use_accelerate_endpoint)
240
+ options.delete(:url) if @accelerate # resource methods pass url
215
241
  @url = options.delete(:url) || bucket_url
216
242
  @fields = {}
217
243
  @key_set = false
@@ -234,7 +260,7 @@ module Aws
234
260
  # as hidden input fields.
235
261
  def fields
236
262
  check_required_values!
237
- datetime = Time.now.utc.strftime("%Y%m%dT%H%M%SZ")
263
+ datetime = Time.now.utc.strftime('%Y%m%dT%H%M%SZ')
238
264
  fields = @fields.dup
239
265
  fields.update('policy' => policy(datetime))
240
266
  fields.update(signature_fields(datetime))
@@ -270,7 +296,7 @@ module Aws
270
296
 
271
297
  # @!group Fields
272
298
 
273
- # The key to use for the uploaded object. Use can use `${filename}`
299
+ # The key to use for the uploaded object. You can use `${filename}`
274
300
  # as a variable in the key. This will be replaced with the name
275
301
  # of the file as provided by the user.
276
302
  #
@@ -505,7 +531,10 @@ module Aws
505
531
  # (KMS) master encryption key to use for the object.
506
532
  # @param [String] value
507
533
  # @return [self]
508
- define_field(:server_side_encryption_aws_kms_key_id, 'x-amz-server-side-encryption-aws-kms-key-id')
534
+ define_field(
535
+ :server_side_encryption_aws_kms_key_id,
536
+ 'x-amz-server-side-encryption-aws-kms-key-id'
537
+ )
509
538
 
510
539
  # @!endgroup
511
540
 
@@ -518,7 +547,10 @@ module Aws
518
547
  # @param [String] value
519
548
  # @see #server_side_encryption_customer_key
520
549
  # @return [self]
521
- define_field(:server_side_encryption_customer_algorithm, 'x-amz-server-side-encryption-customer-algorithm')
550
+ define_field(
551
+ :server_side_encryption_customer_algorithm,
552
+ 'x-amz-server-side-encryption-customer-algorithm'
553
+ )
522
554
 
523
555
  # Specifies the customer-provided encryption key for Amazon S3 to use
524
556
  # in encrypting data. This value is used to store the object and then
@@ -571,8 +603,8 @@ module Aws
571
603
 
572
604
  def check_required_values!
573
605
  unless @key_set
574
- msg = "key required; you must provide a key via :key, "
575
- msg << ":key_starts_with, or :allow_any => ['key']"
606
+ msg = 'key required; you must provide a key via :key, '\
607
+ ":key_starts_with, or :allow_any => ['key']"
576
608
  raise msg
577
609
  end
578
610
  end
@@ -580,10 +612,18 @@ module Aws
580
612
  def bucket_url
581
613
  url = Aws::Partitions::EndpointProvider.resolve(@bucket_region, 's3')
582
614
  url = URI.parse(url)
583
- if Plugins::BucketDns.dns_compatible?(@bucket_name, true)
584
- url.host = @bucket_name + '.' + url.host
615
+ if Plugins::BucketDns.dns_compatible?(@bucket_name, _ssl = true)
616
+ if @accelerate
617
+ url.host = "#{@bucket_name}.s3-accelerate.amazonaws.com"
618
+ else
619
+ url.host = "#{@bucket_name}.#{url.host}"
620
+ end
585
621
  else
586
- url.path = '/' + @bucket_name
622
+ url.path = "/#{@bucket_name}"
623
+ end
624
+ if @bucket_region == 'us-east-1'
625
+ # keep legacy behavior by default
626
+ url.host = Plugins::IADRegionalEndpoint.legacy_host(url.host)
587
627
  end
588
628
  url.to_s
589
629
  end
@@ -613,7 +653,7 @@ module Aws
613
653
 
614
654
  def signature(datetime, string_to_sign)
615
655
  k_secret = @credentials.secret_access_key
616
- k_date = hmac("AWS4" + k_secret, datetime[0,8])
656
+ k_date = hmac('AWS4' + k_secret, datetime[0,8])
617
657
  k_region = hmac(k_date, @bucket_region)
618
658
  k_service = hmac(k_region, 's3')
619
659
  k_credentials = hmac(k_service, 'aws4_request')
@@ -1,27 +1,94 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Aws
2
4
  module S3
3
-
4
- # Allows you to create presigned URLs for S3 operations.
5
- #
6
- # Example Use:
7
- #
8
- # signer = Aws::S3::Presigner.new
9
- # url = signer.presigned_url(:get_object, bucket: "bucket", key: "key")
10
- #
11
5
  class Presigner
12
-
13
6
  # @api private
14
7
  ONE_WEEK = 60 * 60 * 24 * 7
15
8
 
16
9
  # @api private
17
10
  FIFTEEN_MINUTES = 60 * 15
18
11
 
12
+ # @api private
13
+ BLACKLISTED_HEADERS = [
14
+ 'accept',
15
+ 'amz-sdk-request',
16
+ 'cache-control',
17
+ 'content-length', # due to a ELB bug
18
+ 'expect',
19
+ 'from',
20
+ 'if-match',
21
+ 'if-none-match',
22
+ 'if-modified-since',
23
+ 'if-unmodified-since',
24
+ 'if-range',
25
+ 'max-forwards',
26
+ 'pragma',
27
+ 'proxy-authorization',
28
+ 'referer',
29
+ 'te',
30
+ 'user-agent'
31
+ ].freeze
32
+
19
33
  # @option options [Client] :client Optionally provide an existing
20
34
  # S3 client
21
35
  def initialize(options = {})
22
36
  @client = options[:client] || Aws::S3::Client.new
23
37
  end
24
38
 
39
+ # Create presigned URLs for S3 operations.
40
+ #
41
+ # @example
42
+ # signer = Aws::S3::Presigner.new
43
+ # url = signer.presigned_url(:get_object, bucket: "bucket", key: "key")
44
+ #
45
+ # @param [Symbol] method Symbolized method name of the operation you want
46
+ # to presign.
47
+ #
48
+ # @option params [Integer] :expires_in (900) The number of seconds
49
+ # before the presigned URL expires. Defaults to 15 minutes. As signature
50
+ # version 4 has a maximum expiry time of one week for presigned URLs,
51
+ # attempts to set this value to greater than one week (604800) will
52
+ # raise an exception.
53
+ #
54
+ # @option params [Time] :time (Time.now) The starting time for when the
55
+ # presigned url becomes active.
56
+ #
57
+ # @option params [Boolean] :secure (true) When `false`, a HTTP URL
58
+ # is returned instead of the default HTTPS URL.
59
+ #
60
+ # @option params [Boolean] :virtual_host (false) When `true`, the
61
+ # bucket name will be used as the hostname.
62
+ #
63
+ # @option params [Boolean] :use_accelerate_endpoint (false) When `true`,
64
+ # Presigner will attempt to use accelerated endpoint.
65
+ #
66
+ # @option params [Array<String>] :whitelist_headers ([]) Additional
67
+ # headers to be included for the signed request. Certain headers beyond
68
+ # the authorization header could, in theory, be changed for various
69
+ # reasons (including but not limited to proxies) while in transit and
70
+ # after signing. This would lead to signature errors being returned,
71
+ # despite no actual problems with signing. (see BLACKLISTED_HEADERS)
72
+ #
73
+ # @raise [ArgumentError] Raises an ArgumentError if `:expires_in`
74
+ # exceeds one week.
75
+ #
76
+ # @return [String] a presigned url
77
+ def presigned_url(method, params = {})
78
+ url, _headers = _presigned_request(method, params)
79
+ url
80
+ end
81
+
82
+ # Allows you to create presigned URL requests for S3 operations. This
83
+ # method returns a tuple containing the URL and the signed X-amz-* headers
84
+ # to be used with the presigned url.
85
+ #
86
+ # @example
87
+ # signer = Aws::S3::Presigner.new
88
+ # url, headers = signer.presigned_request(
89
+ # :get_object, bucket: "bucket", key: "key"
90
+ # )
91
+ #
25
92
  # @param [Symbol] method Symbolized method name of the operation you want
26
93
  # to presign.
27
94
  #
@@ -31,6 +98,9 @@ module Aws
31
98
  # attempts to set this value to greater than one week (604800) will
32
99
  # raise an exception.
33
100
  #
101
+ # @option params [Time] :time (Time.now) The starting time for when the
102
+ # presigned url becomes active.
103
+ #
34
104
  # @option params [Boolean] :secure (true) When `false`, a HTTP URL
35
105
  # is returned instead of the default HTTPS URL.
36
106
  #
@@ -38,29 +108,51 @@ module Aws
38
108
  # bucket name will be used as the hostname. This will cause
39
109
  # the returned URL to be 'http' and not 'https'.
40
110
  #
41
- # @option params [Boolean] :use_accelerate_endpoint (false) When `true`, Presigner
42
- # will attempt to use accelerated endpoint
111
+ # @option params [Boolean] :use_accelerate_endpoint (false) When `true`,
112
+ # Presigner will attempt to use accelerated endpoint.
113
+ #
114
+ # @option params [Array<String>] :whitelist_headers ([]) Additional
115
+ # headers to be included for the signed request. Certain headers beyond
116
+ # the authorization header could, in theory, be changed for various
117
+ # reasons (including but not limited to proxies) while in transit and
118
+ # after signing. This would lead to signature errors being returned,
119
+ # despite no actual problems with signing. (see BLACKLISTED_HEADERS)
43
120
  #
44
121
  # @raise [ArgumentError] Raises an ArgumentError if `:expires_in`
45
122
  # exceeds one week.
46
123
  #
47
- def presigned_url(method, params = {})
48
- if params[:key].nil? or params[:key] == ''
49
- raise ArgumentError, ":key must not be blank"
50
- end
51
- virtual_host = !!params.delete(:virtual_host)
52
- scheme = http_scheme(params, virtual_host)
124
+ # @return [String, Hash] A tuple with a presigned URL and headers that
125
+ # should be included with the request.
126
+ def presigned_request(method, params = {})
127
+ _presigned_request(method, params, false)
128
+ end
129
+
130
+ private
131
+
132
+ def _presigned_request(method, params, hoist = true)
133
+ virtual_host = params.delete(:virtual_host)
134
+ time = params.delete(:time)
135
+ unsigned_headers = unsigned_headers(params)
136
+ scheme = http_scheme(params)
137
+ expires_in = expires_in(params)
53
138
 
54
139
  req = @client.build_request(method, params)
55
140
  use_bucket_as_hostname(req) if virtual_host
56
- sign_but_dont_send(req, expires_in(params), scheme)
57
- req.send_request.data
141
+ handle_presigned_url_context(req)
142
+
143
+ x_amz_headers = sign_but_dont_send(
144
+ req, expires_in, scheme, time, unsigned_headers, hoist
145
+ )
146
+ [req.send_request.data, x_amz_headers]
58
147
  end
59
148
 
60
- private
149
+ def unsigned_headers(params)
150
+ whitelist_headers = params.delete(:whitelist_headers) || []
151
+ BLACKLISTED_HEADERS - whitelist_headers
152
+ end
61
153
 
62
- def http_scheme(params, virtual_host)
63
- if params.delete(:secure) == false || virtual_host
154
+ def http_scheme(params)
155
+ if params.delete(:secure) == false
64
156
  'http'
65
157
  else
66
158
  @client.config.endpoint.scheme
@@ -68,10 +160,13 @@ module Aws
68
160
  end
69
161
 
70
162
  def expires_in(params)
71
- if expires_in = params.delete(:expires_in)
163
+ if (expires_in = params.delete(:expires_in))
72
164
  if expires_in > ONE_WEEK
73
- msg = "expires_in value of #{expires_in} exceeds one-week maximum"
74
- raise ArgumentError, msg
165
+ raise ArgumentError,
166
+ "expires_in value of #{expires_in} exceeds one-week maximum."
167
+ elsif expires_in <= 0
168
+ raise ArgumentError,
169
+ "expires_in value of #{expires_in} cannot be 0 or less."
75
170
  end
76
171
  expires_in
77
172
  else
@@ -85,14 +180,26 @@ module Aws
85
180
  uri = context.http_request.endpoint
86
181
  uri.host = context.params[:bucket]
87
182
  uri.path.sub!("/#{context.params[:bucket]}", '')
88
- uri.scheme = 'http'
89
- uri.port = 80
183
+ @handler.call(context)
184
+ end
185
+ end
186
+
187
+ # Used for excluding presigned_urls from API request count.
188
+ #
189
+ # Store context information as early as possible, to allow
190
+ # handlers to perform decisions based on this flag if need.
191
+ def handle_presigned_url_context(req)
192
+ req.handle(step: :initialize, priority: 98) do |context|
193
+ context[:presigned_url] = true
90
194
  @handler.call(context)
91
195
  end
92
196
  end
93
197
 
94
198
  # @param [Seahorse::Client::Request] req
95
- def sign_but_dont_send(req, expires_in, scheme)
199
+ def sign_but_dont_send(
200
+ req, expires_in, scheme, time, unsigned_headers, hoist = true
201
+ )
202
+ x_amz_headers = {}
96
203
 
97
204
  http_req = req.context.http_request
98
205
 
@@ -100,11 +207,7 @@ module Aws
100
207
  req.handlers.remove(Aws::S3::Plugins::S3Signer::V4Handler)
101
208
  req.handlers.remove(Seahorse::Client::Plugins::ContentLength::Handler)
102
209
 
103
- signer = build_signer(req.context.config)
104
- req.context[:presigned_url] = true
105
-
106
210
  req.handle(step: :send) do |context|
107
-
108
211
  if scheme != http_req.endpoint.scheme
109
212
  endpoint = http_req.endpoint.dup
110
213
  endpoint.scheme = scheme
@@ -112,57 +215,56 @@ module Aws
112
215
  http_req.endpoint = URI.parse(endpoint.to_s)
113
216
  end
114
217
 
115
- # hoist x-amz-* headers to the querystring
116
218
  query = http_req.endpoint.query ? http_req.endpoint.query.split('&') : []
117
- http_req.headers.keys.each do |key|
118
- if key.match(/^x-amz/i)
119
- value = Aws::Sigv4::Signer.uri_escape(http_req.headers.delete(key))
219
+ http_req.headers.each do |key, value|
220
+ next unless key =~ /^x-amz/i
221
+
222
+ if hoist
223
+ value = Aws::Sigv4::Signer.uri_escape(value)
120
224
  key = Aws::Sigv4::Signer.uri_escape(key)
225
+ # hoist x-amz-* headers to the querystring
226
+ http_req.headers.delete(key)
121
227
  query << "#{key}=#{value}"
228
+ else
229
+ x_amz_headers[key] = value
122
230
  end
123
231
  end
124
232
  http_req.endpoint.query = query.join('&') unless query.empty?
125
233
 
234
+ signing_algorithm = :sigv4
235
+
236
+ # If it's an ARN, get the resolved region and service
237
+ if (arn = context.metadata[:s3_arn])
238
+ region = arn[:resolved_region]
239
+ service = arn[:arn].service
240
+ region = arn[:arn].is_a?(MultiRegionAccessPointARN) ? '*': arn[:resolved_region]
241
+ signing_algorithm = arn[:arn].is_a?(MultiRegionAccessPointARN) ? :sigv4a : :sigv4
242
+ end
243
+
244
+ signer = Aws::Sigv4::Signer.new(
245
+ service: service || 's3',
246
+ region: region || context.config.region,
247
+ signing_algorithm: signing_algorithm,
248
+ credentials_provider: context.config.credentials,
249
+ unsigned_headers: unsigned_headers,
250
+ apply_checksum_header: false,
251
+ uri_escape_path: false
252
+ )
253
+
126
254
  url = signer.presign_url(
127
255
  http_method: http_req.http_method,
128
256
  url: http_req.endpoint,
129
257
  headers: http_req.headers,
130
258
  body_digest: 'UNSIGNED-PAYLOAD',
131
- expires_in: expires_in
259
+ expires_in: expires_in,
260
+ time: time
132
261
  ).to_s
133
262
 
134
263
  Seahorse::Client::Response.new(context: context, data: url)
135
264
  end
265
+ # Return the headers
266
+ x_amz_headers
136
267
  end
137
-
138
- def build_signer(cfg)
139
- Aws::Sigv4::Signer.new(
140
- service: 's3',
141
- region: cfg.region,
142
- credentials_provider: cfg.credentials,
143
- unsigned_headers: [
144
- 'cache-control',
145
- 'content-length', # due to a ELB bug
146
- 'expect',
147
- 'max-forwards',
148
- 'pragma',
149
- 'te',
150
- 'if-match',
151
- 'if-none-match',
152
- 'if-modified-since',
153
- 'if-unmodified-since',
154
- 'if-range',
155
- 'accept',
156
- 'proxy-authorization',
157
- 'from',
158
- 'referer',
159
- 'user-agent',
160
- 'x-amzn-trace-id'
161
- ],
162
- uri_escape_path: false
163
- )
164
- end
165
-
166
268
  end
167
269
  end
168
270
  end
@@ -1,11 +1,25 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # WARNING ABOUT GENERATED CODE
2
4
  #
3
5
  # This file is generated. See the contributing guide for more information:
4
- # https://github.com/aws/aws-sdk-ruby/blob/master/CONTRIBUTING.md
6
+ # https://github.com/aws/aws-sdk-ruby/blob/version-3/CONTRIBUTING.md
5
7
  #
6
8
  # WARNING ABOUT GENERATED CODE
7
9
 
8
10
  module Aws::S3
11
+
12
+ # This class provides a resource oriented interface for S3.
13
+ # To create a resource object:
14
+ #
15
+ # resource = Aws::S3::Resource.new(region: 'us-west-2')
16
+ #
17
+ # You can supply a client object with custom configuration that will be used for all resource operations.
18
+ # If you do not pass `:client`, a default client will be constructed.
19
+ #
20
+ # client = Aws::S3::Client.new(region: 'us-west-2')
21
+ # resource = Aws::S3::Resource.new(client: client)
22
+ #
9
23
  class Resource
10
24
 
11
25
  # @param options ({})
@@ -27,7 +41,7 @@ module Aws::S3
27
41
  # acl: "private", # accepts private, public-read, public-read-write, authenticated-read
28
42
  # bucket: "BucketName", # required
29
43
  # create_bucket_configuration: {
30
- # location_constraint: "EU", # accepts EU, eu-west-1, us-west-1, us-west-2, ap-south-1, ap-southeast-1, ap-southeast-2, ap-northeast-1, sa-east-1, cn-north-1, eu-central-1
44
+ # location_constraint: "af-south-1", # accepts af-south-1, ap-east-1, ap-northeast-1, ap-northeast-2, ap-northeast-3, ap-south-1, ap-southeast-1, ap-southeast-2, ca-central-1, cn-north-1, cn-northwest-1, EU, eu-central-1, eu-north-1, eu-south-1, eu-west-1, eu-west-2, eu-west-3, me-south-1, sa-east-1, us-east-2, us-gov-east-1, us-gov-west-1, us-west-1, us-west-2
31
45
  # },
32
46
  # grant_full_control: "GrantFullControl",
33
47
  # grant_read: "GrantRead",
@@ -35,12 +49,15 @@ module Aws::S3
35
49
  # grant_write: "GrantWrite",
36
50
  # grant_write_acp: "GrantWriteACP",
37
51
  # object_lock_enabled_for_bucket: false,
52
+ # object_ownership: "BucketOwnerPreferred", # accepts BucketOwnerPreferred, ObjectWriter, BucketOwnerEnforced
38
53
  # })
39
54
  # @param [Hash] options ({})
40
55
  # @option options [String] :acl
41
56
  # The canned ACL to apply to the bucket.
42
57
  # @option options [required, String] :bucket
58
+ # The name of the bucket to create.
43
59
  # @option options [Types::CreateBucketConfiguration] :create_bucket_configuration
60
+ # The configuration information for the bucket.
44
61
  # @option options [String] :grant_full_control
45
62
  # Allows grantee the read, write, read ACP, and write ACP permissions on
46
63
  # the bucket.
@@ -49,16 +66,35 @@ module Aws::S3
49
66
  # @option options [String] :grant_read_acp
50
67
  # Allows grantee to read the bucket ACL.
51
68
  # @option options [String] :grant_write
52
- # Allows grantee to create, overwrite, and delete any object in the
53
- # bucket.
69
+ # Allows grantee to create new objects in the bucket.
70
+ #
71
+ # For the bucket and object owners of existing objects, also allows
72
+ # deletions and overwrites of those objects.
54
73
  # @option options [String] :grant_write_acp
55
74
  # Allows grantee to write the ACL for the applicable bucket.
56
75
  # @option options [Boolean] :object_lock_enabled_for_bucket
57
76
  # Specifies whether you want S3 Object Lock to be enabled for the new
58
77
  # bucket.
78
+ # @option options [String] :object_ownership
79
+ # The container element for object ownership for a bucket's ownership
80
+ # controls.
81
+ #
82
+ # BucketOwnerPreferred - Objects uploaded to the bucket change ownership
83
+ # to the bucket owner if the objects are uploaded with the
84
+ # `bucket-owner-full-control` canned ACL.
85
+ #
86
+ # ObjectWriter - The uploading account will own the object if the object
87
+ # is uploaded with the `bucket-owner-full-control` canned ACL.
88
+ #
89
+ # BucketOwnerEnforced - Access control lists (ACLs) are disabled and no
90
+ # longer affect permissions. The bucket owner automatically owns and has
91
+ # full control over every object in the bucket. The bucket only accepts
92
+ # PUT requests that don't specify an ACL or bucket owner full control
93
+ # ACLs, such as the `bucket-owner-full-control` canned ACL or an
94
+ # equivalent form of this ACL expressed in the XML format.
59
95
  # @return [Bucket]
60
96
  def create_bucket(options = {})
61
- resp = @client.create_bucket(options)
97
+ @client.create_bucket(options)
62
98
  Bucket.new(
63
99
  name: options[:bucket],
64
100
  client: @client