azure-storage-common 1.1.0 → 2.0.4

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.
Files changed (60) hide show
  1. checksums.yaml +5 -5
  2. data/lib/azure/core/auth/authorizer.rb +36 -0
  3. data/lib/azure/core/auth/shared_key.rb +125 -0
  4. data/lib/azure/core/auth/shared_key_lite.rb +48 -0
  5. data/lib/azure/core/auth/signer.rb +51 -0
  6. data/lib/azure/core/default.rb +23 -0
  7. data/lib/azure/core/error.rb +21 -0
  8. data/lib/azure/core/filtered_service.rb +45 -0
  9. data/lib/azure/core/http/debug_filter.rb +36 -0
  10. data/lib/azure/core/http/http_error.rb +135 -0
  11. data/lib/azure/core/http/http_filter.rb +53 -0
  12. data/lib/azure/core/http/http_request.rb +195 -0
  13. data/lib/azure/core/http/http_response.rb +102 -0
  14. data/lib/azure/core/http/retry_policy.rb +84 -0
  15. data/lib/azure/core/http/signer_filter.rb +33 -0
  16. data/lib/azure/core/service.rb +46 -0
  17. data/lib/azure/core/signed_service.rb +45 -0
  18. data/lib/azure/core/utility.rb +244 -0
  19. data/lib/azure/core/version.rb +33 -0
  20. data/lib/azure/core.rb +47 -0
  21. data/lib/azure/http_response_helper.rb +38 -0
  22. data/lib/azure/storage/common/autoload.rb +62 -61
  23. data/lib/azure/storage/common/client.rb +162 -162
  24. data/lib/azure/storage/common/client_options.rb +363 -363
  25. data/lib/azure/storage/common/client_options_error.rb +41 -41
  26. data/lib/azure/storage/common/configurable.rb +212 -212
  27. data/lib/azure/storage/common/core/auth/anonymous_signer.rb +43 -43
  28. data/lib/azure/storage/common/core/auth/shared_access_signature.rb +30 -30
  29. data/lib/azure/storage/common/core/auth/shared_access_signature_generator.rb +399 -352
  30. data/lib/azure/storage/common/core/auth/shared_access_signature_signer.rb +57 -57
  31. data/lib/azure/storage/common/core/auth/shared_key.rb +60 -60
  32. data/lib/azure/storage/common/core/auth/token_signer.rb +43 -43
  33. data/lib/azure/storage/common/core/autoload.rb +53 -53
  34. data/lib/azure/storage/common/core/error.rb +43 -43
  35. data/lib/azure/storage/common/core/filter/exponential_retry_filter.rb +64 -64
  36. data/lib/azure/storage/common/core/filter/linear_retry_filter.rb +55 -55
  37. data/lib/azure/storage/common/core/filter/retry_filter.rb +300 -300
  38. data/lib/azure/storage/common/core/http_client.rb +82 -69
  39. data/lib/azure/storage/common/core/sr.rb +85 -85
  40. data/lib/azure/storage/common/core/token_credential.rb +64 -64
  41. data/lib/azure/storage/common/core/utility.rb +261 -255
  42. data/lib/azure/storage/common/core.rb +35 -35
  43. data/lib/azure/storage/common/default.rb +868 -868
  44. data/lib/azure/storage/common/service/access_policy.rb +37 -37
  45. data/lib/azure/storage/common/service/cors.rb +38 -38
  46. data/lib/azure/storage/common/service/cors_rule.rb +48 -48
  47. data/lib/azure/storage/common/service/enumeration_results.rb +32 -32
  48. data/lib/azure/storage/common/service/geo_replication.rb +40 -40
  49. data/lib/azure/storage/common/service/logging.rb +47 -47
  50. data/lib/azure/storage/common/service/metrics.rb +45 -45
  51. data/lib/azure/storage/common/service/retention_policy.rb +37 -37
  52. data/lib/azure/storage/common/service/serialization.rb +335 -335
  53. data/lib/azure/storage/common/service/signed_identifier.rb +40 -40
  54. data/lib/azure/storage/common/service/storage_service.rb +322 -322
  55. data/lib/azure/storage/common/service/storage_service_properties.rb +48 -48
  56. data/lib/azure/storage/common/service/storage_service_stats.rb +39 -39
  57. data/lib/azure/storage/common/service/user_delegation_key.rb +50 -0
  58. data/lib/azure/storage/common/version.rb +49 -49
  59. data/lib/azure/storage/common.rb +26 -26
  60. metadata +85 -17
