aws-sdk-s3 1.0.0.rc1
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 +7 -0
- data/lib/aws-sdk-s3.rb +66 -0
- data/lib/aws-sdk-s3/bucket.rb +595 -0
- data/lib/aws-sdk-s3/bucket_acl.rb +168 -0
- data/lib/aws-sdk-s3/bucket_cors.rb +146 -0
- data/lib/aws-sdk-s3/bucket_lifecycle.rb +164 -0
- data/lib/aws-sdk-s3/bucket_logging.rb +142 -0
- data/lib/aws-sdk-s3/bucket_notification.rb +187 -0
- data/lib/aws-sdk-s3/bucket_policy.rb +138 -0
- data/lib/aws-sdk-s3/bucket_region_cache.rb +79 -0
- data/lib/aws-sdk-s3/bucket_request_payment.rb +128 -0
- data/lib/aws-sdk-s3/bucket_tagging.rb +143 -0
- data/lib/aws-sdk-s3/bucket_versioning.rb +188 -0
- data/lib/aws-sdk-s3/bucket_website.rb +177 -0
- data/lib/aws-sdk-s3/client.rb +3171 -0
- data/lib/aws-sdk-s3/client_api.rb +1991 -0
- data/lib/aws-sdk-s3/customizations.rb +29 -0
- data/lib/aws-sdk-s3/customizations/bucket.rb +127 -0
- data/lib/aws-sdk-s3/customizations/multipart_upload.rb +42 -0
- data/lib/aws-sdk-s3/customizations/object.rb +257 -0
- data/lib/aws-sdk-s3/customizations/object_summary.rb +65 -0
- data/lib/aws-sdk-s3/customizations/types/list_object_versions_output.rb +11 -0
- data/lib/aws-sdk-s3/encryption.rb +19 -0
- data/lib/aws-sdk-s3/encryption/client.rb +369 -0
- data/lib/aws-sdk-s3/encryption/decrypt_handler.rb +178 -0
- data/lib/aws-sdk-s3/encryption/default_cipher_provider.rb +63 -0
- data/lib/aws-sdk-s3/encryption/default_key_provider.rb +38 -0
- data/lib/aws-sdk-s3/encryption/encrypt_handler.rb +50 -0
- data/lib/aws-sdk-s3/encryption/errors.rb +13 -0
- data/lib/aws-sdk-s3/encryption/io_auth_decrypter.rb +50 -0
- data/lib/aws-sdk-s3/encryption/io_decrypter.rb +29 -0
- data/lib/aws-sdk-s3/encryption/io_encrypter.rb +69 -0
- data/lib/aws-sdk-s3/encryption/key_provider.rb +29 -0
- data/lib/aws-sdk-s3/encryption/kms_cipher_provider.rb +71 -0
- data/lib/aws-sdk-s3/encryption/materials.rb +58 -0
- data/lib/aws-sdk-s3/encryption/utils.rb +79 -0
- data/lib/aws-sdk-s3/errors.rb +23 -0
- data/lib/aws-sdk-s3/file_part.rb +75 -0
- data/lib/aws-sdk-s3/file_uploader.rb +58 -0
- data/lib/aws-sdk-s3/legacy_signer.rb +186 -0
- data/lib/aws-sdk-s3/multipart_file_uploader.rb +187 -0
- data/lib/aws-sdk-s3/multipart_upload.rb +287 -0
- data/lib/aws-sdk-s3/multipart_upload_error.rb +16 -0
- data/lib/aws-sdk-s3/multipart_upload_part.rb +314 -0
- data/lib/aws-sdk-s3/object.rb +942 -0
- data/lib/aws-sdk-s3/object_acl.rb +214 -0
- data/lib/aws-sdk-s3/object_copier.rb +99 -0
- data/lib/aws-sdk-s3/object_multipart_copier.rb +179 -0
- data/lib/aws-sdk-s3/object_summary.rb +794 -0
- data/lib/aws-sdk-s3/object_version.rb +406 -0
- data/lib/aws-sdk-s3/plugins/accelerate.rb +92 -0
- data/lib/aws-sdk-s3/plugins/bucket_dns.rb +89 -0
- data/lib/aws-sdk-s3/plugins/bucket_name_restrictions.rb +23 -0
- data/lib/aws-sdk-s3/plugins/dualstack.rb +70 -0
- data/lib/aws-sdk-s3/plugins/expect_100_continue.rb +29 -0
- data/lib/aws-sdk-s3/plugins/get_bucket_location_fix.rb +23 -0
- data/lib/aws-sdk-s3/plugins/http_200_errors.rb +47 -0
- data/lib/aws-sdk-s3/plugins/location_constraint.rb +33 -0
- data/lib/aws-sdk-s3/plugins/md5s.rb +79 -0
- data/lib/aws-sdk-s3/plugins/redirects.rb +41 -0
- data/lib/aws-sdk-s3/plugins/s3_signer.rb +208 -0
- data/lib/aws-sdk-s3/plugins/sse_cpk.rb +68 -0
- data/lib/aws-sdk-s3/plugins/url_encoded_keys.rb +94 -0
- data/lib/aws-sdk-s3/presigned_post.rb +647 -0
- data/lib/aws-sdk-s3/presigner.rb +160 -0
- data/lib/aws-sdk-s3/resource.rb +96 -0
- data/lib/aws-sdk-s3/types.rb +5750 -0
- data/lib/aws-sdk-s3/waiters.rb +178 -0
- metadata +154 -0
@@ -0,0 +1,214 @@
|
|
1
|
+
# WARNING ABOUT GENERATED CODE
|
2
|
+
#
|
3
|
+
# This file is generated. See the contributing for info on making contributions:
|
4
|
+
# https://github.com/aws/aws-sdk-ruby/blob/master/CONTRIBUTING.md
|
5
|
+
#
|
6
|
+
# WARNING ABOUT GENERATED CODE
|
7
|
+
|
8
|
+
module Aws
|
9
|
+
module S3
|
10
|
+
class ObjectAcl
|
11
|
+
|
12
|
+
extend Aws::Deprecations
|
13
|
+
|
14
|
+
# @overload def initialize(bucket_name, object_key, options = {})
|
15
|
+
# @param [String] bucket_name
|
16
|
+
# @param [String] object_key
|
17
|
+
# @option options [Client] :client
|
18
|
+
# @overload def initialize(options = {})
|
19
|
+
# @option options [required, String] :bucket_name
|
20
|
+
# @option options [required, String] :object_key
|
21
|
+
# @option options [Client] :client
|
22
|
+
def initialize(*args)
|
23
|
+
options = Hash === args.last ? args.pop.dup : {}
|
24
|
+
@bucket_name = extract_bucket_name(args, options)
|
25
|
+
@object_key = extract_object_key(args, options)
|
26
|
+
@data = options.delete(:data)
|
27
|
+
@client = options.delete(:client) || Client.new(options)
|
28
|
+
end
|
29
|
+
|
30
|
+
# @!group Read-Only Attributes
|
31
|
+
|
32
|
+
# @return [String]
|
33
|
+
def bucket_name
|
34
|
+
@bucket_name
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [String]
|
38
|
+
def object_key
|
39
|
+
@object_key
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [Types::Owner]
|
43
|
+
def owner
|
44
|
+
data.owner
|
45
|
+
end
|
46
|
+
|
47
|
+
# A list of grants.
|
48
|
+
# @return [Array<Types::Grant>]
|
49
|
+
def grants
|
50
|
+
data.grants
|
51
|
+
end
|
52
|
+
|
53
|
+
# If present, indicates that the requester was successfully charged for
|
54
|
+
# the request.
|
55
|
+
# @return [String]
|
56
|
+
def request_charged
|
57
|
+
data.request_charged
|
58
|
+
end
|
59
|
+
|
60
|
+
# @!endgroup
|
61
|
+
|
62
|
+
# @return [Client]
|
63
|
+
def client
|
64
|
+
@client
|
65
|
+
end
|
66
|
+
|
67
|
+
# Loads, or reloads {#data} for the current {ObjectAcl}.
|
68
|
+
# Returns `self` making it possible to chain methods.
|
69
|
+
#
|
70
|
+
# object_acl.reload.data
|
71
|
+
#
|
72
|
+
# @return [self]
|
73
|
+
def load
|
74
|
+
resp = @client.get_object_acl(
|
75
|
+
bucket: @bucket_name,
|
76
|
+
key: @object_key
|
77
|
+
)
|
78
|
+
@data = resp.data
|
79
|
+
self
|
80
|
+
end
|
81
|
+
alias :reload :load
|
82
|
+
|
83
|
+
# @return [Types::GetObjectAclOutput]
|
84
|
+
# Returns the data for this {ObjectAcl}. Calls
|
85
|
+
# {Client#get_object_acl} if {#data_loaded?} is `false`.
|
86
|
+
def data
|
87
|
+
load unless @data
|
88
|
+
@data
|
89
|
+
end
|
90
|
+
|
91
|
+
# @return [Boolean]
|
92
|
+
# Returns `true` if this resource is loaded. Accessing attributes or
|
93
|
+
# {#data} on an unloaded resource will trigger a call to {#load}.
|
94
|
+
def data_loaded?
|
95
|
+
!!@data
|
96
|
+
end
|
97
|
+
|
98
|
+
# @!group Actions
|
99
|
+
|
100
|
+
# @example Request syntax with placeholder values
|
101
|
+
#
|
102
|
+
# object_acl.put({
|
103
|
+
# acl: "private", # accepts private, public-read, public-read-write, authenticated-read, aws-exec-read, bucket-owner-read, bucket-owner-full-control
|
104
|
+
# access_control_policy: {
|
105
|
+
# grants: [
|
106
|
+
# {
|
107
|
+
# grantee: {
|
108
|
+
# display_name: "DisplayName",
|
109
|
+
# email_address: "EmailAddress",
|
110
|
+
# id: "ID",
|
111
|
+
# type: "CanonicalUser", # required, accepts CanonicalUser, AmazonCustomerByEmail, Group
|
112
|
+
# uri: "URI",
|
113
|
+
# },
|
114
|
+
# permission: "FULL_CONTROL", # accepts FULL_CONTROL, WRITE, WRITE_ACP, READ, READ_ACP
|
115
|
+
# },
|
116
|
+
# ],
|
117
|
+
# owner: {
|
118
|
+
# display_name: "DisplayName",
|
119
|
+
# id: "ID",
|
120
|
+
# },
|
121
|
+
# },
|
122
|
+
# content_md5: "ContentMD5",
|
123
|
+
# grant_full_control: "GrantFullControl",
|
124
|
+
# grant_read: "GrantRead",
|
125
|
+
# grant_read_acp: "GrantReadACP",
|
126
|
+
# grant_write: "GrantWrite",
|
127
|
+
# grant_write_acp: "GrantWriteACP",
|
128
|
+
# request_payer: "requester", # accepts requester
|
129
|
+
# version_id: "ObjectVersionId",
|
130
|
+
# })
|
131
|
+
# @param [Hash] options ({})
|
132
|
+
# @option options [String] :acl
|
133
|
+
# The canned ACL to apply to the object.
|
134
|
+
# @option options [Types::AccessControlPolicy] :access_control_policy
|
135
|
+
# @option options [String] :content_md5
|
136
|
+
# @option options [String] :grant_full_control
|
137
|
+
# Allows grantee the read, write, read ACP, and write ACP permissions on
|
138
|
+
# the bucket.
|
139
|
+
# @option options [String] :grant_read
|
140
|
+
# Allows grantee to list the objects in the bucket.
|
141
|
+
# @option options [String] :grant_read_acp
|
142
|
+
# Allows grantee to read the bucket ACL.
|
143
|
+
# @option options [String] :grant_write
|
144
|
+
# Allows grantee to create, overwrite, and delete any object in the
|
145
|
+
# bucket.
|
146
|
+
# @option options [String] :grant_write_acp
|
147
|
+
# Allows grantee to write the ACL for the applicable bucket.
|
148
|
+
# @option options [String] :request_payer
|
149
|
+
# Confirms that the requester knows that she or he will be charged for
|
150
|
+
# the request. Bucket owners need not specify this parameter in their
|
151
|
+
# requests. Documentation on downloading objects from requester pays
|
152
|
+
# buckets can be found at
|
153
|
+
# http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
|
154
|
+
# @option options [String] :version_id
|
155
|
+
# VersionId used to reference a specific version of the object.
|
156
|
+
# @return [Types::PutObjectAclOutput]
|
157
|
+
def put(options = {})
|
158
|
+
options = options.merge(
|
159
|
+
bucket: @bucket_name,
|
160
|
+
key: @object_key
|
161
|
+
)
|
162
|
+
resp = @client.put_object_acl(options)
|
163
|
+
resp.data
|
164
|
+
end
|
165
|
+
|
166
|
+
# @!group Associations
|
167
|
+
|
168
|
+
# @return [Object]
|
169
|
+
def object
|
170
|
+
Object.new(
|
171
|
+
bucket_name: @bucket_name,
|
172
|
+
key: @object_key,
|
173
|
+
client: @client
|
174
|
+
)
|
175
|
+
end
|
176
|
+
|
177
|
+
# @deprecated
|
178
|
+
# @api private
|
179
|
+
def identifiers
|
180
|
+
{
|
181
|
+
bucket_name: @bucket_name,
|
182
|
+
object_key: @object_key
|
183
|
+
}
|
184
|
+
end
|
185
|
+
deprecated(:identifiers)
|
186
|
+
|
187
|
+
private
|
188
|
+
|
189
|
+
def extract_bucket_name(args, options)
|
190
|
+
value = args[0] || options.delete(:bucket_name)
|
191
|
+
case value
|
192
|
+
when String then value
|
193
|
+
when nil then raise ArgumentError, "missing required option :bucket_name"
|
194
|
+
else
|
195
|
+
msg = "expected :bucket_name to be a String, got #{value.class}"
|
196
|
+
raise ArgumentError, msg
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def extract_object_key(args, options)
|
201
|
+
value = args[1] || options.delete(:object_key)
|
202
|
+
case value
|
203
|
+
when String then value
|
204
|
+
when nil then raise ArgumentError, "missing required option :object_key"
|
205
|
+
else
|
206
|
+
msg = "expected :object_key to be a String, got #{value.class}"
|
207
|
+
raise ArgumentError, msg
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
class Collection < Aws::Resources::Collection; end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
module Aws
|
4
|
+
module S3
|
5
|
+
# @api private
|
6
|
+
class ObjectCopier
|
7
|
+
|
8
|
+
# @param [S3::Object] object
|
9
|
+
def initialize(object, options = {})
|
10
|
+
@object = object
|
11
|
+
@options = options.merge(client: @object.client)
|
12
|
+
end
|
13
|
+
|
14
|
+
def copy_from(source, options = {})
|
15
|
+
copy_object(source, @object, merge_options(source, options))
|
16
|
+
end
|
17
|
+
|
18
|
+
def copy_to(target, options = {})
|
19
|
+
copy_object(@object, target, merge_options(target, options))
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def copy_object(source, target, options)
|
25
|
+
target_bucket, target_key = copy_target(target)
|
26
|
+
options[:bucket] = target_bucket
|
27
|
+
options[:key] = target_key
|
28
|
+
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)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def copy_source(source)
|
38
|
+
case source
|
39
|
+
when String then source
|
40
|
+
when Hash
|
41
|
+
src = "#{source[:bucket]}/#{escape(source[:key])}"
|
42
|
+
src += "?versionId=#{source[:version_id]}" if source.key?(:version_id)
|
43
|
+
src
|
44
|
+
when S3::Object, S3::ObjectSummary
|
45
|
+
"#{source.bucket_name}/#{escape(source.key)}"
|
46
|
+
when S3::ObjectVersion
|
47
|
+
"#{source.bucket_name}/#{escape(source.object_key)}?versionId=#{source.id}"
|
48
|
+
else
|
49
|
+
msg = "expected source to be an Aws::S3::Object, Hash, or String"
|
50
|
+
raise ArgumentError, msg
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def copy_target(target)
|
55
|
+
case target
|
56
|
+
when String then target.match(/([^\/]+?)\/(.+)/)[1,2]
|
57
|
+
when Hash then target.values_at(:bucket, :key)
|
58
|
+
when S3::Object then [target.bucket_name, target.key]
|
59
|
+
else
|
60
|
+
msg = "expected target to be an Aws::S3::Object, Hash, or String"
|
61
|
+
raise ArgumentError, msg
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def merge_options(source_or_target, options)
|
66
|
+
if Hash === source_or_target
|
67
|
+
source_or_target.inject(options.dup) do |opts, (key, value)|
|
68
|
+
opts[key] = value unless [:bucket, :key, :version_id].include?(key)
|
69
|
+
opts
|
70
|
+
end
|
71
|
+
else
|
72
|
+
options.dup
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def apply_source_client(source, options)
|
77
|
+
|
78
|
+
if source.respond_to?(:client)
|
79
|
+
options[:copy_source_client] ||= source.client
|
80
|
+
end
|
81
|
+
|
82
|
+
if options[:copy_source_region]
|
83
|
+
config = @object.client.config
|
84
|
+
config = config.each_pair.inject({}) { |h, (k,v)| h[k] = v; h }
|
85
|
+
config[:region] = options.delete(:copy_source_region)
|
86
|
+
options[:copy_source_client] ||= S3::Client.new(config)
|
87
|
+
end
|
88
|
+
|
89
|
+
options[:copy_source_client] ||= @object.client
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
def escape(str)
|
94
|
+
Seahorse::Util.uri_path_escape(str)
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
module Aws
|
4
|
+
module S3
|
5
|
+
# @api private
|
6
|
+
class ObjectMultipartCopier
|
7
|
+
|
8
|
+
FIVE_MB = 5 * 1024 * 1024 # 5MB
|
9
|
+
|
10
|
+
FILE_TOO_SMALL = "unable to multipart copy files smaller than 5MB"
|
11
|
+
|
12
|
+
MAX_PARTS = 10_000
|
13
|
+
|
14
|
+
# @option options [Client] :client
|
15
|
+
# @option [Integer] :min_part_size (52428800) Size of copied parts.
|
16
|
+
# Defaults to 50MB.
|
17
|
+
# will be constructed from the given `options' hash.
|
18
|
+
# @option [Integer] :thread_count (10) Number of concurrent threads to
|
19
|
+
# use for copying parts.
|
20
|
+
def initialize(options = {})
|
21
|
+
@thread_count = options.delete(:thread_count) || 10
|
22
|
+
@min_part_size = options.delete(:min_part_size) || (FIVE_MB * 10)
|
23
|
+
@client = options[:client] || Client.new
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Client]
|
27
|
+
attr_reader :client
|
28
|
+
|
29
|
+
# @option (see S3::Client#copy_object)
|
30
|
+
def copy(options = {})
|
31
|
+
size = source_size(options)
|
32
|
+
options[:upload_id] = initiate_upload(options)
|
33
|
+
begin
|
34
|
+
parts = copy_parts(size, default_part_size(size), options)
|
35
|
+
complete_upload(parts, options)
|
36
|
+
rescue => error
|
37
|
+
abort_upload(options)
|
38
|
+
raise error
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def initiate_upload(options)
|
45
|
+
options = options_for(:create_multipart_upload, options)
|
46
|
+
@client.create_multipart_upload(options).upload_id
|
47
|
+
end
|
48
|
+
|
49
|
+
def copy_parts(size, default_part_size, options)
|
50
|
+
queue = PartQueue.new(compute_parts(size, default_part_size, options))
|
51
|
+
threads = []
|
52
|
+
@thread_count.times do
|
53
|
+
threads << copy_part_thread(queue)
|
54
|
+
end
|
55
|
+
threads.map(&:value).flatten.sort_by{ |part| part[:part_number] }
|
56
|
+
end
|
57
|
+
|
58
|
+
def copy_part_thread(queue)
|
59
|
+
Thread.new do
|
60
|
+
begin
|
61
|
+
completed = []
|
62
|
+
while part = queue.shift
|
63
|
+
completed << copy_part(part)
|
64
|
+
end
|
65
|
+
completed
|
66
|
+
rescue => error
|
67
|
+
queue.clear!
|
68
|
+
raise error
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def copy_part(part)
|
74
|
+
{
|
75
|
+
etag: @client.upload_part_copy(part).copy_part_result.etag,
|
76
|
+
part_number: part[:part_number],
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
def complete_upload(parts, options)
|
81
|
+
options = options_for(:complete_multipart_upload, options)
|
82
|
+
options[:multipart_upload] = { parts: parts }
|
83
|
+
@client.complete_multipart_upload(options)
|
84
|
+
end
|
85
|
+
|
86
|
+
def abort_upload(options)
|
87
|
+
@client.abort_multipart_upload({
|
88
|
+
bucket: options[:bucket],
|
89
|
+
key: options[:key],
|
90
|
+
upload_id: options[:upload_id],
|
91
|
+
})
|
92
|
+
end
|
93
|
+
|
94
|
+
def compute_parts(size, default_part_size, options)
|
95
|
+
part_number = 1
|
96
|
+
offset = 0
|
97
|
+
parts = []
|
98
|
+
options = options_for(:upload_part_copy, options)
|
99
|
+
while offset < size
|
100
|
+
parts << options.merge({
|
101
|
+
part_number: part_number,
|
102
|
+
copy_source_range: byte_range(offset, default_part_size, size),
|
103
|
+
})
|
104
|
+
part_number += 1
|
105
|
+
offset += default_part_size
|
106
|
+
end
|
107
|
+
parts
|
108
|
+
end
|
109
|
+
|
110
|
+
def byte_range(offset, default_part_size, size)
|
111
|
+
if offset + default_part_size < size
|
112
|
+
"bytes=#{offset}-#{offset + default_part_size - 1}"
|
113
|
+
else
|
114
|
+
"bytes=#{offset}-#{size - 1}"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def source_size(options)
|
119
|
+
return options.delete(:content_length) if options[:content_length]
|
120
|
+
|
121
|
+
client = options[:copy_source_client] || @client
|
122
|
+
|
123
|
+
if vid_match = options[:copy_source].match(/([^\/]+?)\/(.+)\?versionId=(.+)/)
|
124
|
+
bucket, key, version_id = vid_match[1,3]
|
125
|
+
else
|
126
|
+
bucket, key = options[:copy_source].match(/([^\/]+?)\/(.+)/)[1,2]
|
127
|
+
end
|
128
|
+
|
129
|
+
key = CGI.unescape(key)
|
130
|
+
opts = { bucket: bucket, key: key }
|
131
|
+
opts[:version_id] = version_id if version_id
|
132
|
+
client.head_object(opts).content_length
|
133
|
+
end
|
134
|
+
|
135
|
+
def default_part_size(source_size)
|
136
|
+
if source_size < FIVE_MB
|
137
|
+
raise ArgumentError, FILE_TOO_SMALL
|
138
|
+
else
|
139
|
+
[(source_size.to_f / MAX_PARTS).ceil, @min_part_size].max.to_i
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def options_for(operation_name, options)
|
144
|
+
API_OPTIONS[operation_name].inject({}) do |hash, opt_name|
|
145
|
+
hash[opt_name] = options[opt_name] if options.key?(opt_name)
|
146
|
+
hash
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
# @api private
|
151
|
+
def self.options_for(shape_name)
|
152
|
+
Client.api.metadata['shapes'][shape_name].member_names
|
153
|
+
end
|
154
|
+
|
155
|
+
API_OPTIONS = {
|
156
|
+
create_multipart_upload: Types::CreateMultipartUploadRequest.members,
|
157
|
+
upload_part_copy: Types::UploadPartCopyRequest.members,
|
158
|
+
complete_multipart_upload: Types::CompleteMultipartUploadRequest.members,
|
159
|
+
}
|
160
|
+
|
161
|
+
class PartQueue
|
162
|
+
|
163
|
+
def initialize(parts = [])
|
164
|
+
@parts = parts
|
165
|
+
@mutex = Mutex.new
|
166
|
+
end
|
167
|
+
|
168
|
+
def shift
|
169
|
+
@mutex.synchronize { @parts.shift }
|
170
|
+
end
|
171
|
+
|
172
|
+
def clear!
|
173
|
+
@mutex.synchronize { @parts.clear }
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|