aws-sdk-resources 2.3.23 → 3.69.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +5 -5
  2. data/bin/aws-v3.rb +201 -0
  3. data/lib/aws-sdk-resources.rb +223 -87
  4. metadata +3073 -71
  5. data/lib/aws-sdk-resources/batch.rb +0 -143
  6. data/lib/aws-sdk-resources/builder.rb +0 -85
  7. data/lib/aws-sdk-resources/builder_sources.rb +0 -105
  8. data/lib/aws-sdk-resources/collection.rb +0 -107
  9. data/lib/aws-sdk-resources/definition.rb +0 -331
  10. data/lib/aws-sdk-resources/documenter.rb +0 -70
  11. data/lib/aws-sdk-resources/documenter/base_operation_documenter.rb +0 -279
  12. data/lib/aws-sdk-resources/documenter/data_operation_documenter.rb +0 -25
  13. data/lib/aws-sdk-resources/documenter/has_many_operation_documenter.rb +0 -67
  14. data/lib/aws-sdk-resources/documenter/has_operation_documenter.rb +0 -66
  15. data/lib/aws-sdk-resources/documenter/operation_documenter.rb +0 -20
  16. data/lib/aws-sdk-resources/documenter/resource_operation_documenter.rb +0 -53
  17. data/lib/aws-sdk-resources/documenter/waiter_operation_documenter.rb +0 -77
  18. data/lib/aws-sdk-resources/errors.rb +0 -15
  19. data/lib/aws-sdk-resources/operation_methods.rb +0 -83
  20. data/lib/aws-sdk-resources/operations.rb +0 -280
  21. data/lib/aws-sdk-resources/options.rb +0 -17
  22. data/lib/aws-sdk-resources/request.rb +0 -39
  23. data/lib/aws-sdk-resources/request_params.rb +0 -140
  24. data/lib/aws-sdk-resources/resource.rb +0 -243
  25. data/lib/aws-sdk-resources/services/ec2.rb +0 -21
  26. data/lib/aws-sdk-resources/services/ec2/instance.rb +0 -29
  27. data/lib/aws-sdk-resources/services/iam.rb +0 -19
  28. data/lib/aws-sdk-resources/services/s3.rb +0 -19
  29. data/lib/aws-sdk-resources/services/s3/bucket.rb +0 -127
  30. data/lib/aws-sdk-resources/services/s3/encryption.rb +0 -21
  31. data/lib/aws-sdk-resources/services/s3/encryption/client.rb +0 -369
  32. data/lib/aws-sdk-resources/services/s3/encryption/decrypt_handler.rb +0 -174
  33. data/lib/aws-sdk-resources/services/s3/encryption/default_cipher_provider.rb +0 -63
  34. data/lib/aws-sdk-resources/services/s3/encryption/default_key_provider.rb +0 -38
  35. data/lib/aws-sdk-resources/services/s3/encryption/encrypt_handler.rb +0 -50
  36. data/lib/aws-sdk-resources/services/s3/encryption/errors.rb +0 -13
  37. data/lib/aws-sdk-resources/services/s3/encryption/io_auth_decrypter.rb +0 -50
  38. data/lib/aws-sdk-resources/services/s3/encryption/io_decrypter.rb +0 -29
  39. data/lib/aws-sdk-resources/services/s3/encryption/io_encrypter.rb +0 -69
  40. data/lib/aws-sdk-resources/services/s3/encryption/key_provider.rb +0 -29
  41. data/lib/aws-sdk-resources/services/s3/encryption/kms_cipher_provider.rb +0 -71
  42. data/lib/aws-sdk-resources/services/s3/encryption/materials.rb +0 -58
  43. data/lib/aws-sdk-resources/services/s3/encryption/utils.rb +0 -79
  44. data/lib/aws-sdk-resources/services/s3/file_part.rb +0 -75
  45. data/lib/aws-sdk-resources/services/s3/file_uploader.rb +0 -58
  46. data/lib/aws-sdk-resources/services/s3/multipart_file_uploader.rb +0 -187
  47. data/lib/aws-sdk-resources/services/s3/multipart_upload.rb +0 -42
  48. data/lib/aws-sdk-resources/services/s3/multipart_upload_error.rb +0 -16
  49. data/lib/aws-sdk-resources/services/s3/object.rb +0 -257
  50. data/lib/aws-sdk-resources/services/s3/object_copier.rb +0 -99
  51. data/lib/aws-sdk-resources/services/s3/object_multipart_copier.rb +0 -179
  52. data/lib/aws-sdk-resources/services/s3/object_summary.rb +0 -65
  53. data/lib/aws-sdk-resources/services/s3/presigned_post.rb +0 -647
  54. data/lib/aws-sdk-resources/services/sns.rb +0 -7
  55. data/lib/aws-sdk-resources/services/sns/message_verifier.rb +0 -157
  56. data/lib/aws-sdk-resources/services/sqs.rb +0 -7
  57. data/lib/aws-sdk-resources/services/sqs/queue_poller.rb +0 -521
  58. data/lib/aws-sdk-resources/source.rb +0 -39