@@ -0,0 +1,195 @@
1
+ #-------------------------------------------------------------------------
2
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #--------------------------------------------------------------------------
15
+ require 'digest/md5'
16
+ require 'base64'
17
+ require 'net/http'
18
+ require 'time'
19
+ require 'tempfile'
20
+
21
+ require 'azure/core/version'
22
+ require 'azure/core/http/http_response'
23
+ require 'azure/core/http/retry_policy'
24
+ require 'azure/core/default'
25
+ require 'azure/http_response_helper'
26
+
27
+ module Azure
28
+ module Core
29
+ module Http
30
+ # Represents a HTTP request can perform synchronous queries to a
31
+ # HTTP server, returning a HttpResponse
32
+ class HttpRequest
33
+ include Azure::HttpResponseHelper
34
+ alias_method :_method, :method
35
+
36
+ # The HTTP method to use (:get, :post, :put, :delete, etc...)
37
+ attr_accessor :method
38
+
39
+ # The URI of the HTTP endpoint to query
40
+ attr_accessor :uri
41
+
42
+ # The header values as a Hash
43
+ attr_accessor :headers
44
+
45
+ # The body of the request (IO or String)
46
+ attr_accessor :body
47
+
48
+ # Azure client which contains configuration context and http agents
49
+ # @return [Azure::Client]
50
+ attr_accessor :client
51
+
52
+ # The http filter
53
+ attr_accessor :has_retry_filter
54
+
55
+ # Public: Create the HttpRequest
56
+ #
57
+ # @param method [Symbol] The HTTP method to use (:get, :post, :put, :del, etc...)
58
+ # @param uri [URI] The URI of the HTTP endpoint to query
59
+ # @param options_or_body [Hash|IO|String] The request options including {:client, :body} or raw body only
60
+ def initialize(method, uri, options_or_body = {})
61
+ options ||= unless options_or_body.is_a?(Hash)
62
+ {body: options_or_body}
63
+ end || options_or_body || {}
64
+
65
+ @method = method
66
+ @uri = if uri.is_a?(String)
67
+ URI.parse(uri)
68
+ else
69
+ uri
70
+ end
71
+
72
+ @client = options[:client] || Azure
73
+
74
+ self.headers = default_headers(options[:current_time] || Time.now.httpdate).merge(options[:headers] || {})
75
+ self.body = options[:body]
76
+ end
77
+
78
+ # Public: Applies a HttpFilter to the HTTP Pipeline
79
+ #
80
+ # filter - Any object that responds to .call(req, _next) and
81
+ # returns a HttpResponse eg. HttpFilter, Proc,
82
+ # lambda, etc. (optional)
83
+ #
84
+ # options - The options that are used when call Azure::Core::FilteredService.call.
85
+ # It can be used by retry policies to determine changes in the retry.
86
+ #
87
+ # &block - An inline block may be used instead of a filter
88
+ #
89
+ # example:
90
+ #
91
+ # request.with_filter do |req, _next|
92
+ # _next.call
93
+ # end
94
+ #
95
+ # NOTE:
96
+ #
97
+ # The code block provided must call _next or the filter pipeline
98
+ # will not complete and the HTTP request will never execute
99
+ #
100
+ def with_filter(filter=nil, options={}, &block)
101
+ filter = filter || block
102
+ if filter
103
+ is_retry_policy = filter.is_a?(Azure::Core::Http::RetryPolicy)
104
+ filter.retry_data[:request_options] = options if is_retry_policy
105
+ @has_retry_filter ||= is_retry_policy
106
+
107
+ original_call = self._method(:call)
108
+
109
+ # support 1.8.7 (define_singleton_method doesn't exist until 1.9.1)
110
+ filter_call = Proc.new do
111
+ filter.call(self, original_call)
112
+ end
113
+ k = class << self;
114
+ self;
115
+ end
116
+ if k.method_defined? :define_singleton_method
117
+ self.define_singleton_method(:call, filter_call)
118
+ else
119
+ k.send(:define_method, :call, filter_call)
120
+ end
121
+ end
122
+ end
123
+
124
+ # Build a default headers Hash
125
+ def default_headers(current_time)
126
+ {}.tap do |def_headers|
127
+ def_headers['User-Agent'] = Azure::Core::Default::USER_AGENT
128
+ def_headers['x-ms-date'] = current_time
129
+ def_headers['x-ms-version'] = '2014-02-14'
130
+ def_headers['DataServiceVersion'] = '1.0;NetFx'
131
+ def_headers['MaxDataServiceVersion'] = '3.0;NetFx'
132
+ def_headers['Content-Type'] = 'application/atom+xml; charset=utf-8'
133
+ end
134
+ end
135
+
136
+ def http_setup
137
+ @client.agents(uri)
138
+ end
139
+
140
+ def body=(body)
141
+ @body = body
142
+ apply_body_headers
143
+ end
144
+
145
+ # Sends request to HTTP server and returns a HttpResponse
146
+ #
147
+ # @return [HttpResponse]
148
+ def call
149
+ conn = http_setup
150
+ res = set_up_response(method.to_sym, uri, conn, headers ,body)
151
+
152
+ response = HttpResponse.new(res)
153
+ response.uri = uri
154
+ raise response.error if !response.success? && !@has_retry_filter
155
+ response
156
+ end
157
+
158
+ private
159
+
160
+ def apply_body_headers
161
+ return headers['Content-Length'] = '0' unless body
162
+
163
+ return apply_io_headers if IO === body || Tempfile === body
164
+ return apply_string_io_headers if StringIO === body
165
+ return apply_miscellaneous_headers
166
+ end
167
+
168
+ def apply_io_headers
169
+ headers['Content-Length'] = body.size.to_s if body.respond_to?('size')
170
+ if headers['Content-Length'].nil?
171
+ raise ArgumentError, '\'Content-Length\' must be defined if size cannot be obtained from body IO.'
172
+ end
173
+ headers['Content-MD5'] = Digest::MD5.file(body.path).base64digest unless headers['Content-MD5']
174
+ end
175
+
176
+ def apply_string_io_headers
177
+ headers['Content-Length'] = body.size.to_s
178
+ unless headers['Content-MD5']
179
+ headers['Content-MD5'] = Digest::MD5.new.tap do |checksum|
180
+ while chunk = body.read(5242880)
181
+ checksum << chunk
182
+ end
183
+ body.rewind
184
+ end.base64digest
185
+ end
186
+ end
187
+
188
+ def apply_miscellaneous_headers
189
+ headers['Content-Length'] = body.size.to_s
190
+ headers['Content-MD5'] = Base64.strict_encode64(Digest::MD5.digest(body.to_s)) unless headers['Content-MD5']
191
+ end
192
+ end
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,102 @@
1
+ #-------------------------------------------------------------------------
2
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #--------------------------------------------------------------------------
15
+ require 'azure/core/http/http_error'
16
+
17
+ module Azure
18
+ module Core
19
+ module Http
20
+ # A small proxy to clean up the API of Net::HTTPResponse.
21
+ class HttpResponse
22
+ # Public: Initialize a new response.
23
+ #
24
+ # http_response - A Net::HTTPResponse.
25
+ def initialize(http_response, uri='')
26
+ @http_response = http_response
27
+ @uri = uri
28
+ end
29
+
30
+ attr_accessor :uri
31
+
32
+ # Public: Get the response body.
33
+ #
34
+ # Returns a String.
35
+ def body
36
+ @http_response.body
37
+ end
38
+
39
+ # Public: Get the response status code.
40
+ #
41
+ # Returns a Fixnum.
42
+ def status_code
43
+ @http_response.status
44
+ end
45
+
46
+ # Public: Get the response reason phrase.
47
+ #
48
+ # Returns a String.
49
+ def reason_phrase
50
+ @http_response.reason_phrase
51
+ end
52
+
53
+ # Public: Check if this response was successful. A request is considered
54
+ # successful if the response is in the 200 - 399 range.
55
+ #
56
+ # Returns nil|false.
57
+ def success?
58
+ @http_response.success?
59
+ end
60
+
61
+ # Public: Get all the response headers as a Hash.
62
+ #
63
+ # Returns a Hash.
64
+ def headers
65
+ @http_response.headers
66
+ end
67
+
68
+ # Public: Get an error that wraps this HTTP response, as long as this
69
+ # response was unsuccessful. This method will return nil if the
70
+ # response was successful.
71
+ #
72
+ # Returns an Azure::Core::Http::HTTPError.
73
+ def exception
74
+ HTTPError.new(self) unless success?
75
+ end
76
+
77
+ alias_method :error, :exception
78
+
79
+ # TODO: This needs to be deleted and HttpError needs to be refactored to not rely on HttpResponse.
80
+ # The dependency on knowing the internal structure of HttpResponse breaks good design principles.
81
+ # The only reason this class exists is because the HttpError parses the HttpResponse to produce an error msg.
82
+ class MockResponse
83
+ def initialize(code, body, headers)
84
+ @status = code
85
+ @body = body
86
+ @headers = headers
87
+ @headers.each { |k,v|
88
+ @headers[k] = [v] unless v.respond_to? 'first'
89
+ }
90
+ end
91
+ attr_accessor :status
92
+ attr_accessor :body
93
+ attr_accessor :headers
94
+
95
+ def to_hash
96
+ @headers
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,84 @@
1
+ #-------------------------------------------------------------------------
2
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #--------------------------------------------------------------------------
15
+ require "azure/core/http/http_filter"
16
+
17
+ module Azure
18
+ module Core
19
+ module Http
20
+
21
+ # A HttpFilter implementation that handles retrying based on a
22
+ # specific policy when HTTP layer errors occur
23
+ class RetryPolicy < HttpFilter
24
+
25
+ def initialize(&block)
26
+ @block = block
27
+ @retry_data = {}
28
+ end
29
+
30
+ attr_accessor :retry_data
31
+
32
+ # Overrides the base class implementation of call to implement
33
+ # a retry loop that uses should_retry? to determine when to
34
+ # break the loop
35
+ #
36
+ # req - HttpRequest. The HTTP request
37
+ # _next - HttpFilter. The next filter in the pipeline
38
+ def call(req, _next)
39
+ response = nil
40
+ retry_data = @retry_data.dup
41
+ begin
42
+ # URI could change in the retry, e.g. secondary endpoint
43
+ unless retry_data[:uri].nil?
44
+ req.uri = retry_data[:uri]
45
+ end
46
+
47
+ retry_data[:error] = nil
48
+ response = _next.call
49
+ rescue
50
+ retry_data[:error] = $!
51
+ end while should_retry?(response, retry_data)
52
+
53
+ # Assign the error when HTTP error is not thrown from the previous filter
54
+ retry_data[:error] = response.error if response && !response.success?
55
+ if retry_data[:error].nil?
56
+ response
57
+ else
58
+ raise retry_data[:error]
59
+ end
60
+ end
61
+
62
+ # Determines if the HTTP request should continue retrying
63
+ #
64
+ # response - HttpResponse. The response from the active request
65
+ # retry_data - Hash. Stores stateful retry data
66
+ #
67
+ # The retry_data is a Hash which can be used to store
68
+ # stateful data about the request execution context (such as an
69
+ # incrementing counter, timestamp, etc). The retry_data object
70
+ # will be the same instance throughout the lifetime of the request.
71
+ #
72
+ # If an inline block was passed to the constructor, that block
73
+ # will be used here and should return true to retry the job, or
74
+ # false to stop exit. If an inline block was not passed to the
75
+ # constructor the method returns false.
76
+ #
77
+ # Alternatively, a subclass could override this method.
78
+ def should_retry?(response, retry_data)
79
+ @block ? @block.call(response, retry_data) : false
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,33 @@
1
+ #-------------------------------------------------------------------------
2
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #--------------------------------------------------------------------------
15
+ require 'azure/core/http/http_filter'
16
+
17
+ module Azure
18
+ module Core
19
+ module Http
20
+ # A HttpFilter implementation that creates a authorization signature which is added to the request headers
21
+ class SignerFilter < HttpFilter
22
+ def initialize(signer)
23
+ @signer = signer
24
+ end
25
+
26
+ def call(req, _next)
27
+ @signer.sign_request(req)
28
+ _next.call
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,46 @@
1
+ #-------------------------------------------------------------------------
2
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #--------------------------------------------------------------------------
15
+ require 'azure/core/http/http_request'
16
+
17
+ module Azure
18
+ module Core
19
+ # A base class for Service implementations
20
+ class Service
21
+
22
+ # Create a new instance of the Service
23
+ #
24
+ # @param host [String] The hostname. (optional, Default empty)
25
+ # @param options [Hash] options including {:client} (optional, Default {})
26
+ def initialize(host='', options = {})
27
+ @host = host
28
+ @client = options[:client] || Azure
29
+ end
30
+
31
+ attr_accessor :host, :client
32
+
33
+ def call(method, uri, body=nil, headers={})
34
+ request = Core::Http::HttpRequest.new(method, uri, body: body, headers: headers, client: @client)
35
+ yield request if block_given?
36
+ request.call
37
+ end
38
+
39
+ def generate_uri(path='', query={})
40
+ uri = URI.parse(File.join(host, path))
41
+ uri.query = URI.encode_www_form(query) unless query == nil or query.empty?
42
+ uri
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,45 @@
1
+ #-------------------------------------------------------------------------
2
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #--------------------------------------------------------------------------
15
+ require 'azure/core/filtered_service'
16
+ require 'azure/core/http/signer_filter'
17
+ require 'azure/core/auth/shared_key'
18
+
19
+ module Azure
20
+ module Core
21
+ # A base class for Service implementations
22
+ class SignedService < FilteredService
23
+
24
+ # Create a new instance of the SignedService
25
+ #
26
+ # @param signer [Azure::Core::Auth::Signer]. An implementation of Signer used for signing requests. (optional, Default=Azure::Core::Auth::SharedKey.new)
27
+ # @param account_name [String] The account name (optional, Default=Azure.config.storage_account_name)
28
+ # @param options [Hash] options
29
+ def initialize(signer=nil, account_name=nil, options={})
30
+ super('', options)
31
+ signer ||= Core::Auth::SharedKey.new(client.storage_account_name, client.storage_access_key)
32
+ @account_name = account_name || client.storage_account_name
33
+ @signer = signer
34
+ filters.unshift Core::Http::SignerFilter.new(signer) if signer
35
+ end
36
+
37
+ attr_accessor :account_name
38
+ attr_accessor :signer
39
+
40
+ def call(method, uri, body=nil, headers=nil, options={})
41
+ super(method, uri, body, headers, options)
42
+ end
43
+ end
44
+ end
45
+ end