aws-sdk-s3 1.87.0 → 1.143.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1106 -0
  3. data/LICENSE.txt +202 -0
  4. data/VERSION +1 -0
  5. data/lib/aws-sdk-s3/bucket.rb +605 -114
  6. data/lib/aws-sdk-s3/bucket_acl.rb +36 -11
  7. data/lib/aws-sdk-s3/bucket_cors.rb +40 -15
  8. data/lib/aws-sdk-s3/bucket_lifecycle.rb +42 -15
  9. data/lib/aws-sdk-s3/bucket_lifecycle_configuration.rb +43 -13
  10. data/lib/aws-sdk-s3/bucket_logging.rb +40 -11
  11. data/lib/aws-sdk-s3/bucket_notification.rb +30 -12
  12. data/lib/aws-sdk-s3/bucket_policy.rb +82 -13
  13. data/lib/aws-sdk-s3/bucket_request_payment.rb +35 -13
  14. data/lib/aws-sdk-s3/bucket_tagging.rb +38 -13
  15. data/lib/aws-sdk-s3/bucket_versioning.rb +82 -21
  16. data/lib/aws-sdk-s3/bucket_website.rb +38 -13
  17. data/lib/aws-sdk-s3/client.rb +8666 -3425
  18. data/lib/aws-sdk-s3/client_api.rb +774 -225
  19. data/lib/aws-sdk-s3/customizations/bucket.rb +31 -50
  20. data/lib/aws-sdk-s3/customizations/errors.rb +27 -0
  21. data/lib/aws-sdk-s3/customizations/object.rb +211 -37
  22. data/lib/aws-sdk-s3/customizations/types/permanent_redirect.rb +26 -0
  23. data/lib/aws-sdk-s3/customizations.rb +7 -0
  24. data/lib/aws-sdk-s3/encryption/client.rb +7 -3
  25. data/lib/aws-sdk-s3/encryption/decrypt_handler.rb +0 -4
  26. data/lib/aws-sdk-s3/encryption/kms_cipher_provider.rb +13 -9
  27. data/lib/aws-sdk-s3/encryptionV2/client.rb +7 -3
  28. data/lib/aws-sdk-s3/encryptionV2/decrypt_handler.rb +1 -4
  29. data/lib/aws-sdk-s3/encryptionV2/default_cipher_provider.rb +3 -3
  30. data/lib/aws-sdk-s3/encryptionV2/encrypt_handler.rb +0 -4
  31. data/lib/aws-sdk-s3/encryptionV2/kms_cipher_provider.rb +10 -6
  32. data/lib/aws-sdk-s3/endpoint_parameters.rb +178 -0
  33. data/lib/aws-sdk-s3/endpoint_provider.rb +591 -0
  34. data/lib/aws-sdk-s3/endpoints.rb +2590 -0
  35. data/lib/aws-sdk-s3/errors.rb +1 -1
  36. data/lib/aws-sdk-s3/event_streams.rb +1 -1
  37. data/lib/aws-sdk-s3/express_credentials.rb +55 -0
  38. data/lib/aws-sdk-s3/express_credentials_cache.rb +30 -0
  39. data/lib/aws-sdk-s3/express_credentials_provider.rb +36 -0
  40. data/lib/aws-sdk-s3/file_downloader.rb +171 -41
  41. data/lib/aws-sdk-s3/file_uploader.rb +14 -7
  42. data/lib/aws-sdk-s3/multipart_file_uploader.rb +26 -8
  43. data/lib/aws-sdk-s3/multipart_stream_uploader.rb +41 -14
  44. data/lib/aws-sdk-s3/multipart_upload.rb +198 -23
  45. data/lib/aws-sdk-s3/multipart_upload_part.rb +285 -34
  46. data/lib/aws-sdk-s3/object.rb +1824 -266
  47. data/lib/aws-sdk-s3/object_acl.rb +58 -19
  48. data/lib/aws-sdk-s3/object_copier.rb +7 -5
  49. data/lib/aws-sdk-s3/object_multipart_copier.rb +41 -19
  50. data/lib/aws-sdk-s3/object_summary.rb +1579 -299
  51. data/lib/aws-sdk-s3/object_version.rb +372 -64
  52. data/lib/aws-sdk-s3/plugins/accelerate.rb +1 -39
  53. data/lib/aws-sdk-s3/plugins/arn.rb +25 -142
  54. data/lib/aws-sdk-s3/plugins/bucket_dns.rb +3 -39
  55. data/lib/aws-sdk-s3/plugins/bucket_name_restrictions.rb +1 -6
  56. data/lib/aws-sdk-s3/plugins/dualstack.rb +2 -49
  57. data/lib/aws-sdk-s3/plugins/endpoints.rb +274 -0
  58. data/lib/aws-sdk-s3/plugins/expect_100_continue.rb +3 -1
  59. data/lib/aws-sdk-s3/plugins/express_session_auth.rb +91 -0
  60. data/lib/aws-sdk-s3/plugins/get_bucket_location_fix.rb +1 -1
  61. data/lib/aws-sdk-s3/plugins/iad_regional_endpoint.rb +8 -31
  62. data/lib/aws-sdk-s3/plugins/location_constraint.rb +3 -1
  63. data/lib/aws-sdk-s3/plugins/md5s.rb +6 -3
  64. data/lib/aws-sdk-s3/plugins/s3_signer.rb +35 -102
  65. data/lib/aws-sdk-s3/plugins/skip_whole_multipart_get_checksums.rb +31 -0
  66. data/lib/aws-sdk-s3/plugins/streaming_retry.rb +23 -2
  67. data/lib/aws-sdk-s3/presigned_post.rb +99 -78
  68. data/lib/aws-sdk-s3/presigner.rb +43 -51
  69. data/lib/aws-sdk-s3/resource.rb +102 -6
  70. data/lib/aws-sdk-s3/types.rb +7404 -5114
  71. data/lib/aws-sdk-s3/waiters.rb +1 -1
  72. data/lib/aws-sdk-s3.rb +6 -2
  73. data/sig/bucket.rbs +212 -0
  74. data/sig/bucket_acl.rbs +78 -0
  75. data/sig/bucket_cors.rbs +69 -0
  76. data/sig/bucket_lifecycle.rbs +88 -0
  77. data/sig/bucket_lifecycle_configuration.rbs +111 -0
  78. data/sig/bucket_logging.rbs +76 -0
  79. data/sig/bucket_notification.rbs +114 -0
  80. data/sig/bucket_policy.rbs +59 -0
  81. data/sig/bucket_request_payment.rbs +54 -0
  82. data/sig/bucket_tagging.rbs +65 -0
  83. data/sig/bucket_versioning.rbs +77 -0
  84. data/sig/bucket_website.rbs +93 -0
  85. data/sig/client.rbs +2360 -0
  86. data/sig/errors.rbs +34 -0
  87. data/sig/multipart_upload.rbs +110 -0
  88. data/sig/multipart_upload_part.rbs +105 -0
  89. data/sig/object.rbs +436 -0
  90. data/sig/object_acl.rbs +86 -0
  91. data/sig/object_summary.rbs +334 -0
  92. data/sig/object_version.rbs +131 -0
  93. data/sig/resource.rbs +124 -0
  94. data/sig/types.rbs +2562 -0
  95. data/sig/waiters.rbs +83 -0
  96. metadata +51 -17
  97. data/lib/aws-sdk-s3/arn/access_point_arn.rb +0 -62
  98. data/lib/aws-sdk-s3/arn/outpost_access_point_arn.rb +0 -71
