aws-sdk-s3 1.220.0 → 1.232.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +89 -0
- data/VERSION +1 -1
- data/lib/aws-sdk-s3/bucket.rb +26 -2
- data/lib/aws-sdk-s3/bucket_notification.rb +3 -3
- data/lib/aws-sdk-s3/client.rb +869 -62
- data/lib/aws-sdk-s3/client_api.rb +301 -0
- data/lib/aws-sdk-s3/customizations/object.rb +55 -25
- data/lib/aws-sdk-s3/encryptionV2/kms_cipher_provider.rb +14 -1
- data/lib/aws-sdk-s3/encryptionV3/kms_cipher_provider.rb +13 -1
- data/lib/aws-sdk-s3/endpoint_provider.rb +6 -3
- data/lib/aws-sdk-s3/endpoints.rb +68 -0
- data/lib/aws-sdk-s3/errors.rb +66 -0
- data/lib/aws-sdk-s3/file_downloader.rb +3 -1
- data/lib/aws-sdk-s3/multipart_file_uploader.rb +1 -1
- data/lib/aws-sdk-s3/object.rb +150 -8
- data/lib/aws-sdk-s3/object_copier.rb +11 -22
- data/lib/aws-sdk-s3/object_multipart_copier.rb +177 -84
- data/lib/aws-sdk-s3/object_summary.rb +117 -8
- data/lib/aws-sdk-s3/plugins/http_200_errors.rb +1 -1
- data/lib/aws-sdk-s3/transfer_manager.rb +44 -31
- data/lib/aws-sdk-s3/types.rb +1162 -46
- data/lib/aws-sdk-s3.rb +1 -1
- data/sig/bucket.rbs +7 -4
- data/sig/bucket_acl.rbs +1 -1
- data/sig/bucket_cors.rbs +1 -1
- data/sig/bucket_lifecycle.rbs +1 -1
- data/sig/bucket_lifecycle_configuration.rbs +4 -4
- data/sig/bucket_logging.rbs +1 -1
- data/sig/bucket_notification.rbs +9 -9
- data/sig/bucket_tagging.rbs +1 -1
- data/sig/bucket_website.rbs +1 -1
- data/sig/client.rbs +246 -198
- data/sig/errors.rbs +12 -0
- data/sig/multipart_upload.rbs +2 -2
- data/sig/object.rbs +32 -13
- data/sig/object_acl.rbs +1 -1
- data/sig/object_summary.rbs +22 -12
- data/sig/params.rbs +78 -0
- data/sig/resource.rbs +1 -1
- data/sig/types.rbs +249 -39
- metadata +4 -3
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require '
|
|
4
|
-
require
|
|
5
|
-
require
|
|
3
|
+
require 'cgi/escape'
|
|
4
|
+
require 'cgi/util' if RUBY_VERSION < '3.5'
|
|
5
|
+
require 'set'
|
|
6
6
|
|
|
7
7
|
module Aws
|
|
8
8
|
module S3
|
|
9
9
|
# @api private
|
|
10
|
-
class ObjectMultipartCopier
|
|
11
|
-
|
|
12
|
-
FIVE_MB = 5 * 1024 * 1024 # 5MB
|
|
13
|
-
|
|
14
|
-
FILE_TOO_SMALL = "unable to multipart copy files smaller than 5MB"
|
|
15
|
-
|
|
10
|
+
class ObjectMultipartCopier # rubocop:disable Metrics/ClassLength
|
|
11
|
+
MIN_PART_SIZE = 5 * 1024 * 1024 # 5MB
|
|
16
12
|
MAX_PARTS = 10_000
|
|
17
13
|
|
|
14
|
+
API_OPTIONS = {
|
|
15
|
+
create_multipart_upload: Set.new(Client.api.operation(:create_multipart_upload).input.shape.member_names),
|
|
16
|
+
upload_part_copy: Set.new(Client.api.operation(:upload_part_copy).input.shape.member_names),
|
|
17
|
+
complete_multipart_upload: Set.new(Client.api.operation(:complete_multipart_upload).input.shape.member_names)
|
|
18
|
+
}.freeze
|
|
19
|
+
|
|
18
20
|
# @option options [Client] :client
|
|
19
21
|
# @option options [Integer] :min_part_size (52428800)
|
|
20
22
|
# Size of copied parts. Defaults to 50MB.
|
|
@@ -29,29 +31,115 @@ module Aws
|
|
|
29
31
|
def initialize(options = {})
|
|
30
32
|
@use_source_parts = options.delete(:use_source_parts) || false
|
|
31
33
|
@thread_count = options.delete(:thread_count) || 10
|
|
32
|
-
@min_part_size = options.delete(:min_part_size) || (
|
|
34
|
+
@min_part_size = options.delete(:min_part_size) || (MIN_PART_SIZE * 10)
|
|
33
35
|
@client = options[:client] || Client.new
|
|
36
|
+
@source_client = nil
|
|
37
|
+
@source = nil
|
|
38
|
+
@source_etag = nil
|
|
39
|
+
@source_parts_count = nil
|
|
40
|
+
@first_part_size = nil
|
|
34
41
|
end
|
|
35
42
|
|
|
36
43
|
# @return [Client]
|
|
37
44
|
attr_reader :client
|
|
38
45
|
|
|
39
46
|
# @option (see S3::Client#copy_object)
|
|
40
|
-
def copy(options = {})
|
|
41
|
-
|
|
47
|
+
def copy(options = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
48
|
+
@source_client = options[:copy_source_client] || @client
|
|
49
|
+
@source = resolve_source(options[:copy_source])
|
|
50
|
+
metadata = resolve_metadata(options)
|
|
42
51
|
size = metadata[:content_length]
|
|
43
|
-
|
|
52
|
+
@source_etag = metadata[:etag]
|
|
53
|
+
@source[:version_id] ||= metadata[:version_id]
|
|
54
|
+
resolve_source_parts
|
|
55
|
+
tag_set = resolve_tags(options)
|
|
56
|
+
annotations = resolve_annotations(options)
|
|
57
|
+
|
|
58
|
+
create_opts = resolve_create_opts(metadata, options)
|
|
59
|
+
options[:upload_id] = initiate_upload(create_opts)
|
|
60
|
+
|
|
44
61
|
begin
|
|
45
62
|
parts = copy_parts(size, default_part_size(size), options)
|
|
46
|
-
complete_upload(parts, options)
|
|
47
|
-
rescue =>
|
|
63
|
+
resp = complete_upload(parts, options)
|
|
64
|
+
rescue StandardError => e
|
|
48
65
|
abort_upload(options)
|
|
49
|
-
raise
|
|
66
|
+
raise e
|
|
50
67
|
end
|
|
68
|
+
|
|
69
|
+
put_tags(tag_set, resp, options) if tag_set
|
|
70
|
+
put_annotations(annotations, resp, options) if annotations&.any?
|
|
71
|
+
resp
|
|
51
72
|
end
|
|
52
73
|
|
|
53
74
|
private
|
|
54
75
|
|
|
76
|
+
def resolve_source(copy_source)
|
|
77
|
+
bucket, remaining = copy_source.split('/', 2)
|
|
78
|
+
key, version_id = remaining.split('?versionId=', 2)
|
|
79
|
+
result = { bucket: bucket, key: CGI.unescape(key) }
|
|
80
|
+
result[:version_id] = version_id if version_id
|
|
81
|
+
result
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def resolve_metadata(options)
|
|
85
|
+
return options.slice(:content_length) if options[:content_length]
|
|
86
|
+
|
|
87
|
+
resp = @source_client.head_object(@source).to_h
|
|
88
|
+
resp.delete(:server_side_encryption)
|
|
89
|
+
resp.delete(:ssekms_key_id)
|
|
90
|
+
resp
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def resolve_source_parts
|
|
94
|
+
return unless @use_source_parts
|
|
95
|
+
|
|
96
|
+
resp = @source_client.head_object(@source.merge(part_number: 1))
|
|
97
|
+
@source_parts_count = resp.parts_count
|
|
98
|
+
@first_part_size = resp.content_length if @source_parts_count
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def resolve_create_opts(metadata, options)
|
|
102
|
+
return options if options[:metadata_directive] == 'REPLACE'
|
|
103
|
+
|
|
104
|
+
create_opts = metadata.merge(options)
|
|
105
|
+
create_opts.delete(:tagging) if options[:tags_directive]
|
|
106
|
+
create_opts
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def resolve_tags(options) # rubocop:disable Metrics/MethodLength
|
|
110
|
+
return unless options[:tags_directive]
|
|
111
|
+
|
|
112
|
+
case options[:tags_directive]
|
|
113
|
+
when 'COPY'
|
|
114
|
+
resp = @source_client.get_object_tagging(@source)
|
|
115
|
+
resp.tag_set
|
|
116
|
+
when 'REPLACE'
|
|
117
|
+
tagging = options[:tagging]
|
|
118
|
+
return if tagging.nil? || tagging.empty?
|
|
119
|
+
|
|
120
|
+
tagging.split('&').map do |pair|
|
|
121
|
+
k, v = pair.split('=', 2)
|
|
122
|
+
{ key: CGI.unescape(k), value: CGI.unescape(v) }
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def resolve_annotations(options) # rubocop:disable Metrics/MethodLength
|
|
128
|
+
return unless options[:annotations_directive] == 'COPY'
|
|
129
|
+
|
|
130
|
+
list_resp = @source_client.list_object_annotations(@source)
|
|
131
|
+
return if list_resp.annotations.empty?
|
|
132
|
+
|
|
133
|
+
list_resp.annotations.map do |annotation|
|
|
134
|
+
{
|
|
135
|
+
name: annotation.annotation_name,
|
|
136
|
+
payload: @source_client.get_object_annotation(
|
|
137
|
+
@source.merge(annotation_name: annotation.annotation_name)
|
|
138
|
+
).annotation_payload
|
|
139
|
+
}
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
55
143
|
def initiate_upload(options)
|
|
56
144
|
options = options_for(:create_multipart_upload, options)
|
|
57
145
|
@client.create_multipart_upload(options).upload_id
|
|
@@ -63,28 +151,30 @@ module Aws
|
|
|
63
151
|
@thread_count.times do
|
|
64
152
|
threads << copy_part_thread(queue)
|
|
65
153
|
end
|
|
66
|
-
threads.map(&:value).flatten.sort_by{ |part| part[:part_number] }
|
|
154
|
+
threads.map(&:value).flatten.sort_by { |part| part[:part_number] }
|
|
67
155
|
end
|
|
68
156
|
|
|
69
|
-
def copy_part_thread(queue)
|
|
157
|
+
def copy_part_thread(queue) # rubocop:disable Metrics/MethodLength
|
|
70
158
|
Thread.new do
|
|
71
|
-
begin
|
|
159
|
+
begin # rubocop:disable Style/RedundantBegin
|
|
72
160
|
completed = []
|
|
73
|
-
while part = queue.shift
|
|
161
|
+
while (part = queue.shift)
|
|
74
162
|
completed << copy_part(part)
|
|
75
163
|
end
|
|
76
164
|
completed
|
|
77
|
-
rescue =>
|
|
165
|
+
rescue StandardError => e
|
|
78
166
|
queue.clear!
|
|
79
|
-
raise
|
|
167
|
+
raise e
|
|
80
168
|
end
|
|
81
169
|
end
|
|
82
170
|
end
|
|
83
171
|
|
|
84
172
|
def copy_part(part)
|
|
85
|
-
@client.upload_part_copy(part)
|
|
86
|
-
|
|
87
|
-
|
|
173
|
+
@client.upload_part_copy(part)
|
|
174
|
+
.copy_part_result
|
|
175
|
+
.to_h
|
|
176
|
+
.merge({ part_number: part[:part_number] })
|
|
177
|
+
.tap { |result| result.delete(:last_modified) }
|
|
88
178
|
end
|
|
89
179
|
|
|
90
180
|
def complete_upload(parts, options)
|
|
@@ -94,100 +184,104 @@ module Aws
|
|
|
94
184
|
end
|
|
95
185
|
|
|
96
186
|
def abort_upload(options)
|
|
97
|
-
@client.abort_multipart_upload(
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
187
|
+
@client.abort_multipart_upload(
|
|
188
|
+
{
|
|
189
|
+
bucket: options[:bucket],
|
|
190
|
+
key: options[:key],
|
|
191
|
+
upload_id: options[:upload_id]
|
|
192
|
+
}
|
|
193
|
+
)
|
|
102
194
|
end
|
|
103
195
|
|
|
104
|
-
def compute_parts(size, default_part_size, options)
|
|
196
|
+
def compute_parts(size, default_part_size, options) # rubocop:disable Metrics/MethodLength
|
|
105
197
|
part_number = 1
|
|
106
198
|
offset = 0
|
|
107
199
|
parts = []
|
|
108
200
|
options = options_for(:upload_part_copy, options)
|
|
201
|
+
options[:copy_source_if_match] = @source_etag if @source_etag
|
|
109
202
|
while offset < size
|
|
110
203
|
part_size = calculate_part_size(part_number, default_part_size, options)
|
|
111
|
-
parts << options.merge({
|
|
112
|
-
part_number: part_number,
|
|
113
|
-
copy_source_range: byte_range(offset, part_size, size),
|
|
114
|
-
})
|
|
204
|
+
parts << options.merge({ part_number: part_number, copy_source_range: byte_range(offset, part_size, size) })
|
|
115
205
|
part_number += 1
|
|
116
206
|
offset += part_size
|
|
117
207
|
end
|
|
118
208
|
parts
|
|
119
209
|
end
|
|
120
210
|
|
|
121
|
-
def
|
|
122
|
-
if
|
|
123
|
-
|
|
124
|
-
else
|
|
125
|
-
"bytes=#{offset}-#{size - 1}"
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
|
|
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]
|
|
211
|
+
def calculate_part_size(part_number, default_part_size, _options)
|
|
212
|
+
if @source_parts_count
|
|
213
|
+
resolve_part_size(part_number)
|
|
132
214
|
else
|
|
133
215
|
default_part_size
|
|
134
216
|
end
|
|
135
217
|
end
|
|
136
218
|
|
|
137
|
-
def
|
|
138
|
-
@
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def source_metadata(options)
|
|
142
|
-
return options.slice(:content_length) if options[:content_length]
|
|
219
|
+
def resolve_part_size(part_number)
|
|
220
|
+
return @first_part_size if part_number == 1 && @first_part_size
|
|
143
221
|
|
|
144
|
-
|
|
222
|
+
@source_client.head_object(@source.merge(part_number: part_number)).content_length
|
|
223
|
+
end
|
|
145
224
|
|
|
146
|
-
|
|
147
|
-
|
|
225
|
+
def byte_range(offset, part_size, size)
|
|
226
|
+
if offset + part_size < size
|
|
227
|
+
"bytes=#{offset}-#{offset + part_size - 1}"
|
|
148
228
|
else
|
|
149
|
-
|
|
229
|
+
"bytes=#{offset}-#{size - 1}"
|
|
150
230
|
end
|
|
231
|
+
end
|
|
151
232
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
opts[:part_number] = options[:part_number] if options[:part_number]
|
|
155
|
-
}
|
|
233
|
+
def default_part_size(source_size)
|
|
234
|
+
raise ArgumentError, 'unable to multipart copy files smaller than 5MB' if source_size < MIN_PART_SIZE
|
|
156
235
|
|
|
157
|
-
|
|
158
|
-
head.delete(:server_side_encryption)
|
|
159
|
-
head.delete(:ssekms_key_id)
|
|
160
|
-
}
|
|
236
|
+
[(source_size.to_f / MAX_PARTS).ceil, @min_part_size].max.to_i
|
|
161
237
|
end
|
|
162
238
|
|
|
163
|
-
def
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
239
|
+
def put_tags(tags, resp, options)
|
|
240
|
+
@client.put_object_tagging(
|
|
241
|
+
bucket: options[:bucket],
|
|
242
|
+
key: options[:key],
|
|
243
|
+
tagging: { tag_set: tags },
|
|
244
|
+
version_id: resp.version_id
|
|
245
|
+
)
|
|
246
|
+
rescue StandardError => e
|
|
247
|
+
raise StandardError,
|
|
248
|
+
'Object data copied successfully. ' \
|
|
249
|
+
"Failed to copy tags: #{e.message}"
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def put_annotations(annotations, response, options) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
253
|
+
succeeded = []
|
|
254
|
+
failed = []
|
|
255
|
+
|
|
256
|
+
annotations.each do |annotation|
|
|
257
|
+
@client.put_object_annotation(
|
|
258
|
+
bucket: options[:bucket],
|
|
259
|
+
key: options[:key],
|
|
260
|
+
version_id: response.version_id,
|
|
261
|
+
object_if_match: response.etag,
|
|
262
|
+
annotation_name: annotation[:name],
|
|
263
|
+
annotation_payload: annotation[:payload]
|
|
264
|
+
)
|
|
265
|
+
succeeded << annotation[:name]
|
|
266
|
+
rescue StandardError => e
|
|
267
|
+
failed << { key: annotation[:name], error: e }
|
|
168
268
|
end
|
|
269
|
+
return if failed.empty?
|
|
270
|
+
|
|
271
|
+
raise StandardError,
|
|
272
|
+
'Object data copied successfully. Failed to copy annotations: ' \
|
|
273
|
+
"#{failed.map { |f| "#{f[:key]} (#{f[:error].message})" }.join(', ')}. " \
|
|
274
|
+
"Succeeded: #{succeeded.join(', ')}"
|
|
169
275
|
end
|
|
170
276
|
|
|
171
277
|
def options_for(operation_name, options)
|
|
172
|
-
API_OPTIONS[operation_name].
|
|
278
|
+
API_OPTIONS[operation_name].each_with_object({}) do |opt_name, hash|
|
|
173
279
|
hash[opt_name] = options[opt_name] if options.key?(opt_name)
|
|
174
|
-
hash
|
|
175
280
|
end
|
|
176
281
|
end
|
|
177
282
|
|
|
178
|
-
#
|
|
179
|
-
def self.options_for(shape_name)
|
|
180
|
-
Client.api.metadata['shapes'][shape_name].member_names
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
API_OPTIONS = {
|
|
184
|
-
create_multipart_upload: Types::CreateMultipartUploadRequest.members,
|
|
185
|
-
upload_part_copy: Types::UploadPartCopyRequest.members,
|
|
186
|
-
complete_multipart_upload: Types::CompleteMultipartUploadRequest.members,
|
|
187
|
-
}
|
|
188
|
-
|
|
283
|
+
# A thread-safe work queue of part definitions for a multipart copy.
|
|
189
284
|
class PartQueue
|
|
190
|
-
|
|
191
285
|
def initialize(parts = [])
|
|
192
286
|
@parts = parts
|
|
193
287
|
@mutex = Mutex.new
|
|
@@ -200,7 +294,6 @@ module Aws
|
|
|
200
294
|
def clear!
|
|
201
295
|
@mutex.synchronize { @parts.clear }
|
|
202
296
|
end
|
|
203
|
-
|
|
204
297
|
end
|
|
205
298
|
end
|
|
206
299
|
end
|
|
@@ -361,8 +361,9 @@ module Aws::S3
|
|
|
361
361
|
# },
|
|
362
362
|
# metadata_directive: "COPY", # accepts COPY, REPLACE
|
|
363
363
|
# tagging_directive: "COPY", # accepts COPY, REPLACE
|
|
364
|
-
#
|
|
365
|
-
#
|
|
364
|
+
# annotation_directive: "COPY", # accepts COPY, EXCLUDE
|
|
365
|
+
# server_side_encryption: "AES256", # accepts AES256, aws:fsx, aws:backup, aws:kms, aws:kms:dsse
|
|
366
|
+
# storage_class: "STANDARD", # accepts STANDARD, REDUCED_REDUNDANCY, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, GLACIER, DEEP_ARCHIVE, OUTPOSTS, GLACIER_IR, SNOW, EXPRESS_ONEZONE, FSX_OPENZFS, FSX_ONTAP, AWS_BACKUP_WARM, AWS_BACKUP_LOW_COST_WARM
|
|
366
367
|
# website_redirect_location: "WebsiteRedirectLocation",
|
|
367
368
|
# sse_customer_algorithm: "SSECustomerAlgorithm",
|
|
368
369
|
# sse_customer_key: "SSECustomerKey",
|
|
@@ -378,6 +379,9 @@ module Aws::S3
|
|
|
378
379
|
# object_lock_mode: "GOVERNANCE", # accepts GOVERNANCE, COMPLIANCE
|
|
379
380
|
# object_lock_retain_until_date: Time.now,
|
|
380
381
|
# object_lock_legal_hold_status: "ON", # accepts ON, OFF
|
|
382
|
+
# object_lock_event_hold: "ON", # accepts ON, OFF
|
|
383
|
+
# object_lock_event_hold_duration_days: 1,
|
|
384
|
+
# object_lock_event_hold_duration_years: 1,
|
|
381
385
|
# expected_bucket_owner: "AccountId",
|
|
382
386
|
# expected_source_bucket_owner: "AccountId",
|
|
383
387
|
# })
|
|
@@ -711,6 +715,42 @@ module Aws::S3
|
|
|
711
715
|
# value of `x-amz-tagging` is the empty value.
|
|
712
716
|
#
|
|
713
717
|
# </note>
|
|
718
|
+
# @option options [String] :annotation_directive
|
|
719
|
+
# Specifies whether you want to copy annotations from the source object
|
|
720
|
+
# or exclude them. If this header isn't specified, `COPY` is the
|
|
721
|
+
# default behavior.
|
|
722
|
+
#
|
|
723
|
+
# Valid Values: `COPY | EXCLUDE`
|
|
724
|
+
#
|
|
725
|
+
# You can specify this directive as either an HTTP header
|
|
726
|
+
# (`x-amz-object-annotation-directive`) or as a query string parameter.
|
|
727
|
+
# Use the query string form when generating presigned URLs that need to
|
|
728
|
+
# control annotation copy behavior.
|
|
729
|
+
#
|
|
730
|
+
# When set to `COPY`, you must have `s3:GetObjectAnnotation` permission
|
|
731
|
+
# on the source object and `s3:PutObjectAnnotation` permission on the
|
|
732
|
+
# destination. Each annotation copied is billed as a separate PUT
|
|
733
|
+
# request. If annotations on the source are modified during the copy,
|
|
734
|
+
# Amazon S3 returns a retryable error.
|
|
735
|
+
#
|
|
736
|
+
# <note markdown="1"> For directory buckets, annotations are not supported. Use `EXCLUDE` to
|
|
737
|
+
# copy objects to directory buckets without errors. If you specify
|
|
738
|
+
# `COPY` for a directory bucket, the request returns HTTP 501 (Not
|
|
739
|
+
# Implemented).
|
|
740
|
+
#
|
|
741
|
+
# </note>
|
|
742
|
+
#
|
|
743
|
+
# <note markdown="1"> When you copy objects using multipart upload (for example, when the
|
|
744
|
+
# Amazon Web Services CLI or Amazon Web Services SDKs use Transfer
|
|
745
|
+
# Manager for objects larger than approximately 8 MB), annotations are
|
|
746
|
+
# not copied by default. To include annotations, specify `--copy-props
|
|
747
|
+
# default` in the Amazon Web Services CLI or the equivalent SDK
|
|
748
|
+
# configuration. With this opt-in, the SDK reads source annotations,
|
|
749
|
+
# completes the multipart upload, and then writes each annotation to the
|
|
750
|
+
# destination. Between the upload completion and the last annotation
|
|
751
|
+
# write, the destination object exists without all its annotations.
|
|
752
|
+
#
|
|
753
|
+
# </note>
|
|
714
754
|
# @option options [String] :server_side_encryption
|
|
715
755
|
# The server-side encryption algorithm used when storing this object in
|
|
716
756
|
# Amazon S3. Unrecognized or unsupported values won’t write a
|
|
@@ -1083,6 +1123,27 @@ module Aws::S3
|
|
|
1083
1123
|
# <note markdown="1"> This functionality is not supported for directory buckets.
|
|
1084
1124
|
#
|
|
1085
1125
|
# </note>
|
|
1126
|
+
# @option options [String] :object_lock_event_hold
|
|
1127
|
+
# The event hold status to apply to the object copy. Set to `ON` to
|
|
1128
|
+
# enable or `OFF` to disable.
|
|
1129
|
+
#
|
|
1130
|
+
# <note markdown="1"> This functionality is not supported for directory buckets.
|
|
1131
|
+
#
|
|
1132
|
+
# </note>
|
|
1133
|
+
# @option options [Integer] :object_lock_event_hold_duration_days
|
|
1134
|
+
# The event hold duration in days to apply to the object copy. You
|
|
1135
|
+
# cannot specify a duration in both days and years.
|
|
1136
|
+
#
|
|
1137
|
+
# <note markdown="1"> This functionality is not supported for directory buckets.
|
|
1138
|
+
#
|
|
1139
|
+
# </note>
|
|
1140
|
+
# @option options [Integer] :object_lock_event_hold_duration_years
|
|
1141
|
+
# The event hold duration in years to apply to the object copy. You
|
|
1142
|
+
# cannot specify a duration in both days and years.
|
|
1143
|
+
#
|
|
1144
|
+
# <note markdown="1"> This functionality is not supported for directory buckets.
|
|
1145
|
+
#
|
|
1146
|
+
# </note>
|
|
1086
1147
|
# @option options [String] :expected_bucket_owner
|
|
1087
1148
|
# The account ID of the expected destination bucket owner. If the
|
|
1088
1149
|
# account ID that you provide does not match the actual owner of the
|
|
@@ -1485,8 +1546,8 @@ module Aws::S3
|
|
|
1485
1546
|
# metadata: {
|
|
1486
1547
|
# "MetadataKey" => "MetadataValue",
|
|
1487
1548
|
# },
|
|
1488
|
-
# server_side_encryption: "AES256", # accepts AES256, aws:fsx, aws:kms, aws:kms:dsse
|
|
1489
|
-
# storage_class: "STANDARD", # accepts STANDARD, REDUCED_REDUNDANCY, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, GLACIER, DEEP_ARCHIVE, OUTPOSTS, GLACIER_IR, SNOW, EXPRESS_ONEZONE, FSX_OPENZFS, FSX_ONTAP
|
|
1549
|
+
# server_side_encryption: "AES256", # accepts AES256, aws:fsx, aws:backup, aws:kms, aws:kms:dsse
|
|
1550
|
+
# storage_class: "STANDARD", # accepts STANDARD, REDUCED_REDUNDANCY, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, GLACIER, DEEP_ARCHIVE, OUTPOSTS, GLACIER_IR, SNOW, EXPRESS_ONEZONE, FSX_OPENZFS, FSX_ONTAP, AWS_BACKUP_WARM, AWS_BACKUP_LOW_COST_WARM
|
|
1490
1551
|
# website_redirect_location: "WebsiteRedirectLocation",
|
|
1491
1552
|
# sse_customer_algorithm: "SSECustomerAlgorithm",
|
|
1492
1553
|
# sse_customer_key: "SSECustomerKey",
|
|
@@ -1499,6 +1560,9 @@ module Aws::S3
|
|
|
1499
1560
|
# object_lock_mode: "GOVERNANCE", # accepts GOVERNANCE, COMPLIANCE
|
|
1500
1561
|
# object_lock_retain_until_date: Time.now,
|
|
1501
1562
|
# object_lock_legal_hold_status: "ON", # accepts ON, OFF
|
|
1563
|
+
# object_lock_event_hold: "ON", # accepts ON, OFF
|
|
1564
|
+
# object_lock_event_hold_duration_days: 1,
|
|
1565
|
+
# object_lock_event_hold_duration_years: 1,
|
|
1502
1566
|
# expected_bucket_owner: "AccountId",
|
|
1503
1567
|
# checksum_algorithm: "CRC32", # accepts CRC32, CRC32C, SHA1, SHA256, CRC64NVME, SHA512, MD5, XXHASH64, XXHASH3, XXHASH128
|
|
1504
1568
|
# checksum_type: "COMPOSITE", # accepts COMPOSITE, FULL_OBJECT
|
|
@@ -2020,6 +2084,27 @@ module Aws::S3
|
|
|
2020
2084
|
# <note markdown="1"> This functionality is not supported for directory buckets.
|
|
2021
2085
|
#
|
|
2022
2086
|
# </note>
|
|
2087
|
+
# @option options [String] :object_lock_event_hold
|
|
2088
|
+
# Specifies the event hold status to apply to the uploaded object. Set
|
|
2089
|
+
# to `ON` to enable or `OFF` to disable.
|
|
2090
|
+
#
|
|
2091
|
+
# <note markdown="1"> This functionality is not supported for directory buckets.
|
|
2092
|
+
#
|
|
2093
|
+
# </note>
|
|
2094
|
+
# @option options [Integer] :object_lock_event_hold_duration_days
|
|
2095
|
+
# Specifies the event hold duration in days to apply to the uploaded
|
|
2096
|
+
# object. You cannot specify a duration in both days and years.
|
|
2097
|
+
#
|
|
2098
|
+
# <note markdown="1"> This functionality is not supported for directory buckets.
|
|
2099
|
+
#
|
|
2100
|
+
# </note>
|
|
2101
|
+
# @option options [Integer] :object_lock_event_hold_duration_years
|
|
2102
|
+
# Specifies the event hold duration in years to apply to the uploaded
|
|
2103
|
+
# object. You cannot specify a duration in both days and years.
|
|
2104
|
+
#
|
|
2105
|
+
# <note markdown="1"> This functionality is not supported for directory buckets.
|
|
2106
|
+
#
|
|
2107
|
+
# </note>
|
|
2023
2108
|
# @option options [String] :expected_bucket_owner
|
|
2024
2109
|
# The account ID of the expected bucket owner. If the account ID that
|
|
2025
2110
|
# you provide does not match the actual owner of the bucket, the request
|
|
@@ -2091,8 +2176,8 @@ module Aws::S3
|
|
|
2091
2176
|
# metadata: {
|
|
2092
2177
|
# "MetadataKey" => "MetadataValue",
|
|
2093
2178
|
# },
|
|
2094
|
-
# server_side_encryption: "AES256", # accepts AES256, aws:fsx, aws:kms, aws:kms:dsse
|
|
2095
|
-
# storage_class: "STANDARD", # accepts STANDARD, REDUCED_REDUNDANCY, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, GLACIER, DEEP_ARCHIVE, OUTPOSTS, GLACIER_IR, SNOW, EXPRESS_ONEZONE, FSX_OPENZFS, FSX_ONTAP
|
|
2179
|
+
# server_side_encryption: "AES256", # accepts AES256, aws:fsx, aws:backup, aws:kms, aws:kms:dsse
|
|
2180
|
+
# storage_class: "STANDARD", # accepts STANDARD, REDUCED_REDUNDANCY, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, GLACIER, DEEP_ARCHIVE, OUTPOSTS, GLACIER_IR, SNOW, EXPRESS_ONEZONE, FSX_OPENZFS, FSX_ONTAP, AWS_BACKUP_WARM, AWS_BACKUP_LOW_COST_WARM
|
|
2096
2181
|
# website_redirect_location: "WebsiteRedirectLocation",
|
|
2097
2182
|
# sse_customer_algorithm: "SSECustomerAlgorithm",
|
|
2098
2183
|
# sse_customer_key: "SSECustomerKey",
|
|
@@ -2105,6 +2190,9 @@ module Aws::S3
|
|
|
2105
2190
|
# object_lock_mode: "GOVERNANCE", # accepts GOVERNANCE, COMPLIANCE
|
|
2106
2191
|
# object_lock_retain_until_date: Time.now,
|
|
2107
2192
|
# object_lock_legal_hold_status: "ON", # accepts ON, OFF
|
|
2193
|
+
# object_lock_event_hold: "ON", # accepts ON, OFF
|
|
2194
|
+
# object_lock_event_hold_duration_days: 1,
|
|
2195
|
+
# object_lock_event_hold_duration_years: 1,
|
|
2108
2196
|
# expected_bucket_owner: "AccountId",
|
|
2109
2197
|
# })
|
|
2110
2198
|
# @param [Hash] options ({})
|
|
@@ -2730,6 +2818,27 @@ module Aws::S3
|
|
|
2730
2818
|
#
|
|
2731
2819
|
#
|
|
2732
2820
|
# [1]: https://docs.aws.amazon.com/AmazonS3/latest/dev/object-lock.html
|
|
2821
|
+
# @option options [String] :object_lock_event_hold
|
|
2822
|
+
# Specifies the event hold status to apply to this object. Set to `ON`
|
|
2823
|
+
# to enable or `OFF` to disable.
|
|
2824
|
+
#
|
|
2825
|
+
# <note markdown="1"> This functionality is not supported for directory buckets.
|
|
2826
|
+
#
|
|
2827
|
+
# </note>
|
|
2828
|
+
# @option options [Integer] :object_lock_event_hold_duration_days
|
|
2829
|
+
# Specifies the event hold duration in days to apply to this object. You
|
|
2830
|
+
# cannot specify a duration in both days and years.
|
|
2831
|
+
#
|
|
2832
|
+
# <note markdown="1"> This functionality is not supported for directory buckets.
|
|
2833
|
+
#
|
|
2834
|
+
# </note>
|
|
2835
|
+
# @option options [Integer] :object_lock_event_hold_duration_years
|
|
2836
|
+
# Specifies the event hold duration in years to apply to this object.
|
|
2837
|
+
# You cannot specify a duration in both days and years.
|
|
2838
|
+
#
|
|
2839
|
+
# <note markdown="1"> This functionality is not supported for directory buckets.
|
|
2840
|
+
#
|
|
2841
|
+
# </note>
|
|
2733
2842
|
# @option options [String] :expected_bucket_owner
|
|
2734
2843
|
# The account ID of the expected bucket owner. If the account ID that
|
|
2735
2844
|
# you provide does not match the actual owner of the bucket, the request
|
|
@@ -2796,7 +2905,7 @@ module Aws::S3
|
|
|
2796
2905
|
# bucket_name: "BucketName", # required
|
|
2797
2906
|
# prefix: "LocationPrefix", # required
|
|
2798
2907
|
# encryption: {
|
|
2799
|
-
# encryption_type: "AES256", # required, accepts AES256, aws:fsx, aws:kms, aws:kms:dsse
|
|
2908
|
+
# encryption_type: "AES256", # required, accepts AES256, aws:fsx, aws:backup, aws:kms, aws:kms:dsse
|
|
2800
2909
|
# kms_key_id: "SSEKMSKeyId",
|
|
2801
2910
|
# kms_context: "KMSContext",
|
|
2802
2911
|
# },
|
|
@@ -2827,7 +2936,7 @@ module Aws::S3
|
|
|
2827
2936
|
# value: "MetadataValue",
|
|
2828
2937
|
# },
|
|
2829
2938
|
# ],
|
|
2830
|
-
# storage_class: "STANDARD", # accepts STANDARD, REDUCED_REDUNDANCY, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, GLACIER, DEEP_ARCHIVE, OUTPOSTS, GLACIER_IR, SNOW, EXPRESS_ONEZONE, FSX_OPENZFS, FSX_ONTAP
|
|
2939
|
+
# storage_class: "STANDARD", # accepts STANDARD, REDUCED_REDUNDANCY, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, GLACIER, DEEP_ARCHIVE, OUTPOSTS, GLACIER_IR, SNOW, EXPRESS_ONEZONE, FSX_OPENZFS, FSX_ONTAP, AWS_BACKUP_WARM, AWS_BACKUP_LOW_COST_WARM
|
|
2831
2940
|
# },
|
|
2832
2941
|
# },
|
|
2833
2942
|
# },
|
|
@@ -19,7 +19,7 @@ module Aws
|
|
|
19
19
|
private_constant :ENCODINGS_TO_FIX
|
|
20
20
|
|
|
21
21
|
# A regular expression to match detect errors in the response body
|
|
22
|
-
ERROR_PATTERN =
|
|
22
|
+
ERROR_PATTERN = /\A\s*(<\?xml[^>]*\?>\s*)?<Error>/.freeze
|
|
23
23
|
private_constant :ERROR_PATTERN
|
|
24
24
|
|
|
25
25
|
# A regular expression to match an error message in the response body
|