azure 0.7.3 → 0.7.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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