@@ -5,22 +5,6 @@ require 'uri'
5
5
  module Aws
6
6
  module S3
7
7
  class Bucket
8
- # Save the old initialize method so that we can call 'super'.
9
- old_initialize = instance_method(:initialize)
10
- # Make the method redefinable
11
- alias_method :initialize, :initialize
12
- # Define a new initialize method that extracts out a bucket ARN.
13
- define_method(:initialize) do |*args|
14
- old_initialize.bind(self).call(*args)
15
- resolved_region, arn = Plugins::ARN.resolve_arn!(
16
- name,
17
- client.config.region,
18
- client.config.s3_use_arn_region
19
- )
20
- @resolved_region = resolved_region
21
- @arn = arn
22
- end
23
-
24
8
  # Deletes all objects and versioned objects from this bucket
25
9
  #
26
10
  # @example
@@ -88,26 +72,44 @@ module Aws
88
72
  # You can pass `virtual_host: true` to use the bucket name as the
89
73
  # host name.
90
74
  #
91
- # bucket = s3.bucket('my.bucket.com')
75
+ # bucket = s3.bucket('my-bucket.com')
92
76
  # bucket.url(virtual_host: true)
93
- # #=> "http://my.bucket.com"
77
+ # #=> "http://my-bucket.com"
94
78
  #
95
79
  # @option options [Boolean] :virtual_host (false) When `true`,
96
80
  # the bucket name will be used as the host name. This is useful
97
81
  # when you have a CNAME configured for this bucket.
98
82
  #
83
+ # @option options [Boolean] :secure (true) When `false`, http
84
+ # will be used with virtual_host. This is required when
85
+ # the bucket name has a dot (.) in it.
86
+ #
99
87
  # @return [String] the URL for this bucket.
