azure-storage 0.10.0.preview

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/lib/azure/storage.rb +58 -0
  3. data/lib/azure/storage/autoload.rb +71 -0
  4. data/lib/azure/storage/blob/append.rb +154 -0
  5. data/lib/azure/storage/blob/blob.rb +821 -0
  6. data/lib/azure/storage/blob/blob_service.rb +510 -0
  7. data/lib/azure/storage/blob/block.rb +264 -0
  8. data/lib/azure/storage/blob/container.rb +552 -0
  9. data/lib/azure/storage/blob/page.rb +380 -0
  10. data/lib/azure/storage/blob/serialization.rb +297 -0
  11. data/lib/azure/storage/client.rb +185 -0
  12. data/lib/azure/storage/configurable.rb +137 -0
  13. data/lib/azure/storage/core.rb +33 -0
  14. data/lib/azure/storage/core/auth/shared_access_signature.rb +27 -0
  15. data/lib/azure/storage/core/auth/shared_access_signature_generator.rb +194 -0
  16. data/lib/azure/storage/core/auth/shared_access_signature_signer.rb +49 -0
  17. data/lib/azure/storage/core/auth/shared_key.rb +125 -0
  18. data/lib/azure/storage/core/auth/shared_key_lite.rb +55 -0
  19. data/lib/azure/storage/core/auth/signer.rb +60 -0
  20. data/lib/azure/storage/core/autoload.rb +35 -0
  21. data/lib/azure/storage/core/client_options.rb +334 -0
  22. data/lib/azure/storage/core/client_options_error.rb +39 -0
  23. data/lib/azure/storage/core/constants.rb +1077 -0
  24. data/lib/azure/storage/core/error.rb +47 -0
  25. data/lib/azure/storage/core/filtered_service.rb +54 -0
  26. data/lib/azure/storage/core/http/debug_filter.rb +45 -0
  27. data/lib/azure/storage/core/http/http_error.rb +95 -0
  28. data/lib/azure/storage/core/http/http_filter.rb +62 -0
  29. data/lib/azure/storage/core/http/http_request.rb +182 -0
  30. data/lib/azure/storage/core/http/http_response.rb +105 -0
  31. data/lib/azure/storage/core/http/retry_policy.rb +83 -0
  32. data/lib/azure/storage/core/http/signer_filter.rb +42 -0
  33. data/lib/azure/storage/core/http_client.rb +63 -0
  34. data/lib/azure/storage/core/service.rb +55 -0
  35. data/lib/azure/storage/core/signed_service.rb +54 -0
  36. data/lib/azure/storage/core/sr.rb +83 -0
  37. data/lib/azure/storage/core/utility.rb +254 -0
  38. data/lib/azure/storage/queue/message.rb +39 -0
  39. data/lib/azure/storage/queue/queue.rb +37 -0
  40. data/lib/azure/storage/queue/queue_service.rb +580 -0
  41. data/lib/azure/storage/queue/serialization.rb +113 -0
  42. data/lib/azure/storage/service/access_policy.rb +35 -0
  43. data/lib/azure/storage/service/cors.rb +36 -0
  44. data/lib/azure/storage/service/cors_rule.rb +46 -0
  45. data/lib/azure/storage/service/enumeration_results.rb +30 -0
  46. data/lib/azure/storage/service/logging.rb +45 -0
  47. data/lib/azure/storage/service/metrics.rb +43 -0
  48. data/lib/azure/storage/service/retention_policy.rb +35 -0
  49. data/lib/azure/storage/service/serialization.rb +308 -0
  50. data/lib/azure/storage/service/signed_identifier.rb +39 -0
  51. data/lib/azure/storage/service/storage_service.rb +131 -0
  52. data/lib/azure/storage/service/storage_service_properties.rb +46 -0
  53. data/lib/azure/storage/table/auth/shared_key.rb +68 -0
  54. data/lib/azure/storage/table/auth/shared_key_lite.rb +53 -0
  55. data/lib/azure/storage/table/batch.rb +339 -0
  56. data/lib/azure/storage/table/batch_response.rb +127 -0
  57. data/lib/azure/storage/table/edmtype.rb +136 -0
  58. data/lib/azure/storage/table/entity.rb +40 -0
  59. data/lib/azure/storage/table/guid.rb +33 -0
  60. data/lib/azure/storage/table/query.rb +121 -0
  61. data/lib/azure/storage/table/serialization.rb +117 -0
  62. data/lib/azure/storage/table/table_service.rb +571 -0
  63. data/lib/azure/storage/version.rb +46 -0
  64. metadata +329 -0
