excon 0.16.4 → 0.16.5

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.

@@ -1,3 +1,14 @@
1
+ 0.16.5 10/17/2012
2
+ =================
3
+
4
+ Also retry Timeouts on idempotent requests
5
+ Excon.stub now breaks out user/pass from url if supplied
6
+ loosen ssl version requirement to allow negotiation
7
+ eof on read should return '' instead of nil
8
+ build host_port up front to avoid recalculating
9
+ set Proxy-Connection: Keep-Alive for https proxies
10
+ postpone https upgrade until after proxy connect
11
+
1
12
  0.16.4 09/25/2012
2
13
  =================
3
14
 
@@ -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.16.4'
17
- s.date = '2012-09-25'
16
+ s.version = '0.16.5'
17
+ s.date = '2012-10-17'
18
18
  s.rubyforge_project = 'excon'
19
19
 
20
20
  ## Make sure your summary is short. The description may be as long
@@ -119,6 +119,7 @@ Gem::Specification.new do |s|
119
119
  tests/rackups/timeout.ru
120
120
  tests/request_method_tests.rb
121
121
  tests/servers/bad.rb
122
+ tests/servers/eof.rb
122
123
  tests/stub_tests.rb
123
124
  tests/test_helper.rb
124
125
  tests/thread_safety_tests.rb
@@ -103,6 +103,20 @@ module Excon
103
103
  # @param [Hash<Symbol, >] request params to match against, omitted params match all
104
104
  # @param [Hash<Symbol, >] response params to return from matched request or block to call with params
105
105
  def stub(request_params, response_params = nil)
106
+ if url = request_params.delete(:url)
107
+ uri = URI.parse(url)
108
+ request_params.update(
109
+ :host => uri.host,
110
+ :path => uri.path,
111
+ :port => uri.port.to_s,
112
+ :query => uri.query,
113
+ :scheme => uri.scheme
114
+ )
115
+ if uri.user || uri.password
116
+ request_params[:headers] ||= {}
117
+ request_params[:headers]['Authorization'] ||= 'Basic ' << ['' << uri.user.to_s << ':' << uri.password.to_s].pack('m').delete(Excon::CR_NL)
118
+ end
119
+ end
106
120
  if block_given?
107
121
  if response_params
108
122
  raise(ArgumentError.new("stub requires either response_params OR a block"))
@@ -19,11 +19,12 @@ module Excon
19
19
  def initialize(url, params = {})
20
20
  uri = URI.parse(url)
21
21
  @connection = Excon.defaults.merge({
22
- :host => uri.host,
23
- :path => uri.path,
24
- :port => uri.port.to_s,
25
- :query => uri.query,
26
- :scheme => uri.scheme,
22
+ :host => uri.host,
23
+ :host_port => '' << uri.host << ':' << uri.port.to_s,
24
+ :path => uri.path,
25
+ :port => uri.port.to_s,
26
+ :query => uri.query,
27
+ :scheme => uri.scheme,
27
28
  }).merge!(params)
28
29
  # merge does not deep-dup, so make sure headers is not the original
29
30
  @connection[:headers] = @connection[:headers].dup
@@ -56,7 +57,7 @@ module Excon
56
57
  @connection[:headers]['Authorization'] ||= 'Basic ' << ['' << uri.user.to_s << ':' << uri.password.to_s].pack('m').delete(Excon::CR_NL)
57
58
  end
58
59
 
59
- @socket_key = '' << @connection[:host] << ':' << @connection[:port].to_s
60
+ @socket_key = '' << @connection[:host_port]
60
61
  reset
61
62
  end
62
63
 
@@ -74,7 +75,7 @@ module Excon
74
75
  # connection has defaults, merge in new params to override
75
76
  params = @connection.merge(params)
76
77
  params[:headers] = @connection[:headers].merge(params[:headers] || {})
77
- params[:headers]['Host'] ||= '' << params[:host] << ':' << params[:port]
78
+ params[:headers]['Host'] ||= '' << params[:host_port]
78
79
 
79
80
  # if path is empty or doesn't start with '/', insert one
80
81
  unless params[:path][0, 1] == '/'
@@ -101,7 +102,7 @@ module Excon
101
102
  request_kernel(params)
102
103
  end
103
104
  rescue => request_error
104
- if params[:idempotent] && [Excon::Errors::SocketError,
105
+ if params[:idempotent] && [Excon::Errors::Timeout, Excon::Errors::SocketError,
105
106
  Excon::Errors::HTTPStatusError].any? {|ex| request_error.kind_of? ex }
106
107
  retries_remaining ||= params[:retry_limit]
107
108
  retries_remaining -= 1
@@ -194,7 +195,7 @@ module Excon
194
195
  # start with "METHOD /path"
195
196
  request = params[:method].to_s.upcase << ' '
196
197
  if @proxy
197
- request << params[:scheme] << '://' << params[:host] << ':' << params[:port]
198
+ request << params[:scheme] << '://' << params[:host_port]
198
199
  end
199
200
  request << params[:path]
200
201
 
@@ -375,11 +376,12 @@ module Excon
375
376
  raise Excon::Errors::ProxyParseError, "Proxy is invalid"
376
377
  end
377
378
  {
378
- :host => uri.host,
379
- :password => uri.password,
380
- :port => uri.port,
381
- :scheme => uri.scheme,
382
- :user => uri.user
379
+ :host => uri.host,
380
+ :host_port => '' << uri.host << ':' << uri.port.to_s,
381
+ :password => uri.password,
382
+ :port => uri.port,
383
+ :scheme => uri.scheme,
384
+ :user => uri.user
383
385
  }
384
386
  end
385
387
 
@@ -29,7 +29,7 @@ module Excon
29
29
 
30
30
  REDACTED = 'REDACTED'
31
31
 
32
- VERSION = '0.16.4'
32
+ VERSION = '0.16.5'
33
33
 
34
34
  unless ::IO.const_defined?(:WaitReadable)
35
35
  class ::IO
@@ -78,7 +78,7 @@ module Excon
78
78
  def read(max_length=nil)
79
79
  return nil if @eof
80
80
  if @eof
81
- nil
81
+ ''
82
82
  elsif @params[:nonblock]
83
83
  begin
84
84
  if max_length
@@ -9,7 +9,6 @@ module Excon
9
9
 
10
10
  # create ssl context
11
11
  ssl_context = OpenSSL::SSL::SSLContext.new
12
- ssl_context.ssl_version = 'SSLv3'
13
12
 
14
13
  if params[:ssl_verify_peer]
15
14
  # turn verification on
@@ -35,28 +34,26 @@ module Excon
35
34
  ssl_context.key = OpenSSL::PKey::RSA.new(File.read(@params[:client_key]))
36
35
  end
37
36
 
38
- @socket = OpenSSL::SSL::SSLSocket.new(@socket, ssl_context)
39
- @socket.sync_close = true
40
-
41
37
  if @proxy
42
- request = 'CONNECT ' << @params[:host] << ':' << @params[:port] << Excon::HTTP_1_1
43
- request << 'Host: ' << @params[:host] << ':' << @params[:port] << Excon::CR_NL
38
+ request = 'CONNECT ' << @params[:host_port] << Excon::HTTP_1_1
39
+ request << 'Host: ' << @params[:host_port] << Excon::CR_NL
44
40
 
45
41
  if @proxy[:password] || @proxy[:user]
46
42
  auth = ['' << @proxy[:user].to_s << ':' << @proxy[:password].to_s].pack('m').delete(Excon::CR_NL)
47
43
  request << "Proxy-Authorization: Basic " << auth << Excon::CR_NL
48
44
  end
49
45
 
46
+ request << 'Proxy-Connection: Keep-Alive' << Excon::CR_NL
47
+
50
48
  request << Excon::CR_NL
51
49
 
52
50
  # write out the proxy setup request
53
51
  @socket.write(request)
54
-
55
- # eat the proxy's connection response
56
- Excon::Response.parse(@socket, {})
57
52
  end
58
53
 
59
- # connect the new OpenSSL::SSL::SSLSocket
54
+ # convert Socket to OpenSSL::SSL::SSLSocket
55
+ @socket = OpenSSL::SSL::SSLSocket.new(@socket, ssl_context)
56
+ @socket.sync_close = true
60
57
  @socket.connect
61
58
 
62
59
  # Server Name Indication (SNI) RFC 3546
@@ -32,4 +32,16 @@ Shindo.tests('Excon bad server interaction') do
32
32
 
33
33
  end
34
34
 
35
+ with_server('eof') do
36
+
37
+ tests('eof server: causes EOFError') do
38
+
39
+ tests('request').raises(Excon::Errors::SocketError) do
40
+ Excon.get('http://127.0.0.1:9292/eof')
41
+ end
42
+
43
+ end
44
+
45
+ end
46
+
35
47
  end
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "eventmachine"
4
+
5
+ module EOFServer
6
+ def receive_data(data)
7
+ case data
8
+ when %r{^GET /eof\s}
9
+ close_connection(true)
10
+ end
11
+ end
12
+ end
13
+
14
+ EM.run do
15
+ EM.start_server("127.0.0.1", 9292, EOFServer)
16
+ $stderr.puts "ready"
17
+ end
@@ -148,6 +148,16 @@ Shindo.tests('Excon stubs') do
148
148
 
149
149
  Excon.stubs.clear
150
150
 
151
+ tests("stub({:url => 'https://user:pass@foo.bar.com:9999/baz?quux=true'}, {:status => 200})") do
152
+ Excon.stub({:url => 'https://user:pass@foo.bar.com:9999/baz?quux=true'}, {:status => 200})
153
+
154
+ tests("get(:expects => 200)") do
155
+ Excon.new("https://user:pass@foo.bar.com:9999/baz?quux=true", :mock => true).get(:expects => 200)
156
+ end
157
+ end
158
+
159
+ Excon.stubs.clear
160
+
151
161
  tests("stub({}, {:status => 404, :body => 'Not Found'}") do
152
162
 
153
163
  connection = Excon.new('http://127.0.0.1:9292', :mock => true)
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.16.4
4
+ version: 0.16.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,11 +11,11 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-09-25 00:00:00.000000000 Z
14
+ date: 2012-10-17 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activesupport
18
- requirement: &70229726929200 !ruby/object:Gem::Requirement
18
+ requirement: !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ! '>='
@@ -23,10 +23,15 @@ dependencies:
23
23
  version: '0'
24
24
  type: :development
25
25
  prerelease: false
26
- version_requirements: *70229726929200
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - ! '>='
30
+ - !ruby/object:Gem::Version
31
+ version: '0'
27
32
  - !ruby/object:Gem::Dependency
28
33
  name: delorean
29
- requirement: &70229726928740 !ruby/object:Gem::Requirement
34
+ requirement: !ruby/object:Gem::Requirement
30
35
  none: false
31
36
  requirements:
32
37
  - - ! '>='
@@ -34,10 +39,15 @@ dependencies:
34
39
  version: '0'
35
40
  type: :development
36
41
  prerelease: false
37
- version_requirements: *70229726928740
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
38
48
  - !ruby/object:Gem::Dependency
39
49
  name: open4
40
- requirement: &70229726928320 !ruby/object:Gem::Requirement
50
+ requirement: !ruby/object:Gem::Requirement
41
51
  none: false
42
52
  requirements:
43
53
  - - ! '>='
@@ -45,10 +55,15 @@ dependencies:
45
55
  version: '0'
46
56
  type: :development
47
57
  prerelease: false
48
- version_requirements: *70229726928320
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
49
64
  - !ruby/object:Gem::Dependency
50
65
  name: rake
51
- requirement: &70229726927900 !ruby/object:Gem::Requirement
66
+ requirement: !ruby/object:Gem::Requirement
52
67
  none: false
53
68
  requirements:
54
69
  - - ! '>='
@@ -56,10 +71,15 @@ dependencies:
56
71
  version: '0'
57
72
  type: :development
58
73
  prerelease: false
59
- version_requirements: *70229726927900
74
+ version_requirements: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
60
80
  - !ruby/object:Gem::Dependency
61
81
  name: rdoc
62
- requirement: &70229726927480 !ruby/object:Gem::Requirement
82
+ requirement: !ruby/object:Gem::Requirement
63
83
  none: false
64
84
  requirements:
65
85
  - - ! '>='
@@ -67,10 +87,15 @@ dependencies:
67
87
  version: '0'
68
88
  type: :development
69
89
  prerelease: false
70
- version_requirements: *70229726927480
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
71
96
  - !ruby/object:Gem::Dependency
72
97
  name: shindo
73
- requirement: &70229726943440 !ruby/object:Gem::Requirement
98
+ requirement: !ruby/object:Gem::Requirement
74
99
  none: false
75
100
  requirements:
76
101
  - - ! '>='
@@ -78,10 +103,15 @@ dependencies:
78
103
  version: '0'
79
104
  type: :development
80
105
  prerelease: false
81
- version_requirements: *70229726943440
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
82
112
  - !ruby/object:Gem::Dependency
83
113
  name: sinatra
84
- requirement: &70229726943020 !ruby/object:Gem::Requirement
114
+ requirement: !ruby/object:Gem::Requirement
85
115
  none: false
86
116
  requirements:
87
117
  - - ! '>='
@@ -89,7 +119,12 @@ dependencies:
89
119
  version: '0'
90
120
  type: :development
91
121
  prerelease: false
92
- version_requirements: *70229726943020
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ! '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
93
128
  description: EXtended http(s) CONnections
94
129
  email: geemus@gmail.com
95
130
  executables: []
@@ -150,6 +185,7 @@ files:
150
185
  - tests/rackups/timeout.ru
151
186
  - tests/request_method_tests.rb
152
187
  - tests/servers/bad.rb
188
+ - tests/servers/eof.rb
153
189
  - tests/stub_tests.rb
154
190
  - tests/test_helper.rb
155
191
  - tests/thread_safety_tests.rb
@@ -169,7 +205,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
169
205
  version: '0'
170
206
  segments:
171
207
  - 0
172
- hash: 2397568301879595027
208
+ hash: 1584881564479548792
173
209
  required_rubygems_version: !ruby/object:Gem::Requirement
174
210
  none: false
175
211
  requirements:
@@ -178,7 +214,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
178
214
  version: '0'
179
215
  requirements: []
180
216
  rubyforge_project: excon
181
- rubygems_version: 1.8.15
217
+ rubygems_version: 1.8.23
182
218
  signing_key:
183
219
  specification_version: 2
184
220
  summary: speed, persistence, http(s)