net-http-persistent 2.9.4 → 4.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -51,24 +51,13 @@ 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
- @uri = URI.parse 'http://example.com/path'
59
+ @uri = URI 'http://example.com/path'
60
+ @uri_v6 = URI 'http://[2001:db8::1]/path'
72
61
 
73
62
  ENV.delete 'http_proxy'
74
63
  ENV.delete 'HTTP_PROXY'
@@ -80,25 +69,23 @@ class TestNetHttpPersistent < Minitest::Test
80
69
  ENV.delete 'NO_PROXY'
81
70
 
82
71
  Net::HTTP.use_connect :test_connect
83
- Net::HTTP::Persistent::SSLReuse.use_connect :test_connect
84
72
  end
85
73
 
86
74
  def teardown
87
- Thread.current.keys.each do |key|
88
- Thread.current[key] = nil
89
- end
90
-
91
75
  Net::HTTP.use_connect :orig_connect
92
- Net::HTTP::Persistent::SSLReuse.use_connect :orig_connect
93
76
  end
94
77
 
95
78
  class BasicConnection
96
- attr_accessor :started, :finished, :address, :port,
97
- :read_timeout, :open_timeout
79
+ attr_accessor :started, :finished, :address, :port, :use_ssl,
80
+ :read_timeout, :open_timeout, :keep_alive_timeout
81
+ attr_accessor :ciphers, :ssl_timeout, :ssl_version, :min_version,
82
+ :max_version, :verify_depth, :verify_mode, :cert_store,
83
+ :ca_file, :ca_path, :cert, :key
98
84
  attr_reader :req, :debug_output
99
85
  def initialize
100
86
  @started, @finished = 0, 0
101
87
  @address, @port = 'example.com', 80
88
+ @use_ssl = false
102
89
  end
103
90
  def finish
104
91
  @finished += 1
@@ -125,21 +112,34 @@ class TestNetHttpPersistent < Minitest::Test
125
112
  def started?
126
113
  @started >= 1
127
114
  end
115
+ def proxy_address
116
+ end
117
+ def proxy_port
118
+ end
128
119
  end
129
120
 
130
121
  def basic_connection
131
122
  raise "#{@uri} is not HTTP" unless @uri.scheme.downcase == 'http'
132
123
 
133
- c = BasicConnection.new
134
- conns[0]["#{@uri.host}:#{@uri.port}"] = c
135
- c
124
+ net_http_args = [@uri.hostname, @uri.port, nil, nil, nil, nil]
125
+
126
+ connection = Net::HTTP::Persistent::Connection.allocate
127
+ connection.ssl_generation = @http.ssl_generation
128
+ connection.http = BasicConnection.new
129
+ connection.reset
130
+
131
+ @http.pool.available.push connection, connection_args: net_http_args
132
+
133
+ connection
136
134
  end
137
135
 
138
- def connection
139
- c = basic_connection
140
- touts[c.object_id] = Time.now
136
+ def connection uri = @uri
137
+ @uri = uri
138
+
139
+ connection = basic_connection
140
+ connection.last_use = Time.now
141
141
 
142
- def c.request(req)
142
+ def (connection.http).request(req)
143
143
  @req = req
144
144
  r = Net::HTTPResponse.allocate
145
145
  r.instance_variable_set :@header, {}
@@ -149,30 +149,22 @@ class TestNetHttpPersistent < Minitest::Test
149
149
  r
150
150
  end
151
151
 
152
- c
152
+ connection
153
153
  end
154
154
 
155
- def conns
156
- Thread.current[@http.generation_key] ||= Hash.new { |h,k| h[k] = {} }
157
- end
155
+ def ssl_connection
156
+ raise "#{@uri} is not HTTPS" unless @uri.scheme.downcase == 'https'
158
157
 
159
- def reqs
160
- Thread.current[@http.request_key] ||= Hash.new 0
161
- end
158
+ net_http_args = [@uri.hostname, @uri.port, nil, nil, nil, nil]
162
159
 
163
- def ssl_conns
164
- Thread.current[@http.ssl_generation_key] ||= Hash.new { |h,k| h[k] = {} }
165
- end
160
+ connection = Net::HTTP::Persistent::Connection.allocate
161
+ connection.ssl_generation = @http.ssl_generation
162
+ connection.http = BasicConnection.new
163
+ connection.reset
166
164
 
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
165
+ @http.pool.available.push connection, connection_args: net_http_args
173
166
 
174
- def touts
175
- Thread.current[@http.timeout_key] ||= Hash.new Net::HTTP::Persistent::EPOCH
167
+ connection
176
168
  end
177
169
 
178
170
  def test_initialize
@@ -188,7 +180,7 @@ class TestNetHttpPersistent < Minitest::Test
188
180
  end
189
181
 
190
182
  def test_initialize_name
191
- http = Net::HTTP::Persistent.new 'name'
183
+ http = Net::HTTP::Persistent.new name: 'name'
192
184
  assert_equal 'name', http.name
193
185
  end
194
186
 
@@ -212,7 +204,7 @@ class TestNetHttpPersistent < Minitest::Test
212
204
  def test_initialize_proxy
213
205
  proxy_uri = URI.parse 'http://proxy.example'
214
206
 
215
- http = Net::HTTP::Persistent.new nil, proxy_uri
207
+ http = Net::HTTP::Persistent.new proxy: proxy_uri
216
208
 
217
209
  assert_equal proxy_uri, http.proxy_uri
218
210
  end
@@ -224,37 +216,11 @@ class TestNetHttpPersistent < Minitest::Test
224
216
  assert_equal 1, @http.ssl_generation
225
217
  end
226
218
 
227
- def test_can_retry_eh_change_requests
228
- post = Net::HTTP::Post.new '/'
219
+ def test_ca_path_equals
220
+ @http.ca_path = :ca_path
229
221
 
230
- refute @http.can_retry? post
231
-
232
- @http.retry_change_requests = true
233
-
234
- assert @http.can_retry? post
235
- end
236
-
237
- if RUBY_1 then
238
- def test_can_retry_eh_idempotent
239
- head = Net::HTTP::Head.new '/'
240
-
241
- assert @http.can_retry? head
242
-
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 '/'
255
-
256
- refute @http.can_retry? post
257
- end
222
+ assert_equal :ca_path, @http.ca_path
223
+ assert_equal 1, @http.ssl_generation
258
224
  end
259
225
 
260
226
  def test_cert_store_equals
@@ -271,168 +237,163 @@ class TestNetHttpPersistent < Minitest::Test
271
237
  assert_equal 1, @http.ssl_generation
