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 CHANGED
@@ -3,6 +3,7 @@ source "http://rubygems.org"
3
3
  gemspec
4
4
 
5
5
  gem 'jruby-openssl', :platform => :jruby
6
+ gem 'unicorn', :platform => :mri
6
7
 
7
8
  # group :benchmark do
8
9
  # gem 'em-http-request'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- excon (0.26.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 receieved after everything is read to the final empty chunk
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. Because of this it is unavailable in one-off requests (Excon.get, etc.)
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.26.0'
17
- s.date = '2013-09-24'
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 convention mandates complete silence when VERBOSE == nil
80
- $stderr.puts(warning) if !ENV['VERBOSE'].nil?
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
@@ -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})") if !ENV['VERBOSE'].nil?
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
- invalid_keys_warning(params, Excon::VALID_CONNECTION_KEYS)
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
- no_proxy_env = ENV["no_proxy"] || ENV["NO_PROXY"] || ""
59
- no_proxy_list = no_proxy_env.scan(/\*?\.?([^\s,:]+)(?::(\d+))?/i).map { |s| [s[0], s[1]] }
60
- unless no_proxy_list.index { |h| /(^|\.)#{h[0]}$/.match(@data[:host]) && (h[1].nil? || h[1].to_i == @data[:port]) }
61
- if @data[:scheme] == HTTPS && (ENV.has_key?('https_proxy') || ENV.has_key?('HTTPS_PROXY'))
62
- @data[:proxy] = setup_proxy(ENV['https_proxy'] || ENV['HTTPS_PROXY'])
63
- elsif (ENV.has_key?('http_proxy') || ENV.has_key?('HTTP_PROXY'))
64
- @data[:proxy] = setup_proxy(ENV['http_proxy'] || ENV['HTTP_PROXY'])
65
- elsif @data.has_key?(:proxy)
66
- @data[:proxy] = setup_proxy(@data[:proxy])
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] << '://' << @data[:host] << ':' << @data[:port].to_s
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
- datum[:headers]['Host'] ||= '' << datum[:host] << port_string(datum)
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 invalid_keys_warning(argument, valid_keys)
342
- invalid_keys = argument.keys - valid_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
@@ -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
- VALID_CONNECTION_KEYS = [
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
- :tcp_nodelay,
72
- :uri_parser,
73
- :user,
80
+ :socket,
74
81
  :ssl_ca_file,
75
82
  :ssl_verify_peer,
76
- :stack,
77
- :write_timeout
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(:response)
10
- datum.delete(:error)
11
- datum[:connection].request(datum)
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
@@ -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
- with_rackup('basic_auth.ru') do
2
- Shindo.tests('Excon basics (Authorization data redacted)') do
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
- with_rackup('basic.ru') do
2
- Shindo.tests('Excon basics') do
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('GET /content-length/100') do
16
- response = connection.request(:method => :get, :path => '/content-length/100')
17
-
18
- tests('response[:status]').returns(200) do
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
- with_rackup('basic_auth.ru') do
26
- Shindo.tests('Excon basics (Basic Auth Pass)') do
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
- Shindo.tests('Excon basics (Basic Auth Fail)') do
31
- cases = [
32
- ['correct user, no password', 'http://test_user@127.0.0.1:9292'],
33
- ['correct user, wrong password', 'http://test_user:fake_password@127.0.0.1:9292'],
34
- ['wrong user, correct password', 'http://fake_user:test_password@127.0.0.1:9292'],
35
- ]
36
- cases.each do |desc,url|
37
- connection = Excon.new(url)
38
- response = connection.request(:method => :get, :path => '/content-length/100')
39
-
40
- tests("response.status for #{desc}").returns(401) do
41
- response.status
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
- with_rackup('ssl.ru') do
49
- Shindo.tests('Excon basics (ssl)') do
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
- with_rackup('ssl_verify_peer.ru') do
55
- Shindo.tests('Excon basics (ssl file)',['focus']) do
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
- Shindo.tests('Excon basics (ssl file paths)',['focus']) do
77
- connection = Excon::Connection.new({
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
- Shindo.tests('Excon basics (ssl string)', ['focus']) do
97
- connection = Excon::Connection.new({
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, :host => 'cheezburger')
91
- @events.first.payload[:host]
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
@@ -1,5 +1,5 @@
1
- with_rackup('query_string.ru') do
2
- Shindo.tests('Excon query string variants') do
1
+ Shindo.tests('Excon query string variants') do
2
+ with_rackup('query_string.ru') do
3
3
  connection = Excon.new('http://127.0.0.1:9292')
4
4
 
5
5
  tests(":query => {:foo => 'bar'}") do
@@ -1,9 +1,9 @@
1
- with_rackup('basic.ru') do
2
- Shindo.tests('requests should succeed') do
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
- end
30
+ tests('requests should succeed with tcp_nodelay') do
31
31
 
32
- Shindo.tests('requests should succeed with tcp_nodelay') do
32
+ connection = Excon.new('http://127.0.0.1:9292', :tcp_nodelay => true)
33
33
 
34
- connection = Excon.new('http://127.0.0.1:9292', :tcp_nodelay => true)
34
+ tests('GET /content-length/100') do
35
+ responses = connection.requests([
36
+ {:method => :get, :path => '/content-length/100'}
37
+ ])
35
38
 
36
- tests('GET /content-length/100') do
37
- responses = connection.requests([
38
- {:method => :get, :path => '/content-length/100'}
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
- connection.request(:method => :get, :path => '/content-length/100') do |chunk, remaining_length, total_length|
60
- data = [chunk, remaining_length, total_length]
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
@@ -1,5 +1,5 @@
1
- with_rackup('thread_safety.ru') do
2
- Shindo.tests('Excon thread safety') do
1
+ Shindo.tests('Excon thread safety') do
2
+ with_rackup('thread_safety.ru') do
3
3
  connection = Excon.new('http://127.0.0.1:9292')
4
4
 
5
5
  long_thread = Thread.new {
@@ -1,7 +1,7 @@
1
- with_rackup('timeout.ru') do
2
- Shindo.tests('read should timeout') do
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.26.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-09-24 00:00:00.000000000 Z
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: -2550839664096284654
246
+ hash: 1969698144445099887
246
247
  required_rubygems_version: !ruby/object:Gem::Requirement
247
248
  none: false
248
249
  requirements: