net-http-persistent 2.9.4 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of net-http-persistent might be problematic. Click here for more details.

@@ -0,0 +1,40 @@
1
+ ##
2
+ # A Net::HTTP connection wrapper that holds extra information for managing the
3
+ # connection's lifetime.
4
+
5
+ class Net::HTTP::Persistent::Connection # :nodoc:
6
+
7
+ attr_accessor :http
8
+
9
+ attr_accessor :last_use
10
+
11
+ attr_accessor :requests
12
+
13
+ attr_accessor :ssl_generation
14
+
15
+ def initialize http_class, http_args, ssl_generation
16
+ @http = http_class.new(*http_args)
17
+ @ssl_generation = ssl_generation
18
+
19
+ reset
20
+ end
21
+
22
+ def finish
23
+ @http.finish
24
+ rescue IOError
25
+ ensure
26
+ reset
27
+ end
28
+
29
+ def reset
30
+ @last_use = Net::HTTP::Persistent::EPOCH
31
+ @requests = 0
32
+ end
33
+
34
+ def ressl ssl_generation
35
+ @ssl_generation = ssl_generation
36
+
37
+ finish
38
+ end
39
+
40
+ end
@@ -0,0 +1,46 @@
1
+ class Net::HTTP::Persistent::Pool < ConnectionPool # :nodoc:
2
+
3
+ attr_reader :available # :nodoc:
4
+ attr_reader :key # :nodoc:
5
+
6
+ def initialize(options = {}, &block)
7
+ super
8
+
9
+ @available = Net::HTTP::Persistent::TimedStackMulti.new(@size, &block)
10
+ @key = :"current-#{@available.object_id}"
11
+ end
12
+
13
+ def checkin net_http_args
14
+ stack = Thread.current[@key][net_http_args]
15
+
16
+ raise ConnectionPool::Error, 'no connections are checked out' if
17
+ stack.empty?
18
+
19
+ conn = stack.pop
20
+
21
+ if stack.empty?
22
+ @available.push conn, connection_args: net_http_args
23
+ end
24
+
25
+ nil
26
+ end
27
+
28
+ def checkout net_http_args
29
+ stacks = Thread.current[@key] ||= Hash.new { |h, k| h[k] = [] }
30
+ stack = stacks[net_http_args]
31
+
32
+ if stack.empty? then
33
+ conn = @available.pop connection_args: net_http_args
34
+ else
35
+ conn = stack.last
36
+ end
37
+
38
+ stack.push conn
39
+
40
+ conn
41
+ end
42
+
43
+ end
44
+
45
+ require 'net/http/persistent/timed_stack_multi'
46
+
@@ -0,0 +1,69 @@
1
+ class Net::HTTP::Persistent::TimedStackMulti < ConnectionPool::TimedStack # :nodoc:
2
+
3
+ def initialize(size = 0, &block)
4
+ super
5
+
6
+ @enqueued = 0
7
+ @ques = Hash.new { |h, k| h[k] = [] }
8
+ @lru = {}
9
+ @key = :"connection_args-#{object_id}"
10
+ end
11
+
12
+ def empty?
13
+ (@created - @enqueued) >= @max
14
+ end
15
+
16
+ def length
17
+ @max - @created + @enqueued
18
+ end
19
+
20
+ private
21
+
22
+ def connection_stored? options = {} # :nodoc:
23
+ !@ques[options[:connection_args]].empty?
24
+ end
25
+
26
+ def fetch_connection options = {} # :nodoc:
27
+ connection_args = options[:connection_args]
28
+
29
+ @enqueued -= 1
30
+ lru_update connection_args
31
+ @ques[connection_args].pop
32
+ end
33
+
34
+ def lru_update connection_args # :nodoc:
35
+ @lru.delete connection_args
36
+ @lru[connection_args] = true
37
+ end
38
+
39
+ def shutdown_connections # :nodoc:
40
+ @ques.each_key do |key|
41
+ super connection_args: key
42
+ end
43
+ end
44
+
45
+ def store_connection obj, options = {} # :nodoc:
46
+ @ques[options[:connection_args]].push obj
47
+ @enqueued += 1
48
+ end
49
+
50
+ def try_create options = {} # :nodoc:
51
+ connection_args = options[:connection_args]
52
+
53
+ if @created >= @max && @enqueued >= 1
54
+ oldest, = @lru.first
55
+ @lru.delete oldest
56
+ @ques[oldest].pop
57
+
58
+ @created -= 1
59
+ end
60
+
61
+ if @created < @max
62
+ @created += 1
63
+ lru_update connection_args
64
+ return @create_block.call(connection_args)
65
+ end
66
+ end
67
+
68
+ end
69
+
@@ -51,21 +51,9 @@ class Net::HTTP
51
51
  include Net::HTTP::Persistent::TestConnect
52
52
  end
53
53
 
54
- class Net::HTTP::Persistent::SSLReuse
55
- include Net::HTTP::Persistent::TestConnect
56
- end
57
-
58
54
  class TestNetHttpPersistent < Minitest::Test
59
55
 
60
- RUBY_1 = RUBY_VERSION < '2'
61
-
62
56
  def setup
63
- @http_class = if RUBY_1 and HAVE_OPENSSL then
64
- Net::HTTP::Persistent::SSLReuse
65
- else
66
- Net::HTTP
67
- end
68
-
69
57
  @http = Net::HTTP::Persistent.new
70
58
 
71
59
  @uri = URI.parse 'http://example.com/path'
@@ -80,25 +68,23 @@ class TestNetHttpPersistent < Minitest::Test
80
68
  ENV.delete 'NO_PROXY'
81
69
 
82
70
  Net::HTTP.use_connect :test_connect
83
- Net::HTTP::Persistent::SSLReuse.use_connect :test_connect
84
71
  end
85
72
 
86
73
  def teardown
87
- Thread.current.keys.each do |key|
88
- Thread.current[key] = nil
89
- end
90
-
91
74
  Net::HTTP.use_connect :orig_connect
92
- Net::HTTP::Persistent::SSLReuse.use_connect :orig_connect
93
75
  end
94
76
 
95
77
  class BasicConnection
96
- attr_accessor :started, :finished, :address, :port,
97
- :read_timeout, :open_timeout
78
+ attr_accessor :started, :finished, :address, :port, :use_ssl,
79
+ :read_timeout, :open_timeout, :keep_alive_timeout
80
+ attr_accessor :ciphers, :ssl_timeout, :ssl_version,
81
+ :verify_depth, :verify_mode, :cert_store,
82
+ :ca_file, :ca_path, :cert, :key
98
83
  attr_reader :req, :debug_output
99
84
  def initialize
100
85
  @started, @finished = 0, 0
101
86
  @address, @port = 'example.com', 80
87
+ @use_ssl = false
102
88
  end
103
89
  def finish
104
90
  @finished += 1
@@ -125,21 +111,32 @@ class TestNetHttpPersistent < Minitest::Test
125
111
  def started?
126
112
  @started >= 1
127
113
  end
114
+ def proxy_address
115
+ end
116
+ def proxy_port
117
+ end
128
118
  end
129
119
 
130
120
  def basic_connection
131
121
  raise "#{@uri} is not HTTP" unless @uri.scheme.downcase == 'http'
132
122
 
133
- c = BasicConnection.new
134
- conns[0]["#{@uri.host}:#{@uri.port}"] = c
135
- c
123
+ net_http_args = [@uri.host, @uri.port]
124
+
125
+ connection = Net::HTTP::Persistent::Connection.allocate
126
+ connection.ssl_generation = @http.ssl_generation
127
+ connection.http = BasicConnection.new
128
+ connection.reset
129
+
130
+ @http.pool.available.push connection, connection_args: net_http_args
131
+
132
+ connection
136
133
  end
137
134
 
138
135
  def connection
139
- c = basic_connection
140
- touts[c.object_id] = Time.now
136
+ connection = basic_connection
137
+ connection.last_use = Time.now
141
138
 
142
- def c.request(req)
139
+ def (connection.http).request(req)
143
140
  @req = req