272
238
  end
273
239
 
240
+ def test_ciphers_equals
241
+ @http.ciphers = :ciphers
242
+
243
+ assert_equal :ciphers, @http.ciphers
244
+ assert_equal 1, @http.ssl_generation
245
+ end
246
+
274
247
  def test_connection_for
275
248
  @http.open_timeout = 123
276
249
  @http.read_timeout = 321
277
250
  @http.idle_timeout = 42
278
- c = @http.connection_for @uri
251
+ @http.max_retries = 5
279
252
 
280
- assert_kind_of @http_class, c
253
+ used = @http.connection_for @uri do |c|
254
+ assert_kind_of Net::HTTP, c.http
281
255
 
282
- assert c.started?
283
- refute c.proxy?
256
+ assert c.http.started?
257
+ refute c.http.proxy?
284
258
 
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
259
+ assert_equal 123, c.http.open_timeout
260
+ assert_equal 321, c.http.read_timeout
261
+ assert_equal 42, c.http.keep_alive_timeout
262
+ assert_equal 5, c.http.max_retries if c.http.respond_to?(:max_retries)
288
263
 
289
- assert_includes conns[0].keys, 'example.com:80'
290
- assert_same c, conns[0]['example.com:80']
264
+ c
265
+ end
266
+
267
+ stored = @http.pool.checkout ['example.com', 80, nil, nil, nil, nil]
268
+
269
+ assert_same used, stored
291
270
  end
292
271
 
293
272
  def test_connection_for_cached
294
273
  cached = basic_connection
295
- cached.start
296
- conns[0]['example.com:80'] = cached
274
+ cached.http.start
297
275
 
298
276
  @http.read_timeout = 5
299
277
 
300
- c = @http.connection_for @uri
301
-
302
- assert c.started?
278
+ @http.connection_for @uri do |c|
279
+ assert c.http.started?
303
280
 
304
- assert_equal 5, c.read_timeout
281
+ assert_equal 5, c.http.read_timeout
305
282
 
306
- assert_same cached, c
283
+ assert_same cached, c
284
+ end
307
285
  end
308
286
 
309
287
  def test_connection_for_closed
310
288
  cached = basic_connection
311
- cached.start
289
+ cached.http.start
312
290
  if Socket.const_defined? :TCP_NODELAY then
313
291
  io = Object.new
314
292
  def io.setsockopt(*a) raise IOError, 'closed stream' end
315
293
  cached.instance_variable_set :@socket, Net::BufferedIO.new(io)
316
294
  end
317
- conns['example.com:80'] = cached
318
-
319
- c = @http.connection_for @uri
320
-
321
- assert c.started?
322
295
 
323
- assert_includes conns.keys, 'example.com:80'
324
- assert_same c, conns[0]['example.com:80']
296
+ @http.connection_for @uri do |c|
297
+ assert c.http.started?
325
298
 
326
- socket = c.instance_variable_get :@socket
299
+ socket = c.http.instance_variable_get :@socket
327
300
 
328
- refute_includes socket.io.instance_variables, :@setsockopt
329
- refute_includes socket.io.instance_variables, '@setsockopt'
301
+ refute_includes socket.io.instance_variables, :@setsockopt
302
+ refute_includes socket.io.instance_variables, '@setsockopt'
303
+ end
330
304
  end
331
305
 
332
306
  def test_connection_for_debug_output
333
307
  io = StringIO.new
334
308
  @http.debug_output = io
335
309
 
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']
310
+ @http.connection_for @uri do |c|
311
+ assert c.http.started?
312
+ assert_equal io, c.http.instance_variable_get(:@debug_output)
313
+ end
343
314
  end
344
315
 
345
316
  def test_connection_for_cached_expire_always
346
317
  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
318
+ cached.http.start
319
+ cached.requests = 10
320
+ cached.last_use = Time.now # last used right now
351
321
 
352
322
  @http.idle_timeout = 0
353
323
 
354
- c = @http.connection_for @uri
355
-
356
- assert c.started?
324
+ @http.connection_for @uri do |c|
325
+ assert c.http.started?
357
326
 
358
- assert_same cached, c
327
+ assert_same cached, c
359
328
 
360
- assert_equal 0, reqs[cached.object_id],
361
- 'connection reset due to timeout'
329
+ assert_equal 0, c.requests, 'connection reset due to timeout'
330
+ end
362
331
  end
363
332
 
364
333
  def test_connection_for_cached_expire_never
365
334
  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
335
+ cached.http.start
336
+ cached.requests = 10
337
+ cached.last_use = Time.now # last used right now
370
338
 
371
339
  @http.idle_timeout = nil
372
340
 
373
- c = @http.connection_for @uri
374
-
375
- assert c.started?
341
+ @http.connection_for @uri do |c|
342
+ assert c.http.started?
376
343
 
377
- assert_same cached, c
344
+ assert_same cached, c
378
345
 
379
- assert_equal 10, reqs[cached.object_id],
380
- 'connection reset despite no timeout'
346
+ assert_equal 10, c.requests, 'connection reset despite no timeout'
347
+ end
381
348
  end
382
349
 
383
350
  def test_connection_for_cached_expired
384
351
  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
389
-
390
- c = @http.connection_for @uri
391
-
392
- assert c.started?
352
+ cached.http.start
353
+ cached.requests = 10
354
+ cached.last_use = Time.now - 3600
393
355
 
394
- assert_same cached, c
395
- assert_equal 0, reqs[cached.object_id],
396
- 'connection not reset due to timeout'
397
- end
356
+ @http.connection_for @uri do |c|
357
+ assert c.http.started?
398
358
 
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
359
+ assert_same cached, c
360
+ assert_equal 0, cached.requests, 'connection not reset due to timeout'
405
361
  end
406
-
407
- assert_equal 'connection refused: example.com:80', e.message
408
362
  end
409
363
 
410
364
  def test_connection_for_finished_ssl
365
+ skip 'Broken on Windows' if Gem.win_platform?
411
366
  skip 'OpenSSL is missing' unless HAVE_OPENSSL
412
367
 
413
368
  uri = URI.parse 'https://example.com/path'
414
- c = @http.connection_for uri
415
369
 
416
- assert c.started?
417
- assert c.use_ssl?
370
+ @http.connection_for uri do |c|
371
+ assert c.http.started?
372
+ assert c.http.use_ssl?
418
373
 
419
- @http.finish c
374
+ @http.finish c
420
375
 