@@ -0,0 +1,510 @@
1
+ #-------------------------------------------------------------------------
2
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
3
+ #
4
+ # The MIT License(MIT)
5
+
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files(the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions :
12
+
13
+ # The above copyright notice and this permission notice shall be included in
14
+ # all copies or substantial portions of the Software.
15
+
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ # THE SOFTWARE.
23
+ #--------------------------------------------------------------------------
24
+ require 'base64'
25
+ require 'azure/storage/blob/container'
26
+ require 'azure/storage/blob/blob'
27
+ require 'azure/storage/blob/block'
28
+ require 'azure/storage/blob/page'
29
+ require 'azure/storage/blob/append'
30
+
31
+ module Azure::Storage
32
+ include Service
33
+ module Blob
34
+ class BlobService < StorageService
35
+ include Azure::Storage::Blob
36
+ include Azure::Storage::Blob::Container
37
+
38
+ def initialize(options = {})
39
+ client_config = options[:client] || Azure::Storage
40
+ signer = options[:signer] || Auth::SharedKey.new(
41
+ client_config.storage_account_name,
42
+ client_config.storage_access_key)
43
+ super(signer, client_config.storage_account_name, options)
44
+ @host = client.storage_blob_host
45
+ end
46
+
47
+ def call(method, uri, body=nil, headers={})
48
+ # Force the request.body to the content encoding of specified in the header
49
+ # (content encoding probably shouldn't be used this way)
50
+ if headers && !body.nil?
51
+ if headers['Content-Encoding'].nil?
52
+ Service::StorageService.with_header headers, 'Content-Encoding', body.encoding.to_s
53
+ else
54
+ body.force_encoding(headers['Content-Encoding'])
55
+ end
56
+ end
57
+
58
+ response = super
59
+
60
+ # Force the response.body to the content encoding of specified in the header.
61
+ # content-encoding is echo'd back for the blob and is used to store the encoding of the octet stream
62
+ if !response.nil? && !response.body.nil? && response.headers['content-encoding']
63
+ response.body.force_encoding(response.headers['content-encoding'])
64
+ end
65
+
66
+ response
67
+ end
68
+
69
+ # Public: Get a list of Containers from the server.
70
+ #
71
+ # ==== Attributes
72
+ #
73
+ # * +options+ - Hash. Optional parameters.
74
+ #
75
+ # ==== Options
76
+ #
77
+ # Accepted key/value pairs in options parameter are:
78
+ # * +:prefix+ - String. Filters the results to return only containers
79
+ # whose name begins with the specified prefix. (optional)
80
+ #
81
+ # * +:marker+ - String. An identifier the specifies the portion of the
82
+ # list to be returned. This value comes from the property
83
+ # Azure::Service::EnumerationResults.continuation_token when there
84
+ # are more containers available than were returned. The
85
+ # marker value may then be used here to request the next set
86
+ # of list items. (optional)
87
+ #
88
+ # * +:max_results+ - Integer. Specifies the maximum number of containers to return.
89
+ # If max_results is not specified, or is a value greater than
90
+ # 5,000, the server will return up to 5,000 items. If it is set
91
+ # to a value less than or equal to zero, the server will return
92
+ # status code 400 (Bad Request). (optional)
93
+ #
94
+ # * +:metadata+ - Boolean. Specifies whether or not to return the container metadata.
95
+ # (optional, Default=false)
96
+ #
97
+ # * +:timeout+ - Integer. A timeout in seconds.
98
+ #
99
+ # NOTE: Metadata requested with the :metadata parameter must have been stored in
100
+ # accordance with the naming restrictions imposed by the 2009-09-19 version of the Blob
101
+ # service. Beginning with that version, all metadata names must adhere to the naming
102
+ # conventions for C# identifiers.
103
+ #
104
+ # See: http://msdn.microsoft.com/en-us/library/aa664670(VS.71).aspx
105
+ #
106
+ # Any metadata with invalid names which were previously stored, will be returned with the
107
+ # key "x-ms-invalid-name" in the metadata hash. This may contain multiple values and be an
108
+ # Array (vs a String if it only contains a single value).
109
+ #
110
+ # Returns an Azure::Service::EnumerationResults
111
+ #
112
+ def list_containers(options={})
113
+ query = { }
114
+ if options
115
+ StorageService.with_query query, 'prefix', options[:prefix]
116
+ StorageService.with_query query, 'marker', options[:marker]
117
+ StorageService.with_query query, 'maxresults', options[:max_results].to_s if options[:max_results]
118
+ StorageService.with_query query, 'include', 'metadata' if options[:metadata] == true
119
+ StorageService.with_query query, 'timeout', options[:timeout].to_s if options[:timeout]
120
+ end
121
+
122
+ uri = containers_uri(query)
123
+ response = call(:get, uri)
124
+
125
+ Serialization.container_enumeration_results_from_xml(response.body)
126
+ end
127
+
128
+ # Protected: Establishes an exclusive write lock on a container or a blob. The lock duration can be 15 to 60 seconds, or can be infinite.
129
+ # To write to a locked container or blob, a client must provide a lease ID.
130
+ #
131
+ # ==== Attributes
132
+ #
133
+ # * +container+ - String. The container name.
134
+ # * +blob+ - String. The blob name.
135
+ # * +options+ - Hash. Optional parameters.
136
+ #
137
+ # ==== Options
138
+ #
139
+ # Accepted key/value pairs in options parameter are:
140
+ # * +:duration+ - Integer. Default -1. Specifies the duration of the lease, in seconds, or negative one (-1)
141
+ # for a lease that never expires. A non-infinite lease can be between 15 and 60 seconds. (optional)
142
+ # * +:proposed_lease_id+ - String. Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request)
143
+ # if the proposed lease ID is not in the correct format. (optional)
144
+ # * +:timeout+ - Integer. A timeout in seconds.
145
+ # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to acquire the lease
146
+ # only if the blob has been modified since the specified date/time. If the blob has not been modified,
147
+ # the Blob service returns status code 412 (Precondition Failed).
148
+ # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to acquire the lease
149
+ # only if the blob has not been modified since the specified date/time. If the blob has been modified,
150
+ # the Blob service returns status code 412 (Precondition Failed).
151
+ # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to acquire the lease
152
+ # only if the blob's ETag value matches the value specified. If the values do not match,
153
+ # the Blob service returns status code 412 (Precondition Failed).
154
+ # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to acquire the lease
155
+ # only if the blob's ETag value does not match the value specified. If the values are identical,
156
+ # the Blob service returns status code 412 (Precondition Failed).
157
+ #
158
+ # See http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx
159
+ #
160
+ # Returns a String of the new unique lease id. While the lease is active, you must include the lease ID with any request
161
+ # to write, or to renew, change, or release the lease.
162
+ #
163
+ protected
164
+ def acquire_lease(container, blob, options={})
165
+ query = { 'comp' => 'lease' }
166
+ Service::StorageService.with_query query, 'timeout', options[:timeout].to_s if options[:timeout]
167
+
168
+ if blob
169
+ uri = blob_uri(container, blob, query)
170
+ else
171
+ uri = container_uri(container, query)
172
+ end
173
+
174
+ duration = -1
175
+ duration = options[:duration] if options[:duration]
176
+
177
+ headers = Service::StorageService.service_properties_headers
178
+ Service::StorageService.with_header headers, 'x-ms-lease-action', 'acquire'
179
+ Service::StorageService.with_header headers, 'x-ms-lease-duration', duration.to_s if duration
180
+ Service::StorageService.with_header headers, 'x-ms-proposed-lease-id', options[:proposed_lease_id]
181
+ add_blob_conditional_headers options, headers
182
+
183
+ response = call(:put, uri, nil, headers)
184
+ response.headers['x-ms-lease-id']
185
+ end
186
+
187
+ # Protected: Renews the lease. The lease can be renewed if the lease ID specified on the request matches that
188
+ # associated with the blob. Note that the lease may be renewed even if it has expired as long as the container or blob
189
+ # has not been modified or leased again since the expiration of that lease. When you renew a lease, the
190
+ # lease duration clock resets.
191
+ #
192
+ # ==== Attributes
193
+ #
194
+ # * +container+ - String. The container name.
195
+ # * +blob+ - String. The blob name.
196
+ # * +lease+ - String. The lease id
197
+ # * +options+ - Hash. Optional parameters.
198
+ #
199
+ # ==== Options
200
+ #
201
+ # Accepted key/value pairs in options parameter are:
202
+ # * +:timeout+ - Integer. A timeout in seconds.
203
+ # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to renew the lease
204
+ # only if the blob has been modified since the specified date/time. If the blob has not been modified,
205
+ # the Blob service returns status code 412 (Precondition Failed).
206
+ # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to renew the lease
207
+ # only if the blob has not been modified since the specified date/time. If the blob has been modified,
208
+ # the Blob service returns status code 412 (Precondition Failed).
209
+ # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to renew the lease
210
+ # only if the blob's ETag value matches the value specified. If the values do not match,
211
+ # the Blob service returns status code 412 (Precondition Failed).
212
+ # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to renew the lease
213
+ # only if the blob's ETag value does not match the value specified. If the values are identical,
214
+ # the Blob service returns status code 412 (Precondition Failed).
215
+ #
216
+ # See http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx
217
+ #
218
+ # Returns the renewed lease id
219
+ #
220
+ protected
221
+ def renew_lease(container, blob, lease, options={})
222
+ query = { 'comp' => 'lease' }
223
+ Service::StorageService.with_query query, 'timeout', options[:timeout].to_s if options[:timeout]
224
+
225
+ if blob
226
+ uri = blob_uri(container, blob, query)
227
+ else
228
+ uri = container_uri(container, query)
229
+ end
230
+
231
+ headers = Service::StorageService.service_properties_headers
232
+ Service::StorageService.with_header headers, 'x-ms-lease-action', 'renew'
233
+ Service::StorageService.with_header headers, 'x-ms-lease-id', lease
234
+ add_blob_conditional_headers options, headers
235
+
236
+ response = call(:put, uri, nil, headers)
237
+ response.headers['x-ms-lease-id']
238
+ end
239
+
240
+ # Protected: Change the ID of an existing lease.
241
+ #
242
+ # ==== Attributes
243
+ #
244
+ # * +container+ - String. The container name.
245
+ # * +blob+ - String. The blob name.
246
+ # * +lease+ - String. The existing lease id.
247
+ # * +proposed_lease+ - String. Proposed lease ID, in a GUID string format. The Blob service returns 400 (Invalid request)
248
+ # if the proposed lease ID is not in the correct format. (optional).
249
+ # * +options+ - Hash. Optional parameters.
250
+ #
251
+ # ==== Options
252
+ #
253
+ # Accepted key/value pairs in options parameter are:
254
+ # * +:timeout+ - Integer. A timeout in seconds.
255
+ # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to change the lease
256
+ # only if the blob has been modified since the specified date/time. If the blob has not been modified,
257
+ # the Blob service returns status code 412 (Precondition Failed).
258
+ # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to change the lease
259
+ # only if the blob has not been modified since the specified date/time. If the blob has been modified,
260
+ # the Blob service returns status code 412 (Precondition Failed).
261
+ # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to change the lease
262
+ # only if the blob's ETag value matches the value specified. If the values do not match,
263
+ # the Blob service returns status code 412 (Precondition Failed).
264
+ # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to change the lease
265
+ # only if the blob's ETag value does not match the value specified. If the values are identical,
266
+ # the Blob service returns status code 412 (Precondition Failed).
267
+ #
268
+ # See http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx
269
+ #
270
+ # Returns a String of the new unique lease id. While the lease is active, you must include the lease ID with any request
271
+ # to write, or to renew, change, or release the lease.
272
+ #
273
+ protected
274
+ def change_lease(container, blob, lease, proposed_lease, options={})
275
+ query = { 'comp' => 'lease' }
276
+ Service::StorageService.with_query query, 'timeout', options[:timeout].to_s if options[:timeout]
277
+
278
+ if blob
279
+ uri = blob_uri(container, blob, query)
280
+ else
281
+ uri = container_uri(container, query)
282
+ end
283
+
284
+ headers = Service::StorageService.service_properties_headers
285
+ Service::StorageService.with_header headers, 'x-ms-lease-action', 'change'
286
+ Service::StorageService.with_header headers, 'x-ms-lease-id', lease
287
+ Service::StorageService.with_header headers, 'x-ms-proposed-lease-id', proposed_lease
288
+ add_blob_conditional_headers options, headers
289
+
290
+ response = call(:put, uri, nil, headers)
291
+ response.headers['x-ms-lease-id']
292
+ end
293
+
294
+ # Protected: Releases the lease. The lease may be released if the lease ID specified on the request matches that
295
+ # associated with the container or blob. Releasing the lease allows another client to immediately acquire the lease for
296
+ # the container or blob as soon as the release is complete.
297
+ #
298
+ # ==== Attributes
299
+ #
300
+ # * +container+ - String. The container name.
301
+ # * +blob+ - String. The blob name.
302
+ # * +lease+ - String. The lease id.
303
+ # * +options+ - Hash. Optional parameters.
304
+ #
305
+ # ==== Options
306
+ #
307
+ # Accepted key/value pairs in options parameter are:
308
+ # * +:timeout+ - Integer. A timeout in seconds.
309
+ # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to release the lease
310
+ # only if the blob has been modified since the specified date/time. If the blob has not been modified,
311
+ # the Blob service returns status code 412 (Precondition Failed).
312
+ # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to release the lease
313
+ # only if the blob has not been modified since the specified date/time. If the blob has been modified,
314
+ # the Blob service returns status code 412 (Precondition Failed).
315
+ # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to release the lease
316
+ # only if the blob's ETag value matches the value specified. If the values do not match,
317
+ # the Blob service returns status code 412 (Precondition Failed).
318
+ # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to release the lease
319
+ # only if the blob's ETag value does not match the value specified. If the values are identical,
320
+ # the Blob service returns status code 412 (Precondition Failed).
321
+ #
322
+ # See http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx
323
+ #
324
+ # Returns nil on success
325
+ #
326
+ protected
327
+ def release_lease(container, blob, lease, options={})
328
+ query = { 'comp' => 'lease' }
329
+ Service::StorageService.with_query query, 'timeout', options[:timeout].to_s if options[:timeout]
330
+
331
+ if blob
332
+ uri = blob_uri(container, blob, query)
333
+ else
334
+ uri = container_uri(container, query)
335
+ end
336
+
337
+ headers = Service::StorageService.service_properties_headers
338
+ Service::StorageService.with_header headers, 'x-ms-lease-action', 'release'
339
+ Service::StorageService.with_header headers, 'x-ms-lease-id', lease
340
+ add_blob_conditional_headers options, headers
341
+
342
+ call(:put, uri, nil, headers)
343
+ nil
344
+ end
345
+
346
+ # Protected: Breaks the lease, if the container or blob has an active lease. Once a lease is broken, it cannot be renewed. Any
347
+ # authorized request can break the lease; the request is not required to specify a matching lease ID. When a
348
+ # lease is broken, the lease break period is allowed to elapse, during which time no lease operation except
349
+ # break and release can be performed on the container or blob. When a lease is successfully broken, the response indicates
350
+ # the interval in seconds until a new lease can be acquired.
351
+ #
352
+ # A lease that has been broken can also be released, in which case another client may immediately acquire the
353
+ # lease on the container or blob.
354
+ #
355
+ # ==== Attributes
356
+ #
357
+ # * +container+ - String. The container name.
358
+ # * +blob+ - String. The blob name.
359
+ # * +options+ - Hash. Optional parameters.
360
+ #
361
+ # ==== Options
362
+ #
363
+ # Accepted key/value pairs in options parameter are:
364
+ # * +:break_period+ - Integer. The proposed duration of seconds that the lease should continue before it is
365
+ # broken, between 0 and 60 seconds. This break period is only used if it is shorter than
366
+ # the time remaining on the lease. If longer, the time remaining on the lease is used. A
367
+ # new lease will not be available before the break period has expired, but the lease may
368
+ # be held for longer than the break period.
369
+ #
370
+ # If this option is not used, a fixed-duration lease breaks after the remaining lease
371
+ # period elapses, and an infinite lease breaks immediately.
372
+ # * +:timeout+ - Integer. A timeout in seconds.
373
+ # * +:if_modified_since+ - String. A DateTime value. Specify this conditional header to acquire the lease
374
+ # only if the blob has been modified since the specified date/time. If the blob has not been modified,
375
+ # the Blob service returns status code 412 (Precondition Failed).
376
+ # * +:if_unmodified_since+ - String. A DateTime value. Specify this conditional header to acquire the lease
377
+ # only if the blob has not been modified since the specified date/time. If the blob has been modified,
378
+ # the Blob service returns status code 412 (Precondition Failed).
379
+ # * +:if_match+ - String. An ETag value. Specify an ETag value for this conditional header to acquire the lease
380
+ # only if the blob's ETag value matches the value specified. If the values do not match,
381
+ # the Blob service returns status code 412 (Precondition Failed).
382
+ # * +:if_none_match+ - String. An ETag value. Specify an ETag value for this conditional header to acquire the lease
383
+ # only if the blob's ETag value does not match the value specified. If the values are identical,
384
+ # the Blob service returns status code 412 (Precondition Failed).
385
+ #
386
+ # See http://msdn.microsoft.com/en-us/library/azure/ee691972.aspx
387
+ #
388
+ # Returns an Integer of the remaining lease time. This value is the approximate time remaining in the lease
389
+ # period, in seconds. This header is returned only for a successful request to break the lease. If the break
390
+ # is immediate, 0 is returned.
391
+ #
392
+ protected
393
+ def break_lease(container, blob, options={})
394
+ query = { 'comp' => 'lease' }
395
+ Service::StorageService.with_query query, 'timeout', options[:timeout].to_s if options[:timeout]
396
+
397
+ if blob
398
+ uri = blob_uri(container, blob, query)
399
+ else
400
+ uri = container_uri(container, query)
401
+ end
402
+
403
+ headers = Service::StorageService.service_properties_headers
404
+ Service::StorageService.with_header headers, 'x-ms-lease-action', 'break'
405
+ Service::StorageService.with_header headers, 'x-ms-lease-break-period', options[:break_period].to_s if options[:break_period]
406
+ add_blob_conditional_headers options, headers
407
+
408
+ response = call(:put, uri, nil, headers)
409
+ response.headers['x-ms-lease-time'].to_i
410
+ end
411
+
412
+ # Protected: Generate the URI for the collection of containers.
413
+ #
414
+ # ==== Attributes
415
+ #
416
+ # * +query+ - A Hash of key => value query parameters.
417
+ #
418
+ # Returns a URI.
419
+ #
420
+ protected
421
+ def containers_uri(query={})
422
+ query = { 'comp' => 'list' }.merge(query)
423
+ generate_uri('/', query)
424
+ end
425
+
426
+ # Protected: Generate the URI for a specific container.
427
+ #
428
+ # ==== Attributes
429
+ #
430
+ # * +name+ - The container name. If this is a URI, we just return this.
431
+ # * +query+ - A Hash of key => value query parameters.
432
+ #
433
+ # Returns a URI.
434
+ #
435
+ protected
436
+ def container_uri(name, query={})
437
+ return name if name.kind_of? ::URI
438
+ query = { 'restype' => 'container' }.merge(query)
439
+ generate_uri(name, query)
440
+ end
441
+
442
+ # Protected: Generate the URI for a specific Blob.
443
+ #
444
+ # ==== Attributes
445
+ #
446
+ # * +container_name+ - String representing the name of the container.
447
+ # * +blob_name+ - String representing the name of the blob.
448
+ # * +query+ - A Hash of key => value query parameters.
449
+ #
450
+ # Returns a URI.
451
+ #
452
+ protected
453
+ def blob_uri(container_name, blob_name, query={})
454
+ if container_name.nil? || container_name.empty?
455
+ path = blob_name
456
+ else
457
+ path = File.join(container_name, blob_name)
458
+ end
459
+
460
+ path = CGI.escape(path.encode('UTF-8'))
461
+
462
+ # Unencode the forward slashes to match what the server expects.
463
+ path = path.gsub(/%2F/, '/')
464
+ # Unencode the backward slashes to match what the server expects.
465
+ path = path.gsub(/%5C/, '/')
466
+ # Re-encode the spaces (encoded as space) to the % encoding.
467
+ path = path.gsub(/\+/, '%20')
468
+
469
+ generate_uri(path, query)
470
+ end
471
+
472
+ # Adds conditional header with required condition
473
+ #
474
+ # headers - A Hash of HTTP headers
475
+ # options - A Hash of condition name/value pairs
476
+ #
477
+ protected
478
+ def add_blob_conditional_headers(options, headers)
479
+ return unless options
480
+
481
+ # Common conditional headers for blobs: https://msdn.microsoft.com/en-us/library/azure/dd179371.aspx
482
+ Service::StorageService.with_header headers, 'If-Modified-Since', options[:if_modified_since]
483
+ Service::StorageService.with_header headers, 'If-Unmodified-Since', options[:if_unmodified_since]
484
+ Service::StorageService.with_header headers, 'If-Match', options[:if_match]
485
+ Service::StorageService.with_header headers, 'If-None-Match', options[:if_none_match]
486
+
487
+ # Conditional headers for copying blob
488
+ Service::StorageService.with_header headers, 'If-Modified-Since', options[:dest_if_modified_since]
489
+ Service::StorageService.with_header headers, 'If-Unmodified-Since', options[:dest_if_unmodified_since]
490
+ Service::StorageService.with_header headers, 'If-Match', options[:dest_if_match]
491
+ Service::StorageService.with_header headers, 'If-None-Match', options[:dest_if_none_match]
492
+ Service::StorageService.with_header headers, 'x-ms-source-if-modified-since', options[:source_if_modified_since]
493
+ Service::StorageService.with_header headers, 'x-ms-source-if-unmodified-since', options[:source_if_unmodified_since]
494
+ Service::StorageService.with_header headers, 'x-ms-source-if-match', options[:source_if_match]
495
+ Service::StorageService.with_header headers, 'x-ms-source-if-none-match', options[:source_if_none_match]
496
+
497
+ # Conditional headers for page blob
498
+ Service::StorageService.with_header headers, 'x-ms-if-sequence-number-le', options[:if_sequence_number_le]
499
+ Service::StorageService.with_header headers, 'x-ms-if-sequence-number-lt', options[:if_sequence_number_lt]
500
+ Service::StorageService.with_header headers, 'x-ms-if-sequence-number-eq', options[:if_sequence_number_eq]
501
+
502
+ # Conditional headers for append blob
503
+ Service::StorageService.with_header headers, 'x-ms-blob-condition-maxsize', options[:max_size]
504
+ Service::StorageService.with_header headers, 'x-ms-blob-condition-appendpos', options[:append_position]
505
+ end
506
+ end
507
+ end
508
+ end
509
+
510
+ Azure::Storage::BlobService = Azure::Storage::Blob::BlobService