144
141
  r = Net::HTTPResponse.allocate
145
142
  r.instance_variable_set :@header, {}
@@ -149,30 +146,22 @@ class TestNetHttpPersistent < Minitest::Test
149
146
  r
150
147
  end
151
148
 
152
- c
149
+ connection
153
150
  end
154
151
 
155
- def conns
156
- Thread.current[@http.generation_key] ||= Hash.new { |h,k| h[k] = {} }
157
- end
152
+ def ssl_connection
153
+ raise "#{@uri} is not HTTPS" unless @uri.scheme.downcase == 'https'
158
154
 
159
- def reqs
160
- Thread.current[@http.request_key] ||= Hash.new 0
161
- end
155
+ net_http_args = [@uri.host, @uri.port]
162
156
 
163
- def ssl_conns
164
- Thread.current[@http.ssl_generation_key] ||= Hash.new { |h,k| h[k] = {} }
165
- end
157
+ connection = Net::HTTP::Persistent::Connection.allocate
158
+ connection.ssl_generation = @http.ssl_generation
159
+ connection.http = BasicConnection.new
160
+ connection.reset
166
161
 
167
- def ssl_connection generation = 0
168
- raise "#{@uri} is not HTTPS" unless @uri.scheme.downcase == 'https'
169
- c = BasicConnection.new
170
- ssl_conns[generation]["#{@uri.host}:#{@uri.port}"] = c
171
- c
172
- end
162
+ @http.pool.available.push connection, connection_args: net_http_args
173
163
 
174
- def touts
175
- Thread.current[@http.timeout_key] ||= Hash.new Net::HTTP::Persistent::EPOCH
164
+ connection
176
165
  end
177
166
 
178
167
  def test_initialize
@@ -188,7 +177,7 @@ class TestNetHttpPersistent < Minitest::Test
188
177
  end
189
178
 
190
179
  def test_initialize_name
191
- http = Net::HTTP::Persistent.new 'name'
180
+ http = Net::HTTP::Persistent.new name: 'name'
192
181
  assert_equal 'name', http.name
193
182
  end
194
183
 
@@ -212,7 +201,7 @@ class TestNetHttpPersistent < Minitest::Test
212
201
  def test_initialize_proxy
213
202
  proxy_uri = URI.parse 'http://proxy.example'
214
203
 
215
- http = Net::HTTP::Persistent.new nil, proxy_uri
204
+ http = Net::HTTP::Persistent.new proxy: proxy_uri
216
205
 
217
206
  assert_equal proxy_uri, http.proxy_uri
218
207
  end
@@ -224,6 +213,13 @@ class TestNetHttpPersistent < Minitest::Test
224
213
  assert_equal 1, @http.ssl_generation
225
214
  end
226
215
 
216
+ def test_ca_path_equals
217
+ @http.ca_path = :ca_path
218
+
219
+ assert_equal :ca_path, @http.ca_path
220
+ assert_equal 1, @http.ssl_generation
221
+ end
222
+
227
223
  def test_can_retry_eh_change_requests
228
224
  post = Net::HTTP::Post.new '/'
229
225
 
@@ -234,27 +230,14 @@ class TestNetHttpPersistent < Minitest::Test
234
230
  assert @http.can_retry? post
235
231
  end
236
232
 
237
- if RUBY_1 then
238
- def test_can_retry_eh_idempotent
239
- head = Net::HTTP::Head.new '/'
233
+ def test_can_retry_eh_idempotent
234
+ head = Net::HTTP::Head.new '/'
240
235
 
241
- assert @http.can_retry? head
236
+ refute @http.can_retry? head
242
237
 
243
- post = Net::HTTP::Post.new '/'
244
-
245
- refute @http.can_retry? post
246
- end
247
- else
248
- def test_can_retry_eh_idempotent
249
- head = Net::HTTP::Head.new '/'
250
-
251
- assert @http.can_retry? head
252
- refute @http.can_retry? head, true
253
-
254
- post = Net::HTTP::Post.new '/'
238
+ post = Net::HTTP::Post.new '/'
255
239
 
256
- refute @http.can_retry? post
257
- end
240
+ refute @http.can_retry? post
258
241
  end
259
242
 
260
243
  def test_cert_store_equals
@@ -271,168 +254,154 @@ class TestNetHttpPersistent < Minitest::Test
271
254
  assert_equal 1, @http.ssl_generation
272
255
  end
273
256
 
257
+ def test_ciphers_equals
258
+ @http.ciphers = :ciphers
259
+
260
+ assert_equal :ciphers, @http.ciphers
261
+ assert_equal 1, @http.ssl_generation
262
+ end
263
+
274
264
  def test_connection_for
275
265
  @http.open_timeout = 123
276
266
  @http.read_timeout = 321
277
267
  @http.idle_timeout = 42
278
- c = @http.connection_for @uri
279
268
 
280
- assert_kind_of @http_class, c
269
+ used = @http.connection_for @uri do |c|
270
+ assert_kind_of Net::HTTP, c.http
281
271
 
282
- assert c.started?
283
- refute c.proxy?
272
+ assert c.http.started?
273
+ refute c.http.proxy?
284
274
 
285
- assert_equal 123, c.open_timeout
286
- assert_equal 321, c.read_timeout
287
- assert_equal 42, c.keep_alive_timeout unless RUBY_1
275
+ assert_equal 123, c.http.open_timeout
276
+ assert_equal 321, c.http.read_timeout
277
+ assert_equal 42, c.http.keep_alive_timeout
288
278
 
289
- assert_includes conns[0].keys, 'example.com:80'
290
- assert_same c, conns[0]['example.com:80']
279
+ c
280
+ end
281
+
282
+ stored = @http.pool.checkout ['example.com', 80]
283
+
284
+ assert_same used, stored
291
285
  end
292
286
 
293
287
  def test_connection_for_cached
294
288
  cached = basic_connection
295
- cached.start
296
- conns[0]['example.com:80'] = cached
289
+ cached.http.start
297
290
 
298
291
  @http.read_timeout = 5
299
292
 
300
- c = @http.connection_for @uri
301
-
302
- assert c.started?
293
+ @http.connection_for @uri do |c|
294
+ assert c.http.started?
303
295
 
304
- assert_equal 5, c.read_timeout
296
+ assert_equal 5, c.http.read_timeout
305
297
 
306
- assert_same cached, c
298
+ assert_same cached, c
299
+ end
307
300
  end
308
301
 
309
302
  def test_connection_for_closed
310
303
  cached = basic_connection
311
- cached.start
304
+ cached.http.start
312
305
  if Socket.const_defined? :TCP_NODELAY then
313
306
  io = Object.new
314
307
  def io.setsockopt(*a) raise IOError, 'closed stream' end
315
308
  cached.instance_variable_set :@socket, Net::BufferedIO.new(io)
316
309
  end
317
- conns['example.com:80'] = cached
318
-
319
- c = @http.connection_for @uri
320
-
321
- assert c.started?
322
310
 
323
- assert_includes conns.keys, 'example.com:80'
324
- assert_same c, conns[0]['example.com:80']
311
+ @http.connection_for @uri do |c|
312
+ assert c.http.started?
325
313
 
326
- socket = c.instance_variable_get :@socket
314
+ socket = c.http.instance_variable_get :@socket
327
315
 
328
- refute_includes socket.io.instance_variables, :@setsockopt
329
- refute_includes socket.io.instance_variables, '@setsockopt'
316
+ refute_includes socket.io.instance_variables, :@setsockopt
317
+ refute_includes socket.io.instance_variables, '@setsockopt'
318
+ end
330
319
  end
331
320
 
332
321
  def test_connection_for_debug_output
333
322
  io = StringIO.new
334
323
  @http.debug_output = io
335
324
 
336
- c = @http.connection_for @uri
337
-
338
- assert c.started?
339
- assert_equal io, c.instance_variable_get(:@debug_output)
340
-
341
- assert_includes conns[0].keys, 'example.com:80'
342
- assert_same c, conns[0]['example.com:80']
325
+ @http.connection_for @uri do |c|
326
+ assert c.http.started?
327
+ assert_equal io, c.http.instance_variable_get(:@debug_output)
328
+ end
343
329
  end
