excon 0.26.0 → 0.27.0
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/Gemfile +1 -0
- data/Gemfile.lock +8 -1
- data/README.md +24 -8
- data/changelog.txt +11 -0
- data/excon.gemspec +3 -2
- data/lib/excon.rb +5 -2
- data/lib/excon/connection.rb +38 -19
- data/lib/excon/constants.rb +30 -25
- data/lib/excon/middlewares/idempotent.rb +3 -3
- data/lib/excon/ssl_socket.rb +1 -2
- data/lib/excon/unix_socket.rb +22 -0
- data/tests/authorization_header_tests.rb +2 -2
- data/tests/basic_tests.rb +72 -60
- data/tests/middlewares/instrumentation_tests.rb +3 -3
- data/tests/query_string_tests.rb +2 -2
- data/tests/requests_tests.rb +13 -14
- data/tests/test_helper.rb +36 -2
- data/tests/thread_safety_tests.rb +2 -2
- data/tests/timeout_tests.rb +3 -3
- metadata +4 -3
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
excon (0.
|
4
|
+
excon (0.27.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: http://rubygems.org/
|
@@ -21,11 +21,13 @@ GEM
|
|
21
21
|
bouncy-castle-java (>= 1.5.0147)
|
22
22
|
json (1.7.3)
|
23
23
|
json (1.7.3-java)
|
24
|
+
kgio (2.8.0)
|
24
25
|
multi_json (1.3.6)
|
25
26
|
open4 (1.3.0)
|
26
27
|
rack (1.4.1)
|
27
28
|
rack-protection (1.2.0)
|
28
29
|
rack
|
30
|
+
raindrops (0.11.0)
|
29
31
|
rake (0.9.2.2)
|
30
32
|
rdoc (3.12)
|
31
33
|
json (~> 1.4)
|
@@ -36,6 +38,10 @@ GEM
|
|
36
38
|
rack-protection (~> 1.2)
|
37
39
|
tilt (~> 1.3, >= 1.3.3)
|
38
40
|
tilt (1.3.3)
|
41
|
+
unicorn (4.6.3)
|
42
|
+
kgio (~> 2.6)
|
43
|
+
rack
|
44
|
+
raindrops (~> 0.7)
|
39
45
|
|
40
46
|
PLATFORMS
|
41
47
|
java
|
@@ -52,3 +58,4 @@ DEPENDENCIES
|
|
52
58
|
rdoc
|
53
59
|
shindo
|
54
60
|
sinatra
|
61
|
+
unicorn
|
data/README.md
CHANGED
@@ -86,12 +86,6 @@ connection.request(:idempotent => true, :retry_limit => 6)
|
|
86
86
|
# opt-out of nonblocking operations for performance and/or as a workaround
|
87
87
|
connection.request(:nonblock => false)
|
88
88
|
|
89
|
-
# opt-in to omitting port from http:80 and https:443
|
90
|
-
connection.request(:omit_default_port => true)
|
91
|
-
|
92
|
-
# set longer connect_timeout (default is 60 seconds)
|
93
|
-
connection.request(:connect_timeout => 360)
|
94
|
-
|
95
89
|
# set longer read_timeout (default is 60 seconds)
|
96
90
|
connection.request(:read_timeout => 360)
|
97
91
|
|
@@ -104,6 +98,12 @@ connection.request(:write_timeout => 360)
|
|
104
98
|
# requests in time-sensitive scenarios.
|
105
99
|
#
|
106
100
|
connection = Excon.new('http://geemus.com/', :tcp_nodelay => true)
|
101
|
+
|
102
|
+
# opt-in to omitting port from http:80 and https:443
|
103
|
+
connection = Excon.new('http://geemus.com/', :omit_default_port => true)
|
104
|
+
|
105
|
+
# set longer connect_timeout (default is 60 seconds)
|
106
|
+
connection = Excon.new('http://geemus.com/', :connect_timeout => 360)
|
107
107
|
```
|
108
108
|
|
109
109
|
Chunked Requests
|
@@ -116,7 +116,7 @@ file = File.open('data')
|
|
116
116
|
|
117
117
|
chunker = lambda do
|
118
118
|
# Excon.defaults[:chunk_size] defaults to 1048576, ie 1MB
|
119
|
-
# to_s will convert the nil
|
119
|
+
# to_s will convert the nil received after everything is read to the final empty chunk
|
120
120
|
file.read(Excon.defaults[:chunk_size]).to_s
|
121
121
|
end
|
122
122
|
|
@@ -161,14 +161,30 @@ You can specify a proxy URL that Excon will use with both HTTP and HTTPS connect
|
|
161
161
|
```ruby
|
162
162
|
connection = Excon.new('http://geemus.com', :proxy => 'http://my.proxy:3128')
|
163
163
|
connection.request(:method => 'GET')
|
164
|
+
|
165
|
+
Excon.get('http://geemus.com', :proxy => 'http://my.proxy:3128')
|
164
166
|
```
|
165
167
|
|
166
168
|
The proxy URL must be fully specified, including scheme (e.g. "http://") and port.
|
167
169
|
|
168
|
-
Proxy support must be set when establishing a connection object and cannot be overridden in individual requests.
|
170
|
+
Proxy support must be set when establishing a connection object and cannot be overridden in individual requests.
|
169
171
|
|
170
172
|
NOTE: Excon will use the environment variables `http_proxy` and `https_proxy` if they are present. If these variables are set they will take precedence over a :proxy option specified in code. If "https_proxy" is not set, the value of "http_proxy" will be used for both HTTP and HTTPS connections.
|
171
173
|
|
174
|
+
Unix Socket Support
|
175
|
+
------------------
|
176
|
+
|
177
|
+
The Unix socket will work for one-off requests and multiuse connections. A Unix socket path must be provided separate from the resource path.
|
178
|
+
|
179
|
+
```ruby
|
180
|
+
connection = Excon.new('unix:///', :socket => '/tmp/unicorn.sock')
|
181
|
+
connection.request(:method => :get, :path => '/ping')
|
182
|
+
|
183
|
+
Excon.get('unix:///ping', :socket => '/tmp/unicorn.sock')
|
184
|
+
```
|
185
|
+
|
186
|
+
NOTE: Proxies will be ignored when using a Unix socket, since a Unix socket has to be local.
|
187
|
+
|
172
188
|
Stubs
|
173
189
|
-----
|
174
190
|
|
data/changelog.txt
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
0.27.0 10/04/2013
|
2
|
+
=================
|
3
|
+
|
4
|
+
display warnings based on ruby and/or debug settings
|
5
|
+
add missing valid connection keys
|
6
|
+
remove 1.8.7 related nonblock warning
|
7
|
+
add support for unix sockets
|
8
|
+
cleanup constants
|
9
|
+
improve test setup to minimize server spawning
|
10
|
+
separate connection/request key validation
|
11
|
+
|
1
12
|
0.26.0 09/24/2013
|
2
13
|
=================
|
3
14
|
|
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.
|
17
|
-
s.date = '2013-
|
16
|
+
s.version = '0.27.0'
|
17
|
+
s.date = '2013-10-04'
|
18
18
|
s.rubyforge_project = 'excon'
|
19
19
|
|
20
20
|
## Make sure your summary is short. The description may be as long
|
@@ -109,6 +109,7 @@ Gem::Specification.new do |s|
|
|
109
109
|
lib/excon/socket.rb
|
110
110
|
lib/excon/ssl_socket.rb
|
111
111
|
lib/excon/standard_instrumentor.rb
|
112
|
+
lib/excon/unix_socket.rb
|
112
113
|
tests/authorization_header_tests.rb
|
113
114
|
tests/bad_tests.rb
|
114
115
|
tests/basic_tests.rb
|
data/lib/excon.rb
CHANGED
@@ -70,14 +70,17 @@ require 'excon/middlewares/response_parser'
|
|
70
70
|
require 'excon/response'
|
71
71
|
require 'excon/socket'
|
72
72
|
require 'excon/ssl_socket'
|
73
|
+
require 'excon/unix_socket'
|
73
74
|
require 'excon/standard_instrumentor'
|
74
75
|
|
75
76
|
module Excon
|
76
77
|
class << self
|
77
78
|
|
78
79
|
def display_warning(warning)
|
79
|
-
# Ruby
|
80
|
-
|
80
|
+
# Respect Ruby's $VERBOSE setting, unless EXCON_DEBUG is set
|
81
|
+
if !$VERBOSE.nil? || ENV['EXCON_DEBUG']
|
82
|
+
$stderr.puts(warning)
|
83
|
+
end
|
81
84
|
end
|
82
85
|
|
83
86
|
# Status of mocking
|
data/lib/excon/connection.rb
CHANGED
@@ -26,7 +26,7 @@ module Excon
|
|
26
26
|
@data[:proxy]
|
27
27
|
end
|
28
28
|
def proxy=(new_proxy)
|
29
|
-
Excon.display_warning("Excon::Connection#proxy= is deprecated use Excon::Connection#data[:proxy]= instead (#{caller.first})")
|
29
|
+
Excon.display_warning("Excon::Connection#proxy= is deprecated use Excon::Connection#data[:proxy]= instead (#{caller.first})")
|
30
30
|
@data[:proxy] = new_proxy
|
31
31
|
end
|
32
32
|
|
@@ -39,13 +39,14 @@ module Excon
|
|
39
39
|
# @option params [Fixnum] :port The port on which to connect, to the destination host
|
40
40
|
# @option params [Hash] :query Default query; appended to the 'scheme://host:port/path/' in the form of '?key=value'. Will only be used if params[:query] is not supplied to Connection#request
|
41
41
|
# @option params [String] :scheme The protocol; 'https' causes OpenSSL to be used
|
42
|
+
# @option params [String] :socket The path to the unix socket (required for 'unix://' connections)
|
42
43
|
# @option params [String] :ciphers Only use the specified SSL/TLS cipher suites; use OpenSSL cipher spec format e.g. 'HIGH:!aNULL:!3DES' or 'AES256-SHA:DES-CBC3-SHA'
|
43
44
|
# @option params [String] :proxy Proxy server; e.g. 'http://myproxy.com:8888'
|
44
45
|
# @option params [Fixnum] :retry_limit Set how many times we'll retry a failed request. (Default 4)
|
45
46
|
# @option params [Class] :instrumentor Responds to #instrument as in ActiveSupport::Notifications
|
46
47
|
# @option params [String] :instrumentor_name Name prefix for #instrument events. Defaults to 'excon'
|
47
48
|
def initialize(params = {})
|
48
|
-
|
49
|
+
validate_params!(params, VALID_CONNECTION_KEYS)
|
49
50
|
@data = Excon.defaults.dup
|
50
51
|
# merge does not deep-dup, so make sure headers is not the original
|
51
52
|
@data[:headers] = @data[:headers].dup
|
@@ -55,15 +56,17 @@ module Excon
|
|
55
56
|
|
56
57
|
@data.merge!(params)
|
57
58
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
@data[:
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
@data
|
59
|
+
unless @data[:scheme] == UNIX
|
60
|
+
no_proxy_env = ENV["no_proxy"] || ENV["NO_PROXY"] || ""
|
61
|
+
no_proxy_list = no_proxy_env.scan(/\*?\.?([^\s,:]+)(?::(\d+))?/i).map { |s| [s[0], s[1]] }
|
62
|
+
unless no_proxy_list.index { |h| /(^|\.)#{h[0]}$/.match(@data[:host]) && (h[1].nil? || h[1].to_i == @data[:port]) }
|
63
|
+
if @data[:scheme] == HTTPS && (ENV.has_key?('https_proxy') || ENV.has_key?('HTTPS_PROXY'))
|
64
|
+
@data[:proxy] = setup_proxy(ENV['https_proxy'] || ENV['HTTPS_PROXY'])
|
65
|
+
elsif (ENV.has_key?('http_proxy') || ENV.has_key?('HTTP_PROXY'))
|
66
|
+
@data[:proxy] = setup_proxy(ENV['http_proxy'] || ENV['HTTP_PROXY'])
|
67
|
+
elsif @data.has_key?(:proxy)
|
68
|
+
@data[:proxy] = setup_proxy(@data[:proxy])
|
69
|
+
end
|
67
70
|
end
|
68
71
|
end
|
69
72
|
|
@@ -87,7 +90,19 @@ module Excon
|
|
87
90
|
@data[:headers]['Authorization'] ||= 'Basic ' << ['' << user.to_s << ':' << pass.to_s].pack('m').delete(Excon::CR_NL)
|
88
91
|
end
|
89
92
|
|
90
|
-
@socket_key = '' << @data[:scheme]
|
93
|
+
@socket_key = '' << @data[:scheme]
|
94
|
+
if @data[:scheme] == UNIX
|
95
|
+
if @data[:host]
|
96
|
+
raise ArgumentError, "The `:host` parameter should not be set for `unix://` connections.\n" +
|
97
|
+
"When supplying a `unix://` URI, it should start with `unix:/` or `unix:///`."
|
98
|
+
elsif !@data[:socket]
|
99
|
+
raise ArgumentError, 'You must provide a `:socket` for `unix://` connections'
|
100
|
+
else
|
101
|
+
@socket_key << '://' << @data[:socket]
|
102
|
+
end
|
103
|
+
else
|
104
|
+
@socket_key << '://' << @data[:host]<< ':' << @data[:port].to_s
|
105
|
+
end
|
91
106
|
reset
|
92
107
|
end
|
93
108
|
|
@@ -210,18 +225,19 @@ module Excon
|
|
210
225
|
# @param [Hash<Symbol, >] params One or more optional params, override defaults set in Connection.new
|
211
226
|
# @option params [String] :body text to be sent over a socket
|
212
227
|
# @option params [Hash<Symbol, String>] :headers The default headers to supply in a request
|
213
|
-
# @option params [String] :host The destination host's reachable DNS name or IP, in the form of a String
|
214
228
|
# @option params [String] :path appears after 'scheme://host:port/'
|
215
|
-
# @option params [Fixnum] :port The port on which to connect, to the destination host
|
216
229
|
# @option params [Hash] :query appended to the 'scheme://host:port/path/' in the form of '?key=value'
|
217
|
-
# @option params [String] :scheme The protocol; 'https' causes OpenSSL to be used
|
218
230
|
def request(params={}, &block)
|
231
|
+
validate_params!(params, VALID_REQUEST_KEYS)
|
219
232
|
# @data has defaults, merge in new params to override
|
220
233
|
datum = @data.merge(params)
|
221
|
-
invalid_keys_warning(params, VALID_CONNECTION_KEYS)
|
222
234
|
datum[:headers] = @data[:headers].merge(datum[:headers] || {})
|
223
235
|
|
224
|
-
|
236
|
+
if datum[:scheme] == UNIX
|
237
|
+
datum[:headers]['Host'] ||= '' << datum[:socket]
|
238
|
+
else
|
239
|
+
datum[:headers]['Host'] ||= '' << datum[:host] << port_string(datum)
|
240
|
+
end
|
225
241
|
datum[:retries_remaining] ||= datum[:retry_limit]
|
226
242
|
|
227
243
|
# if path is empty or doesn't start with '/', insert one
|
@@ -338,10 +354,11 @@ module Excon
|
|
338
354
|
end
|
339
355
|
end
|
340
356
|
|
341
|
-
def
|
342
|
-
invalid_keys =
|
357
|
+
def validate_params!(params, valid_keys)
|
358
|
+
invalid_keys = params.keys - valid_keys
|
343
359
|
unless invalid_keys.empty?
|
344
360
|
Excon.display_warning("The following keys are invalid: #{invalid_keys.map(&:inspect).join(', ')}")
|
361
|
+
invalid_keys.each {|key| params.delete(key) }
|
345
362
|
end
|
346
363
|
end
|
347
364
|
|
@@ -359,6 +376,8 @@ module Excon
|
|
359
376
|
def socket
|
360
377
|
sockets[@socket_key] ||= if @data[:scheme] == HTTPS
|
361
378
|
Excon::SSLSocket.new(@data)
|
379
|
+
elsif @data[:scheme] == UNIX
|
380
|
+
Excon::UnixSocket.new(@data)
|
362
381
|
else
|
363
382
|
Excon::Socket.new(@data)
|
364
383
|
end
|
data/lib/excon/constants.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module Excon
|
2
2
|
|
3
|
+
VERSION = '0.27.0'
|
4
|
+
|
3
5
|
CR_NL = "\r\n"
|
4
6
|
|
5
7
|
DEFAULT_CA_FILE = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "data", "cacert.pem"))
|
@@ -29,24 +31,18 @@ module Excon
|
|
29
31
|
|
30
32
|
REDACTED = 'REDACTED'
|
31
33
|
|
32
|
-
|
34
|
+
UNIX = 'unix'
|
35
|
+
|
36
|
+
USER_AGENT = 'excon/' << VERSION
|
37
|
+
|
38
|
+
VALID_REQUEST_KEYS = [
|
33
39
|
:body,
|
34
40
|
:captures,
|
35
41
|
:chunk_size,
|
36
|
-
:client_key,
|
37
|
-
:client_cert,
|
38
|
-
:certificate,
|
39
|
-
:private_key,
|
40
|
-
:connect_timeout,
|
41
|
-
:connection,
|
42
42
|
:debug_request,
|
43
43
|
:debug_response,
|
44
|
-
:error,
|
45
|
-
:exception,
|
46
44
|
:expects,
|
47
|
-
:family,
|
48
45
|
:headers,
|
49
|
-
:host,
|
50
46
|
:idempotent,
|
51
47
|
:instrumentor,
|
52
48
|
:instrumentor_name,
|
@@ -54,32 +50,41 @@ module Excon
|
|
54
50
|
:middlewares,
|
55
51
|
:mock,
|
56
52
|
:nonblock,
|
57
|
-
:omit_default_port,
|
58
|
-
:password,
|
59
53
|
:path,
|
60
54
|
:pipeline,
|
61
|
-
:port,
|
62
|
-
:proxy,
|
63
55
|
:query,
|
64
56
|
:read_timeout,
|
65
57
|
:request_block,
|
66
|
-
:response,
|
67
58
|
:response_block,
|
68
|
-
:retries_remaining,
|
59
|
+
:retries_remaining, # used internally
|
69
60
|
:retry_limit,
|
61
|
+
:write_timeout
|
62
|
+
]
|
63
|
+
|
64
|
+
VALID_CONNECTION_KEYS = VALID_REQUEST_KEYS + [
|
65
|
+
:ciphers,
|
66
|
+
:client_key,
|
67
|
+
:client_cert,
|
68
|
+
:certificate,
|
69
|
+
:certificate_path,
|
70
|
+
:private_key,
|
71
|
+
:private_key_path,
|
72
|
+
:connect_timeout,
|
73
|
+
:family,
|
74
|
+
:host,
|
75
|
+
:omit_default_port,
|
76
|
+
:password,
|
77
|
+
:port,
|
78
|
+
:proxy,
|
70
79
|
:scheme,
|
71
|
-
:
|
72
|
-
:uri_parser,
|
73
|
-
:user,
|
80
|
+
:socket,
|
74
81
|
:ssl_ca_file,
|
75
82
|
:ssl_verify_peer,
|
76
|
-
:
|
77
|
-
:
|
83
|
+
:tcp_nodelay,
|
84
|
+
:uri_parser,
|
85
|
+
:user
|
78
86
|
]
|
79
87
|
|
80
|
-
VERSION = '0.26.0'
|
81
|
-
USER_AGENT = 'excon/' << VERSION
|
82
|
-
|
83
88
|
unless ::IO.const_defined?(:WaitReadable)
|
84
89
|
class ::IO
|
85
90
|
module WaitReadable; end
|
@@ -6,9 +6,9 @@ module Excon
|
|
6
6
|
Excon::Errors::HTTPStatusError].any? {|ex| datum[:error].kind_of?(ex) } && datum[:retries_remaining] > 1
|
7
7
|
# reduces remaining retries, reset connection, and restart request_call
|
8
8
|
datum[:retries_remaining] -= 1
|
9
|
-
datum.delete(:
|
10
|
-
datum.
|
11
|
-
|
9
|
+
connection = datum.delete(:connection)
|
10
|
+
datum.reject! {|key, _| !VALID_REQUEST_KEYS.include?(key) }
|
11
|
+
connection.request(datum)
|
12
12
|
else
|
13
13
|
@stack.error_call(datum)
|
14
14
|
end
|
data/lib/excon/ssl_socket.rb
CHANGED
@@ -10,7 +10,7 @@ module Excon
|
|
10
10
|
# create ssl context
|
11
11
|
ssl_context = OpenSSL::SSL::SSLContext.new
|
12
12
|
ssl_context.ciphers = @data[:ciphers]
|
13
|
-
|
13
|
+
|
14
14
|
if @data[:ssl_verify_peer]
|
15
15
|
# turn verification on
|
16
16
|
ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
@@ -103,7 +103,6 @@ module Excon
|
|
103
103
|
def check_nonblock_support
|
104
104
|
# backwards compatability for things lacking nonblock
|
105
105
|
if !DEFAULT_NONBLOCK && @data[:nonblock]
|
106
|
-
Excon.display_warning("Excon nonblock is not supported by your OpenSSL::SSL::SSLSocket")
|
107
106
|
@data[:nonblock] = false
|
108
107
|
end
|
109
108
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Excon
|
2
|
+
class UnixSocket < Excon::Socket
|
3
|
+
|
4
|
+
private
|
5
|
+
|
6
|
+
def connect
|
7
|
+
begin
|
8
|
+
@socket = ::UNIXSocket.new(@data[:socket])
|
9
|
+
rescue Errno::ECONNREFUSED
|
10
|
+
@socket.close if @socket
|
11
|
+
raise
|
12
|
+
end
|
13
|
+
|
14
|
+
if @data[:tcp_nodelay]
|
15
|
+
@socket.setsockopt(::Socket::IPPROTO_TCP,
|
16
|
+
::Socket::TCP_NODELAY,
|
17
|
+
true)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
Shindo.tests('Excon basics (Authorization data redacted)') do
|
2
|
+
with_rackup('basic_auth.ru') do
|
3
3
|
cases = [
|
4
4
|
['user & pass', 'http://user1:pass1@foo.com/', 'Basic dXNlcjE6cGFzczE='],
|
5
5
|
['email & pass', 'http://foo%40bar.com:pass1@foo.com/', 'Basic Zm9vQGJhci5jb206cGFzczE='],
|
data/tests/basic_tests.rb
CHANGED
@@ -1,67 +1,61 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
Shindo.tests('Excon basics') do
|
2
|
+
with_rackup('basic.ru') do
|
3
3
|
basic_tests
|
4
|
-
end
|
5
|
-
|
6
|
-
Shindo.tests('explicit uri passed to connection') do
|
7
|
-
connection = Excon::Connection.new({
|
8
|
-
:host => '127.0.0.1',
|
9
|
-
:nonblock => false,
|
10
|
-
:port => 9292,
|
11
|
-
:scheme => 'http',
|
12
|
-
:ssl_verify_peer => false
|
13
|
-
})
|
14
4
|
|
15
|
-
tests('
|
16
|
-
|
17
|
-
|
18
|
-
|
5
|
+
tests('explicit uri passed to connection') do
|
6
|
+
tests('GET /content-length/100').returns(200) do
|
7
|
+
connection = Excon::Connection.new({
|
8
|
+
:host => '127.0.0.1',
|
9
|
+
:nonblock => false,
|
10
|
+
:port => 9292,
|
11
|
+
:scheme => 'http',
|
12
|
+
:ssl_verify_peer => false
|
13
|
+
})
|
14
|
+
response = connection.request(:method => :get, :path => '/content-length/100')
|
19
15
|
response[:status]
|
20
16
|
end
|
21
17
|
end
|
22
18
|
end
|
23
19
|
end
|
24
20
|
|
25
|
-
|
26
|
-
|
21
|
+
Shindo.tests('Excon basics (Basic Auth Pass)') do
|
22
|
+
with_rackup('basic_auth.ru') do
|
27
23
|
basic_tests('http://test_user:test_password@127.0.0.1:9292')
|
28
|
-
end
|
29
24
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
25
|
+
tests('Excon basics (Basic Auth Fail)') do
|
26
|
+
cases = [
|
27
|
+
['correct user, no password', 'http://test_user@127.0.0.1:9292'],
|
28
|
+
['correct user, wrong password', 'http://test_user:fake_password@127.0.0.1:9292'],
|
29
|
+
['wrong user, correct password', 'http://fake_user:test_password@127.0.0.1:9292'],
|
30
|
+
]
|
31
|
+
cases.each do |desc,url|
|
32
|
+
tests("response.status for #{desc}").returns(401) do
|
33
|
+
connection = Excon.new(url)
|
34
|
+
response = connection.request(:method => :get, :path => '/content-length/100')
|
35
|
+
response.status
|
36
|
+
end
|
42
37
|
end
|
43
|
-
|
44
38
|
end
|
45
39
|
end
|
46
40
|
end
|
47
41
|
|
48
|
-
|
49
|
-
|
42
|
+
Shindo.tests('Excon basics (ssl)') do
|
43
|
+
with_rackup('ssl.ru') do
|
50
44
|
basic_tests('https://127.0.0.1:9443')
|
51
45
|
end
|
52
46
|
end
|
53
47
|
|
54
|
-
|
55
|
-
|
56
|
-
connection = Excon::Connection.new({
|
57
|
-
:host => '127.0.0.1',
|
58
|
-
:nonblock => false,
|
59
|
-
:port => 8443,
|
60
|
-
:scheme => 'https',
|
61
|
-
:ssl_verify_peer => false
|
62
|
-
})
|
48
|
+
Shindo.tests('Excon basics (ssl file)',['focus']) do
|
49
|
+
with_rackup('ssl_verify_peer.ru') do
|
63
50
|
|
64
51
|
tests('GET /content-length/100').raises(Excon::Errors::SocketError) do
|
52
|
+
connection = Excon::Connection.new({
|
53
|
+
:host => '127.0.0.1',
|
54
|
+
:nonblock => false,
|
55
|
+
:port => 8443,
|
56
|
+
:scheme => 'https',
|
57
|
+
:ssl_verify_peer => false
|
58
|
+
})
|
65
59
|
connection.request(:method => :get, :path => '/content-length/100')
|
66
60
|
end
|
67
61
|
|
@@ -72,17 +66,19 @@ with_rackup('ssl_verify_peer.ru') do
|
|
72
66
|
)
|
73
67
|
|
74
68
|
end
|
69
|
+
end
|
75
70
|
|
76
|
-
|
77
|
-
|
78
|
-
:host => '127.0.0.1',
|
79
|
-
:nonblock => false,
|
80
|
-
:port => 8443,
|
81
|
-
:scheme => 'https',
|
82
|
-
:ssl_verify_peer => false
|
83
|
-
})
|
71
|
+
Shindo.tests('Excon basics (ssl file paths)',['focus']) do
|
72
|
+
with_rackup('ssl_verify_peer.ru') do
|
84
73
|
|
85
74
|
tests('GET /content-length/100').raises(Excon::Errors::SocketError) do
|
75
|
+
connection = Excon::Connection.new({
|
76
|
+
:host => '127.0.0.1',
|
77
|
+
:nonblock => false,
|
78
|
+
:port => 8443,
|
79
|
+
:scheme => 'https',
|
80
|
+
:ssl_verify_peer => false
|
81
|
+
})
|
86
82
|
connection.request(:method => :get, :path => '/content-length/100')
|
87
83
|
end
|
88
84
|
|
@@ -92,19 +88,35 @@ with_rackup('ssl_verify_peer.ru') do
|
|
92
88
|
)
|
93
89
|
|
94
90
|
end
|
91
|
+
end
|
95
92
|
|
96
|
-
|
97
|
-
|
98
|
-
:host => '127.0.0.1',
|
99
|
-
:nonblock => false,
|
100
|
-
:port => 8443,
|
101
|
-
:scheme => 'https',
|
102
|
-
:ssl_verify_peer => false
|
103
|
-
})
|
104
|
-
|
93
|
+
Shindo.tests('Excon basics (ssl string)', ['focus']) do
|
94
|
+
with_rackup('ssl_verify_peer.ru') do
|
105
95
|
basic_tests('https://127.0.0.1:8443',
|
106
96
|
:private_key => File.read(File.join(File.dirname(__FILE__), 'data', 'excon.cert.key')),
|
107
97
|
:certificate => File.read(File.join(File.dirname(__FILE__), 'data', 'excon.cert.crt'))
|
108
98
|
)
|
109
99
|
end
|
110
100
|
end
|
101
|
+
|
102
|
+
Shindo.tests('Excon basics (Unix socket)') do
|
103
|
+
pending if RUBY_PLATFORM == 'java' # need to find suitable server for jruby
|
104
|
+
|
105
|
+
file_name = '/tmp/unicorn.sock'
|
106
|
+
with_unicorn('basic.ru', file_name) do
|
107
|
+
basic_tests("unix:/", :socket => file_name)
|
108
|
+
|
109
|
+
tests('explicit uri passed to connection') do
|
110
|
+
tests('GET /content-length/100').returns(200) do
|
111
|
+
connection = Excon::Connection.new({
|
112
|
+
:socket => file_name,
|
113
|
+
:nonblock => false,
|
114
|
+
:scheme => 'unix',
|
115
|
+
:ssl_verify_peer => false
|
116
|
+
})
|
117
|
+
response = connection.request(:method => :get, :path => '/content-length/100')
|
118
|
+
response[:status]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -84,11 +84,11 @@ Shindo.tests('Excon instrumentation') do
|
|
84
84
|
[:host, :path, :port, :scheme].select {|k| @events.first.payload.has_key? k}
|
85
85
|
end
|
86
86
|
|
87
|
-
tests('params in request overwrite those in constructor').returns('cheezburger') do
|
87
|
+
tests('params in request overwrite those in constructor').returns('/cheezburger') do
|
88
88
|
subscribe(/excon/)
|
89
89
|
stub_success
|
90
|
-
make_request(false, :
|
91
|
-
@events.first.payload[:
|
90
|
+
make_request(false, :path => '/cheezburger')
|
91
|
+
@events.first.payload[:path]
|
92
92
|
end
|
93
93
|
|
94
94
|
tests('notify on retry').returns(3) do
|
data/tests/query_string_tests.rb
CHANGED
data/tests/requests_tests.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
connection = Excon.new('http://127.0.0.1:9292')
|
1
|
+
Shindo.tests('requests should succeed') do
|
2
|
+
with_rackup('basic.ru') do
|
5
3
|
|
6
4
|
tests('HEAD /content-length/100, GET /content-length/100') do
|
5
|
+
|
6
|
+
connection = Excon.new('http://127.0.0.1:9292')
|
7
7
|
responses = connection.requests([
|
8
8
|
{:method => :head, :path => '/content-length/100'},
|
9
9
|
{:method => :get, :path => '/content-length/100'}
|
@@ -27,19 +27,18 @@ with_rackup('basic.ru') do
|
|
27
27
|
|
28
28
|
end
|
29
29
|
|
30
|
-
|
30
|
+
tests('requests should succeed with tcp_nodelay') do
|
31
31
|
|
32
|
-
|
32
|
+
connection = Excon.new('http://127.0.0.1:9292', :tcp_nodelay => true)
|
33
33
|
|
34
|
-
|
34
|
+
tests('GET /content-length/100') do
|
35
|
+
responses = connection.requests([
|
36
|
+
{:method => :get, :path => '/content-length/100'}
|
37
|
+
])
|
35
38
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
])
|
40
|
-
|
41
|
-
tests('get content length is 100').returns('100') do
|
42
|
-
responses.last.headers['Content-Length']
|
39
|
+
tests('get content length is 100').returns('100') do
|
40
|
+
responses.last.headers['Content-Length']
|
41
|
+
end
|
43
42
|
end
|
44
43
|
end
|
45
44
|
end
|
data/tests/test_helper.rb
CHANGED
@@ -23,6 +23,7 @@ def basic_tests(url = 'http://127.0.0.1:9292', options = {})
|
|
23
23
|
end
|
24
24
|
|
25
25
|
tests("response.headers['Connection']").returns('Keep-Alive') do
|
26
|
+
pending if connection.data[:scheme] == Excon::UNIX
|
26
27
|
response.headers['Connection']
|
27
28
|
end
|
28
29
|
|
@@ -35,10 +36,12 @@ def basic_tests(url = 'http://127.0.0.1:9292', options = {})
|
|
35
36
|
end
|
36
37
|
|
37
38
|
test("Time.parse(response.headers['Date']).is_a?(Time)") do
|
39
|
+
pending if connection.data[:scheme] == Excon::UNIX
|
38
40
|
Time.parse(response.headers['Date']).is_a?(Time)
|
39
41
|
end
|
40
42
|
|
41
43
|
test("!!(response.headers['Server'] =~ /^WEBrick/)") do
|
44
|
+
pending if connection.data[:scheme] == Excon::UNIX
|
42
45
|
!!(response.headers['Server'] =~ /^WEBrick/)
|
43
46
|
end
|
44
47
|
|
@@ -47,6 +50,7 @@ def basic_tests(url = 'http://127.0.0.1:9292', options = {})
|
|
47
50
|
end
|
48
51
|
|
49
52
|
tests("response.remote_ip").returns("127.0.0.1") do
|
53
|
+
pending if connection.data[:scheme] == Excon::UNIX
|
50
54
|
response.remote_ip
|
51
55
|
end
|
52
56
|
|
@@ -56,8 +60,10 @@ def basic_tests(url = 'http://127.0.0.1:9292', options = {})
|
|
56
60
|
|
57
61
|
tests("deprecated block usage").returns(['x' * 100, 0, 100]) do
|
58
62
|
data = []
|
59
|
-
|
60
|
-
|
63
|
+
silence_warnings do
|
64
|
+
connection.request(:method => :get, :path => '/content-length/100') do |chunk, remaining_length, total_length|
|
65
|
+
data = [chunk, remaining_length, total_length]
|
66
|
+
end
|
61
67
|
end
|
62
68
|
data
|
63
69
|
end
|
@@ -194,6 +200,14 @@ def env_stack
|
|
194
200
|
@env_stack ||= []
|
195
201
|
end
|
196
202
|
|
203
|
+
def silence_warnings
|
204
|
+
orig_verbose = $VERBOSE
|
205
|
+
$VERBOSE = nil
|
206
|
+
yield
|
207
|
+
ensure
|
208
|
+
$VERBOSE = orig_verbose
|
209
|
+
end
|
210
|
+
|
197
211
|
def rackup_path(*parts)
|
198
212
|
File.expand_path(File.join(File.dirname(__FILE__), 'rackups', *parts))
|
199
213
|
end
|
@@ -215,6 +229,26 @@ ensure
|
|
215
229
|
end
|
216
230
|
end
|
217
231
|
|
232
|
+
def with_unicorn(name, file_name='/tmp/unicorn.sock')
|
233
|
+
unless RUBY_PLATFORM == 'java'
|
234
|
+
GC.disable
|
235
|
+
pid, w, r, e = Open4.popen4("unicorn", "-l", "unix://#{file_name}", rackup_path(name))
|
236
|
+
until e.gets =~ /worker=0 ready/; end
|
237
|
+
else
|
238
|
+
# need to find suitable server for jruby
|
239
|
+
end
|
240
|
+
yield
|
241
|
+
ensure
|
242
|
+
unless RUBY_PLATFORM == 'java'
|
243
|
+
Process.kill(9, pid)
|
244
|
+
GC.enable
|
245
|
+
Process.wait(pid)
|
246
|
+
end
|
247
|
+
if File.exist?(file_name)
|
248
|
+
File.delete(file_name)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
218
252
|
def server_path(*parts)
|
219
253
|
File.expand_path(File.join(File.dirname(__FILE__), 'servers', *parts))
|
220
254
|
end
|
data/tests/timeout_tests.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
[false, true].each do |nonblock|
|
1
|
+
Shindo.tests('read should timeout') do
|
2
|
+
with_rackup('timeout.ru') do
|
4
3
|
|
4
|
+
[false, true].each do |nonblock|
|
5
5
|
connection = Excon.new('http://127.0.0.1:9292', :nonblock => nonblock)
|
6
6
|
|
7
7
|
tests("nonblock => #{nonblock} hits read_timeout").raises(Excon::Errors::Timeout) do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: excon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.27.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2013-
|
14
|
+
date: 2013-10-04 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: activesupport
|
@@ -189,6 +189,7 @@ files:
|
|
189
189
|
- lib/excon/socket.rb
|
190
190
|
- lib/excon/ssl_socket.rb
|
191
191
|
- lib/excon/standard_instrumentor.rb
|
192
|
+
- lib/excon/unix_socket.rb
|
192
193
|
- tests/authorization_header_tests.rb
|
193
194
|
- tests/bad_tests.rb
|
194
195
|
- tests/basic_tests.rb
|
@@ -242,7 +243,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
242
243
|
version: '0'
|
243
244
|
segments:
|
244
245
|
- 0
|
245
|
-
hash:
|
246
|
+
hash: 1969698144445099887
|
246
247
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
247
248
|
none: false
|
248
249
|
requirements:
|