100
88
  def url(options = {})
101
89
  if options[:virtual_host]
102
- "http://#{name}"
103
- elsif @arn
104
- Plugins::ARN.resolve_url!(
105
- client.config.endpoint.dup,
106
- @arn,
107
- @resolved_region
108
- ).to_s
90
+ scheme = options.fetch(:secure, true) ? 'https' : 'http'
91
+ "#{scheme}://#{name}"
109
92
  else
110
- s3_bucket_url
93
+ # Taken from Aws::S3::Endpoints module
94
+ unless client.config.regional_endpoint
95
+ endpoint = client.config.endpoint.to_s
96
+ end
97
+ params = Aws::S3::EndpointParameters.new(
98
+ bucket: name,
99
+ region: client.config.region,
100
+ use_fips: client.config.use_fips_endpoint,
101
+ use_dual_stack: client.config.use_dualstack_endpoint,
102
+ endpoint: endpoint,
103
+ force_path_style: client.config.force_path_style,
104
+ accelerate: client.config.use_accelerate_endpoint,
105
+ use_global_endpoint: client.config.s3_us_east_1_regional_endpoint == 'legacy',
106
+ use_object_lambda_endpoint: nil,
107
+ disable_access_points: nil,
108
+ disable_multi_region_access_points: client.config.s3_disable_multiregion_access_points,
109
+ use_arn_region: client.config.s3_use_arn_region,
110
+ )
111
+ endpoint = Aws::S3::EndpointProvider.new.resolve_endpoint(params)
112
+ endpoint.url
111
113
  end
112
114
  end
113
115
 
@@ -132,34 +134,13 @@ module Aws
132
134
 
133
135
  # @api private
134
136
  def load
135
- @data = client.list_buckets.buckets.find { |b| b.name == name }
137
+ @data = Aws::Plugins::UserAgent.feature('resource') do
138
+ client.list_buckets.buckets.find { |b| b.name == name }
139
+ end
136
140
  raise "unable to load bucket #{name}" if @data.nil?
137
141
 
138
142
  self
139
143
  end
140
-
141
- private
142
-
143
- def s3_bucket_url
144
- url = client.config.endpoint.dup
145
- if bucket_as_hostname?(url.scheme == 'https')
146
- url.host = "#{name}.#{url.host}"
147
- else
148
- url.path += '/' unless url.path[-1] == '/'
149
- url.path += Seahorse::Util.uri_escape(name)
150
- end
151
- if (client.config.region == 'us-east-1') &&
152
- (client.config.s3_us_east_1_regional_endpoint == 'legacy')
153
- url.host = Plugins::IADRegionalEndpoint.legacy_host(url.host)
154
- end
155
- url.to_s
156
- end
157
-
158
- def bucket_as_hostname?(https)
159
- Plugins::BucketDns.dns_compatible?(name, https) &&
160
- !client.config.force_path_style
161
- end
162
-
163
144
  end
164
145
  end
165
146
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module S3
5
+ module Errors
6
+ # Hijack PermanentRedirect dynamic error to also include endpoint
7
+ # and bucket.
8
+ class PermanentRedirect < ServiceError
9
+ # @param [Seahorse::Client::RequestContext] context
10
+ # @param [String] message
11
+ # @param [Aws::S3::Types::PermanentRedirect] _data
12
+ def initialize(context, message, _data = Aws::EmptyStructure.new)
13
+ data = Aws::S3::Types::PermanentRedirect.new(message: message)
14
+ body = context.http_response.body_contents
15
+ if (endpoint = body.match(/<Endpoint>(.+?)<\/Endpoint>/))
16
+ data.endpoint = endpoint[1]
17
+ end
18
+ if (bucket = body.match(/<Bucket>(.+?)<\/Bucket>/))
19
+ data.bucket = bucket[1]
20
+ end
21
+ data.region = context.http_response.headers['x-amz-bucket-region']
22
+ super(context, message, data)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -27,10 +27,13 @@ module Aws
27
27
  # necessary for objects larger than 5GB and can provide
28
28
  # performance improvements on large objects. Amazon S3 does
29
29
  # not accept multipart copies for objects smaller than 5MB.
30
+ # Object metadata such as Content-Type will be copied, however,
31
+ # Checksums are not copied.
30
32
  #
31
33
  # @option options [Integer] :content_length Only used when
32
34
  # `:multipart_copy` is `true`. Passing this options avoids a HEAD
33
- # request to query the source object size. Raises an `ArgumentError` if
35
+ # request to query the source object size but prevents object metadata
36
+ # from being copied. Raises an `ArgumentError` if
34
37
  # this option is provided when `:multipart_copy` is `false` or not set.