344
330
 
345
331
  def test_connection_for_cached_expire_always
346
332
  cached = basic_connection
347
- cached.start
348
- conns[0]['example.com:80'] = cached
349
- reqs[cached.object_id] = 10
350
- touts[cached.object_id] = Time.now # last used right now
333
+ cached.http.start
334
+ cached.requests = 10
335
+ cached.last_use = Time.now # last used right now
351
336
 
352
337
  @http.idle_timeout = 0
353
338
 
354
- c = @http.connection_for @uri
339
+ @http.connection_for @uri do |c|
340
+ assert c.http.started?
355
341
 
356
- assert c.started?
342
+ assert_same cached, c
357
343
 
358
- assert_same cached, c
359
-
360
- assert_equal 0, reqs[cached.object_id],
361
- 'connection reset due to timeout'
344
+ assert_equal 0, c.requests, 'connection reset due to timeout'
345
+ end
362
346
  end
363
347
 
364
348
  def test_connection_for_cached_expire_never
365
349
  cached = basic_connection
366
- cached.start
367
- conns[0]['example.com:80'] = cached
368
- reqs[cached.object_id] = 10
369
- touts[cached.object_id] = Time.now # last used right now
350
+ cached.http.start
351
+ cached.requests = 10
352
+ cached.last_use = Time.now # last used right now
370
353
 
371
354
  @http.idle_timeout = nil
372
355
 
373
- c = @http.connection_for @uri
374
-
375
- assert c.started?
356
+ @http.connection_for @uri do |c|
357
+ assert c.http.started?
376
358
 
377
- assert_same cached, c
359
+ assert_same cached, c
378
360
 
379
- assert_equal 10, reqs[cached.object_id],
380
- 'connection reset despite no timeout'
361
+ assert_equal 10, c.requests, 'connection reset despite no timeout'
362
+ end
381
363
  end
382
364
 
383
365
  def test_connection_for_cached_expired
384
366
  cached = basic_connection
385
- cached.start
386
- conns[0]['example.com:80'] = cached
387
- reqs[cached.object_id] = 10
388
- touts[cached.object_id] = Time.now - 3600
367
+ cached.http.start
368
+ cached.requests = 10
369
+ cached.last_use = Time.now - 3600
389
370
 
390
- c = @http.connection_for @uri
371
+ @http.connection_for @uri do |c|
372
+ assert c.http.started?
391
373
 
392
- assert c.started?
393
-
394
- assert_same cached, c
395
- assert_equal 0, reqs[cached.object_id],
396
- 'connection not reset due to timeout'
397
- end
398
-
399
- def test_connection_for_refused
400
- Net::HTTP.use_connect :refused_connect
401
- Net::HTTP::Persistent::SSLReuse.use_connect :refused_connect
402
-
403
- e = assert_raises Net::HTTP::Persistent::Error do
404
- @http.connection_for @uri
374
+ assert_same cached, c
375
+ assert_equal 0, cached.requests, 'connection not reset due to timeout'
405
376
  end
406
-
407
- assert_equal 'connection refused: example.com:80', e.message
408
377
  end
409
378
 
410
379
  def test_connection_for_finished_ssl
411
380
  skip 'OpenSSL is missing' unless HAVE_OPENSSL
412
381
 
413
382
  uri = URI.parse 'https://example.com/path'
414
- c = @http.connection_for uri
415
383
 
416
- assert c.started?
417
- assert c.use_ssl?
384
+ @http.connection_for uri do |c|
385
+ assert c.http.started?
386
+ assert c.http.use_ssl?
418
387
 
419
- @http.finish c
388
+ @http.finish c
420
389
 
421
- refute c.started?
422
-
423
- c2 = @http.connection_for uri
390
+ refute c.http.started?
391
+ end
424
392
 
425
- assert c2.started?
393
+ @http.connection_for uri do |c2|
394
+ assert c2.http.started?
395
+ end
426
396
  end
427
397
 
428
398
  def test_connection_for_host_down
429
- cached = basic_connection
430
- def cached.start; raise Errno::EHOSTDOWN end
431
- def cached.started?; false end
432
- conns[0]['example.com:80'] = cached
399
+ c = basic_connection
400
+ def (c.http).start; raise Errno::EHOSTDOWN end
401
+ def (c.http).started?; false end
433
402
 
434
403
  e = assert_raises Net::HTTP::Persistent::Error do
435
- @http.connection_for @uri
404
+ @http.connection_for @uri do end
436
405
  end
437
406
 
438
407
  assert_equal 'host down: example.com:80', e.message
@@ -440,8 +409,10 @@ class TestNetHttpPersistent < Minitest::Test
440
409
 
441
410
  def test_connection_for_http_class_with_fakeweb
442
411
  Object.send :const_set, :FakeWeb, nil
443
- c = @http.connection_for @uri
444
- assert_instance_of Net::HTTP, c
412
+
413
+ @http.connection_for @uri do |c|
414
+ assert_instance_of Net::HTTP, c.http
415
+ end
445
416
  ensure
446
417
  if Object.const_defined?(:FakeWeb) then
447
418
  Object.send :remove_const, :FakeWeb
@@ -450,8 +421,9 @@ class TestNetHttpPersistent < Minitest::Test
450
421
 
451
422
  def test_connection_for_http_class_with_webmock
452
423
  Object.send :const_set, :WebMock, nil
453
- c = @http.connection_for @uri
454
- assert_instance_of Net::HTTP, c
424
+ @http.connection_for @uri do |c|
425
+ assert_instance_of Net::HTTP, c.http
426
+ end
455
427
  ensure
456
428
  if Object.const_defined?(:WebMock) then
457
429
  Object.send :remove_const, :WebMock
@@ -460,8 +432,9 @@ class TestNetHttpPersistent < Minitest::Test
460
432
 
461
433
  def test_connection_for_http_class_with_artifice
462
434
  Object.send :const_set, :Artifice, nil
463
- c = @http.connection_for @uri
464
- assert_instance_of Net::HTTP, c
435
+ @http.connection_for @uri do |c|
436
+ assert_instance_of Net::HTTP, c.http
437
+ end
465
438
  ensure
466
439
  if Object.const_defined?(:Artifice) then
467
440
  Object.send :remove_const, :Artifice
@@ -469,23 +442,12 @@ class TestNetHttpPersistent < Minitest::Test
469
442
  end
470
443
 
471
444
  def test_connection_for_name
472
- http = Net::HTTP::Persistent.new 'name'
445
+ http = Net::HTTP::Persistent.new name: 'name'
473
446
  uri = URI.parse 'http://example/'
474
447
 
475
- c = http.connection_for uri
476
-
477
- assert c.started?
478
-
479
- refute_includes conns.keys, 'example:80'
480
- end
481
-
482
- def test_connection_for_no_ssl_reuse
483
- @http.reuse_ssl_sessions = false
484
- @http.open_timeout = 123
485
- @http.read_timeout = 321
486
- c = @http.connection_for @uri
487
-
488
- assert_instance_of Net::HTTP, c
448
+ http.connection_for uri do |c|
449
+ assert c.http.started?
450
+ end
489
451
  end
490
452
 
491
453
  def test_connection_for_proxy
@@ -493,16 +455,20 @@ class TestNetHttpPersistent < Minitest::Test
493
455
  uri.user = 'johndoe'
494
456
  uri.password = 'muffins'
495
457
 
496
- http = Net::HTTP::Persistent.new nil, uri
458
+ http = Net::HTTP::Persistent.new proxy: uri
497
459
 
498
- c = http.connection_for @uri
460
+ used = http.connection_for @uri do |c|
461
+ assert c.http.started?
462
+ assert c.http.proxy?
499
463
 
500
- assert c.started?
501
- assert c.proxy?
464
+ c
465
+ end
466
+
467
+ stored = http.pool.checkout ['example.com', 80,
468
+ 'proxy.example', 80,
469
+ 'johndoe', 'muffins']
502
470
 