421
- refute c.started?
376
+ refute c.http.started?
377
+ end
422
378
 
423
- c2 = @http.connection_for uri
379
+ @http.connection_for uri do |c2|
380
+ assert c2.http.started?
381
+ end
382
+ end
424
383
 
425
- assert c2.started?
384
+ def test_connection_for_ipv6
385
+ @http.connection_for @uri_v6 do |c|
386
+ assert_equal '2001:db8::1', c.http.address
387
+ end
426
388
  end
427
389
 
428
390
  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
391
+ c = basic_connection
392
+ def (c.http).start; raise Errno::EHOSTDOWN end
393
+ def (c.http).started?; false end
433
394
 
434
395
  e = assert_raises Net::HTTP::Persistent::Error do
435
- @http.connection_for @uri
396
+ @http.connection_for @uri do end
436
397
  end
437
398
 
438
399
  assert_equal 'host down: example.com:80', e.message
@@ -440,8 +401,10 @@ class TestNetHttpPersistent < Minitest::Test
440
401
 
441
402
  def test_connection_for_http_class_with_fakeweb
442
403
  Object.send :const_set, :FakeWeb, nil
443
- c = @http.connection_for @uri
444
- assert_instance_of Net::HTTP, c
404
+
405
+ @http.connection_for @uri do |c|
406
+ assert_instance_of Net::HTTP, c.http
407
+ end
445
408
  ensure
446
409
  if Object.const_defined?(:FakeWeb) then
447
410
  Object.send :remove_const, :FakeWeb
@@ -450,8 +413,9 @@ class TestNetHttpPersistent < Minitest::Test
450
413
 
451
414
  def test_connection_for_http_class_with_webmock
452
415
  Object.send :const_set, :WebMock, nil
453
- c = @http.connection_for @uri
454
- assert_instance_of Net::HTTP, c
416
+ @http.connection_for @uri do |c|
417
+ assert_instance_of Net::HTTP, c.http
418
+ end
455
419
  ensure
456
420
  if Object.const_defined?(:WebMock) then
457
421
  Object.send :remove_const, :WebMock
@@ -460,8 +424,9 @@ class TestNetHttpPersistent < Minitest::Test
460
424
 
461
425
  def test_connection_for_http_class_with_artifice
462
426
  Object.send :const_set, :Artifice, nil
463
- c = @http.connection_for @uri
464
- assert_instance_of Net::HTTP, c
427
+ @http.connection_for @uri do |c|
428
+ assert_instance_of Net::HTTP, c.http
429
+ end
465
430
  ensure
466
431
  if Object.const_defined?(:Artifice) then
467
432
  Object.send :remove_const, :Artifice
@@ -469,23 +434,12 @@ class TestNetHttpPersistent < Minitest::Test
469
434
  end
470
435
 
471
436
  def test_connection_for_name
472
- http = Net::HTTP::Persistent.new 'name'
437
+ http = Net::HTTP::Persistent.new name: 'name'
473
438
  uri = URI.parse 'http://example/'
474
439
 
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
440
+ http.connection_for uri do |c|
441
+ assert c.http.started?
442
+ end
489
443
  end
490
444
 
491
445
  def test_connection_for_proxy
@@ -493,16 +447,20 @@ class TestNetHttpPersistent < Minitest::Test
493
447
  uri.user = 'johndoe'
494
448
  uri.password = 'muffins'
495
449
 
496
- http = Net::HTTP::Persistent.new nil, uri
450
+ http = Net::HTTP::Persistent.new proxy: uri
497
451
 
498
- c = http.connection_for @uri
452
+ used = http.connection_for @uri do |c|
453
+ assert c.http.started?
454
+ assert c.http.proxy?
455
+
456
+ c
457
+ end
499
458
 
500
- assert c.started?
501
- assert c.proxy?
459
+ stored = http.pool.checkout ['example.com', 80,
460
+ 'proxy.example', 80,
461
+ 'johndoe', 'muffins']
502
462
 
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']
463
+ assert_same used, stored
506
464
  end
507
465
 
508
466
  def test_connection_for_proxy_unescaped
@@ -511,25 +469,28 @@ class TestNetHttpPersistent < Minitest::Test
511
469
  uri.password = 'muf%3Afins'
512
470
  uri.freeze
513
471
 
514
- http = Net::HTTP::Persistent.new nil, uri
515
- c = http.connection_for @uri
472
+ http = Net::HTTP::Persistent.new proxy: uri
473
+
474
+ http.connection_for @uri do end
475
+
476
+ stored = http.pool.checkout ['example.com', 80,
477
+ 'proxy.example', 80,
478
+ 'john@doe', 'muf:fins']
516
479
 
517
- assert_includes conns[1].keys,
518
- 'example.com:80:proxy.example:80:john@doe:muf:fins'
480
+ assert stored
519
481
  end
520
482
 
521
483
  def test_connection_for_proxy_host_down
522
484
  Net::HTTP.use_connect :host_down_connect
523
- Net::HTTP::Persistent::SSLReuse.use_connect :host_down_connect
524
485
 
525
486
  uri = URI.parse 'http://proxy.example'
526
487
  uri.user = 'johndoe'
527
488
  uri.password = 'muffins'
528
489
 
529
- http = Net::HTTP::Persistent.new nil, uri
490
+ http = Net::HTTP::Persistent.new proxy: uri
530
491
 
531
492
  e = assert_raises Net::HTTP::Persistent::Error do
532
- http.connection_for @uri
493
+ http.connection_for @uri do end
533
494
  end
534
495
 
535
496
  assert_equal 'host down: proxy.example:80', e.message
@@ -537,16 +498,15 @@ class TestNetHttpPersistent < Minitest::Test
537
498
 
538
499
  def test_connection_for_proxy_refused
539
500
  Net::HTTP.use_connect :refused_connect
540
- Net::HTTP::Persistent::SSLReuse.use_connect :refused_connect
541
501
 
542
502
  uri = URI.parse 'http://proxy.example'
543
503
  uri.user = 'johndoe'
544
504
  uri.password = 'muffins'
545
505
 
546
- http = Net::HTTP::Persistent.new nil, uri
506
+ http = Net::HTTP::Persistent.new proxy: uri
547
507
 
548
508
  e = assert_raises Net::HTTP::Persistent::Error do
549
- http.connection_for @uri
509
+ http.connection_for @uri do end
550
510
  end
551
511
 
552
512
  assert_equal 'connection refused: proxy.example:80', e.message