35
38
  #
36
39
  # @option options [S3::Client] :copy_source_client Only used when
@@ -43,6 +46,14 @@ module Aws
43
46
  # different region. You do not need to specify this option
44
47
  # if you have provided a `:source_client` or a `:content_length`.
45
48
  #
49
+ # @option options [Boolean] :use_source_parts (false) Only used when
50
+ # `:multipart_copy` is `true`. Use part sizes defined on the source
51
+ # object if any exist. If copying or moving an object that
52
+ # is already multipart, this does not re-part the object, instead
53
+ # re-using the part definitions on the original. That means the etag
54
+ # and any checksums will not change. This is especially useful if the
55
+ # source object has parts with varied sizes.
56
+ #
46
57
  # @example Basic object copy
47
58
  #
48
59
  # bucket = Aws::S3::Bucket.new('target-bucket')
@@ -65,11 +76,13 @@ module Aws
65
76
  # @see #copy_to
66
77
  #
67
78
  def copy_from(source, options = {})
68
- if Hash === source && source[:copy_source]
69
- # for backwards compatibility
70
- @client.copy_object(source.merge(bucket: bucket_name, key: key))
71
- else
72
- ObjectCopier.new(self, options).copy_from(source, options)
79
+ Aws::Plugins::UserAgent.feature('resource') do
80
+ if Hash === source && source[:copy_source]
81
+ # for backwards compatibility
82
+ @client.copy_object(source.merge(bucket: bucket_name, key: key))
83
+ else
84
+ ObjectCopier.new(self, options).copy_from(source, options)
85
+ end
73
86
  end
74
87
  end
75
88
 
@@ -106,7 +119,9 @@ module Aws
106
119
  # object.copy_to('src-bucket/src-key', multipart_copy: true)
107
120
  #
108
121
  def copy_to(target, options = {})
109
- ObjectCopier.new(self, options).copy_to(target, options)
122
+ Aws::Plugins::UserAgent.feature('resource') do
123
+ ObjectCopier.new(self, options).copy_to(target, options)
124
+ end
110
125
  end
111
126
 
112
127
  # Copies and deletes the current object. The object will only be deleted
@@ -153,21 +168,35 @@ module Aws
153
168
  # obj.presigned_url(:put, acl: 'public-read')
154
169
  # #=> "https://bucket-name.s3.amazonaws.com/object-key?..."
155
170
  #
156
- # @param [Symbol] http_method
157
- # The HTTP method to generate a presigned URL for. Valid values
158
- # are `:get`, `:put`, `:head`, and `:delete`.
171
+ # @example Pre-signed UploadPart PUT
172
+ #
173
+ # # the object uploaded using this URL will be publicly accessible
174
+ # obj.presigned_url(:upload_part, part_number: 1, upload_id: 'uploadIdToken')
175
+ # #=> "https://bucket-name.s3.amazonaws.com/object-key?..."
176
+ #
177
+ # @param [Symbol] method
178
+ # The S3 operation to generate a presigned URL for. Valid values
179
+ # are `:get`, `:put`, `:head`, `:delete`, `:create_multipart_upload`,
180
+ # `:list_multipart_uploads`, `:complete_multipart_upload`,
181
+ # `:abort_multipart_upload`, `:list_parts`, and `:upload_part`.
159
182
  #
160
183
  # @param [Hash] params
161
184
  # Additional request parameters to use when generating the pre-signed
162
185
  # URL. See the related documentation in {Client} for accepted
163
186
  # params.
164
187
  #
165
- # | HTTP Method | Client Method |
166
- # |---------------|------------------------|
167
- # | `:get` | {Client#get_object} |
168
- # | `:put` | {Client#put_object} |
169
- # | `:head` | {Client#head_object} |
170
- # | `:delete` | {Client#delete_object} |
188
+ # | Method | Client Method |
189
+ # |------------------------------|------------------------------------|
190
+ # | `:get` | {Client#get_object} |
191
+ # | `:put` | {Client#put_object} |
192
+ # | `:head` | {Client#head_object} |
193
+ # | `:delete` | {Client#delete_object} |
194
+ # | `:create_multipart_upload` | {Client#create_multipart_upload} |
195
+ # | `:list_multipart_uploads` | {Client#list_multipart_uploads} |
196
+ # | `:complete_multipart_upload` | {Client#complete_multipart_upload} |
197
+ # | `:abort_multipart_upload` | {Client#abort_multipart_upload} |
198
+ # | `:list_parts` | {Client#list_parts} |
199
+ # | `:upload_part` | {Client#upload_part} |
171
200
  #
172
201
  # @option params [Boolean] :virtual_host (false) When `true` the
