aws-sdk-s3 1.10.0 → 1.208.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.
Files changed (153) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1517 -0
  3. data/LICENSE.txt +202 -0
  4. data/VERSION +1 -0
  5. data/lib/aws-sdk-s3/access_grants_credentials.rb +57 -0
  6. data/lib/aws-sdk-s3/access_grants_credentials_provider.rb +250 -0
  7. data/lib/aws-sdk-s3/bucket.rb +1062 -99
  8. data/lib/aws-sdk-s3/bucket_acl.rb +67 -17
  9. data/lib/aws-sdk-s3/bucket_cors.rb +80 -17
  10. data/lib/aws-sdk-s3/bucket_lifecycle.rb +71 -19
  11. data/lib/aws-sdk-s3/bucket_lifecycle_configuration.rb +126 -20
  12. data/lib/aws-sdk-s3/bucket_logging.rb +68 -18
  13. data/lib/aws-sdk-s3/bucket_notification.rb +56 -20
  14. data/lib/aws-sdk-s3/bucket_policy.rb +108 -17
  15. data/lib/aws-sdk-s3/bucket_region_cache.rb +11 -5
  16. data/lib/aws-sdk-s3/bucket_request_payment.rb +60 -15
  17. data/lib/aws-sdk-s3/bucket_tagging.rb +71 -17
  18. data/lib/aws-sdk-s3/bucket_versioning.rb +166 -17
  19. data/lib/aws-sdk-s3/bucket_website.rb +78 -17
  20. data/lib/aws-sdk-s3/client.rb +20068 -3879
  21. data/lib/aws-sdk-s3/client_api.rb +1957 -209
  22. data/lib/aws-sdk-s3/customizations/bucket.rb +57 -38
  23. data/lib/aws-sdk-s3/customizations/errors.rb +40 -0
  24. data/lib/aws-sdk-s3/customizations/multipart_upload.rb +2 -0
  25. data/lib/aws-sdk-s3/customizations/object.rb +338 -68
  26. data/lib/aws-sdk-s3/customizations/object_summary.rb +17 -0
  27. data/lib/aws-sdk-s3/customizations/object_version.rb +13 -0
  28. data/lib/aws-sdk-s3/customizations/types/list_object_versions_output.rb +2 -0
  29. data/lib/aws-sdk-s3/customizations/types/permanent_redirect.rb +26 -0
  30. data/lib/aws-sdk-s3/customizations.rb +30 -27
  31. data/lib/aws-sdk-s3/default_executor.rb +103 -0
  32. data/lib/aws-sdk-s3/encryption/client.rb +29 -8
  33. data/lib/aws-sdk-s3/encryption/decrypt_handler.rb +71 -29
  34. data/lib/aws-sdk-s3/encryption/default_cipher_provider.rb +45 -5
  35. data/lib/aws-sdk-s3/encryption/default_key_provider.rb +2 -0
  36. data/lib/aws-sdk-s3/encryption/encrypt_handler.rb +15 -2
  37. data/lib/aws-sdk-s3/encryption/errors.rb +2 -0
  38. data/lib/aws-sdk-s3/encryption/io_auth_decrypter.rb +11 -3
  39. data/lib/aws-sdk-s3/encryption/io_decrypter.rb +11 -3
  40. data/lib/aws-sdk-s3/encryption/io_encrypter.rb +2 -0
  41. data/lib/aws-sdk-s3/encryption/key_provider.rb +2 -0
  42. data/lib/aws-sdk-s3/encryption/kms_cipher_provider.rb +48 -11
  43. data/lib/aws-sdk-s3/encryption/materials.rb +8 -6
  44. data/lib/aws-sdk-s3/encryption/utils.rb +25 -0
  45. data/lib/aws-sdk-s3/encryption.rb +4 -0
  46. data/lib/aws-sdk-s3/encryptionV2/client.rb +645 -0
  47. data/lib/aws-sdk-s3/encryptionV2/decrypt_handler.rb +68 -0
  48. data/lib/aws-sdk-s3/encryptionV2/decryption.rb +205 -0
  49. data/lib/aws-sdk-s3/encryptionV2/default_cipher_provider.rb +187 -0
  50. data/lib/aws-sdk-s3/encryptionV2/default_key_provider.rb +40 -0
  51. data/lib/aws-sdk-s3/encryptionV2/encrypt_handler.rb +67 -0
  52. data/lib/aws-sdk-s3/encryptionV2/errors.rb +37 -0
  53. data/lib/aws-sdk-s3/encryptionV2/io_auth_decrypter.rb +58 -0
  54. data/lib/aws-sdk-s3/encryptionV2/io_decrypter.rb +37 -0
  55. data/lib/aws-sdk-s3/encryptionV2/io_encrypter.rb +75 -0
  56. data/lib/aws-sdk-s3/encryptionV2/key_provider.rb +31 -0
  57. data/lib/aws-sdk-s3/encryptionV2/kms_cipher_provider.rb +181 -0
  58. data/lib/aws-sdk-s3/encryptionV2/materials.rb +60 -0
  59. data/lib/aws-sdk-s3/encryptionV2/utils.rb +108 -0
  60. data/lib/aws-sdk-s3/encryptionV3/client.rb +885 -0
  61. data/lib/aws-sdk-s3/encryptionV3/decrypt_handler.rb +98 -0
  62. data/lib/aws-sdk-s3/encryptionV3/decryption.rb +244 -0
  63. data/lib/aws-sdk-s3/encryptionV3/default_cipher_provider.rb +159 -0
  64. data/lib/aws-sdk-s3/encryptionV3/default_key_provider.rb +35 -0
  65. data/lib/aws-sdk-s3/encryptionV3/encrypt_handler.rb +98 -0
  66. data/lib/aws-sdk-s3/encryptionV3/errors.rb +47 -0
  67. data/lib/aws-sdk-s3/encryptionV3/io_auth_decrypter.rb +60 -0
  68. data/lib/aws-sdk-s3/encryptionV3/io_decrypter.rb +35 -0
  69. data/lib/aws-sdk-s3/encryptionV3/io_encrypter.rb +84 -0
  70. data/lib/aws-sdk-s3/encryptionV3/key_provider.rb +28 -0
  71. data/lib/aws-sdk-s3/encryptionV3/kms_cipher_provider.rb +159 -0
  72. data/lib/aws-sdk-s3/encryptionV3/materials.rb +58 -0
  73. data/lib/aws-sdk-s3/encryptionV3/utils.rb +321 -0
  74. data/lib/aws-sdk-s3/encryption_v2.rb +24 -0
  75. data/lib/aws-sdk-s3/encryption_v3.rb +24 -0
  76. data/lib/aws-sdk-s3/endpoint_parameters.rb +181 -0
  77. data/lib/aws-sdk-s3/endpoint_provider.rb +886 -0
  78. data/lib/aws-sdk-s3/endpoints.rb +1544 -0
  79. data/lib/aws-sdk-s3/errors.rb +181 -1
  80. data/lib/aws-sdk-s3/event_streams.rb +69 -0
  81. data/lib/aws-sdk-s3/express_credentials.rb +55 -0
  82. data/lib/aws-sdk-s3/express_credentials_provider.rb +59 -0
  83. data/lib/aws-sdk-s3/file_downloader.rb +261 -82
  84. data/lib/aws-sdk-s3/file_part.rb +16 -13
  85. data/lib/aws-sdk-s3/file_uploader.rb +37 -22
  86. data/lib/aws-sdk-s3/legacy_signer.rb +19 -26
  87. data/lib/aws-sdk-s3/multipart_download_error.rb +8 -0
  88. data/lib/aws-sdk-s3/multipart_file_uploader.rb +142 -80
  89. data/lib/aws-sdk-s3/multipart_stream_uploader.rb +191 -0
  90. data/lib/aws-sdk-s3/multipart_upload.rb +342 -31
  91. data/lib/aws-sdk-s3/multipart_upload_error.rb +5 -4
  92. data/lib/aws-sdk-s3/multipart_upload_part.rb +387 -47
  93. data/lib/aws-sdk-s3/object.rb +2733 -204
  94. data/lib/aws-sdk-s3/object_acl.rb +112 -25
  95. data/lib/aws-sdk-s3/object_copier.rb +9 -5
  96. data/lib/aws-sdk-s3/object_multipart_copier.rb +50 -23
  97. data/lib/aws-sdk-s3/object_summary.rb +2265 -181
  98. data/lib/aws-sdk-s3/object_version.rb +542 -74
  99. data/lib/aws-sdk-s3/plugins/accelerate.rb +17 -64
  100. data/lib/aws-sdk-s3/plugins/access_grants.rb +178 -0
  101. data/lib/aws-sdk-s3/plugins/arn.rb +70 -0
  102. data/lib/aws-sdk-s3/plugins/bucket_dns.rb +7 -43
  103. data/lib/aws-sdk-s3/plugins/bucket_name_restrictions.rb +20 -3
  104. data/lib/aws-sdk-s3/plugins/checksum_algorithm.rb +31 -0
  105. data/lib/aws-sdk-s3/plugins/dualstack.rb +7 -50
  106. data/lib/aws-sdk-s3/plugins/endpoints.rb +86 -0
  107. data/lib/aws-sdk-s3/plugins/expect_100_continue.rb +5 -4
  108. data/lib/aws-sdk-s3/plugins/express_session_auth.rb +88 -0
  109. data/lib/aws-sdk-s3/plugins/get_bucket_location_fix.rb +3 -1
  110. data/lib/aws-sdk-s3/plugins/http_200_errors.rb +62 -17
  111. data/lib/aws-sdk-s3/plugins/iad_regional_endpoint.rb +44 -0
  112. data/lib/aws-sdk-s3/plugins/location_constraint.rb +5 -1
  113. data/lib/aws-sdk-s3/plugins/md5s.rb +14 -67
  114. data/lib/aws-sdk-s3/plugins/redirects.rb +5 -1
  115. data/lib/aws-sdk-s3/plugins/s3_host_id.rb +2 -0
  116. data/lib/aws-sdk-s3/plugins/s3_signer.rb +67 -93
  117. data/lib/aws-sdk-s3/plugins/sse_cpk.rb +3 -1
  118. data/lib/aws-sdk-s3/plugins/streaming_retry.rb +137 -0
  119. data/lib/aws-sdk-s3/plugins/url_encoded_keys.rb +4 -1
  120. data/lib/aws-sdk-s3/presigned_post.rb +160 -99
  121. data/lib/aws-sdk-s3/presigner.rb +178 -81
  122. data/lib/aws-sdk-s3/resource.rb +164 -15
  123. data/lib/aws-sdk-s3/transfer_manager.rb +303 -0
  124. data/lib/aws-sdk-s3/types.rb +15981 -4168
  125. data/lib/aws-sdk-s3/waiters.rb +67 -1
  126. data/lib/aws-sdk-s3.rb +46 -31
  127. data/sig/bucket.rbs +231 -0
  128. data/sig/bucket_acl.rbs +78 -0
  129. data/sig/bucket_cors.rbs +69 -0
  130. data/sig/bucket_lifecycle.rbs +88 -0
  131. data/sig/bucket_lifecycle_configuration.rbs +115 -0
  132. data/sig/bucket_logging.rbs +76 -0
  133. data/sig/bucket_notification.rbs +114 -0
  134. data/sig/bucket_policy.rbs +59 -0
  135. data/sig/bucket_request_payment.rbs +54 -0
  136. data/sig/bucket_tagging.rbs +65 -0
  137. data/sig/bucket_versioning.rbs +77 -0
  138. data/sig/bucket_website.rbs +93 -0
  139. data/sig/client.rbs +2612 -0
  140. data/sig/customizations/bucket.rbs +19 -0
  141. data/sig/customizations/object.rbs +38 -0
  142. data/sig/customizations/object_summary.rbs +35 -0
  143. data/sig/errors.rbs +44 -0
  144. data/sig/multipart_upload.rbs +120 -0
  145. data/sig/multipart_upload_part.rbs +109 -0
  146. data/sig/object.rbs +464 -0
  147. data/sig/object_acl.rbs +86 -0
  148. data/sig/object_summary.rbs +347 -0
  149. data/sig/object_version.rbs +143 -0
  150. data/sig/resource.rbs +141 -0
  151. data/sig/types.rbs +2899 -0
  152. data/sig/waiters.rbs +95 -0
  153. metadata +97 -14