@@ -558,38 +518,53 @@ class TestNetHttpPersistent < Minitest::Test
558
518
  uri.password = 'muffins'
559
519
  uri.query = 'no_proxy=example.com'
560
520
 
561
- http = Net::HTTP::Persistent.new nil, uri
521
+ http = Net::HTTP::Persistent.new proxy: uri
522
+
523
+ http.connection_for @uri do |c|
524
+ assert c.http.started?
525
+ refute c.http.proxy?
526
+ end
527
+
528
+ stored = http.pool.checkout ['example.com', 80]
562
529
 
563
- c = http.connection_for @uri
530
+ assert stored
531
+ end
532
+
533
+ def test_connection_for_no_proxy_from_env
534
+ ENV['http_proxy'] = 'proxy.example'
535
+ ENV['no_proxy'] = 'localhost, example.com,'
536
+ ENV['proxy_user'] = 'johndoe'
537
+ ENV['proxy_password'] = 'muffins'
564
538
 
565
- assert c.started?
566
- refute c.proxy?
539
+ http = Net::HTTP::Persistent.new proxy: :ENV
567
540
 
568
- assert_includes conns[1].keys, 'example.com:80'
569
- assert_same c, conns[1]['example.com:80']
541
+ http.connection_for @uri do |c|
542
+ assert c.http.started?
543
+ refute c.http.proxy?
544
+ refute c.http.proxy_from_env?
545
+ end
570
546
  end
571
547
 
572
548
  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
549
+ Net::HTTP.use_connect :refused_connect
577
550
 
578
551
  e = assert_raises Net::HTTP::Persistent::Error do
579
- @http.connection_for @uri
552
+ @http.connection_for @uri do end
580
553
  end
581
554
 
582
- assert_match %r%connection refused%, e.message
555
+ assert_equal 'connection refused: example.com:80', e.message
583
556
  end
584
557
 
585
558
  def test_connection_for_ssl
559
+ skip 'Broken on Windows' if Gem.win_platform?
586
560
  skip 'OpenSSL is missing' unless HAVE_OPENSSL
587
561
 
588
562
  uri = URI.parse 'https://example.com/path'
589
- c = @http.connection_for uri
590
563
 
591
- assert c.started?
592
- assert c.use_ssl?
564
+ @http.connection_for uri do |c|
565
+ assert c.http.started?
566
+ assert c.http.use_ssl?
567
+ end
593
568
  end
594
569
 
595
570
  def test_connection_for_ssl_cached
@@ -597,11 +572,11 @@ class TestNetHttpPersistent < Minitest::Test
597
572
 
598
573
  @uri = URI.parse 'https://example.com/path'
599
574
 
600
- cached = ssl_connection 0
601
-
602
- c = @http.connection_for @uri
575
+ cached = ssl_connection
603
576
 
604
- assert_same cached, c
577
+ @http.connection_for @uri do |c|
578
+ assert_same cached, c
579
+ end
605
580
  end
606
581
 
607
582
  def test_connection_for_ssl_cached_reconnect
@@ -611,46 +586,39 @@ class TestNetHttpPersistent < Minitest::Test
611
586
 
612
587
  cached = ssl_connection
613
588
 
614
- @http.reconnect_ssl
589
+ ssl_generation = @http.ssl_generation
615
590
 
616
- c = @http.connection_for @uri
591
+ @http.reconnect_ssl
617
592
 
618
- refute_same cached, c
593
+ @http.connection_for @uri do |c|
594
+ assert_same cached, c
595
+ refute_equal ssl_generation, c.ssl_generation
596
+ end
619
597
  end
620
598
 
621
599
  def test_connection_for_ssl_case
600
+ skip 'Broken on Windows' if Gem.win_platform?
622
601
  skip 'OpenSSL is missing' unless HAVE_OPENSSL
623
602
 
624
603
  uri = URI.parse 'HTTPS://example.com/path'
625
- c = @http.connection_for uri
626
-
627
- assert c.started?
628
- assert c.use_ssl?
604
+ @http.connection_for uri do |c|
605
+ assert c.http.started?
606
+ assert c.http.use_ssl?
607
+ end
629
608
  end
630
609
 
631
610
  def test_connection_for_timeout
632
611
  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
637
-
638
- c = @http.connection_for @uri
612
+ cached.http.start
613
+ cached.requests = 10
614
+ cached.last_use = Time.now - 6
639
615
 
640
- assert c.started?
641
- assert_equal 0, reqs[c.object_id]
616
+ @http.connection_for @uri do |c|
617
+ assert c.http.started?
618
+ assert_equal 0, c.requests
642
619
 
643
- assert_same cached, c
644
- end
645
-
646
- def test_error_message
647
- c = basic_connection
648
- touts[c.object_id] = Time.now - 1
649
- reqs[c.object_id] = 5
650
-
651
- message = @http.error_message(c)
652
- assert_match %r%after 4 requests on #{c.object_id}%, message
653
- assert_match %r%, last used [\d.]+ seconds ago%, message
620
+ assert_same cached, c
621
+ end
654
622
  end
655
623
 
656
624
  def test_escape
@@ -666,9 +634,10 @@ class TestNetHttpPersistent < Minitest::Test
666
634
  end
667
635
 
668
636
  def test_expired_eh
637
+ skip 'Broken on Windows' if Gem.win_platform?
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,59 @@ 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
678
+ c.http.instance_variable_set(:@last_communicated, Process.clock_gettime(Process::CLOCK_MONOTONIC))
709
679
 
710
680
  @http.finish c
711
681
 
712
- refute c.started?
713
- assert c.finished?
714
- assert_equal 0, reqs[c.object_id]
682
+ refute c.http.started?
683
+ assert c.http.finished?
684
+
685
+ assert_equal 0, c.requests
686
+ assert_equal Net::HTTP::Persistent::EPOCH, c.last_use
687
+ assert_nil c.http.instance_variable_get(:@last_communicated)
715
688
  end
716
689
 
717
690
  def test_finish_io_error
718
691
  c = basic_connection
719
- def c.finish; @finished += 1; raise IOError end
720
- reqs[c.object_id] = 5
692
+ def (c.http).finish; @finished += 1; raise IOError end
693
+ c.requests = 5
694
+
695
+ @http.finish c
696
+
697
+ refute c.http.started?
698
+ assert c.http.finished?
699
+ end
700
+
701
+ def test_finish_ssl_no_session_reuse
702
+ http = Net::HTTP.new 'localhost', 443, ssl: true
703
+ http.instance_variable_set :@ssl_session, :something
704
+
705
+ c = Net::HTTP::Persistent::Connection.allocate
706
+ c.instance_variable_set :@http, http
707
+
708
+ @http.reuse_ssl_sessions = false
721
709
 