173
202
  # presigned URL will use the bucket name as a virtual host.
@@ -188,10 +217,88 @@ module Aws
188
217
  #
189
218
  # @return [String]
190
219
  #
191
- def presigned_url(http_method, params = {})
220
+ def presigned_url(method, params = {})
192
221
  presigner = Presigner.new(client: client)
222
+
223
+ if %w(delete head get put).include?(method.to_s)
224
+ method = "#{method}_object".to_sym
225
+ end
226
+
193
227
  presigner.presigned_url(
194
- "#{http_method.downcase}_object",
228
+ method.downcase,
229
+ params.merge(bucket: bucket_name, key: key)
230
+ )
231
+ end
232
+
233
+ # Allows you to create presigned URL requests for S3 operations. This
234
+ # method returns a tuple containing the URL and the signed X-amz-* headers
235
+ # to be used with the presigned url.
236
+ #
237
+ # @example Pre-signed GET URL, valid for one hour
238
+ #
239
+ # obj.presigned_request(:get, expires_in: 3600)
240
+ # #=> ["https://bucket-name.s3.amazonaws.com/object-key?...", {}]
241
+ #
242
+ # @example Pre-signed PUT with a canned ACL
243
+ #
244
+ # # the object uploaded using this URL will be publicly accessible
245
+ # obj.presigned_request(:put, acl: 'public-read')
246
+ # #=> ["https://bucket-name.s3.amazonaws.com/object-key?...",
247
+ # {"x-amz-acl"=>"public-read"}]
248
+ #
249
+ # @param [Symbol] method
250
+ # The S3 operation to generate a presigned request for. Valid values
251
+ # are `:get`, `:put`, `:head`, `:delete`, `:create_multipart_upload`,
252
+ # `:list_multipart_uploads`, `:complete_multipart_upload`,
253
+ # `:abort_multipart_upload`, `:list_parts`, and `:upload_part`.
254
+ #
255
+ # @param [Hash] params
256
+ # Additional request parameters to use when generating the pre-signed
257
+ # request. See the related documentation in {Client} for accepted
258
+ # params.
259
+ #
260
+ # | Method | Client Method |
261
+ # |------------------------------|------------------------------------|
262
+ # | `:get` | {Client#get_object} |
263
+ # | `:put` | {Client#put_object} |
264
+ # | `:head` | {Client#head_object} |
265
+ # | `:delete` | {Client#delete_object} |
266
+ # | `:create_multipart_upload` | {Client#create_multipart_upload} |
267
+ # | `:list_multipart_uploads` | {Client#list_multipart_uploads} |
268
+ # | `:complete_multipart_upload` | {Client#complete_multipart_upload} |
269
+ # | `:abort_multipart_upload` | {Client#abort_multipart_upload} |
270
+ # | `:list_parts` | {Client#list_parts} |
271
+ # | `:upload_part` | {Client#upload_part} |
272
+ #
273
+ # @option params [Boolean] :virtual_host (false) When `true` the
274
+ # presigned URL will use the bucket name as a virtual host.
275
+ #
276
+ # bucket = Aws::S3::Bucket.new('my.bucket.com')
277
+ # bucket.object('key').presigned_request(virtual_host: true)
278
+ # #=> ["http://my.bucket.com/key?...", {}]
279
+ #
280
+ # @option params [Integer] :expires_in (900) Number of seconds before
281
+ # the pre-signed URL expires. This may not exceed one week (604800
282
+ # seconds). Note that the pre-signed URL is also only valid as long as
283
+ # credentials used to sign it are. For example, when using IAM roles,
284
+ # temporary tokens generated for signing also have a default expiration
285
+ # which will affect the effective expiration of the pre-signed URL.
286
+ #
287
+ # @raise [ArgumentError] Raised if `:expires_in` exceeds one week
288
+ # (604800 seconds).
289
+ #
290
+ # @return [String, Hash] A tuple with a presigned URL and headers that
291
+ # should be included with the request.
292
+ #
293
+ def presigned_request(method, params = {})
294
+ presigner = Presigner.new(client: client)
295
+
296
+ if %w(delete head get put).include?(method.to_s)
297
+ method = "#{method}_object".to_sym
298
+ end
299
+
300
+ presigner.presigned_request(
301
+ method.downcase,
195
302
  params.merge(bucket: bucket_name, key: key)
196
303
  )
197
304
  end
@@ -201,16 +308,22 @@ module Aws
201
308
  # s3.bucket('bucket-name').object('obj-key').public_url
202
309
  # #=> "https://bucket-name.s3.amazonaws.com/obj-key"
203
310
  #
