aws-sdk-s3 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/lib/aws-sdk-s3.rb +66 -0
  3. data/lib/aws-sdk-s3/bucket.rb +595 -0
  4. data/lib/aws-sdk-s3/bucket_acl.rb +168 -0
  5. data/lib/aws-sdk-s3/bucket_cors.rb +146 -0
  6. data/lib/aws-sdk-s3/bucket_lifecycle.rb +164 -0
  7. data/lib/aws-sdk-s3/bucket_logging.rb +142 -0
  8. data/lib/aws-sdk-s3/bucket_notification.rb +187 -0
  9. data/lib/aws-sdk-s3/bucket_policy.rb +138 -0
  10. data/lib/aws-sdk-s3/bucket_region_cache.rb +79 -0
  11. data/lib/aws-sdk-s3/bucket_request_payment.rb +128 -0
  12. data/lib/aws-sdk-s3/bucket_tagging.rb +143 -0
  13. data/lib/aws-sdk-s3/bucket_versioning.rb +188 -0
  14. data/lib/aws-sdk-s3/bucket_website.rb +177 -0
  15. data/lib/aws-sdk-s3/client.rb +3171 -0
  16. data/lib/aws-sdk-s3/client_api.rb +1991 -0
  17. data/lib/aws-sdk-s3/customizations.rb +29 -0
  18. data/lib/aws-sdk-s3/customizations/bucket.rb +127 -0
  19. data/lib/aws-sdk-s3/customizations/multipart_upload.rb +42 -0
  20. data/lib/aws-sdk-s3/customizations/object.rb +257 -0
  21. data/lib/aws-sdk-s3/customizations/object_summary.rb +65 -0
  22. data/lib/aws-sdk-s3/customizations/types/list_object_versions_output.rb +11 -0
  23. data/lib/aws-sdk-s3/encryption.rb +19 -0
  24. data/lib/aws-sdk-s3/encryption/client.rb +369 -0
  25. data/lib/aws-sdk-s3/encryption/decrypt_handler.rb +178 -0
  26. data/lib/aws-sdk-s3/encryption/default_cipher_provider.rb +63 -0
  27. data/lib/aws-sdk-s3/encryption/default_key_provider.rb +38 -0
  28. data/lib/aws-sdk-s3/encryption/encrypt_handler.rb +50 -0
  29. data/lib/aws-sdk-s3/encryption/errors.rb +13 -0
  30. data/lib/aws-sdk-s3/encryption/io_auth_decrypter.rb +50 -0
  31. data/lib/aws-sdk-s3/encryption/io_decrypter.rb +29 -0
  32. data/lib/aws-sdk-s3/encryption/io_encrypter.rb +69 -0
  33. data/lib/aws-sdk-s3/encryption/key_provider.rb +29 -0
  34. data/lib/aws-sdk-s3/encryption/kms_cipher_provider.rb +71 -0
  35. data/lib/aws-sdk-s3/encryption/materials.rb +58 -0
  36. data/lib/aws-sdk-s3/encryption/utils.rb +79 -0
  37. data/lib/aws-sdk-s3/errors.rb +23 -0
  38. data/lib/aws-sdk-s3/file_part.rb +75 -0
  39. data/lib/aws-sdk-s3/file_uploader.rb +58 -0
  40. data/lib/aws-sdk-s3/legacy_signer.rb +186 -0
  41. data/lib/aws-sdk-s3/multipart_file_uploader.rb +187 -0
  42. data/lib/aws-sdk-s3/multipart_upload.rb +287 -0
  43. data/lib/aws-sdk-s3/multipart_upload_error.rb +16 -0
  44. data/lib/aws-sdk-s3/multipart_upload_part.rb +314 -0
  45. data/lib/aws-sdk-s3/object.rb +942 -0
  46. data/lib/aws-sdk-s3/object_acl.rb +214 -0
  47. data/lib/aws-sdk-s3/object_copier.rb +99 -0
  48. data/lib/aws-sdk-s3/object_multipart_copier.rb +179 -0
  49. data/lib/aws-sdk-s3/object_summary.rb +794 -0
  50. data/lib/aws-sdk-s3/object_version.rb +406 -0
  51. data/lib/aws-sdk-s3/plugins/accelerate.rb +92 -0
  52. data/lib/aws-sdk-s3/plugins/bucket_dns.rb +89 -0
  53. data/lib/aws-sdk-s3/plugins/bucket_name_restrictions.rb +23 -0
  54. data/lib/aws-sdk-s3/plugins/dualstack.rb +70 -0
  55. data/lib/aws-sdk-s3/plugins/expect_100_continue.rb +29 -0
  56. data/lib/aws-sdk-s3/plugins/get_bucket_location_fix.rb +23 -0
  57. data/lib/aws-sdk-s3/plugins/http_200_errors.rb +47 -0
  58. data/lib/aws-sdk-s3/plugins/location_constraint.rb +33 -0
  59. data/lib/aws-sdk-s3/plugins/md5s.rb +79 -0
  60. data/lib/aws-sdk-s3/plugins/redirects.rb +41 -0
  61. data/lib/aws-sdk-s3/plugins/s3_signer.rb +208 -0
  62. data/lib/aws-sdk-s3/plugins/sse_cpk.rb +68 -0
  63. data/lib/aws-sdk-s3/plugins/url_encoded_keys.rb +94 -0
  64. data/lib/aws-sdk-s3/presigned_post.rb +647 -0
  65. data/lib/aws-sdk-s3/presigner.rb +160 -0
  66. data/lib/aws-sdk-s3/resource.rb +96 -0
  67. data/lib/aws-sdk-s3/types.rb +5750 -0
  68. data/lib/aws-sdk-s3/waiters.rb +178 -0
  69. metadata +154 -0