722
710
  @http.finish c
723
711
 
724
- refute c.started?
725
- assert c.finished?
712
+ assert_nil c.http.instance_variable_get :@ssl_session
726
713
  end
727
714
 
728
715
  def test_http_version
@@ -735,23 +722,21 @@ class TestNetHttpPersistent < Minitest::Test
735
722
  assert_equal '1.1', @http.http_version(@uri)
736
723
  end
737
724
 
738
- def test_idempotent_eh
739
- assert @http.idempotent? Net::HTTP::Delete.new '/'
740
- assert @http.idempotent? Net::HTTP::Get.new '/'
741
- assert @http.idempotent? Net::HTTP::Head.new '/'
742
- assert @http.idempotent? Net::HTTP::Options.new '/'
743
- assert @http.idempotent? Net::HTTP::Put.new '/'
744
- assert @http.idempotent? Net::HTTP::Trace.new '/'
725
+ def test_http_version_IPv6
726
+ assert_nil @http.http_version @uri_v6
745
727
 
746
- refute @http.idempotent? Net::HTTP::Post.new '/'
747
- end
728
+ connection @uri_v6
748
729
 
749
- def test_max_age
750
- assert_in_delta Time.now - 5, @http.max_age
730
+ @http.request @uri_v6
751
731
 
752
- @http.idle_timeout = nil
732
+ assert_equal '1.1', @http.http_version(@uri_v6)
733
+ end
753
734
 
754
- assert_in_delta Time.now + 1, @http.max_age
735
+ def test_max_retries_equals
736
+ @http.max_retries = 5
737
+
738
+ assert_equal 5, @http.max_retries
739
+ assert_equal 1, @http.generation
755
740
  end
756
741
 
757
742
  def test_normalize_uri
@@ -774,8 +759,7 @@ class TestNetHttpPersistent < Minitest::Test
774
759
  skip 'net-http-pipeline not installed' unless defined?(Net::HTTP::Pipeline)
775
760
 
776
761
  cached = basic_connection
777
- cached.start
778
- conns['example.com:80'] = cached
762
+ cached.http.start
779
763
 
