excon 0.6.0 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of excon might be problematic. Click here for more details.
- data/README.rdoc +13 -0
- data/changelog.txt +7 -0
- data/excon.gemspec +2 -2
- data/lib/excon.rb +40 -1
- data/lib/excon/connection.rb +57 -28
- data/lib/excon/errors.rb +2 -0
- data/lib/excon/response.rb +13 -4
- data/tests/basic_tests.rb +1 -39
- data/tests/proxy_tests.rb +89 -17
- data/tests/query_string_tests.rb +15 -17
- data/tests/rackups/basic.ru +2 -2
- data/tests/rackups/proxy.ru +6 -4
- data/tests/rackups/query_string.ru +2 -2
- data/tests/rackups/thread_safety.ru +2 -2
- data/tests/stub_tests.rb +51 -1
- data/tests/test_helper.rb +40 -0
- data/tests/thread_safety_tests.rb +0 -2
- metadata +5 -5
data/README.rdoc
CHANGED
@@ -34,6 +34,19 @@ You can also stream responses by passing a block that will receive each chunk.
|
|
34
34
|
|
35
35
|
These options can be combined to make pretty much any request you might need.
|
36
36
|
|
37
|
+
== Proxy Support
|
38
|
+
|
39
|
+
You can specify a proxy URL that Excon will use with both HTTP and HTTPS connections:
|
40
|
+
|
41
|
+
connection = Excon.new('http://geemus.com', :proxy => 'http://my.proxy:3128')
|
42
|
+
connection.request(:method => 'GET')
|
43
|
+
|
44
|
+
The proxy URL must be fully specified, including scheme (e.g. "http://") and port.
|
45
|
+
|
46
|
+
Excon will also use the environment variables "http_proxy" and "https_proxy" if they are present. "http_proxy" will be used for HTTPS connections if "https_proxy" is not set.
|
47
|
+
|
48
|
+
Environment variables will take precedence over a :proxy option that has been specified in code.
|
49
|
+
|
37
50
|
== HTTPS/SSL Issues
|
38
51
|
|
39
52
|
By default excon will try to verify peer certificates when using ssl for https, unfortunately on some operating systems the defaults will not work. This will likely manifest itself as something like "Excon::Errors::SocketError: SSL_connect returned=1 ..."
|
data/changelog.txt
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
0.6.1 04/05/11
|
2
|
+
==============
|
3
|
+
|
4
|
+
* add support for HTTPS proxies. thanks mrowe
|
5
|
+
* add support for http_proxy and https_proxy ENV variables. thanks mrowe
|
6
|
+
* fix progress for requests with blocks that are chunked or connection close
|
7
|
+
|
1
8
|
0.6.0 03/30/11
|
2
9
|
==============
|
3
10
|
|
data/excon.gemspec
CHANGED
@@ -13,8 +13,8 @@ Gem::Specification.new do |s|
|
|
13
13
|
## If your rubyforge_project name is different, then edit it and comment out
|
14
14
|
## the sub! line in the Rakefile
|
15
15
|
s.name = 'excon'
|
16
|
-
s.version = '0.6.
|
17
|
-
s.date = '2011-
|
16
|
+
s.version = '0.6.1'
|
17
|
+
s.date = '2011-04-05'
|
18
18
|
s.rubyforge_project = 'excon'
|
19
19
|
|
20
20
|
## Make sure your summary is short. The description may be as long
|
data/lib/excon.rb
CHANGED
@@ -13,7 +13,7 @@ require 'excon/response'
|
|
13
13
|
|
14
14
|
module Excon
|
15
15
|
unless const_defined?(:VERSION)
|
16
|
-
VERSION = '0.6.
|
16
|
+
VERSION = '0.6.1'
|
17
17
|
end
|
18
18
|
|
19
19
|
unless const_defined?(:CHUNK_SIZE)
|
@@ -30,6 +30,21 @@ module Excon
|
|
30
30
|
# setup ssl defaults based on platform
|
31
31
|
@ssl_verify_peer = Config::CONFIG['host_os'] !~ /mswin|win32|dos|cygwin|mingw/i
|
32
32
|
|
33
|
+
# default mocking to off
|
34
|
+
@mock = false
|
35
|
+
|
36
|
+
# Status of mocking
|
37
|
+
def mock
|
38
|
+
@mock
|
39
|
+
end
|
40
|
+
|
41
|
+
# Change the status of mocking
|
42
|
+
# false is the default and works as expected
|
43
|
+
# true returns a value from stubs or raises
|
44
|
+
def mock=(new_mock)
|
45
|
+
@mock = new_mock
|
46
|
+
end
|
47
|
+
|
33
48
|
# @see Connection#initialize
|
34
49
|
# Initializes a new keep-alive session for a given remote host
|
35
50
|
# @param [String] url The destination URL
|
@@ -45,6 +60,30 @@ module Excon
|
|
45
60
|
@ssl_verify_peer = new_ssl_verify_peer && true || false
|
46
61
|
end
|
47
62
|
|
63
|
+
# push an additional stub onto the list to check for mock requests
|
64
|
+
# @param [Hash<Symbol, >] request params to match against, omitted params match all
|
65
|
+
# @param [Hash<Symbol, >] response params to return from matched request or block to call with params
|
66
|
+
def stub(request_params, response_params = nil)
|
67
|
+
if block_given?
|
68
|
+
if response_params
|
69
|
+
raise(ArgumentError.new("stub requires either response_params OR a block"))
|
70
|
+
else
|
71
|
+
stub = [request_params, Proc.new]
|
72
|
+
end
|
73
|
+
elsif response_params
|
74
|
+
stub = [request_params, response_params]
|
75
|
+
else
|
76
|
+
raise(ArgumentError.new("stub requires either response_params OR a block"))
|
77
|
+
end
|
78
|
+
stubs << stub
|
79
|
+
stub
|
80
|
+
end
|
81
|
+
|
82
|
+
# get a list of defined stubs
|
83
|
+
def stubs
|
84
|
+
@stubs ||= []
|
85
|
+
end
|
86
|
+
|
48
87
|
# Generic non-persistent HTTP methods
|
49
88
|
%w{connect delete get head options post put trace}.each do |method|
|
50
89
|
eval <<-DEF
|
data/lib/excon/connection.rb
CHANGED
@@ -22,16 +22,31 @@ module Excon
|
|
22
22
|
@connection = {
|
23
23
|
:headers => {},
|
24
24
|
:host => uri.host,
|
25
|
+
:mock => Excon.mock,
|
25
26
|
:path => uri.path,
|
26
27
|
:port => uri.port.to_s,
|
27
28
|
:query => uri.query,
|
28
29
|
:scheme => uri.scheme
|
29
30
|
}.merge!(params)
|
30
31
|
|
31
|
-
if
|
32
|
+
# use proxy from the environment if present
|
33
|
+
if ENV.has_key?('http_proxy')
|
34
|
+
@proxy = setup_proxy(ENV['http_proxy'])
|
35
|
+
elsif params.has_key?(:proxy)
|
36
|
+
@proxy = setup_proxy(params[:proxy])
|
37
|
+
end
|
38
|
+
|
39
|
+
if https?
|
40
|
+
# use https_proxy if that has been specified
|
41
|
+
if ENV.has_key?('https_proxy')
|
42
|
+
@proxy = setup_proxy(ENV['https_proxy'])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
if @proxy
|
32
47
|
@connection[:headers]['Proxy-Connection'] ||= 'Keep-Alive'
|
33
|
-
setup_proxy(params[:proxy])
|
34
48
|
end
|
49
|
+
|
35
50
|
@socket_key = '' << @connection[:host] << ':' << @connection[:port]
|
36
51
|
reset
|
37
52
|
end
|
@@ -58,14 +73,21 @@ module Excon
|
|
58
73
|
params[:path].insert(0, '/')
|
59
74
|
end
|
60
75
|
|
61
|
-
|
62
|
-
for stub, response in stubs
|
76
|
+
if params[:mock]
|
77
|
+
for stub, response in Excon.stubs
|
63
78
|
# all specified non-headers params match and no headers were specified or all specified headers match
|
64
79
|
if [stub.keys - [:headers]].all? {|key| stub[key] == params[key] } &&
|
65
80
|
(!stub.has_key?(:headers) || stub[:headers].keys.all? {|key| stub[:headers][key] == params[:headers][key]})
|
66
|
-
|
81
|
+
case response
|
82
|
+
when Proc
|
83
|
+
return Excon::Response.new(response.call(params))
|
84
|
+
else
|
85
|
+
return Excon::Response.new(response)
|
86
|
+
end
|
67
87
|
end
|
68
88
|
end
|
89
|
+
# if we reach here no stubs matched
|
90
|
+
raise(Excon::Errors::StubNotFound.new('no stubs matched ' << params.inspect))
|
69
91
|
end
|
70
92
|
|
71
93
|
# start with "METHOD /path"
|
@@ -144,6 +166,8 @@ module Excon
|
|
144
166
|
end
|
145
167
|
|
146
168
|
response
|
169
|
+
rescue Excon::Errors::StubNotFound => stub_not_found
|
170
|
+
raise(stub_not_found)
|
147
171
|
rescue => socket_error
|
148
172
|
reset
|
149
173
|
raise(Excon::Errors::SocketError.new(socket_error))
|
@@ -174,21 +198,11 @@ module Excon
|
|
174
198
|
(old_socket = sockets.delete(@socket_key)) && old_socket.close
|
175
199
|
end
|
176
200
|
|
177
|
-
def stub(request_params, response_params)
|
178
|
-
stub = [request_params, response_params]
|
179
|
-
stubs << stub
|
180
|
-
stub
|
181
|
-
end
|
182
|
-
|
183
|
-
def stubs
|
184
|
-
@stubs ||= []
|
185
|
-
end
|
186
|
-
|
187
201
|
private
|
188
202
|
def connect
|
189
203
|
new_socket = open_socket
|
190
204
|
|
191
|
-
if
|
205
|
+
if https?
|
192
206
|
# create ssl context
|
193
207
|
ssl_context = OpenSSL::SSL::SSLContext.new
|
194
208
|
|
@@ -214,15 +228,30 @@ module Excon
|
|
214
228
|
ssl_context.key = OpenSSL::PKey::RSA.new(File.read(@connection[:client_key]))
|
215
229
|
end
|
216
230
|
|
217
|
-
|
218
|
-
|
219
|
-
new_socket.sync_close = true
|
220
|
-
new_socket.connect
|
231
|
+
new_socket = open_ssl_socket(new_socket, ssl_context)
|
232
|
+
end
|
221
233
|
|
222
|
-
|
223
|
-
|
234
|
+
new_socket
|
235
|
+
end
|
236
|
+
|
237
|
+
def open_ssl_socket(socket, ssl_context)
|
238
|
+
|
239
|
+
new_socket = OpenSSL::SSL::SSLSocket.new(socket, ssl_context)
|
240
|
+
new_socket.sync_close = true
|
241
|
+
|
242
|
+
if @proxy
|
243
|
+
new_socket << "CONNECT " << @connection[:host] << ":" << @connection[:port] << HTTP_1_1
|
244
|
+
new_socket << "Host: " << @connection[:host] << ":" << @connection[:port] << CR_NL << CR_NL
|
245
|
+
|
246
|
+
# eat the proxy's connection response
|
247
|
+
while line = new_socket.readline.strip
|
248
|
+
break if line.empty?
|
249
|
+
end
|
224
250
|
end
|
225
251
|
|
252
|
+
new_socket.connect
|
253
|
+
# verify connection
|
254
|
+
new_socket.post_connection_check(@connection[:host])
|
226
255
|
new_socket
|
227
256
|
end
|
228
257
|
|
@@ -242,17 +271,17 @@ module Excon
|
|
242
271
|
def sockets
|
243
272
|
Thread.current[:_excon_sockets] ||= {}
|
244
273
|
end
|
245
|
-
|
274
|
+
|
275
|
+
def https?
|
276
|
+
@connection[:scheme] == 'https'
|
277
|
+
end
|
278
|
+
|
246
279
|
def setup_proxy(proxy)
|
247
280
|
uri = URI.parse(proxy)
|
248
281
|
unless uri.host and uri.port and uri.scheme
|
249
282
|
raise Excon::Errors::ProxyParseError, "Proxy is invalid"
|
250
283
|
end
|
251
|
-
|
252
|
-
:host => uri.host,
|
253
|
-
:port => uri.port,
|
254
|
-
:scheme => uri.scheme
|
255
|
-
}
|
284
|
+
{:host => uri.host, :port => uri.port, :scheme => uri.scheme}
|
256
285
|
end
|
257
286
|
|
258
287
|
end
|
data/lib/excon/errors.rb
CHANGED
data/lib/excon/response.rb
CHANGED
@@ -4,6 +4,14 @@ module Excon
|
|
4
4
|
|
5
5
|
attr_accessor :body, :headers, :status
|
6
6
|
|
7
|
+
def attributes
|
8
|
+
{
|
9
|
+
:body => body,
|
10
|
+
:headers => headers,
|
11
|
+
:status => status
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
7
15
|
def initialize(attrs={})
|
8
16
|
@body = attrs[:body] || ''
|
9
17
|
@headers = attrs[:headers] || {}
|
@@ -35,16 +43,17 @@ module Excon
|
|
35
43
|
|
36
44
|
if block_given
|
37
45
|
if transfer_encoding_chunked
|
46
|
+
# 2 == "/r/n".length
|
38
47
|
while (chunk_size = socket.readline.chop!.to_i(16)) > 0
|
39
|
-
yield
|
48
|
+
yield(socket.read(chunk_size + 2).chop!, nil, content_length)
|
40
49
|
end
|
41
|
-
socket.read(2)
|
50
|
+
socket.read(2)
|
42
51
|
elsif connection_close
|
43
|
-
yield
|
52
|
+
yield(socket.read, remaining, content_length)
|
44
53
|
else
|
45
54
|
remaining = content_length
|
46
55
|
while remaining > 0
|
47
|
-
yield
|
56
|
+
yield(socket.read([CHUNK_SIZE, remaining].min), [remaining - CHUNK_SIZE, 0].max, content_length)
|
48
57
|
remaining -= CHUNK_SIZE
|
49
58
|
end
|
50
59
|
end
|
data/tests/basic_tests.rb
CHANGED
@@ -1,43 +1,5 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
|
2
|
-
|
3
1
|
with_rackup('basic.ru') do
|
4
2
|
Shindo.tests('Excon basics') do
|
5
|
-
|
6
|
-
|
7
|
-
connection = Excon.new('http://127.0.0.1:9292')
|
8
|
-
response = connection.request(:method => :get, :path => '/content-length/100')
|
9
|
-
|
10
|
-
tests('response.status').returns(200) do
|
11
|
-
response.status
|
12
|
-
end
|
13
|
-
|
14
|
-
tests("response.headers['Connection']").returns('Keep-Alive') do
|
15
|
-
response.headers['Connection']
|
16
|
-
end
|
17
|
-
|
18
|
-
tests("response.headers['Content-Length']").returns('100') do
|
19
|
-
response.headers['Content-Length']
|
20
|
-
end
|
21
|
-
|
22
|
-
tests("response.headers['Content-Type']").returns('text/html;charset=utf-8') do
|
23
|
-
response.headers['Content-Type']
|
24
|
-
end
|
25
|
-
|
26
|
-
test("Time.parse(response.headers['Date']).is_a?(Time)") do
|
27
|
-
Time.parse(response.headers['Date']).is_a?(Time)
|
28
|
-
end
|
29
|
-
|
30
|
-
test("!!(response.headers['Server'] =~ /^WEBrick/)") do
|
31
|
-
!!(response.headers['Server'] =~ /^WEBrick/)
|
32
|
-
end
|
33
|
-
|
34
|
-
tests("response.headers['Custom']").returns("Foo: bar") do
|
35
|
-
response.headers['Custom']
|
36
|
-
end
|
37
|
-
|
38
|
-
tests("response.body").returns('x' * 100) do
|
39
|
-
response.body
|
40
|
-
end
|
41
|
-
end
|
3
|
+
basic_tests
|
42
4
|
end
|
43
5
|
end
|
data/tests/proxy_tests.rb
CHANGED
@@ -1,64 +1,136 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
|
2
|
-
|
3
1
|
Shindo.tests('Excon proxy support') do
|
4
2
|
|
5
3
|
tests('proxy configuration') do
|
6
|
-
|
4
|
+
|
7
5
|
tests('no proxy') do
|
8
6
|
connection = Excon.new('http://foo.com')
|
9
|
-
|
7
|
+
|
10
8
|
tests('connection.proxy').returns(nil) do
|
11
9
|
connection.proxy
|
12
10
|
end
|
13
11
|
end
|
14
|
-
|
12
|
+
|
15
13
|
tests('with fully-specified proxy: https://myproxy.net:8080') do
|
16
14
|
connection = Excon.new('http://foo.com', :proxy => 'https://myproxy.net:8080')
|
17
|
-
|
15
|
+
|
18
16
|
tests('connection.proxy.host').returns('myproxy.net') do
|
19
17
|
connection.proxy[:host]
|
20
18
|
end
|
21
|
-
|
19
|
+
|
22
20
|
tests('connection.proxy.port').returns(8080) do
|
23
21
|
connection.proxy[:port]
|
24
22
|
end
|
25
|
-
|
23
|
+
|
26
24
|
tests('connection.proxy.scheme').returns('https') do
|
27
25
|
connection.proxy[:scheme]
|
28
26
|
end
|
29
27
|
end
|
30
|
-
|
28
|
+
|
29
|
+
tests('with proxy config from the environment') do
|
30
|
+
ENV['http_proxy'] = 'http://myproxy:8080'
|
31
|
+
ENV['https_proxy'] = 'http://mysecureproxy:8081'
|
32
|
+
|
33
|
+
tests('an http connection') do
|
34
|
+
connection = Excon.new('http://foo.com')
|
35
|
+
|
36
|
+
tests('connection.proxy.host').returns('myproxy') do
|
37
|
+
connection.proxy[:host]
|
38
|
+
end
|
39
|
+
|
40
|
+
tests('connection.proxy.port').returns(8080) do
|
41
|
+
connection.proxy[:port]
|
42
|
+
end
|
43
|
+
|
44
|
+
tests('connection.proxy.scheme').returns('http') do
|
45
|
+
connection.proxy[:scheme]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
tests('an https connection') do
|
50
|
+
connection = Excon.new('https://secret.com')
|
51
|
+
|
52
|
+
tests('connection.proxy.host').returns('mysecureproxy') do
|
53
|
+
connection.proxy[:host]
|
54
|
+
end
|
55
|
+
|
56
|
+
tests('connection.proxy.port').returns(8081) do
|
57
|
+
connection.proxy[:port]
|
58
|
+
end
|
59
|
+
|
60
|
+
tests('connection.proxy.scheme').returns('http') do
|
61
|
+
connection.proxy[:scheme]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
tests('http proxy from the environment overrides config') do
|
66
|
+
connection = Excon.new('http://foo.com', :proxy => 'http://hard.coded.proxy:6666')
|
67
|
+
|
68
|
+
tests('connection.proxy.host').returns('myproxy') do
|
69
|
+
connection.proxy[:host]
|
70
|
+
end
|
71
|
+
|
72
|
+
tests('connection.proxy.port').returns(8080) do
|
73
|
+
connection.proxy[:port]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
ENV.delete('http_proxy')
|
78
|
+
ENV.delete('https_proxy')
|
79
|
+
end
|
80
|
+
|
81
|
+
tests('with only http_proxy config from the environment') do
|
82
|
+
ENV['http_proxy'] = 'http://myproxy:8080'
|
83
|
+
ENV.delete('https_proxy')
|
84
|
+
|
85
|
+
tests('an https connection') do
|
86
|
+
connection = Excon.new('https://secret.com')
|
87
|
+
|
88
|
+
tests('connection.proxy.host').returns('myproxy') do
|
89
|
+
connection.proxy[:host]
|
90
|
+
end
|
91
|
+
|
92
|
+
tests('connection.proxy.port').returns(8080) do
|
93
|
+
connection.proxy[:port]
|
94
|
+
end
|
95
|
+
|
96
|
+
tests('connection.proxy.scheme').returns('http') do
|
97
|
+
connection.proxy[:scheme]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
ENV.delete('http_proxy')
|
102
|
+
end
|
103
|
+
|
31
104
|
end
|
32
105
|
|
33
106
|
with_rackup('proxy.ru') do
|
34
|
-
|
107
|
+
|
35
108
|
tests('http proxying: http://foo.com:8080') do
|
36
109
|
connection = Excon.new('http://foo.com:8080', :proxy => 'http://localhost:9292')
|
37
110
|
response = connection.request(:method => :get, :path => '/bar', :query => {:alpha => 'kappa'})
|
38
|
-
|
111
|
+
|
39
112
|
tests('response.status').returns(200) do
|
40
113
|
response.status
|
41
114
|
end
|
42
|
-
|
115
|
+
|
43
116
|
# must be absolute form for proxy requests
|
44
117
|
tests('sent Request URI').returns('http://foo.com:8080/bar?alpha=kappa') do
|
45
118
|
response.headers['Sent-Request-Uri']
|
46
119
|
end
|
47
|
-
|
120
|
+
|
48
121
|
tests('sent Host header').returns('foo.com:8080') do
|
49
122
|
response.headers['Sent-Host']
|
50
123
|
end
|
51
|
-
|
124
|
+
|
52
125
|
tests('sent Proxy-Connection header').returns('Keep-Alive') do
|
53
126
|
response.headers['Sent-Proxy-Connection']
|
54
127
|
end
|
55
|
-
|
128
|
+
|
56
129
|
tests('response.body (proxied content)').returns('proxied content') do
|
57
130
|
response.body
|
58
131
|
end
|
59
132
|
end
|
60
|
-
|
133
|
+
|
61
134
|
end
|
62
135
|
|
63
136
|
end
|
64
|
-
|
data/tests/query_string_tests.rb
CHANGED
@@ -1,60 +1,58 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
|
2
|
-
|
3
1
|
with_rackup('query_string.ru') do
|
4
2
|
Shindo.tests('Excon query string variants') do
|
5
3
|
connection = Excon.new('http://127.0.0.1:9292')
|
6
|
-
|
4
|
+
|
7
5
|
tests(":query => {:foo => 'bar'}") do
|
8
6
|
|
9
7
|
response = connection.request(:method => :get, :path => '/query', :query => {:foo => 'bar'})
|
10
8
|
query_string = response.body[7..-1] # query string sent
|
11
|
-
|
9
|
+
|
12
10
|
tests("query string sent").returns('foo=bar') do
|
13
11
|
query_string
|
14
12
|
end
|
15
|
-
|
13
|
+
|
16
14
|
end
|
17
|
-
|
15
|
+
|
18
16
|
tests(":query => {:foo => nil}") do
|
19
17
|
|
20
18
|
response = connection.request(:method => :get, :path => '/query', :query => {:foo => nil})
|
21
19
|
query_string = response.body[7..-1] # query string sent
|
22
|
-
|
20
|
+
|
23
21
|
tests("query string sent").returns('foo') do
|
24
22
|
query_string
|
25
23
|
end
|
26
|
-
|
24
|
+
|
27
25
|
end
|
28
|
-
|
26
|
+
|
29
27
|
tests(":query => {:foo => 'bar', :me => nil}") do
|
30
28
|
|
31
29
|
response = connection.request(:method => :get, :path => '/query', :query => {:foo => 'bar', :me => nil})
|
32
30
|
query_string = response.body[7..-1] # query string sent
|
33
|
-
|
31
|
+
|
34
32
|
test("query string sent includes 'foo=bar'") do
|
35
33
|
query_string.split('&').include?('foo=bar')
|
36
34
|
end
|
37
|
-
|
35
|
+
|
38
36
|
test("query string sent includes 'me'") do
|
39
37
|
query_string.split('&').include?('me')
|
40
38
|
end
|
41
|
-
|
39
|
+
|
42
40
|
end
|
43
|
-
|
41
|
+
|
44
42
|
tests(":query => {:foo => 'bar', :me => 'too'}") do
|
45
43
|
|
46
44
|
response = connection.request(:method => :get, :path => '/query', :query => {:foo => 'bar', :me => 'too'})
|
47
45
|
query_string = response.body[7..-1] # query string sent
|
48
|
-
|
46
|
+
|
49
47
|
test("query string sent includes 'foo=bar'") do
|
50
48
|
query_string.split('&').include?('foo=bar')
|
51
49
|
end
|
52
|
-
|
50
|
+
|
53
51
|
test("query string sent includes 'me=too'") do
|
54
52
|
query_string.split('&').include?('me=too')
|
55
53
|
end
|
56
|
-
|
54
|
+
|
57
55
|
end
|
58
|
-
|
56
|
+
|
59
57
|
end
|
60
58
|
end
|
data/tests/rackups/basic.ru
CHANGED
data/tests/rackups/proxy.ru
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
require 'sinatra'
|
2
2
|
|
3
3
|
class App < Sinatra::Base
|
4
|
-
get
|
5
|
-
headers
|
6
|
-
|
7
|
-
|
4
|
+
get('/bar') do
|
5
|
+
headers(
|
6
|
+
"Sent-Request-Uri" => request.env['REQUEST_URI'].to_s,
|
7
|
+
"Sent-Host" => request.env['HTTP_HOST'].to_s,
|
8
|
+
"Sent-Proxy-Connection" => request.env['HTTP_PROXY_CONNECTION'].to_s
|
9
|
+
)
|
8
10
|
'proxied content'
|
9
11
|
end
|
10
12
|
end
|
data/tests/stub_tests.rb
CHANGED
@@ -1,8 +1,24 @@
|
|
1
1
|
Shindo.tests('Excon stubs') do
|
2
|
+
Excon.mock = true
|
3
|
+
|
4
|
+
tests("missing stub").raises(Excon::Errors::StubNotFound) do
|
5
|
+
connection = Excon.new('http://127.0.0.1:9292')
|
6
|
+
response = connection.request(:method => :get, :path => '/content-length/100')
|
7
|
+
end
|
8
|
+
|
9
|
+
tests("stub({})").raises(ArgumentError) do
|
10
|
+
Excon.stub({})
|
11
|
+
end
|
12
|
+
|
13
|
+
tests("stub({}, {}) {}").raises(ArgumentError) do
|
14
|
+
Excon.stub({}, {}) {}
|
15
|
+
end
|
16
|
+
|
2
17
|
tests("stub({:method => :get}, {:body => 'body', :status => 200})") do
|
3
18
|
|
19
|
+
Excon.stub({:method => :get}, {:body => 'body', :status => 200})
|
20
|
+
|
4
21
|
connection = Excon.new('http://127.0.0.1:9292')
|
5
|
-
connection.stub({:method => :get}, {:body => 'body', :status => 200})
|
6
22
|
response = connection.request(:method => :get, :path => '/content-length/100')
|
7
23
|
|
8
24
|
tests('response.body').returns('body') do
|
@@ -17,5 +33,39 @@ Shindo.tests('Excon stubs') do
|
|
17
33
|
response.status
|
18
34
|
end
|
19
35
|
|
36
|
+
Excon.stubs.pop
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
tests("stub({:body => 'body', :method => :get}) {|params| {:body => params[:body], :headers => params[:headers], :status => 200}}") do
|
41
|
+
|
42
|
+
Excon.stub({:body => 'body', :method => :get}) {|params| {:body => params[:body], :headers => params[:headers], :status => 200}}
|
43
|
+
|
44
|
+
connection = Excon.new('http://127.0.0.1:9292')
|
45
|
+
response = connection.request(:body => 'body', :method => :get, :path => '/content-length/100')
|
46
|
+
|
47
|
+
tests('response.body').returns('body') do
|
48
|
+
response.body
|
49
|
+
end
|
50
|
+
|
51
|
+
tests('response.headers').returns({'Host' => '127.0.0.1:9292'}) do
|
52
|
+
response.headers
|
53
|
+
end
|
54
|
+
|
55
|
+
tests('response.status').returns(200) do
|
56
|
+
response.status
|
57
|
+
end
|
58
|
+
|
59
|
+
Excon.stubs.pop
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
Excon.mock = false
|
64
|
+
|
65
|
+
tests('mock = false') do
|
66
|
+
with_rackup('basic.ru') do
|
67
|
+
basic_tests
|
68
|
+
end
|
20
69
|
end
|
70
|
+
|
21
71
|
end
|
data/tests/test_helper.rb
CHANGED
@@ -3,6 +3,46 @@ require 'bundler'
|
|
3
3
|
|
4
4
|
Bundler.require(:default, :development)
|
5
5
|
|
6
|
+
def basic_tests
|
7
|
+
tests('GET /content-length/100') do
|
8
|
+
|
9
|
+
connection = Excon.new('http://127.0.0.1:9292')
|
10
|
+
response = connection.request(:method => :get, :path => '/content-length/100')
|
11
|
+
|
12
|
+
tests('response.status').returns(200) do
|
13
|
+
response.status
|
14
|
+
end
|
15
|
+
|
16
|
+
tests("response.headers['Connection']").returns('Keep-Alive') do
|
17
|
+
response.headers['Connection']
|
18
|
+
end
|
19
|
+
|
20
|
+
tests("response.headers['Content-Length']").returns('100') do
|
21
|
+
response.headers['Content-Length']
|
22
|
+
end
|
23
|
+
|
24
|
+
tests("response.headers['Content-Type']").returns('text/html;charset=utf-8') do
|
25
|
+
response.headers['Content-Type']
|
26
|
+
end
|
27
|
+
|
28
|
+
test("Time.parse(response.headers['Date']).is_a?(Time)") do
|
29
|
+
Time.parse(response.headers['Date']).is_a?(Time)
|
30
|
+
end
|
31
|
+
|
32
|
+
test("!!(response.headers['Server'] =~ /^WEBrick/)") do
|
33
|
+
!!(response.headers['Server'] =~ /^WEBrick/)
|
34
|
+
end
|
35
|
+
|
36
|
+
tests("response.headers['Custom']").returns("Foo: bar") do
|
37
|
+
response.headers['Custom']
|
38
|
+
end
|
39
|
+
|
40
|
+
tests("response.body").returns('x' * 100) do
|
41
|
+
response.body
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
6
46
|
def rackup_path(*parts)
|
7
47
|
File.expand_path(File.join(File.dirname(__FILE__), 'rackups', *parts))
|
8
48
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: excon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 5
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 6
|
9
|
-
-
|
10
|
-
version: 0.6.
|
9
|
+
- 1
|
10
|
+
version: 0.6.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- geemus (Wesley Beary)
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-04-05 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -150,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
150
150
|
requirements: []
|
151
151
|
|
152
152
|
rubyforge_project: excon
|
153
|
-
rubygems_version: 1.4.
|
153
|
+
rubygems_version: 1.4.2
|
154
154
|
signing_key:
|
155
155
|
specification_version: 2
|
156
156
|
summary: speed, persistence, http(s)
|