@@ -1,11 +1,14 @@
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
+
9
12
  class ObjectAcl
10
13
 
11
14
  extend Aws::Deprecations
@@ -24,6 +27,7 @@ module Aws::S3
24
27
  @object_key = extract_object_key(args, options)
25
28
  @data = options.delete(:data)
26
29
  @client = options.delete(:client) || Client.new(options)
30
+ @waiter_block_warned = false
27
31
  end
28
32
 
29
33
  # @!group Read-Only Attributes
@@ -38,6 +42,7 @@ module Aws::S3
38
42
  @object_key
39
43
  end
40
44
 
45
+ # Container for the bucket owner's ID.
41
46
  # @return [Types::Owner]
42
47
  def owner
43
48
  data[:owner]
@@ -50,7 +55,17 @@ module Aws::S3
50
55
  end
51
56
 
52
57
  # If present, indicates that the requester was successfully charged for
53
- # the request.
58
+ # the request. For more information, see [Using Requester Pays buckets
59
+ # for storage transfers and usage][1] in the *Amazon Simple Storage
60
+ # Service user guide*.
61
+ #
62
+ # <note markdown="1"> This functionality is not supported for directory buckets.
63
+ #
64
+ # </note>
65
+ #
66
+ #
67
+ #
68
+ # [1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/RequesterPaysBuckets.html
54
69
  # @return [String]