780
764
  requests = [
781
765
  Net::HTTP::Get.new((@uri + '1').request_uri),
@@ -810,7 +794,7 @@ class TestNetHttpPersistent < Minitest::Test
810
794
  def test_proxy_equals_nil
811
795
  @http.proxy = nil
812
796
 
813
- assert_equal nil, @http.proxy_uri
797
+ assert_nil @http.proxy_uri
814
798
 
815
799
  assert_equal 1, @http.generation, 'generation'
816
800
  assert_equal 1, @http.ssl_generation, 'ssl_generation'
@@ -824,6 +808,14 @@ class TestNetHttpPersistent < Minitest::Test
824
808
  assert_equal proxy_uri, @http.proxy_uri
825
809
  end
826
810
 
811
+ def test_proxy_equals_uri_IPv6
812
+ proxy_uri = @uri_v6
813
+
814
+ @http.proxy = proxy_uri
815
+
816
+ assert_equal proxy_uri, @http.proxy_uri
817
+ end
818
+
827
819
  def test_proxy_from_env
828
820
  ENV['http_proxy'] = 'proxy.example'
829
821
  ENV['http_proxy_user'] = 'johndoe'
@@ -935,18 +927,47 @@ class TestNetHttpPersistent < Minitest::Test
935
927
  end
936
928
 
937
929
  def test_reconnect_ssl
938
- result = @http.reconnect_ssl
930
+ skip 'OpenSSL is missing' unless HAVE_OPENSSL
939
931
 
940
- assert_equal 1, result
932
+ @uri = URI 'https://example.com'
933
+ now = Time.now
934
+
935
+ ssl_http = ssl_connection
936
+
937
+ def (ssl_http.http).finish
938
+ @started = 0
939
+ end
940
+
941
+ used1 = @http.connection_for @uri do |c|
942
+ c.requests = 1
943
+ c.last_use = now
944
+ c
945
+ end
946
+
947
+ assert_equal OpenSSL::SSL::VERIFY_PEER, used1.http.verify_mode
948
+
949
+ @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
950
+ @http.reconnect_ssl
951
+
952
+ used2 = @http.connection_for @uri do |c|
953
+ c
954
+ end
955
+
956
+ assert_same used1, used2
957
+
958
+ assert_equal OpenSSL::SSL::VERIFY_NONE, used2.http.verify_mode,
959
+ 'verify mode must change'
960
+ assert_equal 0, used2.requests
961
+ assert_equal Net::HTTP::Persistent::EPOCH, used2.last_use
941
962
  end
942
963
 
943
- def test_request
964
+ def test_requestx
944
965
  @http.override_headers['user-agent'] = 'test ua'
945
966
  @http.headers['accept'] = 'text/*'
946
967
  c = connection
947
968
 
948
969
  res = @http.request @uri
949
- req = c.req
970
+ req = c.http.req
950
971
 
951
972
  assert_kind_of Net::HTTPResponse, res
952
973
 
@@ -959,86 +980,12 @@ class TestNetHttpPersistent < Minitest::Test
959
980
  assert_equal 'keep-alive', req['connection']
960
981
  assert_equal '30', req['keep-alive']
961
982
 
962
- assert_in_delta Time.now, touts[c.object_id]
963
-
964
- assert_equal 1, reqs[c.object_id]
965
- end
966
-
967
- def test_request_ETIMEDOUT
968
- c = basic_connection
969
- def c.request(*a) raise Errno::ETIMEDOUT, "timed out" end
970
-
971
- e = assert_raises Net::HTTP::Persistent::Error do
972
- @http.request @uri
973
- end
974
-
975
- assert_equal 0, reqs[c.object_id]
976
- assert_match %r%too many connection resets%, e.message
977
- end
978
-
979
- def test_request_bad_response
980
- c = basic_connection
981
- def c.request(*a) raise Net::HTTPBadResponse end
982
-
983
- e = assert_raises Net::HTTP::Persistent::Error do
984
- @http.request @uri
985
- end
986
-
987
- assert_equal 0, reqs[c.object_id]
988
- assert_match %r%too many bad responses%, e.message
989
- end
990
-
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
1005
-
1006
- @http.request @uri
1007
-
1008
- assert c.finished?
983
+ # There's some roounding issue on jruby preventing this from passing
984
+ unless RUBY_PLATFORM == "java"
985
+ assert_in_delta Time.now, c.last_use
1009
986
  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
987
 
1021
- assert c.finished?
1022
- end
1023
- end
1024
-
1025
- def test_request_bad_response_unsafe
1026
- c = basic_connection
1027
- def c.request(*a)
1028
- if instance_variable_defined? :@request then
1029
- raise 'POST must not be retried'
1030
- else
1031
- @request = true
1032
- raise Net::HTTPBadResponse
1033
- end
1034
- end
1035
-
1036
- e = assert_raises Net::HTTP::Persistent::Error do
1037
- @http.request @uri, Net::HTTP::Post.new(@uri.path)
1038
- end
1039
-
1040
- assert_equal 0, reqs[c.object_id]
1041
- assert_match %r%too many bad responses%, e.message
988
+ assert_equal 1, c.requests
1042
989
  end
1043
990
 
1044
991
  def test_request_block
@@ -1050,7 +997,7 @@ class TestNetHttpPersistent < Minitest::Test
1050
997
  body = r.read_body
1051
998
  end
1052
999
 
1053
- req = c.req
1000
+ req = c.http.req
1054
1001
 
1055
1002
  assert_kind_of Net::HTTPResponse, res
1056
1003
  refute_nil body
@@ -1061,17 +1008,17 @@ class TestNetHttpPersistent < Minitest::Test
1061
1008
  assert_equal '30', req['keep-alive']
1062
1009
  assert_match %r%test ua%, req['user-agent']
1063
1010
 
1064
- assert_equal 1, reqs[c.object_id]
1011
+ assert_equal 1, c.requests
1065
1012
  end
1066
1013
 
1067
1014
  def test_request_close_1_0
1068
1015
  c = connection
1069
1016
 
1070
- class << c
1017
+ class << c.http
1071
1018
  remove_method :request
1072
1019
  end
1073
1020
 
1074
- def c.request req
1021
+ def (c.http).request req
1075
1022
  @req = req
1076
1023
  r = Net::HTTPResponse.allocate
1077
1024
  r.instance_variable_set :@header, {}
@@ -1084,7 +1031,7 @@ class TestNetHttpPersistent < Minitest::Test
1084
1031
  request = Net::HTTP::Get.new @uri.request_uri
1085
1032
 
1086
1033
  res = @http.request @uri, request
1087
- req = c.req
1034
+ req = c.http.req
1088
1035
 
1089
1036
  assert_kind_of Net::HTTPResponse, res
1090
1037
 
@@ -1093,7 +1040,7 @@ class TestNetHttpPersistent < Minitest::Test
1093
1040
  assert_equal 'keep-alive', req['connection']
1094
1041
  assert_equal '30', req['keep-alive']
1095
1042
 
1096
- assert c.finished?
1043
+ assert c.http.finished?
1097
1044
  end
1098
1045
 
1099
1046
  def test_request_connection_close_request
@@ -1103,26 +1050,26 @@ class TestNetHttpPersistent < Minitest::Test
1103
1050
  request['connection'] = 'close'
1104
1051
 
1105
1052
  res = @http.request @uri, request
1106
- req = c.req
1053
+ req = c.http.req
1107
1054
 
1108
1055
  assert_kind_of Net::HTTPResponse, res
1109
1056
 
1110
1057
  assert_kind_of Net::HTTP::Get, req
1111
1058
  assert_equal '/path', req.path
1112
1059
  assert_equal 'close', req['connection']
1113
- assert_equal nil, req['keep-alive']
1060
+ assert_nil req['keep-alive']
1114
1061
 
1115
- assert c.finished?
1062
+ assert c.http.finished?
1116
1063
  end
1117
1064
 
1118
1065
  def test_request_connection_close_response
1119
1066
  c = connection
1120
1067
 
1121
- class << c
1068
+ class << c.http
1122
1069
  remove_method :request
1123
1070
  end
1124
1071
 
1125
- def c.request req
1072
+ def (c.http).request req
1126
1073
  @req = req
1127
1074
  r = Net::HTTPResponse.allocate
1128
1075
  r.instance_variable_set :@header, {}
@@ -1136,7 +1083,7 @@ class TestNetHttpPersistent < Minitest::Test
1136
1083
  request = Net::HTTP::Get.new @uri.request_uri
1137
1084
 
1138
1085
  res = @http.request @uri, request
1139
- req = c.req
1086
+ req = c.http.req
1140
1087
 
1141
1088
  assert_kind_of Net::HTTPResponse, res
1142
1089
 
@@ -1145,53 +1092,33 @@ class TestNetHttpPersistent < Minitest::Test
1145
1092
  assert_equal 'keep-alive', req['connection']
1146
1093
  assert_equal '30', req['keep-alive']
1147
1094
 
1148
- assert c.finished?
1095
+ assert c.http.finished?
1149
1096
  end
1150
1097
 
1151
1098
  def test_request_exception
1152
1099
  c = basic_connection
1153
- def c.request(*a) raise Exception, "very bad things happened" end
1100
+ def (c.http).request(*a)
1101
+ raise Exception, "very bad things happened"
1102
+ end
1154
1103
 
1155
1104
  assert_raises Exception do
1156
1105
  @http.request @uri
1157
1106
  end
1158
1107
 
1159
- assert_equal 0, reqs[c.object_id]
1160
- assert c.finished?
1108
+ assert_equal 0, c.requests
1109
+ assert c.http.finished?
1161
1110
  end
1162
1111
 
1163
1112
  def test_request_invalid
1164
1113
  c = basic_connection
1165
- def c.request(*a) raise Errno::EINVAL, "write" end
1114
+ def (c.http).request(*a) raise Errno::EINVAL, "write" end
1166
1115
 
1167
- e = assert_raises Net::HTTP::Persistent::Error do
1116
+ e = assert_raises Errno::EINVAL do
1168
1117
  @http.request @uri
1169
1118
  end
1170
1119
 
1171
- assert_equal 0, reqs[c.object_id]
1172
- assert_match %r%too many connection resets%, e.message
1173
- end
1174
-
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?
1120
+ assert_equal 0, c.requests
1121
+ assert_match %r%Invalid argument - write%, e.message
1195
1122
  end
1196
1123
 
1197
1124
  def test_request_post
@@ -1200,96 +1127,11 @@ class TestNetHttpPersistent < Minitest::Test
1200
1127
  post = Net::HTTP::Post.new @uri.path
1201
1128
 
1202
1129
  @http.request @uri, post
1203
- req = c.req
1130
+ req = c.http.req
1204
1131
 
1205
1132
  assert_same post, req
1206
1133
  end
1207
1134
 
1208
- def test_request_reset
1209
- c = basic_connection
1210
- def c.request(*a) raise Errno::ECONNRESET end
1211
-
1212
- e = assert_raises Net::HTTP::Persistent::Error do
1213
- @http.request @uri
1214
- end
1215
-
1216
- assert_equal 0, reqs[c.object_id]
1217
- assert_match %r%too many connection resets%, e.message
1218
- end
1219
-
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
1237
-
1238
- assert c.reset?
1239
- assert c.finished?
1240
- end
1241
- else
1242
- def test_request_reset_retry
1243
- c = basic_connection
1244
- touts[c.object_id] = Time.now
1245
-
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?
1256
- end
1257
- end
1258
-
1259
- def test_request_reset_unsafe
1260
- c = basic_connection
1261
- def c.request(*a)
1262
- if instance_variable_defined? :@request then
1263
- raise 'POST must not be retried'
1264
- else
1265
- @request = true
1266
- raise Errno::ECONNRESET
1267
- end
1268
- end
1269
-
1270
- e = assert_raises Net::HTTP::Persistent::Error do
1271
- @http.request @uri, Net::HTTP::Post.new(@uri.path)
1272
- end
1273
-
1274
- assert_equal 0, reqs[c.object_id]
1275
- assert_match %r%too many connection resets%, e.message
1276
- end
1277
-
1278
- def test_request_ssl_error
1279
- skip 'OpenSSL is missing' unless HAVE_OPENSSL
1280
-
1281
- 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
1286
-
1287
- e = assert_raises Net::HTTP::Persistent::Error do
1288
- @http.request uri
1289
- end
1290
- assert_match %r%bad write retry%, e.message
1291
- end
1292
-
1293
1135
  def test_request_setup
1294
1136
  @http.override_headers['user-agent'] = 'test ua'
1295
1137
  @http.headers['accept'] = 'text/*'
@@ -1308,59 +1150,51 @@ class TestNetHttpPersistent < Minitest::Test
1308
1150
  assert_equal '30', req['keep-alive']
1309
1151
  end
1310
1152
 
1311
- def test_request_setup_uri
1312
- uri = @uri + '?a=b'
1313
-
1314
- req = @http.request_setup uri
1153
+ def test_request_string
1154
+ @http.override_headers['user-agent'] = 'test ua'
1155
+ @http.headers['accept'] = 'text/*'
1156
+ c = connection
1315
1157
 
1316
- assert_kind_of Net::HTTP::Get, req
1317
- assert_equal '/path?a=b', req.path
1318
- end
1158
+ res = @http.request @uri.to_s
1159
+ req = c.http.req
1319
1160
 
1320
- def test_request_failed
1321
- c = basic_connection
1322
- reqs[c.object_id] = 1
1323
- touts[c.object_id] = Time.now
1161
+ assert_kind_of Net::HTTPResponse, res
1324
1162
 
1325
- original = nil
1163
+ assert_kind_of Net::HTTP::Get, req
1164
+ assert_equal '/path', req.path
1326
1165
 
1327
- begin
1328
- raise 'original'
1329
- rescue => original
1330
- end
1166
+ assert_equal 1, c.requests
1167
+ end
1331
1168
 
1332
- req = Net::HTTP::Get.new '/'
1333
-
1334
- e = assert_raises Net::HTTP::Persistent::Error do
1335
- @http.request_failed original, req, c
1336
- end
1169
+ def test_request_setup_uri
1170
+ uri = @uri + '?a=b'
1337
1171
 
1338
- assert_match "too many connection resets (due to original - RuntimeError)",
1339
- e.message
1172
+ req = @http.request_setup uri
1340
1173
 
1341
- assert_equal original.backtrace, e.backtrace
1174
+ assert_kind_of Net::HTTP::Get, req
1175
+ assert_equal '/path?a=b', req.path
1342
1176
  end
1343
1177
 
1344
1178
  def test_reset
1345
1179
  c = basic_connection
1346
- c.start
1347
- touts[c.object_id] = Time.now
1348
- reqs[c.object_id] = 5
1180
+ c.http.start
1181
+ c.last_use = Time.now
1182
+ c.requests = 5
1349
1183
 
1350
1184
  @http.reset c
1351
1185
 
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]
1186
+ assert c.http.started?
1187
+ assert c.http.finished?
1188
+ assert c.http.reset?
1189
+ assert_equal 0, c.requests
1190
+ assert_equal Net::HTTP::Persistent::EPOCH, c.last_use
1357
1191
  end