@@ -0,0 +1,406 @@
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 ObjectVersion
11
+
12
+ extend Aws::Deprecations
13
+
14
+ # @overload def initialize(bucket_name, object_key, id, options = {})
15
+ # @param [String] bucket_name
16
+ # @param [String] object_key
17
+ # @param [String] id
18
+ # @option options [Client] :client
19
+ # @overload def initialize(options = {})
20
+ # @option options [required, String] :bucket_name
21
+ # @option options [required, String] :object_key
22
+ # @option options [required, String] :id
23
+ # @option options [Client] :client
24
+ def initialize(*args)
25
+ options = Hash === args.last ? args.pop.dup : {}
26
+ @bucket_name = extract_bucket_name(args, options)
27
+ @object_key = extract_object_key(args, options)
28
+ @id = extract_id(args, options)
29
+ @data = options.delete(:data)
30
+ @client = options.delete(:client) || Client.new(options)
31
+ end
32
+
33
+ # @!group Read-Only Attributes
34
+
35
+ # @return [String]
36
+ def bucket_name
37
+ @bucket_name
38
+ end
39
+
40
+ # @return [String]
41
+ def object_key
42
+ @object_key
43
+ end
44
+
45
+ # @return [String]
46
+ def id
47
+ @id
48
+ end
49
+
50
+ # @return [String]
51
+ def etag
52
+ data.etag
53
+ end
54
+
55
+ # Size in bytes of the object.
56
+ # @return [Integer]
57
+ def size
58
+ data.size
59
+ end
60
+
61
+ # The class of storage used to store the object.
62
+ # @return [String]
63
+ def storage_class
64
+ data.storage_class
65
+ end
66
+
67
+ # The object key.
68
+ # @return [String]
69
+ def key
70
+ data.key
71
+ end
72
+
73
+ # Version ID of an object.
74
+ # @return [String]
75
+ def version_id
76
+ data.version_id
77
+ end
78
+
79
+ # Specifies whether the object is (true) or is not (false) the latest
80
+ # version of an object.
81
+ # @return [Boolean]
82
+ def is_latest
83
+ data.is_latest
84
+ end
85
+
86
+ # Date and time the object was last modified.
87
+ # @return [Time]
88
+ def last_modified
89
+ data.last_modified
90
+ end
91
+
92
+ # @return [Types::Owner]
93
+ def owner
94
+ data.owner
95
+ end
96
+
97
+ # @!endgroup
98
+
99
+ # @return [Client]
100
+ def client
101
+ @client
102
+ end
103
+
104
+ # @raise [Errors::ResourceNotLoadable]
105
+ # @api private
106
+ def load
107
+ msg = "#load is not implemented, data only available via enumeration"
108
+ raise Errors::ResourceNotLoadable, msg
109
+ end
110
+ alias :reload :load
111
+
112
+ # @raise [Errors::ResourceNotLoadableError] Raises when {#data_loaded?} is `false`.
113
+ # @return [Types::ObjectVersion]
114
+ # Returns the data for this {ObjectVersion}.
115
+ def data
116
+ load unless @data
117
+ @data
118
+ end
119
+
120
+ # @return [Boolean]
121
+ # Returns `true` if this resource is loaded. Accessing attributes or
122
+ # {#data} on an unloaded resource will trigger a call to {#load}.
123
+ def data_loaded?
124
+ !!@data
125
+ end
126
+
127
+ # @!group Actions
128
+
129
+ # @example Request syntax with placeholder values
130
+ #
131
+ # object_version.delete({
132
+ # mfa: "MFA",
133
+ # request_payer: "requester", # accepts requester
134
+ # })
135
+ # @param [Hash] options ({})
136
+ # @option options [String] :mfa
137
+ # The concatenation of the authentication device's serial number, a
138
+ # space, and the value that is displayed on your authentication device.
139
+ # @option options [String] :request_payer
140
+ # Confirms that the requester knows that she or he will be charged for
141
+ # the request. Bucket owners need not specify this parameter in their
142
+ # requests. Documentation on downloading objects from requester pays
143
+ # buckets can be found at
144
+ # http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
145
+ # @return [Types::DeleteObjectOutput]
146
+ def delete(options = {})
147
+ options = options.merge(
148
+ bucket: @bucket_name,
149
+ key: @object_key,
150
+ version_id: @id
151
+ )
152
+ resp = @client.delete_object(options)
153
+ resp.data
154
+ end
155
+
156
+ # @example Request syntax with placeholder values
157
+ #
158
+ # object_version.get({
159
+ # if_match: "IfMatch",
160
+ # if_modified_since: Time.now,
161
+ # if_none_match: "IfNoneMatch",
162
+ # if_unmodified_since: Time.now,
163
+ # range: "Range",
164
+ # response_cache_control: "ResponseCacheControl",
165
+ # response_content_disposition: "ResponseContentDisposition",
166
+ # response_content_encoding: "ResponseContentEncoding",
167
+ # response_content_language: "ResponseContentLanguage",
168
+ # response_content_type: "ResponseContentType",
169
+ # response_expires: Time.now,
170
+ # sse_customer_algorithm: "SSECustomerAlgorithm",
171
+ # sse_customer_key: "SSECustomerKey",
172
+ # sse_customer_key_md5: "SSECustomerKeyMD5",
173
+ # request_payer: "requester", # accepts requester
174
+ # part_number: 1,
175
+ # })
176
+ # @param [Hash] options ({})
177
+ # @option options [String] :if_match
178
+ # Return the object only if its entity tag (ETag) is the same as the one
179
+ # specified, otherwise return a 412 (precondition failed).
180
+ # @option options [Time,DateTime,Date,Integer,String] :if_modified_since
181
+ # Return the object only if it has been modified since the specified
182
+ # time, otherwise return a 304 (not modified).
183
+ # @option options [String] :if_none_match
184
+ # Return the object only if its entity tag (ETag) is different from the
185
+ # one specified, otherwise return a 304 (not modified).
186
+ # @option options [Time,DateTime,Date,Integer,String] :if_unmodified_since
187
+ # Return the object only if it has not been modified since the specified
188
+ # time, otherwise return a 412 (precondition failed).
189
+ # @option options [String] :range
190
+ # Downloads the specified range bytes of an object. For more information
191
+ # about the HTTP Range header, go to
192
+ # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.
193
+ # @option options [String] :response_cache_control
194
+ # Sets the Cache-Control header of the response.
195
+ # @option options [String] :response_content_disposition
196
+ # Sets the Content-Disposition header of the response
197
+ # @option options [String] :response_content_encoding
198
+ # Sets the Content-Encoding header of the response.
199
+ # @option options [String] :response_content_language
200
+ # Sets the Content-Language header of the response.
201
+ # @option options [String] :response_content_type
202
+ # Sets the Content-Type header of the response.
203
+ # @option options [Time,DateTime,Date,Integer,String] :response_expires
204
+ # Sets the Expires header of the response.
205
+ # @option options [String] :sse_customer_algorithm
206
+ # Specifies the algorithm to use to when encrypting the object (e.g.,
207
+ # AES256).
208
+ # @option options [String] :sse_customer_key
209
+ # Specifies the customer-provided encryption key for Amazon S3 to use in
210
+ # encrypting data. This value is used to store the object and then it is
211
+ # discarded; Amazon does not store the encryption key. The key must be
212
+ # appropriate for use with the algorithm specified in the
213
+ # x-amz-server-side​-encryption​-customer-algorithm header.
214
+ # @option options [String] :sse_customer_key_md5
215
+ # Specifies the 128-bit MD5 digest of the encryption key according to
216
+ # RFC 1321. Amazon S3 uses this header for a message integrity check to
217
+ # ensure the encryption key was transmitted without error.
218
+ # @option options [String] :request_payer
219
+ # Confirms that the requester knows that she or he will be charged for
220
+ # the request. Bucket owners need not specify this parameter in their
221
+ # requests. Documentation on downloading objects from requester pays
222
+ # buckets can be found at
223
+ # http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
224
+ # @option options [Integer] :part_number
225
+ # Part number of the object being read. This is a positive integer
226
+ # between 1 and 10,000. Effectively performs a 'ranged' GET request
227
+ # for the part specified. Useful for downloading just a part of an
228
+ # object.
229
+ # @return [Types::GetObjectOutput]
230
+ def get(options = {})
231
+ options = options.merge(
232
+ bucket: @bucket_name,
233
+ key: @object_key,
234
+ version_id: @id
235
+ )
236
+ resp = @client.get_object(options)
237
+ resp.data
238
+ end
239
+
240
+ # @example Request syntax with placeholder values
241
+ #
242
+ # object_version.head({
243
+ # if_match: "IfMatch",
244
+ # if_modified_since: Time.now,
245
+ # if_none_match: "IfNoneMatch",
246
+ # if_unmodified_since: Time.now,
247
+ # range: "Range",
248
+ # sse_customer_algorithm: "SSECustomerAlgorithm",
249
+ # sse_customer_key: "SSECustomerKey",
250
+ # sse_customer_key_md5: "SSECustomerKeyMD5",
251
+ # request_payer: "requester", # accepts requester
252
+ # part_number: 1,
253
+ # })
254
+ # @param [Hash] options ({})
255
+ # @option options [String] :if_match
256
+ # Return the object only if its entity tag (ETag) is the same as the one
257
+ # specified, otherwise return a 412 (precondition failed).
258
+ # @option options [Time,DateTime,Date,Integer,String] :if_modified_since
259
+ # Return the object only if it has been modified since the specified
260
+ # time, otherwise return a 304 (not modified).
261
+ # @option options [String] :if_none_match
262
+ # Return the object only if its entity tag (ETag) is different from the
263
+ # one specified, otherwise return a 304 (not modified).
264
+ # @option options [Time,DateTime,Date,Integer,String] :if_unmodified_since
265
+ # Return the object only if it has not been modified since the specified
266
+ # time, otherwise return a 412 (precondition failed).
267
+ # @option options [String] :range
268
+ # Downloads the specified range bytes of an object. For more information
269
+ # about the HTTP Range header, go to
270
+ # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.
271
+ # @option options [String] :sse_customer_algorithm
272
+ # Specifies the algorithm to use to when encrypting the object (e.g.,
273
+ # AES256).
274
+ # @option options [String] :sse_customer_key
275
+ # Specifies the customer-provided encryption key for Amazon S3 to use in
276
+ # encrypting data. This value is used to store the object and then it is
277
+ # discarded; Amazon does not store the encryption key. The key must be
278
+ # appropriate for use with the algorithm specified in the
279
+ # x-amz-server-side​-encryption​-customer-algorithm header.
280
+ # @option options [String] :sse_customer_key_md5
281
+ # Specifies the 128-bit MD5 digest of the encryption key according to
282
+ # RFC 1321. Amazon S3 uses this header for a message integrity check to
283
+ # ensure the encryption key was transmitted without error.
284
+ # @option options [String] :request_payer
285
+ # Confirms that the requester knows that she or he will be charged for
286
+ # the request. Bucket owners need not specify this parameter in their
287
+ # requests. Documentation on downloading objects from requester pays
288
+ # buckets can be found at
289
+ # http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
290
+ # @option options [Integer] :part_number
291
+ # Part number of the object being read. This is a positive integer
292
+ # between 1 and 10,000. Effectively performs a 'ranged' HEAD request
293
+ # for the part specified. Useful querying about the size of the part and
294
+ # the number of parts in this object.
295
+ # @return [Types::HeadObjectOutput]
296
+ def head(options = {})
297
+ options = options.merge(
298
+ bucket: @bucket_name,
299
+ key: @object_key,
300
+ version_id: @id
301
+ )
302
+ resp = @client.head_object(options)
303
+ resp.data
304
+ end
305
+
306
+ # @!group Associations
307
+
308
+ # @return [Object]
309
+ def object
310
+ Object.new(
311
+ bucket_name: @bucket_name,
312
+ key: @object_key,
313
+ client: @client
314
+ )
315
+ end
316
+
317
+ # @deprecated
318
+ # @api private
319
+ def identifiers
320
+ {
321
+ bucket_name: @bucket_name,
322
+ object_key: @object_key,
323
+ id: @id
324
+ }
325
+ end
326
+ deprecated(:identifiers)
327
+
328
+ private
329
+
330
+ def extract_bucket_name(args, options)
331
+ value = args[0] || options.delete(:bucket_name)
332
+ case value
333
+ when String then value
334
+ when nil then raise ArgumentError, "missing required option :bucket_name"
335
+ else
336
+ msg = "expected :bucket_name to be a String, got #{value.class}"
337
+ raise ArgumentError, msg
338
+ end
339
+ end
340
+
341
+ def extract_object_key(args, options)
342
+ value = args[1] || options.delete(:object_key)
343
+ case value
344
+ when String then value
345
+ when nil then raise ArgumentError, "missing required option :object_key"
346
+ else
347
+ msg = "expected :object_key to be a String, got #{value.class}"
348
+ raise ArgumentError, msg
349
+ end
350
+ end
351
+
352
+ def extract_id(args, options)
353
+ value = args[2] || options.delete(:id)
354
+ case value
355
+ when String then value
356
+ when nil then raise ArgumentError, "missing required option :id"
357
+ else
358
+ msg = "expected :id to be a String, got #{value.class}"
359
+ raise ArgumentError, msg
360
+ end
361
+ end
362
+
363
+ class Collection < Aws::Resources::Collection
364
+
365
+ # @!group Batch Actions
366
+
367
+ # @example Request syntax with placeholder values
368
+ #
369
+ # object_version.batch_delete!({
370
+ # mfa: "MFA",
371
+ # request_payer: "requester", # accepts requester
372
+ # })
373
+ # @param options ({})
374
+ # @option options [String] :mfa
375
+ # The concatenation of the authentication device's serial number, a
376
+ # space, and the value that is displayed on your authentication device.
377
+ # @option options [String] :request_payer
378
+ # Confirms that the requester knows that she or he will be charged for
379
+ # the request. Bucket owners need not specify this parameter in their
380
+ # requests. Documentation on downloading objects from requester pays
381
+ # buckets can be found at
382
+ # http://docs.aws.amazon.com/AmazonS3/latest/dev/ObjectsinRequesterPaysBuckets.html
383
+ # @return [void]
384
+ def batch_delete!(options = {})
385
+ batch_enum.each do |batch|
386
+ params = Aws::Util.copy_hash(options)
387
+ params[:bucket] = batch[0].bucket_name
388
+ params[:delete] ||= {}
389
+ params[:delete][:objects] ||= []
390
+ batch.each do |item|
391
+ params[:delete][:objects] << {
392
+ key: item.object_key,
393
+ version_id: item.id
394
+ }
395
+ end
396
+ batch[0].client.delete_objects(params)
397
+ end
398
+ nil
399
+ end
400
+
401
+ # @!endgroup
402
+
403
+ end
404
+ end
405
+ end
406
+ end
@@ -0,0 +1,92 @@
1
+ module Aws
2
+ module S3
3
+ module Plugins
4
+
5
+ # Provides support for using `Aws::S3::Client` with Amazon S3 Transfer
6
+ # Acceleration.
7
+ #
8
+ # Go here for more information about transfer acceleration:
9
+ # [http://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html](http://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html)
10
+ class Accelerate < Seahorse::Client::Plugin
11
+
12
+ option(:use_accelerate_endpoint,
13
+ default: false,
14
+ doc_type: 'Boolean',
15
+ docstring: <<-DOCS)
16
+ When set to `true`, accelerated bucket endpoints will be used
17
+ for all object operations. You must first enable accelerate for
18
+ each bucket. [Go here for more information](http://docs.aws.amazon.com/AmazonS3/latest/dev/transfer-acceleration.html).
19
+ DOCS
20
+
21
+ def add_handlers(handlers, config)
22
+ operations = config.api.operation_names - [
23
+ :create_bucket, :list_buckets, :delete_bucket,
24
+ ]
25
+ handlers.add(OptionHandler, step: :initialize, operations: operations)
26
+ handlers.add(AccelerateHandler, step: :build, priority: 0, operations: operations)
27
+ end
28
+
29
+ # @api private
30
+ class OptionHandler < Seahorse::Client::Handler
31
+ def call(context)
32
+ accelerate = context.params.delete(:use_accelerate_endpoint)
33
+ accelerate = context.config.use_accelerate_endpoint if accelerate.nil?
34
+ context[:use_accelerate_endpoint] = accelerate
35
+ @handler.call(context)
36
+ end
37
+ end
38
+
39
+ # @api private
40
+ class AccelerateHandler < Seahorse::Client::Handler
41
+
42
+ def call(context)
43
+ if context[:use_accelerate_endpoint]
44
+ if context[:use_dualstack_endpoint]
45
+ use_combined_accelerate_dualstack_endpoint(context)
46
+ else
47
+ use_accelerate_endpoint(context)
48
+ end
49
+ end
50
+ @handler.call(context)
51
+ end
52
+
53
+ private
54
+
55
+ def use_accelerate_endpoint(context)
56
+ bucket_name = context.params[:bucket]
57
+ validate_bucket_name!(bucket_name)
58
+ endpoint = URI.parse(context.http_request.endpoint.to_s)
59
+ endpoint.scheme = 'https'
60
+ endpoint.port = 443
61
+ endpoint.host = "#{bucket_name}.s3-accelerate.amazonaws.com"
62
+ context.http_request.endpoint = endpoint.to_s
63
+ end
64
+
65
+ def use_combined_accelerate_dualstack_endpoint(context)
66
+ bucket_name = context.params[:bucket]
67
+ validate_bucket_name!(bucket_name)
68
+ endpoint = URI.parse(context.http_request.endpoint.to_s)
69
+ endpoint.scheme = 'https'
70
+ endpoint.port = 443
71
+ endpoint.host = "#{bucket_name}.s3-accelerate.dualstack.amazonaws.com"
72
+ context.http_request.endpoint = endpoint.to_s
73
+ end
74
+
75
+ def validate_bucket_name!(bucket_name)
76
+ unless BucketDns.dns_compatible?(bucket_name, ssl = true)
77
+ msg = "unable to use `accelerate: true` on buckets with "
78
+ msg << "non-DNS compatible names"
79
+ raise ArgumentError, msg
80
+ end
81
+ if bucket_name.include?('.')
82
+ msg = "unable to use `accelerate: true` on buckets with dots"
83
+ msg << "in their name: #{bucket_name.inspect}"
84
+ raise ArgumentError, msg
85
+ end
86
+ end
87
+
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end