204
- # To use virtual hosted bucket url (disables https):
311
+ # To use virtual hosted bucket url.
312
+ # Uses https unless secure: false is set. If the bucket
313
+ # name contains dots (.) then you will need to set secure: false.
205
314
  #
206
- # s3.bucket('my.bucket.com').object('key')
315
+ # s3.bucket('my-bucket.com').object('key')
207
316
  # .public_url(virtual_host: true)
208
- # #=> "http://my.bucket.com/key"
317
+ # #=> "https://my-bucket.com/key"
209
318
  #
210
319
  # @option options [Boolean] :virtual_host (false) When `true`, the bucket
211
320
  # name will be used as the host name. This is useful when you have
212
321
  # a CNAME configured for the bucket.
213
322
  #
323
+ # @option options [Boolean] :secure (true) When `false`, http
324
+ # will be used with virtual_host. This is required when
325
+ # the bucket name has a dot (.) in it.
326
+ #
214
327
  # @return [String]
215
328
  def public_url(options = {})
216
329
  url = URI.parse(bucket.url(options))
@@ -240,6 +353,10 @@ module Aws
240
353
  # obj.upload_stream do |write_stream|
241
354
  # IO.copy_stream(STDIN, write_stream)
242
355
  # end
356
+ # @param [Hash] options
357
+ # Additional options for {Client#create_multipart_upload},
358
+ # {Client#complete_multipart_upload},
359
+ # and {Client#upload_part} can be provided.
243
360
  #
244
361
  # @option options [Integer] :thread_count (10) The number of parallel
245
362
  # multipart uploads
@@ -262,6 +379,9 @@ module Aws
262
379
  # @return [Boolean] Returns `true` when the object is uploaded
263
380
  # without any errors.
264
381
  #
382
+ # @see Client#create_multipart_upload
383
+ # @see Client#complete_multipart_upload
384
+ # @see Client#upload_part
265
385
  def upload_stream(options = {}, &block)
266
386
  uploading_options = options.dup
267
387
  uploader = MultipartStreamUploader.new(
@@ -270,10 +390,12 @@ module Aws
270
390
  tempfile: uploading_options.delete(:tempfile),
271
391
  part_size: uploading_options.delete(:part_size)
272
392
  )
273
- uploader.upload(
274
- uploading_options.merge(bucket: bucket_name, key: key),
275
- &block
276
- )
393
+ Aws::Plugins::UserAgent.feature('resource') do
394
+ uploader.upload(
395
+ uploading_options.merge(bucket: bucket_name, key: key),
396
+ &block
397
+ )
398
+ end
277
399
  true
278
400
  end
279
401
 
@@ -302,7 +424,7 @@ module Aws
302
424
  # progress = Proc.new do |bytes, totals|
303
425
  # puts bytes.map.with_index { |b, i| "Part #{i+1}: #{b} / #{totals[i]}"}.join(' ') + "Total: #{100.0 * bytes.sum / totals.sum }%" }
304
426
  # end
305
- # obj.upload_file('/path/to/file')
427
+ # obj.upload_file('/path/to/file', progress_callback: progress)
306
428
  #
307
429
  # @param [String, Pathname, File, Tempfile] source A file on the local
308
430
  # file system that will be uploaded as this object. This can either be
@@ -312,10 +434,17 @@ module Aws
312
434
  # using an open Tempfile, rewind it before uploading or else the object
313
435
  # will be empty.
314
436
  #
315
- # @option options [Integer] :multipart_threshold (15728640) Files larger
437
+ # @param [Hash] options
438
+ # Additional options for {Client#put_object}
439
+ # when file sizes below the multipart threshold. For files larger than
440
+ # the multipart threshold, options for {Client#create_multipart_upload},
441
+ # {Client#complete_multipart_upload},
442
+ # and {Client#upload_part} can be provided.
443
+ #
444
+ # @option options [Integer] :multipart_threshold (104857600) Files larger
316
445
  # than or equal to `:multipart_threshold` are uploaded using the S3
317
446
  # multipart APIs.
318
- # Default threshold is 15MB.
447
+ # Default threshold is 100MB.
319
448
  #
320
449
  # @option options [Integer] :thread_count (10) The number of parallel
321
450
  # multipart uploads. This option is not used if the file is smaller than
@@ -333,16 +462,23 @@ module Aws
333
462
  #
334
463
  # @return [Boolean] Returns `true` when the object is uploaded
335
464
  # without any errors.
465
+ #
466
+ # @see Client#put_object
467
+ # @see Client#create_multipart_upload
468
+ # @see Client#complete_multipart_upload
469
+ # @see Client#upload_part
336
470
  def upload_file(source, options = {})
337
471
  uploading_options = options.dup