1358
1192
 
1359
1193
  def test_reset_host_down
1360
1194
  c = basic_connection
1361
- touts[c.object_id] = Time.now
1362
- def c.start; raise Errno::EHOSTDOWN end
1363
- reqs[c.object_id] = 5
1195
+ c.last_use = Time.now
1196
+ def (c.http).start; raise Errno::EHOSTDOWN end
1197
+ c.requests = 5
1364
1198
 
1365
1199
  e = assert_raises Net::HTTP::Persistent::Error do
1366
1200
  @http.reset c
@@ -1372,20 +1206,20 @@ class TestNetHttpPersistent < Minitest::Test
1372
1206
 
1373
1207
  def test_reset_io_error
1374
1208
  c = basic_connection
1375
- touts[c.object_id] = Time.now
1376
- reqs[c.object_id] = 5
1209
+ c.last_use = Time.now
1210
+ c.requests = 5
1377
1211
 
1378
1212
  @http.reset c
1379
1213
 
1380
- assert c.started?
1381
- assert c.finished?
1214
+ assert c.http.started?
1215
+ assert c.http.finished?
1382
1216
  end
1383
1217
 
1384
1218
  def test_reset_refused
1385
1219
  c = basic_connection
1386
- touts[c.object_id] = Time.now
1387
- def c.start; raise Errno::ECONNREFUSED end
1388
- reqs[c.object_id] = 5
1220
+ c.last_use = Time.now
1221
+ def (c.http).start; raise Errno::ECONNREFUSED end
1222
+ c.requests = 5
1389
1223
 
1390
1224
  e = assert_raises Net::HTTP::Persistent::Error do
1391
1225
  @http.reset c
@@ -1395,167 +1229,39 @@ class TestNetHttpPersistent < Minitest::Test
1395
1229
  assert_match __FILE__, e.backtrace.first
1396
1230
  end