503
- assert_includes conns[1].keys,
504
- 'example.com:80:proxy.example:80:johndoe:muffins'
505
- assert_same c, conns[1]['example.com:80:proxy.example:80:johndoe:muffins']
471
+ assert_same used, stored
506
472
  end
507
473
 
508
474
  def test_connection_for_proxy_unescaped
@@ -511,25 +477,28 @@ class TestNetHttpPersistent < Minitest::Test
511
477
  uri.password = 'muf%3Afins'
512
478
  uri.freeze
513
479
 
514
- http = Net::HTTP::Persistent.new nil, uri
515
- c = http.connection_for @uri
480
+ http = Net::HTTP::Persistent.new proxy: uri
481
+
482
+ http.connection_for @uri do end
483
+
484
+ stored = http.pool.checkout ['example.com', 80,
485
+ 'proxy.example', 80,
486
+ 'john@doe', 'muf:fins']
516
487
 
517
- assert_includes conns[1].keys,
518
- 'example.com:80:proxy.example:80:john@doe:muf:fins'
488
+ assert stored
519
489
  end
520
490
 
521
491
  def test_connection_for_proxy_host_down
522
492
  Net::HTTP.use_connect :host_down_connect
523
- Net::HTTP::Persistent::SSLReuse.use_connect :host_down_connect
524
493
 
525
494
  uri = URI.parse 'http://proxy.example'
526
495
  uri.user = 'johndoe'
527
496
  uri.password = 'muffins'
528
497
 
529
- http = Net::HTTP::Persistent.new nil, uri
498
+ http = Net::HTTP::Persistent.new proxy: uri
530
499
 
531
500
  e = assert_raises Net::HTTP::Persistent::Error do
532
- http.connection_for @uri
501
+ http.connection_for @uri do end
533
502
  end
534
503
 
535
504
  assert_equal 'host down: proxy.example:80', e.message
@@ -537,16 +506,15 @@ class TestNetHttpPersistent < Minitest::Test
537
506
 
538
507
  def test_connection_for_proxy_refused
539
508
  Net::HTTP.use_connect :refused_connect
540
- Net::HTTP::Persistent::SSLReuse.use_connect :refused_connect
541
509
 
542
510
  uri = URI.parse 'http://proxy.example'
543
511
  uri.user = 'johndoe'
544
512
  uri.password = 'muffins'
545
513
 
546
- http = Net::HTTP::Persistent.new nil, uri
514
+ http = Net::HTTP::Persistent.new proxy: uri
547
515
 
548
516
  e = assert_raises Net::HTTP::Persistent::Error do
549
- http.connection_for @uri
517
+ http.connection_for @uri do end
550
518
  end
551
519
 
552
520
  assert_equal 'connection refused: proxy.example:80', e.message
@@ -558,38 +526,37 @@ class TestNetHttpPersistent < Minitest::Test
558
526
  uri.password = 'muffins'
559
527
  uri.query = 'no_proxy=example.com'
560
528
 
561
- http = Net::HTTP::Persistent.new nil, uri
529
+ http = Net::HTTP::Persistent.new proxy: uri
562
530
 
563
- c = http.connection_for @uri
531
+ http.connection_for @uri do |c|
532
+ assert c.http.started?
533
+ refute c.http.proxy?
534
+ end
564
535
 
565
- assert c.started?
566
- refute c.proxy?
536
+ stored = http.pool.checkout ['example.com', 80]
567
537
 
568
- assert_includes conns[1].keys, 'example.com:80'
569
- assert_same c, conns[1]['example.com:80']
538
+ assert stored
570
539
  end
571
540
 
572
541
  def test_connection_for_refused
573
- cached = basic_connection
574
- def cached.start; raise Errno::ECONNREFUSED end
575
- def cached.started?; false end
576
- conns[0]['example.com:80'] = cached
542
+ Net::HTTP.use_connect :refused_connect
577
543
 
578
544
  e = assert_raises Net::HTTP::Persistent::Error do
579
- @http.connection_for @uri
545
+ @http.connection_for @uri do end
580
546
  end
581
547
 
582
- assert_match %r%connection refused%, e.message
548
+ assert_equal 'connection refused: example.com:80', e.message
583
549
  end
584
550
 
585
551
  def test_connection_for_ssl
586
552
  skip 'OpenSSL is missing' unless HAVE_OPENSSL
587
553
 
588
554
  uri = URI.parse 'https://example.com/path'
589
- c = @http.connection_for uri
590
555
 
591
- assert c.started?
592
- assert c.use_ssl?
556
+ @http.connection_for uri do |c|
557
+ assert c.http.started?
558
+ assert c.http.use_ssl?
559
+ end
593
560
  end
594
561
 
595
562
  def test_connection_for_ssl_cached
@@ -597,11 +564,11 @@ class TestNetHttpPersistent < Minitest::Test
597
564
 
598
565
  @uri = URI.parse 'https://example.com/path'
599
566
 
600
- cached = ssl_connection 0
601
-
602
- c = @http.connection_for @uri
567
+ cached = ssl_connection
603
568
 
604
- assert_same cached, c
569
+ @http.connection_for @uri do |c|
570
+ assert_same cached, c
571
+ end
605
572
  end
606
573
 
607
574
  def test_connection_for_ssl_cached_reconnect
@@ -611,45 +578,47 @@ class TestNetHttpPersistent < Minitest::Test
611
578
 
612
579
  cached = ssl_connection
613
580
 
614
- @http.reconnect_ssl
581
+ ssl_generation = @http.ssl_generation
615
582
 
616
- c = @http.connection_for @uri
583
+ @http.reconnect_ssl
617
584
 
618
- refute_same cached, c
585
+ @http.connection_for @uri do |c|
586
+ assert_same cached, c
587
+ refute_equal ssl_generation, c.ssl_generation
588
+ end
619
589
  end
620
590
 
621
591
  def test_connection_for_ssl_case
622
592
  skip 'OpenSSL is missing' unless HAVE_OPENSSL
623
593
 
624
594
  uri = URI.parse 'HTTPS://example.com/path'
625
- c = @http.connection_for uri
626
-
627
- assert c.started?
628
- assert c.use_ssl?
595
+ @http.connection_for uri do |c|
596
+ assert c.http.started?
597
+ assert c.http.use_ssl?
598
+ end
629
599
  end
630
600
 
631
601
  def test_connection_for_timeout
632
602
  cached = basic_connection
633
- cached.start
634
- reqs[cached.object_id] = 10
635
- touts[cached.object_id] = Time.now - 6
636
- conns[0]['example.com:80'] = cached
603
+ cached.http.start
604
+ cached.requests = 10
605
+ cached.last_use = Time.now - 6
637
606
 
638
- c = @http.connection_for @uri
607
+ @http.connection_for @uri do |c|
608
+ assert c.http.started?
609
+ assert_equal 0, c.requests
639
610
 
640
- assert c.started?
641
- assert_equal 0, reqs[c.object_id]
642
-
643
- assert_same cached, c
611
+ assert_same cached, c
612
+ end
644
613
  end
645
614
 
646
615
  def test_error_message
647
616
  c = basic_connection
648
- touts[c.object_id] = Time.now - 1
649
- reqs[c.object_id] = 5
617
+ c.last_use = Time.now - 1
618
+ c.requests = 5
650
619
 
651
- message = @http.error_message(c)
652
- assert_match %r%after 4 requests on #{c.object_id}%, message
620
+ message = @http.error_message c
621
+ assert_match %r%after 4 requests on #{c.http.object_id}%, message
653
622
  assert_match %r%, last used [\d.]+ seconds ago%, message
654
623
  end
655
624
 
@@ -667,8 +636,8 @@ class TestNetHttpPersistent < Minitest::Test
667
636
 
668
637
  def test_expired_eh
669
638
  c = basic_connection
670
- reqs[c.object_id] = 0
671
- touts[c.object_id] = Time.now - 11
639
+ c.requests = 0
640
+ c.last_use = Time.now - 11
672
641
 