@@ -1,42 +0,0 @@
1
- module Aws
2
- module S3
3
- class MultipartUpload
4
-
5
- alias_method :basic_complete, :complete
6
-
7
- # Completes the upload, requires a list of completed parts. You can
8
- # provide the list of parts with `:part_number` and `:etag` values.
9
- #
10
- # upload.complete(multipart_upload: { parts: [
11
- # { part_number: 1, etag:'etag1' },
12
- # { part_number: 2, etag:'etag2' },
13
- # ...
14
- # ]})
15
- #
16
- # Alternatively, you can pass **`compute_parts: true`** and the part
17
- # list will be computed by calling {Client#list_parts}.
18
- #
19
- # upload.complete(compute_parts: true)
20
- #
21
- # @option options [Boolean] :compute_parts (false) When `true`,
22
- # the {Client#list_parts} method will be called to determine
23
- # the list of required part numbers and their ETags.
24
- #
25
- def complete(options = {})
26
- if options.delete(:compute_parts)
27
- options[:multipart_upload] = { parts: compute_parts }
28
- end
29
- basic_complete(options)
30
- end
31
-
32
- private
33
-
34
- def compute_parts
35
- parts.sort_by(&:part_number).each.with_object([]) do |part, part_list|
36
- part_list << { part_number: part.part_number, etag: part.etag }
37
- end
38
- end
39
-
40
- end
41
- end
42
- end
@@ -1,16 +0,0 @@
1
- module Aws
2
- module S3
3
- class MultipartUploadError < StandardError
4
-
5
- def initialize(message, errors)
6
- @errors = errors
7
- super(message)
8
- end
9
-
10
- # @return [Array<StandardError>] The list of errors encountered
11
- # when uploading or aborting the upload.
12
- attr_reader :errors
13
-
14
- end
15
- end
16
- end
@@ -1,257 +0,0 @@
1
- module Aws
2
- module S3
3
- class Object
4
-
5
- alias size content_length
6
-
7
- # Copies another object to this object. Use `multipart_copy: true`
8
- # for large objects. This is required for objects that exceed 5GB.
9
- #
10
- # @param [S3::Object, S3::ObjectVersion, S3::ObjectSummary, String, Hash] source
11
- # Where to copy object data from. `source` must be one of the following:
12
- #
13
- # * {Aws::S3::Object}
14
- # * {Aws::S3::ObjectSummary}
15
- # * {Aws::S3::ObjectVersion}
16
- # * Hash - with `:bucket` and `:key` and optional `:version_id`
17
- # * String - formatted like `"source-bucket-name/uri-escaped-key"`
18
- # or `"source-bucket-name/uri-escaped-key?versionId=version-id"`
19
- #
20
- # @option options [Boolean] :multipart_copy (false) When `true`,
21
- # the object will be copied using the multipart APIs. This is
22
- # necessary for objects larger than 5GB and can provide
23
- # performance improvements on large objects. Amazon S3 does
24
- # not accept multipart copies for objects smaller than 5MB.
25
- #
26
- # @option options [Integer] :content_length Only used when
27
- # `:multipart_copy` is `true`. Passing this options avoids a HEAD
28
- # request to query the source object size.
29
- #
30
- # @option options [S3::Client] :copy_source_client Only used when
31
- # `:multipart_copy` is `true` and the source object is in a
32
- # different region. You do not need to specify this option
33
- # if you have provided `:content_length`.
34
- #
35
- # @option options [String] :copy_source_region Only used when
36
- # `:multipart_copy` is `true` and the source object is in a
37
- # different region. You do not need to specify this option
38
- # if you have provided a `:source_client` or a `:content_length`.
39
- #
40
- # @example Basic object copy
41
- #
42
- # bucket = Aws::S3::Bucket.new('target-bucket')
43
- # object = bucket.object('target-key')
44
- #
45
- # # source as String
46
- # object.copy_from('source-bucket/source-key')
47
- #
48
- # # source as Hash
49
- # object.copy_from(bucket:'source-bucket', key:'source-key')
50
- #
51
- # # source as Aws::S3::Object
52
- # object.copy_from(bucket.object('source-key'))
53
- #
54
- # @example Managed copy of large objects
55
- #
56
- # # uses multipart upload APIs to copy object
57
- # object.copy_from('src-bucket/src-key', multipart_copy: true)
58
- #
59
- # @see #copy_to
60
- #
61
- def copy_from(source, options = {})
62
- if Hash === source && source[:copy_source]
63
- # for backwards compatibility
64
- @client.copy_object(source.merge(bucket: bucket_name, key: key))
65
- else
66
- ObjectCopier.new(self, options).copy_from(source, options)
67
- end
68
- end
69
-
70
- # Copies this object to another object. Use `multipart_copy: true`
71
- # for large objects. This is required for objects that exceed 5GB.
72
- #
73
- # @note If you need to copy to a bucket in a different region, use
74
- # {#copy_from}.
75
- #
76
- # @param [S3::Object, String, Hash] target Where to copy the object
77
- # data to. `target` must be one of the following:
78
- #
79
- # * {Aws::S3::Object}
80
- # * Hash - with `:bucket` and `:key`
81
- # * String - formatted like `"target-bucket-name/target-key"`
82
- #
83
- # @example Basic object copy
84
- #
85
- # bucket = Aws::S3::Bucket.new('source-bucket')
86
- # object = bucket.object('source-key')
87
- #
88
- # # target as String
89
- # object.copy_to('target-bucket/target-key')
90
- #
91
- # # target as Hash
92
- # object.copy_to(bucket: 'target-bucket', key: 'target-key')
93
- #
94
- # # target as Aws::S3::Object
95
- # object.copy_to(bucket.object('target-key'))
96
- #
97
- # @example Managed copy of large objects
98
- #
99
- # # uses multipart upload APIs to copy object
100
- # object.copy_to('src-bucket/src-key', multipart_copy: true)
101
- #
102
- def copy_to(target, options = {})
103
- ObjectCopier.new(self, options).copy_to(target, options)
104
- end
105
-
106
- # Copies and deletes the current object. The object will only be
107
- # deleted if the copy operation succeeds.
108
- # @param (see Object#copy_to)
109
- # @option (see Object#copy_to)
110
- # @return [void]
111
- # @see Object#copy_to
112
- # @see Object#delete
113
- def move_to(target, options = {})
114
- copy_to(target, options)
115
- delete
116
- end
117
-
118
- # Creates a {PresignedPost} that makes it easy to upload a file from
119
- # a web browser direct to Amazon S3 using an HTML post form with
120
- # a file field.
121
- #
122
- # See the {PresignedPost} documentation for more information.
123
- #
124
- # @option (see PresignedPost#initialize)
125
- # @return [PresignedPost]
126
- # @see PresignedPost
127
- def presigned_post(options = {})
128
- PresignedPost.new(
129
- client.config.credentials,
130
- client.config.region,
131
- bucket_name,
132
- {
133
- key: key,
134
- url: bucket.url,
135
- }.merge(options)
136
- )
137
- end
138
-
139
- # Generates a pre-signed URL for this object.
140
- #
141
- # @example Pre-signed GET URL, valid for one hour
142
- #
143
- # obj.presigned_url(:get, expires_in: 3600)
144
- # #=> "https://bucket-name.s3.amazonaws.com/object-key?..."
145
- #
146
- # @example Pre-signed PUT with a canned ACL
147
- #
148
- # # the object uploaded using this URL will be publicly accessible
149
- # obj.presigned_url(:put, acl: 'public-read')
150
- # #=> "https://bucket-name.s3.amazonaws.com/object-key?..."
151
- #
152
- # @param [Symbol] http_method
153
- # The HTTP method to generate a presigned URL for. Valid values
154
- # are `:get`, `:put`, `:head`, and `:delete`.
155
- #
156
- # @param [Hash] params
157
- # Additional request parameters to use when generating the pre-signed
158
- # URL. See the related documentation in {Client} for accepted
159
- # params.
160
- #
161
- # | HTTP Method | Client Method |
162
- # |---------------|------------------------|
163
- # | `:get` | {Client#get_object} |
164
- # | `:put` | {Client#put_object} |
165
- # | `:head` | {Client#head_object} |
166
- # | `:delete` | {Client#delete_object} |
167
- #
168
- # @option params [Boolean] :virtual_host (false) When `true` the
169
- # presigned URL will use the bucket name as a virtual host.
170
- #
171
- # bucket = Aws::S3::Bucket.new('my.bucket.com')
172
- # bucket.object('key').presigned_url(virtual_host: true)
173
- # #=> "http://my.bucket.com/key?..."
174
- #
175
- # @option params [Integer] :expires_in (900) Number of seconds before
176
- # the pre-signed URL expires. This may not exceed one week (604800
177
- # seconds). Note that the pre-signed URL is also only valid as long as
178
- # credentials used to sign it are. For example, when using IAM roles,
179
- # temporary tokens generated for signing also have a default expiration
180
- # which will affect the effective expiration of the pre-signed URL.
181
- #
182
- # @raise [ArgumentError] Raised if `:expires_in` exceeds one week
183
- # (604800 seconds).
184
- #
185
- # @return [String]
186
- #
187
- def presigned_url(http_method, params = {})
188
- presigner = Presigner.new(client: client)
189
- presigner.presigned_url("#{http_method.downcase}_object", params.merge(
190
- bucket: bucket_name,
191
- key: key,
192
- ))
193
- end
194
-
195
- # Returns the public (un-signed) URL for this object.
196
- #
197
- # s3.bucket('bucket-name').object('obj-key').public_url
198
- # #=> "https://bucket-name.s3.amazonaws.com/obj-key"
199
- #
200
- # To use virtual hosted bucket url (disables https):
201
- #
202
- # s3.bucket('my.bucket.com').object('key').public_url(virtual_host: true)
203
- # #=> "http://my.bucket.com/key"
204
- #
205
- # @option options [Boolean] :virtual_host (false) When `true`, the bucket
206
- # name will be used as the host name. This is useful when you have
207
- # a CNAME configured for the bucket.
208
- #
209
- # @return [String]
210
- def public_url(options = {})
211
- url = URI.parse(bucket.url(options))
212
- url.path += '/' unless url.path[-1] == '/'
213
- url.path += key.gsub(/[^\/]+/) { |s| Seahorse::Util.uri_escape(s) }
214
- url.to_s
215
- end
216
-
217
- # Uploads a file from disk to the current object in S3.
218
- #
219
- # # small files are uploaded in a single API call
220
- # obj.upload_file('/path/to/file')
221
- #
222
- # Files larger than `:multipart_threshold` are uploaded using the
223
- # Amazon S3 multipart upload APIs.
224
- #
225
- # # large files are automatically split into parts
226
- # # and the parts are uploaded in parallel
227
- # obj.upload_file('/path/to/very_large_file')
228
- #
229
- # @param [String,Pathname,File,Tempfile] source A file or path to a file
230
- # on the local file system that should be uploaded to this object.
231
- # If you pass an open file object, then it is your responsibility
232
- # to close the file object once the upload completes.
233
- #
234
- # @option options [Integer] :multipart_threshold (15728640) Files larger
235
- # than `:multipart_threshold` are uploaded using the S3 multipart APIs.
236
- # Default threshold is 15MB.
237
- #
238
- # @raise [MultipartUploadError] If an object is being uploaded in
239
- # parts, and the upload can not be completed, then the upload is
240
- # aborted and this error is raised. The raised error has a `#errors`
241
- # method that returns the failures that caused the upload to be
242
- # aborted.
243
- #
244
- # @return [Boolean] Returns `true` when the object is uploaded
245
- # without any errors.
246
- #
247
- def upload_file(source, options = {})
248
- uploader = FileUploader.new(
249
- multipart_threshold: options.delete(:multipart_threshold),
250
- client: client)
251
- uploader.upload(source, options.merge(bucket: bucket_name, key: key))
252
- true
253
- end
254
-
255
- end
256
- end
257
- end
@@ -1,99 +0,0 @@
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
@@ -1,179 +0,0 @@
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: options_for('CreateMultipartUploadRequest'),
157
- upload_part_copy: options_for('UploadPartCopyRequest'),
158
- complete_multipart_upload: options_for('CompleteMultipartUploadRequest'),
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