55
70
  def request_charged
56
71
  data[:request_charged]
@@ -70,10 +85,12 @@ module Aws::S3
70
85
  #
71
86
  # @return [self]
72
87
  def load
73
- resp = @client.get_object_acl(
88
+ resp = Aws::Plugins::UserAgent.metric('RESOURCE_MODEL') do
89
+ @client.get_object_acl(
74
90
  bucket: @bucket_name,
75
91
  key: @object_key
76
92
  )
93
+ end
77
94
  @data = resp.data
78
95
  self
79
96
  end
@@ -99,7 +116,8 @@ module Aws::S3
99
116
  # Waiter polls an API operation until a resource enters a desired
100
117
  # state.
101
118
  #
102
- # @note The waiting operation is performed on a copy. The original resource remains unchanged
119
+ # @note The waiting operation is performed on a copy. The original resource
120
+ # remains unchanged.
103
121
  #
104
122
  # ## Basic Usage
105
123
  #
@@ -112,13 +130,15 @@ module Aws::S3
112
130
  #
113
131
  # ## Example
114
132
  #
115
- # instance.wait_until(max_attempts:10, delay:5) {|instance| instance.state.name == 'running' }
133
+ # instance.wait_until(max_attempts:10, delay:5) do |instance|
134
+ # instance.state.name == 'running'
135
+ # end
116
136
  #
117
137
  # ## Configuration
118
138
  #
119
139
  # You can configure the maximum number of polling attempts, and the
120
- # delay (in seconds) between each polling attempt. The waiting condition is set
121
- # by passing a block to {#wait_until}:
140
+ # delay (in seconds) between each polling attempt. The waiting condition is
141
+ # set by passing a block to {#wait_until}:
122
142
  #
123
143
  # # poll for ~25 seconds
124
144
  # resource.wait_until(max_attempts:5,delay:5) {|resource|...}
@@ -149,17 +169,16 @@ module Aws::S3
149
169
  # # resource did not enter the desired state in time
150
170
  # end
151
171
  #
172
+ # @yieldparam [Resource] resource to be used in the waiting condition.
152
173
  #
153
- # @yield param [Resource] resource to be used in the waiting condition
154
- #
155
- # @raise [Aws::Waiters::Errors::FailureStateError] Raised when the waiter terminates
156
- # because the waiter has entered a state that it will not transition
157
- # out of, preventing success.
174
+ # @raise [Aws::Waiters::Errors::FailureStateError] Raised when the waiter
175
+ # terminates because the waiter has entered a state that it will not
176
+ # transition out of, preventing success.
158
177
  #
159
178
  # yet successful.
160
179
  #
161
- # @raise [Aws::Waiters::Errors::UnexpectedError] Raised when an error is encountered
162
- # while polling for a resource that is not expected.
180
+ # @raise [Aws::Waiters::Errors::UnexpectedError] Raised when an error is
181
+ # encountered while polling for a resource that is not expected.
163
182
  #
164
183
  # @raise [NotImplementedError] Raised when the resource does not
165
184
  #
@@ -186,7 +205,9 @@ module Aws::S3
186
205
  :retry
187
206
  end
188
207
  end
189
- Aws::Waiters::Waiter.new(options).wait({})
208
+ Aws::Plugins::UserAgent.metric('RESOURCE_MODEL') do
209
+ Aws::Waiters::Waiter.new(options).wait({})
210
+ end
190
211
  end
191
212
 
192
213
  # @!group Actions
@@ -214,6 +235,7 @@ module Aws::S3
214
235
  # },
215
236
  # },
216
237
  # content_md5: "ContentMD5",
238
+ # checksum_algorithm: "CRC32", # accepts CRC32, CRC32C, SHA1, SHA256, CRC64NVME
217
239
  # grant_full_control: "GrantFullControl",
218
240
  # grant_read: "GrantRead",
219
241
  # grant_read_acp: "GrantReadACP",
@@ -221,39 +243,104 @@ module Aws::S3
221
243
  # grant_write_acp: "GrantWriteACP",
222
244
  # request_payer: "requester", # accepts requester
223
245
  # version_id: "ObjectVersionId",
246
+ # expected_bucket_owner: "AccountId",
224
247
  # })
225
248
  # @param [Hash] options ({})
226
249
  # @option options [String] :acl
227
- # The canned ACL to apply to the object.
250
+ # The canned ACL to apply to the object. For more information, see
251
+ # [Canned ACL][1].
252
+ #
253
+ #
254
+ #
255
+ # [1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#CannedACL
228
256
  # @option options [Types::AccessControlPolicy] :access_control_policy
257
+ # Contains the elements that set the ACL permissions for an object per
258
+ # grantee.
229
259
  # @option options [String] :content_md5
260
+ # The Base64 encoded 128-bit `MD5` digest of the data. This header must
261
+ # be used as a message integrity check to verify that the request body
262
+ # was not corrupted in transit. For more information, go to [RFC
263
+ # 1864.&gt;][1]
264
+ #
265
+ # For requests made using the Amazon Web Services Command Line Interface
266
+ # (CLI) or Amazon Web Services SDKs, this field is calculated
267
+ # automatically.
268
+ #
269
+ #
270
+ #
271
+ # [1]: http://www.ietf.org/rfc/rfc1864.txt
272
+ # @option options [String] :checksum_algorithm
273
+ # Indicates the algorithm used to create the checksum for the object
274
+ # when you use the SDK. This header will not provide any additional
275
+ # functionality if you don't use the SDK. When you send this header,
276
+ # there must be a corresponding `x-amz-checksum` or `x-amz-trailer`
277
+ # header sent. Otherwise, Amazon S3 fails the request with the HTTP
278
+ # status code `400 Bad Request`. For more information, see [Checking
279
+ # object integrity][1] in the *Amazon S3 User Guide*.
280
+ #
281
+ # If you provide an individual checksum, Amazon S3 ignores any provided
282
+ # `ChecksumAlgorithm` parameter.
283
+ #
284
+ #
285
+ #
286
+ # [1]: https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html
230
287
  # @option options [String] :grant_full_control
231
288
  # Allows grantee the read, write, read ACP, and write ACP permissions on
232
289
  # the bucket.
290
+ #
291
+ # This functionality is not supported for Amazon S3 on Outposts.
233
292
  # @option options [String] :grant_read
234
293
  # Allows grantee to list the objects in the bucket.
294
+ #
295
+ # This functionality is not supported for Amazon S3 on Outposts.
235
296
  # @option options [String] :grant_read_acp
236
297
  # Allows grantee to read the bucket ACL.
298
+ #
299
+ # This functionality is not supported for Amazon S3 on Outposts.
237
300
  # @option options [String] :grant_write
238
- # Allows grantee to create, overwrite, and delete any object in the
239
- # bucket.
301
+ # Allows grantee to create new objects in the bucket.
302
+ #
303
+ # For the bucket and object owners of existing objects, also allows
304
+ # deletions and overwrites of those objects.
240
305
  # @option options [String] :grant_write_acp
241
306
  # Allows grantee to write the ACL for the applicable bucket.
307
+ #
308
+ # This functionality is not supported for Amazon S3 on Outposts.
242
309
  # @option options [String] :request_payer
243
- # Confirms that the requester knows that she or he will be charged for
244
- # the request. Bucket owners need not specify this parameter in their
245
- # requests. Documentation on downloading objects from requester pays
246
- # buckets can be found at
247
- # http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
310
+ # Confirms that the requester knows that they will be charged for the
311
+ # request. Bucket owners need not specify this parameter in their
312
+ # requests. If either the source or destination S3 bucket has Requester
313
+ # Pays enabled, the requester will pay for corresponding charges to copy
314
+ # the object. For information about downloading objects from Requester
315
+ # Pays buckets, see [Downloading Objects in Requester Pays Buckets][1]
316
+ # in the *Amazon S3 User Guide*.
317
+ #
318
+ # <note markdown="1"> This functionality is not supported for directory buckets.
319
+ #
320
+ # </note>
321
+ #
322
+ #
323
+ #
324
+ # [1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
248
325
  # @option options [String] :version_id
249
- # VersionId used to reference a specific version of the object.
326
+ # Version ID used to reference a specific version of the object.
327
+ #
328
+ # <note markdown="1"> This functionality is not supported for directory buckets.
329
+ #
330
+ # </note>
331
+ # @option options [String] :expected_bucket_owner
332
+ # The account ID of the expected bucket owner. If the account ID that
333
+ # you provide does not match the actual owner of the bucket, the request
334
+ # fails with the HTTP status code `403 Forbidden` (access denied).
250
335
  # @return [Types::PutObjectAclOutput]
251
336
  def put(options = {})
252
337
  options = options.merge(
253
338
  bucket: @bucket_name,
254
339
  key: @object_key
255
340
  )
256
- resp = @client.put_object_acl(options)
341
+ resp = Aws::Plugins::UserAgent.metric('RESOURCE_MODEL') do
342
+ @client.put_object_acl(options)
343
+ end
257
344
  resp.data
258
345
  end
259
346
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'thread'
2
4
 
3
5
  module Aws
@@ -26,11 +28,13 @@ module Aws
26
28
  options[:bucket] = target_bucket
27
29
  options[:key] = target_key
28
30
  options[:copy_source] = copy_source(source)
29
- if options.delete(:multipart_copy)
30
- apply_source_client(source, options)
31
- ObjectMultipartCopier.new(@options).copy(options)
32
- else
33
- @object.client.copy_object(options)
31
+ Aws::Plugins::UserAgent.metric('S3_TRANSFER') do
32
+ if options.delete(:multipart_copy)
33
+ apply_source_client(source, options)
34
+ ObjectMultipartCopier.new(@options).copy(options)
35
+ else
36
+ @object.client.copy_object(options)
37
+ end
34
38
  end
35
39
  end
36
40
 
@@ -1,5 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'thread'
2
- require 'cgi'
4
+ require "cgi/escape"
5
+ require "cgi/util" if RUBY_VERSION < "3.5"
3
6
 
4
7
  module Aws
5
8
  module S3
@@ -13,12 +16,18 @@ module Aws
13
16
  MAX_PARTS = 10_000
14
17
 
15
18
  # @option options [Client] :client
16
- # @option [Integer] :min_part_size (52428800) Size of copied parts.
17
- # Defaults to 50MB.
18
- # will be constructed from the given `options' hash.
19
- # @option [Integer] :thread_count (10) Number of concurrent threads to
20
- # use for copying parts.
19
+ # @option options [Integer] :min_part_size (52428800)
20
+ # Size of copied parts. Defaults to 50MB.
21
+ # @option options [Integer] :thread_count (10) Number of concurrent
22
+ # threads to use for copying parts.
23
+ # @option options [Boolean] :use_source_parts (false) Use part sizes
24
+ # defined on the source object if any exist. If copying or moving an
25
+ # object that is already multipart, this does not re-part the object,
26
+ # instead re-using the part definitions on the original. That means
27
+ # the etag and any checksums will not change. This is especially
28
+ # useful if the source object has parts with varied sizes.
21
29
  def initialize(options = {})
30
+ @use_source_parts = options.delete(:use_source_parts) || false
22
31
  @thread_count = options.delete(:thread_count) || 10
23
32
  @min_part_size = options.delete(:min_part_size) || (FIVE_MB * 10)
24
33
  @client = options[:client] || Client.new
@@ -29,8 +38,9 @@ module Aws
29
38
 
30
39
  # @option (see S3::Client#copy_object)
31
40
  def copy(options = {})
32
- size = source_size(options)
33
- options[:upload_id] = initiate_upload(options)
41
+ metadata = source_metadata(options)
42
+ size = metadata[:content_length]
43
+ options[:upload_id] = initiate_upload(metadata.merge(options))
34
44
  begin
35
45
  parts = copy_parts(size, default_part_size(size), options)
36
46
  complete_upload(parts, options)
@@ -72,10 +82,9 @@ module Aws
72
82
  end
73
83
 
74
84
  def copy_part(part)
75
- {
76
- etag: @client.upload_part_copy(part).copy_part_result.etag,
77
- part_number: part[:part_number],
78
- }
85
+ @client.upload_part_copy(part).copy_part_result.to_h.merge({
86
+ part_number: part[:part_number]
87
+ }).tap { |result| result.delete(:last_modified) }
79
88
  end
80
89
 
81
90
  def complete_upload(parts, options)
@@ -98,26 +107,39 @@ module Aws
98
107
  parts = []
99
108
  options = options_for(:upload_part_copy, options)
100
109
  while offset < size
110
+ part_size = calculate_part_size(part_number, default_part_size, options)
101
111
  parts << options.merge({
102
112
  part_number: part_number,
103
- copy_source_range: byte_range(offset, default_part_size, size),
113
+ copy_source_range: byte_range(offset, part_size, size),
104
114
  })
105
115
  part_number += 1
106
- offset += default_part_size
116
+ offset += part_size
107
117
  end
108
118
  parts
109
119
  end
110
120
 
111
- def byte_range(offset, default_part_size, size)
112
- if offset + default_part_size < size
113
- "bytes=#{offset}-#{offset + default_part_size - 1}"
121
+ def byte_range(offset, part_size, size)
122
+ if offset + part_size < size
123
+ "bytes=#{offset}-#{offset + part_size - 1}"
114
124
  else
115
125
  "bytes=#{offset}-#{size - 1}"
116
126
  end
117
127
  end
118
128
 
119
- def source_size(options)
120
- return options.delete(:content_length) if options[:content_length]
129
+ def calculate_part_size(part_number, default_part_size, options)
130
+ if @use_source_parts && source_has_parts(options)
131
+ source_metadata(options.merge({ part_number: part_number }))[:content_length]
132
+ else
133
+ default_part_size
134
+ end
135
+ end
136
+
137
+ def source_has_parts(options)
138
+ @source_has_parts ||= source_metadata(options.merge({ part_number: 1 }))[:parts_count]
139
+ end
140
+
141
+ def source_metadata(options)
142
+ return options.slice(:content_length) if options[:content_length]
121
143
 
122
144
  client = options[:copy_source_client] || @client
123
145
 
@@ -127,10 +149,15 @@ module Aws
127
149
  bucket, key = options[:copy_source].match(/([^\/]+?)\/(.+)/)[1,2]
128
150
  end
129
151
 
130
- key = CGI.unescape(key)
131
- opts = { bucket: bucket, key: key }
132
- opts[:version_id] = version_id if version_id
133
- client.head_object(opts).content_length
152
+ head_opts = { bucket: bucket, key: CGI.unescape(key) }.tap { |opts|
153
+ opts[:version_id] = version_id if version_id
154
+ opts[:part_number] = options[:part_number] if options[:part_number]
155
+ }
156
+
157
+ client.head_object(head_opts).to_h.tap { |head|
158
+ head.delete(:server_side_encryption)
159
+ head.delete(:ssekms_key_id)
160
+ }
134
161
  end
135
162
 
136
163
  def default_part_size(source_size)