338
472
  uploader = FileUploader.new(
339
473
  multipart_threshold: uploading_options.delete(:multipart_threshold),
340
474
  client: client
341
475
  )
342
- response = uploader.upload(
343
- source,
344
- uploading_options.merge(bucket: bucket_name, key: key)
345
- )
476
+ response = Aws::Plugins::UserAgent.feature('resource') do
477
+ uploader.upload(
478
+ source,
479
+ uploading_options.merge(bucket: bucket_name, key: key)
480
+ )
481
+ end
346
482
  yield response if block_given?
347
483
  true
348
484
  end
@@ -358,15 +494,28 @@ module Aws
358
494
  # # and the parts are downloaded in parallel
359
495
  # obj.download_file('/path/to/very_large_file')
360
496
  #
497
+ # You can provide a callback to monitor progress of the download:
498
+ #
499
+ # # bytes and part_sizes are each an array with 1 entry per part
500
+ # # part_sizes may not be known until the first bytes are retrieved
501
+ # progress = Proc.new do |bytes, part_sizes, file_size|
502
+ # puts bytes.map.with_index { |b, i| "Part #{i+1}: #{b} / #{part_sizes[i]}"}.join(' ') + "Total: #{100.0 * bytes.sum / file_size}%" }
503
+ # end
504
+ # obj.download_file('/path/to/file', progress_callback: progress)
505
+ #
361
506
  # @param [String] destination Where to download the file to.
362
507
  #
508
+ # @param [Hash] options
509
+ # Additional options for {Client#get_object} and #{Client#head_object}
510
+ # may be provided.
511
+ #
363
512
  # @option options [String] mode `auto`, `single_request`, `get_range`
364
513
  # `single_request` mode forces only 1 GET request is made in download,
365
514
  # `get_range` mode allows `chunk_size` parameter to configured in
366
515
  # customizing each range size in multipart_download,
367
516
  # By default, `auto` mode is enabled, which performs multipart_download
368
517
  #
369
- # @option options [String] chunk_size required in get_range mode.
518
+ # @option options [Integer] chunk_size required in get_range mode.
370
519
  #
371
520
  # @option options [Integer] thread_count (10) Customize threads used in
372
521
  # the multipart download.
@@ -375,14 +524,39 @@ module Aws
375
524
  # retrieve the object. For more about object versioning, see:
376
525
  # https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectVersioning.html
377
526
  #
527
+ # @option options [String] checksum_mode (ENABLED) When `ENABLED` and
528
+ # the object has a stored checksum, it will be used to validate the
529
+ # download and will raise an `Aws::Errors::ChecksumError` if
530
+ # checksum validation fails. You may provide a `on_checksum_validated`
531
+ # callback if you need to verify that validation occurred and which
532
+ # algorithm was used. To disable checksum validation, set
533
+ # `checksum_mode` to "DISABLED".
534
+ #
535
+ # @option options [Callable] on_checksum_validated Called each time a
536
+ # request's checksum is validated with the checksum algorithm and the
537
+ # response. For multipart downloads, this will be called for each
538
+ # part that is downloaded and validated.
539
+ #
540
+ # @option options [Proc] :progress_callback
541
+ # A Proc that will be called when each chunk of the download is received.
542
+ # It will be invoked with [bytes_read], [part_sizes], file_size.
543
+ # When the object is downloaded as parts (rather than by ranges), the
544
+ # part_sizes will not be known ahead of time and will be nil in the
545
+ # callback until the first bytes in the part are received.
546
+ #
378
547
  # @return [Boolean] Returns `true` when the file is downloaded without
379
548
  # any errors.
549
+ #
550
+ # @see Client#get_object
551
+ # @see Client#head_object
380
552
  def download_file(destination, options = {})
381
553
  downloader = FileDownloader.new(client: client)
382
- downloader.download(
383
- destination,
384
- options.merge(bucket: bucket_name, key: key)
385
- )
554
+ Aws::Plugins::UserAgent.feature('resource') do
555
+ downloader.download(
556
+ destination,
557
+ options.merge(bucket: bucket_name, key: key)
558
+ )
559
+ end
386
560
  true
387
561
  end
388
562
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module S3
5
+ module Types
6
+ # This error is not modeled.
7
+ #
8
+ # The bucket you are attempting to access must be addressed using the
9
+ # specified endpoint. Please send all future requests to this endpoint.
10
+ #
11
+ # @!attribute [rw] endpoint
12
+ # @return [String]
13
+ #
14
+ # @!attribute [rw] bucket
15
+ # @return [String]
16
+ #
17
+ # @!attribute [rw] message
18
+ # @return [String]
19
+ #
20
+ class PermanentRedirect < Struct.new(:endpoint, :bucket, :region, :message)
21
+ SENSITIVE = []
22
+ include Aws::Structure
23
+ end
24
+ end
25
+ end
26
+ end
@@ -16,12 +16,19 @@ require 'aws-sdk-s3/object_multipart_copier'
16
16
  require 'aws-sdk-s3/presigned_post'