673
642
  @http.idle_timeout = 0
674
643
  assert @http.expired? c
@@ -688,41 +657,57 @@ class TestNetHttpPersistent < Minitest::Test
688
657
 
689
658
  def test_expired_due_to_max_requests
690
659
  c = basic_connection
691
- reqs[c.object_id] = 0
692
- touts[c.object_id] = Time.now
660
+ c.requests = 0
661
+ c.last_use = Time.now
693
662
 
694
663
  refute @http.expired? c
695
664
 
696
- reqs[c.object_id] = 10
665
+ c.requests = 10
697
666
  refute @http.expired? c
698
667
 
699
668
  @http.max_requests = 10
700
669
  assert @http.expired? c
701
670
 
702
- reqs[c.object_id] = 9
671
+ c.requests = 9
703
672
  refute @http.expired? c
704
673
  end
705
674
 
706
675
  def test_finish
707
676
  c = basic_connection
708
- reqs[c.object_id] = 5
677
+ c.requests = 5
709
678
 
710
679
  @http.finish c
711
680
 
712
- refute c.started?
713
- assert c.finished?
714
- assert_equal 0, reqs[c.object_id]
681
+ refute c.http.started?
682
+ assert c.http.finished?
683
+
684
+ assert_equal 0, c.requests
685
+ assert_equal Net::HTTP::Persistent::EPOCH, c.last_use
715
686
  end
716
687
 
717
688
  def test_finish_io_error
718
689
  c = basic_connection
719
- def c.finish; @finished += 1; raise IOError end
720
- reqs[c.object_id] = 5
690
+ def (c.http).finish; @finished += 1; raise IOError end
691
+ c.requests = 5
721
692
 
722
693
  @http.finish c
723
694
 
724
- refute c.started?
725
- assert c.finished?
695
+ refute c.http.started?
696
+ assert c.http.finished?
697
+ end
698
+
699
+ def test_finish_ssl_no_session_reuse
700
+ http = Net::HTTP.new 'localhost', 443, ssl: true
701
+ http.instance_variable_set :@ssl_session, :something
702
+
703
+ c = Net::HTTP::Persistent::Connection.allocate
704
+ c.instance_variable_set :@http, http
705
+
706
+ @http.reuse_ssl_sessions = false
707
+
708
+ @http.finish c
709
+
710
+ assert_nil c.http.instance_variable_get :@ssl_session
726
711
  end
727
712
 
728
713
  def test_http_version
@@ -746,14 +731,6 @@ class TestNetHttpPersistent < Minitest::Test
746
731
  refute @http.idempotent? Net::HTTP::Post.new '/'
747
732
  end
748
733
 
749
- def test_max_age
750
- assert_in_delta Time.now - 5, @http.max_age
751
-
752
- @http.idle_timeout = nil
753
-
754
- assert_in_delta Time.now + 1, @http.max_age
755
- end
756
-
757
734
  def test_normalize_uri
758
735
  assert_equal 'http://example', @http.normalize_uri('example')
759
736
  assert_equal 'http://example', @http.normalize_uri('http://example')
@@ -775,7 +752,6 @@ class TestNetHttpPersistent < Minitest::Test
775
752
 
776
753
  cached = basic_connection
777
754
  cached.start
778
- conns['example.com:80'] = cached
779
755
 
