resource_accessor 1.1.1 → 1.2.0
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.
- checksums.yaml +4 -4
- data/CHANGES +5 -1
- data/README.md +13 -1
- data/lib/resource_accessor/resource_accessor.rb +17 -16
- data/lib/resource_accessor/version.rb +1 -1
- data/spec/gateway.rb +68 -0
- data/spec/gateway_spec.rb +16 -92
- data/spec/resource_accessor_spec.rb +20 -8
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4960ccbbb27df69a3854814ceabe214ac8df1db
|
4
|
+
data.tar.gz: 95a5e556ed7578ec209e64f8eb990f2f4dcd6686
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c284b9bf41355ecc21da3f33074f24579bc046740ff201af4d85cf4101eae4562fa61447cdf88e570e0a471db63801bef186cdbf97ad4b2b6f6bb4691cf6a9da
|
7
|
+
data.tar.gz: 5e5d853984783360508491f8f3b72179736f14961264248310fea33a843059fb8939e07263fcd5e8402b4626255145615d40e195a2595908fc7a011b072d6fb2
|
data/CHANGES
CHANGED
data/README.md
CHANGED
@@ -43,6 +43,7 @@ response = accessor.get_response :url => some_url, :method => :post, :cookie =>
|
|
43
43
|
response = accessor.get_response :url => some_url, :method => :post, :cookie => cookie,
|
44
44
|
:body => some_string
|
45
45
|
```
|
46
|
+
|
46
47
|
You have to specify HTTP method explicitly here (post).
|
47
48
|
|
48
49
|
If you want to get AJAX resource, add special header to the request or use special method:
|
@@ -69,6 +70,18 @@ response = accessor.get_response {:url => some_url}, {'Content-Type" => "applica
|
|
69
70
|
response2 = accessor.get_json_response :url => some_url
|
70
71
|
```
|
71
72
|
|
73
|
+
If you want to provide additional parameters in GET call, use **query** parameter:
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
response = accessor.get_response :url => some_url, :query => {:param1 => 'p1', :param2 => 'p2'}
|
77
|
+
```
|
78
|
+
|
79
|
+
or
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
response = accessor.get_response :url => "#{some_url?param1=p1¶m2=p2}"
|
83
|
+
```
|
84
|
+
|
72
85
|
You can setup timeout for your accessor object in milliseconds:
|
73
86
|
|
74
87
|
```ruby
|
@@ -82,7 +95,6 @@ accessor.validate_ssl_cert = true
|
|
82
95
|
accessor.ca_file = 'your cert file location'
|
83
96
|
```
|
84
97
|
|
85
|
-
|
86
98
|
## Contributing
|
87
99
|
|
88
100
|
1. Fork it
|
@@ -4,6 +4,8 @@ require 'cgi'
|
|
4
4
|
class ResourceAccessor
|
5
5
|
attr_accessor :timeout, :ca_file, :validate_ssl_cert
|
6
6
|
|
7
|
+
alias validate_ssl_cert? validate_ssl_cert
|
8
|
+
|
7
9
|
def initialize timeout = 10000, ca_file = nil, validate_ssl_cert = false
|
8
10
|
@timeout = timeout
|
9
11
|
@ca_file = ca_file
|
@@ -11,7 +13,7 @@ class ResourceAccessor
|
|
11
13
|
end
|
12
14
|
|
13
15
|
def get_response params, headers = {}
|
14
|
-
locate_response(params[:url], params[:method], headers, params[:body], params[:cookie])
|
16
|
+
locate_response(params[:url], params[:query], params[:method], headers, params[:body], params[:cookie])
|
15
17
|
end
|
16
18
|
|
17
19
|
def get_soap_response params, headers = {}
|
@@ -19,19 +21,19 @@ class ResourceAccessor
|
|
19
21
|
headers["SOAPAction"] = "" unless headers["SOAPAction"]
|
20
22
|
headers["Content-Type"] = "text/xml;charset=UTF-8" unless headers["Content-Type"]
|
21
23
|
|
22
|
-
locate_response(params[:url], params[:method], headers, params[:body], params[:cookie])
|
24
|
+
locate_response(params[:url], params[:query], params[:method], headers, params[:body], params[:cookie])
|
23
25
|
end
|
24
26
|
|
25
27
|
def get_ajax_response params, headers = {}
|
26
28
|
headers['X-Requested-With'] = 'XMLHttpRequest'
|
27
29
|
|
28
|
-
locate_response(params[:url], params[:method], headers, params[:body], params[:cookie])
|
30
|
+
locate_response(params[:url], params[:query], params[:method], headers, params[:body], params[:cookie])
|
29
31
|
end
|
30
32
|
|
31
33
|
def get_json_response params, headers = {}
|
32
34
|
headers["Content-Type"] = "application/json;charset=UTF-8"
|
33
35
|
|
34
|
-
locate_response(params[:url], params[:method], headers, params[:body], params[:cookie])
|
36
|
+
locate_response(params[:url], params[:query], params[:method], headers, params[:body], params[:cookie])
|
35
37
|
end
|
36
38
|
|
37
39
|
def get_cookie url, user_name, password
|
@@ -44,16 +46,16 @@ class ResourceAccessor
|
|
44
46
|
response.response['set-cookie']
|
45
47
|
end
|
46
48
|
|
47
|
-
def query_from_hash(params)
|
48
|
-
return
|
49
|
+
def self.query_from_hash(params)
|
50
|
+
return nil if params.nil? or params.empty?
|
49
51
|
|
50
|
-
params.sort.map {|
|
52
|
+
params.sort.map {|key, value| "#{key}=#{value.nil? ? '' : CGI.escape(value)}"}.join("&")
|
51
53
|
end
|
52
54
|
|
53
55
|
private
|
54
56
|
|
55
|
-
def locate_response url, method, headers, body, cookie=nil
|
56
|
-
response = execute_request url, method, headers, body, cookie
|
57
|
+
def locate_response url, query, method, headers, body, cookie=nil
|
58
|
+
response = execute_request url, query, method, headers, body, cookie
|
57
59
|
|
58
60
|
if response.class == Net::HTTPMovedPermanently
|
59
61
|
response = execute_request response['location'], method, headers, body, cookie
|
@@ -62,15 +64,18 @@ class ResourceAccessor
|
|
62
64
|
response
|
63
65
|
end
|
64
66
|
|
65
|
-
def execute_request url, method, headers, body, cookie=nil
|
66
|
-
headers["User-Agent"] = "Ruby/#{RUBY_VERSION}
|
67
|
+
def execute_request url, query, method, headers, body, cookie=nil
|
68
|
+
headers["User-Agent"] = "Ruby/#{RUBY_VERSION}" unless headers["User-Agent"]
|
67
69
|
headers["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8" unless headers["Content-Type"]
|
68
70
|
|
69
71
|
if cookie
|
70
72
|
headers['Cookie'] = cookie
|
71
73
|
end
|
72
74
|
|
73
|
-
|
75
|
+
query_string = ResourceAccessor.query_from_hash(query)
|
76
|
+
new_url = query_string.nil? ? url : "#{url}?#{query_string}"
|
77
|
+
|
78
|
+
uri = URI.parse(URI.escape(new_url))
|
74
79
|
|
75
80
|
connection = Net::HTTP.new(uri.host, uri.port)
|
76
81
|
|
@@ -110,8 +115,4 @@ class ResourceAccessor
|
|
110
115
|
end
|
111
116
|
end
|
112
117
|
|
113
|
-
def validate_ssl_cert?
|
114
|
-
validate_ssl_cert
|
115
|
-
end
|
116
|
-
|
117
118
|
end
|
data/spec/gateway.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
require 'resource_accessor'
|
3
|
+
|
4
|
+
GatewayError = Class.new(Exception)
|
5
|
+
|
6
|
+
class Gateway
|
7
|
+
include Log4r
|
8
|
+
|
9
|
+
attr_accessor :accessor, :logger
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@accessor = ResourceAccessor.new
|
13
|
+
@accessor.timeout = 30
|
14
|
+
|
15
|
+
@logger = Logger.new 'my_logger'
|
16
|
+
#@logger.outputters = Outputter.stdout
|
17
|
+
end
|
18
|
+
|
19
|
+
def bad_response? response
|
20
|
+
response.class == Net::HTTPNotFound or (response.kind_of?(Net::HTTPOK) and !!(response.body =~/error/))
|
21
|
+
end
|
22
|
+
|
23
|
+
def get params = {}, headers = {}
|
24
|
+
with_exception_handler(params, headers) do |params, headers|
|
25
|
+
@accessor.get_response(params, headers)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def post params = {}, headers = {}
|
30
|
+
with_exception_handler(params, headers) do |params, headers|
|
31
|
+
@accessor.get_response(params.merge(:method => :post), headers)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def soap_post params = {}, headers = {}
|
36
|
+
with_exception_handler(params, headers) do |params, headers|
|
37
|
+
response = @accessor.get_soap_response(params.merge(:method => :post), headers)
|
38
|
+
|
39
|
+
logger.debug "#{params[:body]}" if params[:body]
|
40
|
+
|
41
|
+
response
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def with_exception_handler params, headers, &code
|
46
|
+
params[:url] = @url unless params[:url]
|
47
|
+
|
48
|
+
begin
|
49
|
+
response = code.call(params, headers)
|
50
|
+
|
51
|
+
if bad_response?(response)
|
52
|
+
log.error(response, "#{self.class.name} failed with #{response.code}:#{response.message}\n#{response.body}")
|
53
|
+
|
54
|
+
raise GatewayError, "#{response.code} #{response.message}\n#{response.body}\n(URL: '#{params[:url]}')"
|
55
|
+
else
|
56
|
+
logger.info("Got #{response.code} response from #{self.class.name} Service")
|
57
|
+
end
|
58
|
+
|
59
|
+
response
|
60
|
+
rescue GatewayError
|
61
|
+
raise
|
62
|
+
rescue Exception => e
|
63
|
+
logger.error("#{self.class.name} received error: #{e}")
|
64
|
+
|
65
|
+
raise GatewayError, "Error: #{e} (URL: '#{params[:url]}')"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/spec/gateway_spec.rb
CHANGED
@@ -1,77 +1,14 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
require 'resource_accessor'
|
6
|
-
require 'log4r'
|
7
|
-
|
8
|
-
class Gateway
|
9
|
-
include Log4r
|
10
|
-
|
11
|
-
attr_accessor :accessor, :logger
|
12
|
-
|
13
|
-
def initialize
|
14
|
-
@accessor = ResourceAccessor.new
|
15
|
-
@accessor.timeout = 30
|
16
|
-
|
17
|
-
@logger = Logger.new 'my_logger'
|
18
|
-
#@logger.outputters = Outputter.stdout
|
19
|
-
end
|
20
|
-
|
21
|
-
def bad_response? response
|
22
|
-
response.class == Net::HTTPNotFound or (response.kind_of?(Net::HTTPSuccess) and !!(response.body =~/error/))
|
23
|
-
end
|
24
|
-
|
25
|
-
def get params = {}, headers = {}
|
26
|
-
with_exception_handler(params, headers) do |params, headers|
|
27
|
-
@accessor.get_response(params, headers)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def post params = {}, headers = {}
|
32
|
-
with_exception_handler(params, headers) do |params, headers|
|
33
|
-
@accessor.get_response(params.merge(:method => :post), headers)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def soap_post params = {}, headers = {}
|
38
|
-
with_exception_handler(params, headers) do |params, headers|
|
39
|
-
response = @accessor.get_soap_response(params.merge(:method => :post), headers)
|
40
|
-
|
41
|
-
logger.debug "#{params[:body]}" if params[:body]
|
42
|
-
|
43
|
-
response
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def with_exception_handler params, headers, &code
|
48
|
-
begin
|
49
|
-
response = code.call(params, headers)
|
50
|
-
|
51
|
-
if bad_response?(response)
|
52
|
-
log.error(response, "#{self.class.name} failed with #{response.code}:#{response.message}\n#{response.body}")
|
53
|
-
|
54
|
-
raise GatewayError, "#{response.code} #{response.message}\n#{response.body}\n(URL: '#{params[:url]}')"
|
55
|
-
else
|
56
|
-
logger.info("Got #{response.code} response from #{self.class.name} Service")
|
57
|
-
end
|
58
|
-
rescue GatewayError
|
59
|
-
raise
|
60
|
-
rescue Exception => e
|
61
|
-
logger.error("#{self.class.name} received error: #{e}")
|
62
|
-
|
63
|
-
raise GatewayError, "Error: #{e} (URL: '#{params[:url]}')"
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
3
|
+
require 'gateway'
|
67
4
|
|
68
5
|
describe Gateway do
|
69
6
|
let(:some_https_url) { "https://somehost.com" }
|
70
7
|
|
71
8
|
let(:simple_response) do
|
72
|
-
|
73
|
-
|
74
|
-
|
9
|
+
response = Net::HTTPSuccess.new "1.1", "200", "success"
|
10
|
+
response.stubs(:stream_check => '')
|
11
|
+
response
|
75
12
|
end
|
76
13
|
|
77
14
|
it "uses certificate file and OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT as verify mode if validate_ssl_cert is on" do
|
@@ -82,8 +19,7 @@ describe Gateway do
|
|
82
19
|
Net::HTTP.any_instance.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT)
|
83
20
|
Net::HTTP.any_instance.expects(:ca_file=).with('some_ca_file')
|
84
21
|
|
85
|
-
|
86
|
-
Net::HTTP.any_instance.stubs(:request).returns(stub_everything(:kind_of? => true))
|
22
|
+
Net::HTTP.any_instance.stubs(:request => stub_everything)
|
87
23
|
|
88
24
|
subject.get(:url => some_https_url)
|
89
25
|
end
|
@@ -96,15 +32,13 @@ describe Gateway do
|
|
96
32
|
Net::HTTP.any_instance.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
|
97
33
|
Net::HTTP.any_instance.expects(:ca_file=).with('some_ca_file').never
|
98
34
|
|
99
|
-
|
100
|
-
Net::HTTP.any_instance.stubs(:request).returns(stub_everything(:kind_of? => true))
|
35
|
+
Net::HTTP.any_instance.stubs(:request => stub_everything)
|
101
36
|
|
102
37
|
subject.get(:url => some_https_url)
|
103
38
|
end
|
104
39
|
|
105
40
|
it "logs error and raises exception if response is bad" do
|
106
|
-
|
107
|
-
Net::HTTP.any_instance.expects(:request).returns(simple_response)
|
41
|
+
Net::HTTP.any_instance.expects(:request => simple_response)
|
108
42
|
|
109
43
|
subject.stubs(:bad_response? => true)
|
110
44
|
|
@@ -116,9 +50,7 @@ describe Gateway do
|
|
116
50
|
end
|
117
51
|
|
118
52
|
it "should set content type to text/xml for soap post request" do
|
119
|
-
Net::HTTP.any_instance.expects(:request
|
120
|
-
|
121
|
-
Timeout.expects(:timeout).yields
|
53
|
+
Net::HTTP.any_instance.expects(:request => simple_response)
|
122
54
|
|
123
55
|
params = {:url => some_https_url}
|
124
56
|
headers = {}
|
@@ -129,13 +61,8 @@ describe Gateway do
|
|
129
61
|
end
|
130
62
|
|
131
63
|
it "should set content type to application/x-www-form-urlencoded for regular post request" do
|
132
|
-
post_request = Net::HTTP::Post.new 'someurl.com'
|
133
|
-
Net::HTTP::Post.expects(:new).returns(post_request)
|
134
|
-
|
135
64
|
Net::HTTP.any_instance.expects(:request => simple_response)
|
136
65
|
|
137
|
-
Timeout.expects(:timeout).yields
|
138
|
-
|
139
66
|
params = {:url => some_https_url}
|
140
67
|
headers = {}
|
141
68
|
|
@@ -144,12 +71,18 @@ describe Gateway do
|
|
144
71
|
headers["Content-Type"].should match "application/x-www-form-urlencoded"
|
145
72
|
end
|
146
73
|
|
74
|
+
it "logs body of request" do
|
75
|
+
Net::HTTP.any_instance.expects(:request => simple_response)
|
76
|
+
|
77
|
+
subject.logger.expects(:debug).with('some_request')
|
78
|
+
|
79
|
+
subject.soap_post(:url => some_https_url, :body => 'some_request')
|
80
|
+
end
|
81
|
+
|
147
82
|
it "should log timeout errors and raise GatewayError" do
|
148
83
|
subject.logger.expects(:error).with("#{subject.class.name} received error: Timeout::Error")
|
149
84
|
Net::HTTP.any_instance.expects(:request).raises(Timeout::Error.new(nil))
|
150
85
|
|
151
|
-
Timeout.expects(:timeout).yields
|
152
|
-
|
153
86
|
expect do
|
154
87
|
subject.soap_post(:url => some_https_url, :body => 'body')
|
155
88
|
end.to raise_error(GatewayError)
|
@@ -170,19 +103,10 @@ describe Gateway do
|
|
170
103
|
subject.logger.expects(:error).with("#{subject.class.name} received error: Connection reset by peer")
|
171
104
|
|
172
105
|
Net::HTTP.any_instance.expects(:request).raises(Errno::ECONNRESET)
|
173
|
-
Timeout.expects(:timeout).yields
|
174
106
|
|
175
107
|
expect do
|
176
108
|
subject.get(:url => some_https_url, :body => '')
|
177
109
|
end.to raise_error(GatewayError)
|
178
110
|
end
|
179
111
|
|
180
|
-
it "logs body of request" do
|
181
|
-
Net::HTTP.any_instance.expects(:request).returns(simple_response)
|
182
|
-
|
183
|
-
subject.logger.expects(:debug).with('some_request')
|
184
|
-
|
185
|
-
subject.soap_post(:url => some_https_url, :body => 'some_request')
|
186
|
-
end
|
187
|
-
|
188
112
|
end
|
@@ -3,19 +3,31 @@ require_relative 'spec_helper'
|
|
3
3
|
require 'resource_accessor'
|
4
4
|
|
5
5
|
describe ResourceAccessor do
|
6
|
+
context "#get_response" do
|
7
|
+
it "should use provided url" do
|
8
|
+
Net::HTTP.expects(:new).with("someurl.com", 80).returns(stub_everything(:request => stub_everything))
|
6
9
|
|
7
|
-
|
8
|
-
|
10
|
+
subject.get_response :url => "http://someurl.com"
|
11
|
+
end
|
9
12
|
|
10
|
-
|
11
|
-
|
13
|
+
it "should use provided query parameters" do
|
14
|
+
Net::HTTP.expects(:new).with("someurl.com", 80).returns(stub_everything(:request => stub_everything))
|
15
|
+
|
16
|
+
Net::HTTP::Get.expects(:new).with("/?param1=p1¶m2=p2", {'User-Agent' => 'user_agent', 'Content-Type' => 'content_type'})
|
12
17
|
|
13
|
-
|
14
|
-
|
18
|
+
subject.get_response({:url => "http://someurl.com", :query => {:param1 => 'p1', :param2 => 'p2'}},
|
19
|
+
{'User-Agent' => 'user_agent', 'Content-Type' => 'content_type'})
|
20
|
+
end
|
15
21
|
end
|
16
22
|
|
17
|
-
|
18
|
-
|
23
|
+
context "#query_from_hash" do
|
24
|
+
it "escapes ampersands and spaces in values" do
|
25
|
+
subject.class.query_from_hash({:name1 => "name 1", :name2 => "name 2"}).should eql "name1=name+1&name2=name+2"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "maps properly nil values " do
|
29
|
+
subject.class.query_from_hash({:param1 => nil, :param2 => "A&B", :param3 => "C & D"}).should eql "param1=¶m2=A%26B¶m3=C+%26+D"
|
30
|
+
end
|
19
31
|
end
|
20
32
|
|
21
33
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resource_accessor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Shvets
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-08-
|
11
|
+
date: 2013-08-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gemspec_deps_gen
|
@@ -61,6 +61,7 @@ files:
|
|
61
61
|
- lib/resource_accessor/version.rb
|
62
62
|
- resource_accessor.gemspec
|
63
63
|
- resource_accessor.gemspec.erb
|
64
|
+
- spec/gateway.rb
|
64
65
|
- spec/gateway_spec.rb
|
65
66
|
- spec/resource_accessor_spec.rb
|
66
67
|
- spec/spec_helper.rb
|
@@ -90,6 +91,7 @@ specification_version: 4
|
|
90
91
|
summary: This library is used to simplify access to protected or unprotected http
|
91
92
|
resource
|
92
93
|
test_files:
|
94
|
+
- spec/gateway.rb
|
93
95
|
- spec/gateway_spec.rb
|
94
96
|
- spec/resource_accessor_spec.rb
|
95
97
|
- spec/spec_helper.rb
|