azure 0.7.3 → 0.7.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.
@@ -1,51 +0,0 @@
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 'openssl'
16
- require 'base64'
17
-
18
- module Azure
19
- module Core
20
- module Auth
21
- # Utility class to sign strings with HMAC-256 and then encode the
22
- # signed string using Base64.
23
- class Signer
24
- # The access key for the account
25
- attr :access_key
26
-
27
- # Initialize the Signer.
28
- #
29
- # @param access_key [String] The access_key encoded in Base64.
30
- def initialize(access_key)
31
- if access_key.nil?
32
- raise ArgumentError, 'Signing key must be provided'
33
- end
34
-
35
- @access_key = Base64.strict_decode64(access_key)
36
- end
37
-
38
- # Generate an HMAC signature.
39
- #
40
- # @param body [String] The string to sign.
41
- #
42
- # @return [String] a Base64 String signed with HMAC.
43
- def sign(body)
44
- signed = OpenSSL::HMAC.digest('sha256', access_key, body)
45
- Base64.strict_encode64(signed)
46
- end
47
-
48
- end
49
- end
50
- end
51
- end
@@ -1,21 +0,0 @@
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
- module Azure
16
- module Core
17
- # Superclass for errors generated from this library, so people can
18
- # just rescue this for generic error handling
19
- class Error < StandardError;end
20
- end
21
- end
@@ -1,45 +0,0 @@
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/service'
16
-
17
- module Azure
18
- module Core
19
- # A base class for Service implementations
20
- class FilteredService < Service
21
-
22
- # Create a new instance of the FilteredService
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
- super
28
- @filters = []
29
- end
30
-
31
- attr_accessor :filters
32
-
33
- def call(method, uri, body=nil, headers=nil)
34
- super(method, uri, body, headers) do |request|
35
- filters.each { |filter| request.with_filter filter } if filters
36
- end
37
- end
38
-
39
- def with_filter(filter=nil, &block)
40
- filter = filter || block
41
- filters.push filter if filter
42
- end
43
- end
44
- end
45
- end
@@ -1,36 +0,0 @@
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 displays information about the request and response for debugging
21
- class DebugFilter < HttpFilter
22
- def call(req, _next)
23
- puts "--REQUEST-BEGIN---------------------------"
24
- puts "method:", req.method, "uri:", req.uri, "headers:", req.headers, "body:", req.body
25
- puts "--REQUEST-END---------------------------"
26
-
27
- r = _next.call
28
- puts "--RESPONSE-BEGIN---------------------------"
29
- puts "status_code:", r.status_code, "headers:", r.headers, "body:", r.body
30
- puts "--RESPONSE-END---------------------------"
31
- r
32
- end
33
- end
34
- end
35
- end
36
- end
@@ -1,86 +0,0 @@
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/error'
16
-
17
- module Azure
18
- module Core
19
- module Http
20
- # Public: Class for handling all HTTP response errors
21
- class HTTPError < Azure::Core::Error
22
-
23
- attr :uri
24
-
25
- # Public: The HTTP status code of this error
26
- #
27
- # Returns a Fixnum
28
- attr :status_code
29
-
30
- # Public: The type of error
31
- #
32
- # http://msdn.microsoft.com/en-us/library/azure/dd179357
33
- #
34
- # Returns a String
35
- attr :type
36
-
37
- # Public: Description of the error
38
- #
39
- # Returns a String
40
- attr :description
41
-
42
- # Public: Detail of the error
43
- #
44
- # Returns a String
45
- attr :detail
46
-
47
- # Public: Initialize an error
48
- #
49
- # http_response - An Azure::Core::HttpResponse
50
- def initialize(http_response)
51
- @http_response = http_response
52
- @uri = http_response.uri
53
- @status_code = http_response.status_code
54
- parse_response
55
- super("#{type} (#{status_code}): #{description}")
56
- end
57
-
58
- # Extract the relevant information from the response's body. If the response
59
- # body is not an XML, we return an 'Unknown' error with the entire body as
60
- # the description
61
- #
62
- # Returns nothing
63
- def parse_response
64
- if @http_response.body && @http_response.body.include?('<')
65
-
66
- document = Nokogiri.Slop(@http_response.body)
67
-
68
- @type = document.css('code').first.text if document.css('code').any?
69
- @type = document.css('Code').first.text if document.css('Code').any?
70
- @description = document.css('message').first.text if document.css('message').any?
71
- @description = document.css('Message').first.text if document.css('Message').any?
72
-
73
- # service bus uses detail instead of message
74
- @detail = document.css('detail').first.text if document.css('detail').any?
75
- @detail = document.css('Detail').first.text if document.css('Detail').any?
76
- else
77
- @type = 'Unknown'
78
- if @http_response.body
79
- @description = "#{@http_response.body.strip}"
80
- end
81
- end
82
- end
83
- end
84
- end
85
- end
86
- end
@@ -1,53 +0,0 @@
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
- module Azure
16
- module Core
17
- module Http
18
- # A filter which can modify the HTTP pipeline both before and
19
- # after requests/responses. Multiple filters can be nested in a
20
- # "Russian Doll" model to create a compound HTTP pipeline
21
- class HttpFilter
22
-
23
- # Initialize a HttpFilter
24
- #
25
- # &block - An inline block which implements the filter.
26
- #
27
- # The inline block should take parameters |request, _next| where
28
- # request is a HttpRequest and _next is an object that implements
29
- # a method .call which returns an HttpResponse. The block passed
30
- # to the constructor should also return HttpResponse, either as
31
- # the result of calling _next.call or by customized logic.
32
- #
33
- def initialize(&block)
34
- @block = block
35
- end
36
-
37
- # Executes the filter
38
- #
39
- # request - HttpRequest. The request
40
- # _next - An object that implements .call (no params)
41
- #
42
- # NOTE: _next is a either a subsequent HttpFilter wrapped in a
43
- # closure, or the HttpRequest object's call method. Either way,
44
- # it must have it's .call method executed within each filter to
45
- # complete the pipeline. _next.call should return an HttpResponse
46
- # and so should this Filter.
47
- def call(request, _next)
48
- @block ? @block.call(request, _next) : _next.call
49
- end
50
- end
51
- end
52
- end
53
- end
@@ -1,162 +0,0 @@
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
-
20
- require 'azure/version'
21
- require 'azure/core/http/http_response'
22
-
23
- module Azure
24
- module Core
25
- module Http
26
- # Represents a HTTP request can perform synchronous queries to a
27
- # HTTP server, returning a HttpResponse
28
- class HttpRequest
29
- include Azure::HttpResponseHelper
30
- alias_method :_method, :method
31
-
32
- # The HTTP method to use (:get, :post, :put, :delete, etc...)
33
- attr_accessor :method
34
-
35
- # The URI of the HTTP endpoint to query
36
- attr_accessor :uri
37
-
38
- # The header values as a Hash
39
- attr_accessor :headers
40
-
41
- # The body of the request (IO or String)
42
- attr_accessor :body
43
-
44
- # Azure client which contains configuration context and http agents
45
- # @return [Azure::Client]
46
- attr_accessor :client
47
-
48
- # Public: Create the HttpRequest
49
- #
50
- # @param method [Symbol] The HTTP method to use (:get, :post, :put, :del, etc...)
51
- # @param uri [URI] The URI of the HTTP endpoint to query
52
- # @param options_or_body [Hash|IO|String] The request options including {:client, :body} or raw body only
53
- def initialize(method, uri, options_or_body = {})
54
- options ||= unless options_or_body.is_a?(Hash)
55
- {body: options_or_body}
56
- end || options_or_body || {}
57
-
58
- @method = method
59
- @uri = if uri.is_a?(String)
60
- URI.parse(uri)
61
- else
62
- uri
63
- end
64
-
65
- @client = options[:client] || Azure
66
-
67
- self.headers = default_headers(options[:current_time] || Time.now.httpdate).merge(options[:headers] || {})
68
- self.body = options[:body]
69
- end
70
-
71
- # Public: Applies a HttpFilter to the HTTP Pipeline
72
- #
73
- # filter - Any object that responds to .call(req, _next) and
74
- # returns a HttpResponse eg. HttpFilter, Proc,
75
- # lambda, etc. (optional)
76
- #
77
- # &block - An inline block may be used instead of a filter
78
- #
79
- # example:
80
- #
81
- # request.with_filter do |req, _next|
82
- # _next.call
83
- # end
84
- #
85
- # NOTE:
86
- #
87
- # The code block provided must call _next or the filter pipeline
88
- # will not complete and the HTTP request will never execute
89
- #
90
- def with_filter(filter=nil, &block)
91
- filter = filter || block
92
- if filter
93
- old_impl = self._method(:call)
94
-
95
- # support 1.8.7 (define_singleton_method doesn't exist until 1.9.1)
96
- new_impl = Proc.new do
97
- filter.call(self, old_impl)
98
- end
99
- k = class << self;
100
- self;
101
- end
102
- if k.method_defined? :define_singleton_method
103
- self.define_singleton_method(:call, new_impl)
104
- else
105
- k.send(:define_method, :call, new_impl)
106
- end
107
- end
108
- end
109
-
110
- # Build a default headers Hash
111
- def default_headers(current_time)
112
- {}.tap do |def_headers|
113
- def_headers['User-Agent'] = Azure::Default::USER_AGENT
114
- def_headers['x-ms-date'] = current_time
115
- def_headers['x-ms-version'] = '2014-02-14'
116
- def_headers['DataServiceVersion'] = '1.0;NetFx'
117
- def_headers['MaxDataServiceVersion'] = '2.0;NetFx'
118
- def_headers['Content-Type'] = 'application/atom+xml; charset=utf-8'
119
- end
120
- end
121
-
122
- def http_setup
123
- @client.agents(uri)
124
- end
125
-
126
- def body=(body)
127
- @body = body
128
- apply_body_headers
129
- end
130
-
131
- # Sends request to HTTP server and returns a HttpResponse
132
- #
133
- # @return [HttpResponse]
134
- def call
135
- conn = http_setup
136
- res = set_up_response(method.to_sym, uri, conn, headers ,body)
137
- response = HttpResponse.new(res)
138
- response.uri = uri
139
- raise response.error unless response.success?
140
- response
141
- end
142
-
143
- private
144
-
145
- def apply_body_headers
146
- if body
147
- if IO === body
148
- headers['Content-Length'] = body.size.to_s
149
- headers['Content-MD5'] = Digest::MD5.file(body.path).base64digest
150
- else
151
- headers['Content-Length'] = body.bytesize.to_s
152
- headers['Content-MD5'] = Base64.strict_encode64(Digest::MD5.digest(body))
153
- end
154
- else
155
- headers['Content-Length'] = '0'
156
- end
157
- end
158
-
159
- end
160
- end
161
- end
162
- end
@@ -1,96 +0,0 @@
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
-
23
- # Public: Initialize a new response.
24
- #
25
- # http_response - A Net::HTTPResponse.
26
- def initialize(http_response, uri='')
27
- @http_response = http_response
28
- @uri = uri
29
- end
30
-
31
- attr_accessor :uri
32
-
33
- # Public: Get the response body.
34
- #
35
- # Returns a String.
36
- def body
37
- @http_response.body
38
- end
39
-
40
- # Public: Get the response status code.
41
- #
42
- # Returns a Fixnum.
43
- def status_code
44
- @http_response.status
45
- end
46
-
47
- # Public: Check if this response was successful. A request is considered
48
- # successful if the response is in the 200 - 399 range.
49
- #
50
- # Returns nil|false.
51
- def success?
52
- @http_response.success?
53
- end
54
-
55
- # Public: Get all the response headers as a Hash.
56
- #
57
- # Returns a Hash.
58
- def headers
59
- @http_response.headers
60
- end
61
-
62
- # Public: Get an error that wraps this HTTP response, as long as this
63
- # response was unsuccessful. This method will return nil if the
64
- # response was successful.
65
- #
66
- # Returns an Azure::Core::Http::HTTPError.
67
- def exception
68
- HTTPError.new(self) unless success?
69
- end
70
-
71
- alias_method :error, :exception
72
-
73
- # TODO: This needs to be deleted and HttpError needs to be refactored to not rely on HttpResponse.
74
- # The dependency on knowing the internal structure of HttpResponse breaks good design principles.
75
- # The only reason this class exists is because the HttpError parses the HttpResponse to produce an error msg.
76
- class MockResponse
77
- def initialize(code, body, headers)
78
- @status = code
79
- @body = body
80
- @headers = headers
81
- @headers.each { |k,v|
82
- @headers[k] = [v] unless v.respond_to? first
83
- }
84
- end
85
- attr_accessor :status
86
- attr_accessor :body
87
- attr_accessor :headers
88
-
89
- def to_hash
90
- @headers
91
- end
92
- end
93
- end
94
- end
95
- end
96
- end
@@ -1,74 +0,0 @@
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
- end
28
-
29
- attr_accessor :retry_data
30
-
31
- # Overrides the base class implementation of call to implement
32
- # a retry loop that uses should_retry? to determine when to
33
- # break the loop
34
- #
35
- # req - HttpRequest. The HTTP request
36
- # _next - HttpFilter. The next filter in the pipeline
37
- def call(req, _next)
38
- retry_data = {}
39
- response = nil
40
- begin
41
- response = _next.call
42
- rescue
43
- retry_data[:error] = $!
44
- end while should_retry?(response, retry_data)
45
- if retry_data.has_key?(:error)
46
- raise retry_data[:error]
47
- else
48
- response
49
- end
50
- end
51
-
52
- # Determines if the HTTP request should continue retrying
53
- #
54
- # response - HttpResponse. The response from the active request
55
- # retry_data - Hash. Stores stateful retry data
56
- #
57
- # The retry_data is a Hash which can be used to store
58
- # stateful data about the request execution context (such as an
59
- # incrementing counter, timestamp, etc). The retry_data object
60
- # will be the same instance throughout the lifetime of the request.
61
- #
62
- # If an inline block was passed to the constructor, that block
63
- # will be used here and should return true to retry the job, or
64
- # false to stop exit. If an inline block was not passed to the
65
- # constructor the method returns false.
66
- #
67
- # Alternatively, a subclass could override this method.
68
- def should_retry?(response, retry_data)
69
- @block ? @block.call(response, retry_data) : false
70
- end
71
- end
72
- end
73
- end
74
- end
@@ -1,33 +0,0 @@
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