780
756
  requests = [
781
757
  Net::HTTP::Get.new((@uri + '1').request_uri),
@@ -935,9 +911,38 @@ class TestNetHttpPersistent < Minitest::Test
935
911
  end
936
912
 
937
913
  def test_reconnect_ssl
938
- result = @http.reconnect_ssl
914
+ skip 'OpenSSL is missing' unless HAVE_OPENSSL
939
915
 
940
- assert_equal 1, result
916
+ @uri = URI 'https://example.com'
917
+ now = Time.now
918
+
919
+ ssl_http = ssl_connection
920
+
921
+ def (ssl_http.http).finish
922
+ @started = 0
923
+ end
924
+
925
+ used1 = @http.connection_for @uri do |c|
926
+ c.requests = 1
927
+ c.last_use = now
928
+ c
929
+ end
930
+
931
+ assert_equal OpenSSL::SSL::VERIFY_PEER, used1.http.verify_mode
932
+
933
+ @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
934
+ @http.reconnect_ssl
935
+
936
+ used2 = @http.connection_for @uri do |c|
937
+ c
938
+ end
939
+
940
+ assert_same used1, used2
941
+
942
+ assert_equal OpenSSL::SSL::VERIFY_NONE, used2.http.verify_mode,
943
+ 'verify mode must change'
944
+ assert_equal 0, used2.requests
945
+ assert_equal Net::HTTP::Persistent::EPOCH, used2.last_use
941
946
  end
942
947
 
943
948
  def test_request
@@ -946,7 +951,7 @@ class TestNetHttpPersistent < Minitest::Test
946
951
  c = connection
947
952
 
948
953
  res = @http.request @uri
949
- req = c.req
954
+ req = c.http.req
950
955
 
951
956
  assert_kind_of Net::HTTPResponse, res
952
957
 
@@ -959,72 +964,51 @@ class TestNetHttpPersistent < Minitest::Test
959
964
  assert_equal 'keep-alive', req['connection']
960
965
  assert_equal '30', req['keep-alive']
961
966
 
962
- assert_in_delta Time.now, touts[c.object_id]
967
+ assert_in_delta Time.now, c.last_use
963
968
 
964
- assert_equal 1, reqs[c.object_id]
969
+ assert_equal 1, c.requests
965
970
  end
966
971
 
967
972
  def test_request_ETIMEDOUT
968
973
  c = basic_connection
969
- def c.request(*a) raise Errno::ETIMEDOUT, "timed out" end
974
+ def (c.http).request(*a) raise Errno::ETIMEDOUT, "timed out" end
970
975
 
971
976
  e = assert_raises Net::HTTP::Persistent::Error do
972
977
  @http.request @uri
973
978
  end
974
979
 
975
- assert_equal 0, reqs[c.object_id]
980
+ assert_equal 0, c.requests
976
981
  assert_match %r%too many connection resets%, e.message
977
982
  end
978
983
 
979
984
  def test_request_bad_response
980
985
  c = basic_connection
981
- def c.request(*a) raise Net::HTTPBadResponse end
986
+ def (c.http).request(*a) raise Net::HTTPBadResponse end
982
987
 
983
988
  e = assert_raises Net::HTTP::Persistent::Error do
984
989
  @http.request @uri
985
990
  end
986
991
 
987
- assert_equal 0, reqs[c.object_id]
992
+ assert_equal 0, c.requests
988
993
  assert_match %r%too many bad responses%, e.message
989
994
  end
990
995
 
991
- if RUBY_1 then
992
- def test_request_bad_response_retry
993
- c = basic_connection
994
- def c.request(*a)
995
- if defined? @called then
996
- r = Net::HTTPResponse.allocate
997
- r.instance_variable_set :@header, {}
998
- def r.http_version() '1.1' end
999
- r
1000
- else
1001
- @called = true
1002
- raise Net::HTTPBadResponse
1003
- end
1004
- end
996
+ def test_request_bad_response_retry
997
+ c = basic_connection
998
+ def (c.http).request(*a)
999
+ raise Net::HTTPBadResponse
1000
+ end
1005
1001
 
1002
+ assert_raises Net::HTTP::Persistent::Error do
1006
1003
  @http.request @uri
1007
-
1008
- assert c.finished?
1009
1004
  end
1010
- else
1011
- def test_request_bad_response_retry
1012
- c = basic_connection
1013
- def c.request(*a)
1014
- raise Net::HTTPBadResponse
1015
- end
1016
-
1017
- assert_raises Net::HTTP::Persistent::Error do
1018
- @http.request @uri
1019
- end
1020
1005
 
1021
- assert c.finished?
1022
- end
1006
+ assert c.http.finished?
1023
1007
  end
1024
1008
 
1025
1009
  def test_request_bad_response_unsafe
1026
1010
  c = basic_connection
1027
- def c.request(*a)
1011
+ def (c.http).request(*a)
1028
1012
  if instance_variable_defined? :@request then
1029
1013
  raise 'POST must not be retried'
1030
1014
  else
@@ -1037,7 +1021,7 @@ class TestNetHttpPersistent < Minitest::Test
1037
1021
  @http.request @uri, Net::HTTP::Post.new(@uri.path)
1038
1022
  end
1039
1023
 
1040
- assert_equal 0, reqs[c.object_id]
1024
+ assert_equal 0, c.requests
1041
1025
  assert_match %r%too many bad responses%, e.message
1042
1026
  end
1043
1027
 
@@ -1050,7 +1034,7 @@ class TestNetHttpPersistent < Minitest::Test
1050
1034
  body = r.read_body
1051
1035
  end
1052
1036
 
1053
- req = c.req
1037
+ req = c.http.req
1054
1038
 
1055
1039
  assert_kind_of Net::HTTPResponse, res
1056
1040
  refute_nil body
@@ -1061,17 +1045,17 @@ class TestNetHttpPersistent < Minitest::Test
1061
1045
  assert_equal '30', req['keep-alive']
1062
1046
  assert_match %r%test ua%, req['user-agent']
1063
1047
 
1064
- assert_equal 1, reqs[c.object_id]
1048
+ assert_equal 1, c.requests
1065
1049
  end
1066
1050
 
1067
1051
  def test_request_close_1_0
1068
1052
  c = connection
1069
1053
 
1070
- class << c
1054
+ class << c.http
1071
1055
  remove_method :request
1072
1056
  end
1073
1057
 
1074
- def c.request req
1058
+ def (c.http).request req
1075
1059
  @req = req
1076
1060
  r = Net::HTTPResponse.allocate
1077
1061
  r.instance_variable_set :@header, {}
@@ -1084,7 +1068,7 @@ class TestNetHttpPersistent < Minitest::Test
1084
1068
  request = Net::HTTP::Get.new @uri.request_uri
1085
1069
 
1086
1070
  res = @http.request @uri, request
1087
- req = c.req
1071
+ req = c.http.req
1088
1072
 
1089
1073
  assert_kind_of Net::HTTPResponse, res
1090
1074
 
@@ -1093,7 +1077,7 @@ class TestNetHttpPersistent < Minitest::Test
1093
1077
  assert_equal 'keep-alive', req['connection']
1094
1078
  assert_equal '30', req['keep-alive']
1095
1079
 
1096
- assert c.finished?
1080
+ assert c.http.finished?
1097
1081
  end
1098
1082
 
1099
1083
  def test_request_connection_close_request
@@ -1103,7 +1087,7 @@ class TestNetHttpPersistent < Minitest::Test
1103
1087
  request['connection'] = 'close'
1104
1088
 
1105
1089
  res = @http.request @uri, request
1106
- req = c.req
1090
+ req = c.http.req
1107
1091
 
1108
1092
  assert_kind_of Net::HTTPResponse, res
1109
1093
 
@@ -1112,17 +1096,17 @@ class TestNetHttpPersistent < Minitest::Test
1112
1096
  assert_equal 'close', req['connection']
1113
1097
  assert_equal nil, req['keep-alive']
1114
1098
 
1115
- assert c.finished?
1099
+ assert c.http.finished?
1116
1100
  end
1117
1101
 
1118
1102
  def test_request_connection_close_response
1119
1103
  c = connection
1120
1104
 
1121
- class << c
1105
+ class << c.http
1122
1106
  remove_method :request
1123
1107
  end
1124
1108
 
1125
- def c.request req
1109
+ def (c.http).request req
1126
1110
  @req = req
1127
1111
  r = Net::HTTPResponse.allocate
1128
1112
  r.instance_variable_set :@header, {}
@@ -1136,7 +1120,7 @@ class TestNetHttpPersistent < Minitest::Test
1136
1120
  request = Net::HTTP::Get.new @uri.request_uri
1137
1121
 
1138
1122
  res = @http.request @uri, request
1139
- req = c.req
1123
+ req = c.http.req
1140
1124
 
1141
1125
  assert_kind_of Net::HTTPResponse, res
1142
1126
 
@@ -1145,120 +1129,77 @@ class TestNetHttpPersistent < Minitest::Test
1145
1129
  assert_equal 'keep-alive', req['connection']
1146
1130
  assert_equal '30', req['keep-alive']
1147
1131
 
1148
- assert c.finished?
1132
+ assert c.http.finished?
1149
1133
  end
1150
1134
 
1151
1135
  def test_request_exception
1152
1136
  c = basic_connection
1153
- def c.request(*a) raise Exception, "very bad things happened" end
1137
+ def (c.http).request(*a)
1138
+ raise Exception, "very bad things happened"
1139
+ end
1154
1140
 
1155
1141
  assert_raises Exception do
1156
1142
  @http.request @uri
1157
1143
  end
1158
1144
 
1159
- assert_equal 0, reqs[c.object_id]
1160
- assert c.finished?
1145
+ assert_equal 0, c.requests
1146
+ assert c.http.finished?
1161
1147
  end
1162
1148
 
1163
1149
  def test_request_invalid
1164
1150
  c = basic_connection
1165
- def c.request(*a) raise Errno::EINVAL, "write" end
1151
+ def (c.http).request(*a) raise Errno::EINVAL, "write" end
1166
1152
 
1167
1153
  e = assert_raises Net::HTTP::Persistent::Error do
1168
1154
  @http.request @uri
1169
1155
  end
1170
1156
 
1171
- assert_equal 0, reqs[c.object_id]
1157
+ assert_equal 0, c.requests
1172
1158
  assert_match %r%too many connection resets%, e.message
1173
1159
  end
1174
1160
 
1175
- def test_request_invalid_retry
1176
- c = basic_connection
1177
- touts[c.object_id] = Time.now
1178
-
1179
- def c.request(*a)
1180
- if defined? @called then
1181
- r = Net::HTTPResponse.allocate
1182
- r.instance_variable_set :@header, {}
1183
- def r.http_version() '1.1' end
1184
- r
1185
- else
1186
- @called = true
1187
- raise Errno::EINVAL, "write"
1188
- end
1189
- end
1190
-
1191
- @http.request @uri
1192
-
1193
- assert c.reset?
1194
- assert c.finished?
1195
- end
1196
-
1197
1161
  def test_request_post
1198
1162
  c = connection
1199
1163
 
1200
1164
  post = Net::HTTP::Post.new @uri.path
1201
1165
 
1202
1166
  @http.request @uri, post
1203
- req = c.req
1167
+ req = c.http.req
1204
1168
 
1205
1169
  assert_same post, req
1206
1170
  end
1207
1171
 
1208
1172
  def test_request_reset
1209
1173
  c = basic_connection
1210
- def c.request(*a) raise Errno::ECONNRESET end
1174
+ def (c.http).request(*a) raise Errno::ECONNRESET end
1211
1175
 
1212
1176
  e = assert_raises Net::HTTP::Persistent::Error do
1213
1177
  @http.request @uri
1214
1178
  end
1215
1179
 
1216
- assert_equal 0, reqs[c.object_id]
1180
+ assert_equal 0, c.requests
1217
1181
  assert_match %r%too many connection resets%, e.message
1218
1182
  end
1219
1183
 
1220
- if RUBY_1 then
1221
- def test_request_reset_retry
1222
- c = basic_connection
1223
- touts[c.object_id] = Time.now
1224
- def c.request(*a)
1225
- if defined? @called then
1226
- r = Net::HTTPResponse.allocate
1227
- r.instance_variable_set :@header, {}
1228
- def r.http_version() '1.1' end
1229
- r
1230
- else
1231
- @called = true
1232
- raise Errno::ECONNRESET
1233
- end
1234
- end
1235
-
1236
- @http.request @uri
1184
+ def test_request_reset_retry
1185
+ c = basic_connection
1186
+ c.last_use = Time.now
1237
1187
 
1238
- assert c.reset?
1239
- assert c.finished?
1188
+ def (c.http).request(*a)
1189
+ raise Errno::ECONNRESET
1240
1190
  end
1241
- else
1242
- def test_request_reset_retry
1243
- c = basic_connection
1244
- touts[c.object_id] = Time.now
1245
1191
 
1246
- def c.request(*a)
1247
- raise Errno::ECONNRESET
1248
- end
1249
-
1250
- assert_raises Net::HTTP::Persistent::Error do
1251
- @http.request @uri
1252
- end
1253
-
1254
- refute c.reset?
1255
- assert c.finished?
1192
+ assert_raises Net::HTTP::Persistent::Error do
1193
+ @http.request @uri
1256
1194
  end
1195
+
1196
+ refute (c.http).reset?
1197
+ assert (c.http).finished?
1257
1198
  end
1258
1199
 
1259
1200
  def test_request_reset_unsafe
1260
1201
  c = basic_connection
1261
- def c.request(*a)
1202
+ def (c.http).request(*a)
1262
1203
  if instance_variable_defined? :@request then
1263
1204
  raise 'POST must not be retried'
1264
1205
  else
@@ -1271,7 +1212,7 @@ class TestNetHttpPersistent < Minitest::Test
1271
1212
  @http.request @uri, Net::HTTP::Post.new(@uri.path)
1272
1213
  end
1273
1214
 
1274
- assert_equal 0, reqs[c.object_id]
1215
+ assert_equal 0, c.requests
1275
1216
  assert_match %r%too many connection resets%, e.message
1276
1217
  end
1277
1218
 
@@ -1279,15 +1220,16 @@ class TestNetHttpPersistent < Minitest::Test
1279
1220
  skip 'OpenSSL is missing' unless HAVE_OPENSSL
1280
1221
 
1281
1222
  uri = URI.parse 'https://example.com/path'
1282
- c = @http.connection_for uri
1283
- def c.request(*)
1284
- raise OpenSSL::SSL::SSLError, "SSL3_WRITE_PENDING:bad write retry"
1285
- end
1223
+ @http.connection_for uri do |c|
1224
+ def (c.http).request(*)
1225
+ raise OpenSSL::SSL::SSLError, "SSL3_WRITE_PENDING:bad write retry"
1226
+ end
1286
1227
 
1287
- e = assert_raises Net::HTTP::Persistent::Error do
1288
- @http.request uri
1228
+ e = assert_raises Net::HTTP::Persistent::Error do
1229
+ @http.request uri
1230
+ end
1231
+ assert_match %r%bad write retry%, e.message
1289
1232
  end
1290
- assert_match %r%bad write retry%, e.message
1291
1233
  end
1292
1234
 
1293
1235
  def test_request_setup
@@ -1308,6 +1250,22 @@ class TestNetHttpPersistent < Minitest::Test
1308
1250
  assert_equal '30', req['keep-alive']
1309
1251
  end
1310
1252
 
1253
+ def test_request_string
1254
+ @http.override_headers['user-agent'] = 'test ua'
1255
+ @http.headers['accept'] = 'text/*'
1256
+ c = connection
1257
+
1258
+ res = @http.request @uri.to_s
1259
+ req = c.http.req
1260
+
1261
+ assert_kind_of Net::HTTPResponse, res
1262
+
1263
+ assert_kind_of Net::HTTP::Get, req
1264
+ assert_equal '/path', req.path
1265
+
1266
+ assert_equal 1, c.requests
1267
+ end
1268
+
1311
1269
  def test_request_setup_uri
1312
1270
  uri = @uri + '?a=b'
1313
1271
 
@@ -1319,8 +1277,8 @@ class TestNetHttpPersistent < Minitest::Test
1319
1277
 
1320
1278
  def test_request_failed
1321
1279
  c = basic_connection
1322
- reqs[c.object_id] = 1
1323
- touts[c.object_id] = Time.now
1280
+ c.requests = 1
1281
+ c.last_use = Time.now
1324
1282
 
1325
1283
  original = nil
1326
1284
 
@@ -1330,7 +1288,7 @@ class TestNetHttpPersistent < Minitest::Test
1330
1288
  end
1331
1289
 
1332
1290
  req = Net::HTTP::Get.new '/'
1333
-
1291
+
1334
1292
  e = assert_raises Net::HTTP::Persistent::Error do
1335
1293
  @http.request_failed original, req, c
1336
1294
  end
@@ -1343,24 +1301,24 @@ class TestNetHttpPersistent < Minitest::Test
1343
1301
 
1344
1302
  def test_reset
1345
1303
  c = basic_connection
1346
- c.start
1347
- touts[c.object_id] = Time.now
1348
- reqs[c.object_id] = 5
1304
+ c.http.start
1305
+ c.last_use = Time.now
1306
+ c.requests = 5
1349
1307
 
1350
1308
  @http.reset c
1351
1309
 
1352
- assert c.started?
1353
- assert c.finished?
1354
- assert c.reset?
1355
- assert_equal 0, reqs[c.object_id]
1356
- assert_equal Net::HTTP::Persistent::EPOCH, touts[c.object_id]
1310
+ assert c.http.started?
1311
+ assert c.http.finished?
1312
+ assert c.http.reset?
1313
+ assert_equal 0, c.requests
1314
+ assert_equal Net::HTTP::Persistent::EPOCH, c.last_use
1357
1315
  end
1358
1316
 
1359
1317
  def test_reset_host_down
1360
1318
  c = basic_connection
1361
- touts[c.object_id] = Time.now
1362
- def c.start; raise Errno::EHOSTDOWN end
1363
- reqs[c.object_id] = 5
1319
+ c.last_use = Time.now
1320
+ def (c.http).start; raise Errno::EHOSTDOWN end
1321
+ c.requests = 5
1364
1322
 
1365
1323
  e = assert_raises Net::HTTP::Persistent::Error do
1366
1324
  @http.reset c
@@ -1372,20 +1330,20 @@ class TestNetHttpPersistent < Minitest::Test
1372
1330
 
1373
1331
  def test_reset_io_error
1374
1332
  c = basic_connection
1375
- touts[c.object_id] = Time.now
1376
- reqs[c.object_id] = 5
1333
+ c.last_use = Time.now
1334
+ c.requests = 5
1377
1335
 
1378
1336
  @http.reset c
1379
1337
 
1380
- assert c.started?
1381
- assert c.finished?
1338
+ assert c.http.started?
1339
+ assert c.http.finished?
1382
1340
  end
1383
1341
 
1384
1342
  def test_reset_refused
1385
1343
  c = basic_connection
1386
- touts[c.object_id] = Time.now
1387
- def c.start; raise Errno::ECONNREFUSED end
1388
- reqs[c.object_id] = 5
1344
+ c.last_use = Time.now
1345
+ def (c.http).start; raise Errno::ECONNREFUSED end
1346
+ c.requests = 5
1389
1347
 
1390
1348
  e = assert_raises Net::HTTP::Persistent::Error do
1391
1349
  @http.reset c
@@ -1401,161 +1359,50 @@ class TestNetHttpPersistent < Minitest::Test
1401
1359
 
1402
1360
  refute @http.retry_change_requests
1403
1361
 
1404
- if RUBY_1 then
1405
- assert @http.can_retry?(get)
1406
- else
1407
- assert @http.can_retry?(get)
1408
- end
1409
- refute @http.can_retry?(get, true)
1362
+ refute @http.can_retry?(get)
1410
1363
  refute @http.can_retry?(post)
1411
1364
 
1412
1365
  @http.retry_change_requests = true
1413
1366
 
1414
1367
  assert @http.retry_change_requests
1415
1368
 
1416
- if RUBY_1 then
1417
- assert @http.can_retry?(get)
1418
- else
1419
- assert @http.can_retry?(get)
1420
- refute @http.can_retry?(get, true)
1421
- end
1422
-
1369
+ refute @http.can_retry?(get)
1423
1370
  assert @http.can_retry?(post)
1424
1371
  end
1425
1372
 
1426
1373
  def test_shutdown
1427
- ssl_conns
1428
1374
  c = connection
1429
- rs = reqs
1430
- ts = touts
1431
1375
 
1432
1376
  orig = @http
1433
- @http = Net::HTTP::Persistent.new 'name'
1377
+ @http = Net::HTTP::Persistent.new name: 'name'
1434
1378
  c2 = connection
1435
1379
 
1436
1380
  orig.shutdown
1437
1381
 
1438
1382
  @http = orig
1439
1383
 
1440
- assert c.finished?, 'last-generation connection must be finished'
1441
- refute c2.finished?, 'present generation connection must not be finished'
1442
-
1443
- refute_same rs, reqs
1444
- refute_same ts, touts
1445
-
1446
- assert_empty conns
1447
- assert_empty ssl_conns
1448
-
1449
- assert_empty reqs
1450
- assert_empty touts
1451
- end
1452
-
1453
- def test_shutdown_in_all_threads
1454
- conns
1455
- ssl_conns
1456
-
1457
- t = Thread.new do
1458
- c = connection
1459
- ssl_conns
1460
- conns
1461
- reqs
1462
-
1463
- Thread.stop
1464
-
1465
- c
1466
- end
1467
-
1468
- Thread.pass until t.status == 'sleep'
1469
-
1470
- c = connection
1471
-
1472
- assert_nil @http.shutdown_in_all_threads
1473
-
1474
- assert c.finished?, 'connection in same thread must be finished'
1475
-
1476
- assert_empty Thread.current[@http.generation_key]
1477
-
1478
- assert_nil Thread.current[@http.request_key]
1479
-
1480
- t.run
1481
- assert t.value.finished?, 'connection in other thread must be finished'
1482
-
1483
- assert_empty t[@http.generation_key]
1484
-
1485
- assert_nil t[@http.request_key]
1486
- end
1487
-
1488
- def test_shutdown_no_connections
1489
- @http.shutdown
1490
-
1491
- assert_nil Thread.current[@http.generation_key]
1492
- assert_nil Thread.current[@http.ssl_generation_key]
1493
-
1494
- assert_nil Thread.current[@http.request_key]
1495
- assert_nil Thread.current[@http.timeout_key]
1496
- end
1497
-
1498
- def test_shutdown_not_started
1499
- ssl_conns
1500
-
1501
- c = basic_connection
1502
- def c.finish() raise IOError end
1503
-
1504
- conns[0]["#{@uri.host}:#{@uri.port}"] = c
1505
-
1506
- @http.shutdown
1507
-
1508
- assert_empty Thread.current[@http.generation_key]
1509
- assert_empty Thread.current[@http.ssl_generation_key]
1510
-
1511
- assert_nil Thread.current[@http.request_key]
1512
- assert_nil Thread.current[@http.timeout_key]
1384
+ assert c.http.finished?, 'last-generation connection must be finished'
1385
+ refute c2.http.finished?, 'present generation connection must not be finished'
1513
1386
  end
1514
1387
 
1515
- def test_shutdown_ssl
1388
+ def test_ssl
1516
1389
  skip 'OpenSSL is missing' unless HAVE_OPENSSL
1517
1390
 
1518
- @uri = URI 'https://example'
1519
-
1520
- @http.connection_for @uri
1521
-
1522
- @http.shutdown
1523
-
1524
- assert_empty ssl_conns
1525
- end
1526
-
1527
- def test_shutdown_thread
1528
- t = Thread.new do
1529
- c = connection
1530
- conns
1531
- ssl_conns
1532
-
1533
- reqs
1534
-
1535
- Thread.stop
1536
-
1537
- c
1538
- end
1539
-
1540
- Thread.pass until t.status == 'sleep'
1541
-
1542
- c = connection
1543
-
1544
- @http.shutdown t
1391
+ @http.verify_callback = :callback
1392
+ c = Net::HTTP.new 'localhost', 80
1545
1393
 
1546
- refute c.finished?
1394
+ @http.ssl c
1547
1395
 
1548
- t.run
1549
- assert t.value.finished?
1550
- assert_empty t[@http.generation_key]
1551
- assert_empty t[@http.ssl_generation_key]
1552
- assert_nil t[@http.request_key]
1553
- assert_nil t[@http.timeout_key]
1396
+ assert c.use_ssl?
1397
+ assert_equal OpenSSL::SSL::VERIFY_PEER, c.verify_mode
1398
+ assert_kind_of OpenSSL::X509::Store, c.cert_store
1399
+ assert_nil c.verify_callback
1554
1400
  end
1555
1401
 
1556
- def test_ssl
1402
+ def test_ssl_ca_file
1557
1403
  skip 'OpenSSL is missing' unless HAVE_OPENSSL
1558
1404
 
1405
+ @http.ca_file = 'ca_file'
1559
1406
  @http.verify_callback = :callback
1560
1407
  c = Net::HTTP.new 'localhost', 80
1561
1408
 
@@ -1563,14 +1410,13 @@ class TestNetHttpPersistent < Minitest::Test
1563
1410
 
1564
1411
  assert c.use_ssl?
1565
1412
  assert_equal OpenSSL::SSL::VERIFY_PEER, c.verify_mode
1566
- assert_kind_of OpenSSL::X509::Store, c.cert_store
1567
- assert_nil c.verify_callback
1413
+ assert_equal :callback, c.verify_callback
1568
1414
  end
1569
1415
 
1570
- def test_ssl_ca_file
1416
+ def test_ssl_ca_path
1571
1417
  skip 'OpenSSL is missing' unless HAVE_OPENSSL
1572
1418
 
1573
- @http.ca_file = 'ca_file'
1419
+ @http.ca_path = 'ca_path'
1574
1420
  @http.verify_callback = :callback
1575
1421
  c = Net::HTTP.new 'localhost', 80
1576
1422
 
@@ -1667,23 +1513,11 @@ class TestNetHttpPersistent < Minitest::Test
1667
1513
  end
1668
1514
  end
1669
1515
 
1670
- def test_ssl_cleanup
1671
- skip 'OpenSSL is missing' unless HAVE_OPENSSL
1672
-
1673
- uri1 = URI.parse 'https://one.example'
1674
-
1675
- c1 = @http.connection_for uri1
1676
-
1677
- touts[c1.object_id] = Time.now
1678
- reqs[c1.object_id] = 5
1679
-
1680
- @http.reconnect_ssl
1681
-
1682
- @http.ssl_cleanup @http.ssl_generation
1516
+ def test_ssl_timeout_equals
1517
+ @http.ssl_timeout = :ssl_timeout
1683
1518
 
1684
- assert_empty ssl_conns
1685
- assert_empty touts
1686
- assert_empty reqs # sanity check, performed by #finish
1519
+ assert_equal :ssl_timeout, @http.ssl_timeout
1520
+ assert_equal 1, @http.ssl_generation
1687
1521
  end
1688
1522
 
1689
1523
  def test_ssl_version_equals
@@ -1691,10 +1525,11 @@ class TestNetHttpPersistent < Minitest::Test
1691
1525
 
1692
1526
  assert_equal :ssl_version, @http.ssl_version
1693
1527
  assert_equal 1, @http.ssl_generation
1694
- end unless RUBY_1
1528
+ end
1695
1529
 
1696
1530
  def test_start
1697
1531
  c = basic_connection
1532
+ c = c.http
1698
1533
 
1699
1534
  @http.socket_options << [Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1]
1700
1535
  @http.debug_output = $stderr
@@ -1722,6 +1557,13 @@ class TestNetHttpPersistent < Minitest::Test
1722
1557
  assert_equal 1, @http.ssl_generation
1723
1558
  end
1724
1559
 
1560
+ def test_verify_depth_equals
1561
+ @http.verify_depth = :verify_depth
1562
+
1563
+ assert_equal :verify_depth, @http.verify_depth
1564
+ assert_equal 1, @http.ssl_generation
1565
+ end
1566
+
1725
1567
  def test_verify_mode_equals
1726
1568
  @http.verify_mode = :verify_mode
1727
1569