17
17
  require 'aws-sdk-s3/presigner'
18
18
 
19
+ # s3 express session auth
20
+ require 'aws-sdk-s3/express_credentials'
21
+ require 'aws-sdk-s3/express_credentials_cache'
22
+ require 'aws-sdk-s3/express_credentials_provider'
23
+
19
24
  # customizations to generated classes
20
25
  require 'aws-sdk-s3/customizations/bucket'
26
+ require 'aws-sdk-s3/customizations/errors'
21
27
  require 'aws-sdk-s3/customizations/object'
22
28
  require 'aws-sdk-s3/customizations/object_summary'
23
29
  require 'aws-sdk-s3/customizations/multipart_upload'
24
30
  require 'aws-sdk-s3/customizations/types/list_object_versions_output'
31
+ require 'aws-sdk-s3/customizations/types/permanent_redirect'
25
32
 
26
33
  [
27
34
  Aws::S3::Object::Collection,
@@ -120,7 +120,7 @@ module Aws
120
120
  # attr_reader :encryption_materials
121
121
  #
122
122
  # def key_for(matdesc)
123
- # key_name = JSON.load(matdesc)['key']
123
+ # key_name = JSON.parse(matdesc)['key']
124
124
  # if key = @keys[key_name]
125
125
  # key
126
126
  # else
@@ -270,7 +270,9 @@ module Aws
270
270
  envelope_location: @envelope_location,
271
271
  instruction_file_suffix: @instruction_file_suffix,
272
272
  }
273
- req.send_request
273
+ Aws::Plugins::UserAgent.feature('S3CryptoV1n') do
274
+ req.send_request
275
+ end
274
276
  end
275
277
 
276
278
  # Gets an object from Amazon S3, decrypting data locally.
@@ -298,7 +300,9 @@ module Aws
298
300
  envelope_location: envelope_location,
299
301
  instruction_file_suffix: instruction_file_suffix,
300
302
  }
301
- req.send_request(target: block)
303
+ Aws::Plugins::UserAgent.feature('S3CryptoV1n') do
304
+ req.send_request(target: block)
305
+ end
302
306
  end
303
307
 
304
308
  private
@@ -165,10 +165,6 @@ module Aws
165
165
  # to initialize the cipher, and the decrypter truncates the
166
166
  # auth tag from the body when writing the final bytes.
167
167
  def authenticated_decrypter(context, cipher, envelope)
168
- if RUBY_VERSION.match(/1.9/)
169
- raise "authenticated decryption not supported by OpenSSL in Ruby version ~> 1.9"
170
- raise Aws::Errors::NonSupportedRubyVersionError, msg
171
- end
172
168
  http_resp = context.http_response
173
169
  content_length = http_resp.headers['content-length'].to_i
174
170
  auth_tag_length = auth_tag_length(envelope)
@@ -17,11 +17,13 @@ module Aws
17
17
  # envelope and encryption cipher.
18
18
  def encryption_cipher
19
19
  encryption_context = { "kms_cmk_id" => @kms_key_id }
20
- key_data = @kms_client.generate_data_key(
21
- key_id: @kms_key_id,
22
- encryption_context: encryption_context,
23
- key_spec: 'AES_256',
24
- )
20
+ key_data = Aws::Plugins::UserAgent.feature('S3CryptoV1n') do
21
+ @kms_client.generate_data_key(
22
+ key_id: @kms_key_id,
23
+ encryption_context: encryption_context,
24
+ key_spec: 'AES_256'
25
+ )
26
+ end
25
27
  cipher = Utils.aes_encryption_cipher(:CBC)
26
28
  cipher.key = key_data.plaintext
27
29
  envelope = {
@@ -58,10 +60,12 @@ module Aws
58
60
  "#{envelope['x-amz-wrap-alg']}"
59
61
  end
60
62
 
61
- key = @kms_client.decrypt(
62
- ciphertext_blob: decode64(envelope['x-amz-key-v2']),
63
- encryption_context: encryption_context
64
- ).plaintext
63
+ key = Aws::Plugins::UserAgent.feature('S3CryptoV1n') do
64
+ @kms_client.decrypt(
65
+ ciphertext_blob: decode64(envelope['x-amz-key-v2']),
66
+ encryption_context: encryption_context
67
+ ).plaintext
68
+ end
65
69
 
66
70
  iv = decode64(envelope['x-amz-iv'])
67
71
  block_mode =