1397
1231
 
1398
- def test_retry_change_requests_equals
1399
- get = Net::HTTP::Get.new('/')
1400
- post = Net::HTTP::Post.new('/')
1401
-
1402
- refute @http.retry_change_requests
1403
-
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)
1410
- refute @http.can_retry?(post)
1411
-
1412
- @http.retry_change_requests = true
1413
-
1414
- assert @http.retry_change_requests
1415
-
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
-
1423
- assert @http.can_retry?(post)
1424
- end
1425
-
1426
1232
  def test_shutdown
1427
- ssl_conns
1428
1233
  c = connection
1429
- rs = reqs
1430
- ts = touts
1431
1234
 
1432
1235
  orig = @http
1433
- @http = Net::HTTP::Persistent.new 'name'
1236
+ @http = Net::HTTP::Persistent.new name: 'name'
1434
1237
  c2 = connection
1435
1238
 
1436
1239
  orig.shutdown
1437
1240
 
1438
1241
  @http = orig
1439
1242
 
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
1243
+ assert c.http.finished?, 'last-generation connection must be finished'
1244
+ refute c2.http.finished?, 'present generation connection must not be finished'
1451
1245
  end
1452
1246
 
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]
1513
- end
1514
-
1515
- def test_shutdown_ssl
1247
+ def test_ssl
1516
1248
  skip 'OpenSSL is missing' unless HAVE_OPENSSL
1517
1249
 
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
1250
+ @http.verify_callback = :callback
1251
+ c = Net::HTTP.new 'localhost', 80
1545
1252
 
1546
- refute c.finished?
1253
+ @http.ssl c
1547
1254
 
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]
1255
+ assert c.use_ssl?
1256
+ assert_equal OpenSSL::SSL::VERIFY_PEER, c.verify_mode
1257
+ assert_kind_of OpenSSL::X509::Store, c.cert_store
1258
+ assert_nil c.verify_callback
1554
1259
  end
1555
1260
 
1556
- def test_ssl
1261
+ def test_ssl_ca_file
1557
1262
  skip 'OpenSSL is missing' unless HAVE_OPENSSL
1558
1263
 
1264
+ @http.ca_file = 'ca_file'
1559
1265
  @http.verify_callback = :callback
1560
1266
  c = Net::HTTP.new 'localhost', 80
1561
1267
 
@@ -1563,14 +1269,13 @@ class TestNetHttpPersistent < Minitest::Test
1563
1269
 
1564
1270
  assert c.use_ssl?
1565
1271
  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
1272
+ assert_equal :callback, c.verify_callback
1568
1273
  end
1569
1274
 
1570
- def test_ssl_ca_file
1275
+ def test_ssl_ca_path
1571
1276
  skip 'OpenSSL is missing' unless HAVE_OPENSSL
1572
1277
 
1573
- @http.ca_file = 'ca_file'
1278
+ @http.ca_path = 'ca_path'
1574
1279
  @http.verify_callback = :callback
1575
1280
  c = Net::HTTP.new 'localhost', 80
1576
1281
 
@@ -1667,34 +1372,37 @@ class TestNetHttpPersistent < Minitest::Test
1667
1372
  end
1668
1373
  end
1669
1374
 
1670
- def test_ssl_cleanup
1671
- skip 'OpenSSL is missing' unless HAVE_OPENSSL
1672
-
1673
- uri1 = URI.parse 'https://one.example'
1375
+ def test_ssl_timeout_equals
1376
+ @http.ssl_timeout = :ssl_timeout
1674
1377
 
1675
- c1 = @http.connection_for uri1
1378
+ assert_equal :ssl_timeout, @http.ssl_timeout
1379
+ assert_equal 1, @http.ssl_generation
1380
+ end
1676
1381
 
1677
- touts[c1.object_id] = Time.now
1678
- reqs[c1.object_id] = 5
1382
+ def test_ssl_version_equals
1383
+ @http.ssl_version = :ssl_version
1679
1384
 
1680
- @http.reconnect_ssl
1385
+ assert_equal :ssl_version, @http.ssl_version
1386
+ assert_equal 1, @http.ssl_generation
1387
+ end
1681
1388
 
1682
- @http.ssl_cleanup @http.ssl_generation
1389
+ def test_min_version_equals
1390
+ @http.min_version = :min_version
1683
1391
 
1684
- assert_empty ssl_conns
1685
- assert_empty touts
1686
- assert_empty reqs # sanity check, performed by #finish
1392
+ assert_equal :min_version, @http.min_version
1393
+ assert_equal 1, @http.ssl_generation
1687
1394
  end
1688
1395
 
1689
- def test_ssl_version_equals
1690
- @http.ssl_version = :ssl_version
1396
+ def test_max_version_equals
1397
+ @http.max_version = :max_version
1691
1398
 
1692
- assert_equal :ssl_version, @http.ssl_version
1399
+ assert_equal :max_version, @http.max_version
1693
1400
  assert_equal 1, @http.ssl_generation
1694
- end unless RUBY_1
1401
+ end
1695
1402
 
1696
1403
  def test_start
1697
1404
  c = basic_connection
1405
+ c = c.http
1698
1406
 
1699
1407
  @http.socket_options << [Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1]
1700
1408
  @http.debug_output = $stderr
@@ -1722,6 +1430,13 @@ class TestNetHttpPersistent < Minitest::Test
1722
1430
  assert_equal 1, @http.ssl_generation
1723
1431
  end
1724
1432
 
1433
+ def test_verify_depth_equals
1434
+ @http.verify_depth = :verify_depth
1435
+
1436
+ assert_equal :verify_depth, @http.verify_depth
1437
+ assert_equal 1, @http.ssl_generation
1438
+ end
1439
+
1725
1440
  def test_verify_mode_equals
1726
1441
  @http.verify_mode = :verify_mode
1727
1442
 
@@ -1729,5 +1444,15 @@ class TestNetHttpPersistent < Minitest::Test
1729
1444
  assert_equal 1, @http.ssl_generation
1730
1445
  end
1731
1446
 
1447
+ def test_connection_pool_after_fork
1448
+ # ConnectionPool 2.4+ calls `checkin(force: true)` after fork
1449
+ @http.pool.checkin(force: true)
1450
+
1451
+ @http.pool.checkout ['example.com', 80, nil, nil, nil, nil]
1452
+ @http.pool.checkin(force: true)
1453
+ @http.pool.reload do |connection|
1454
+ connection.close
1455
+ end
1456
+ end
1732
1457
  end
1733
1458