net-http-persistent 2.9.4 → 4.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,53 @@
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
+
24
+ Thread.current[@key].delete(net_http_args)
25
+ Thread.current[@key] = nil if Thread.current[@key].empty?
26
+ end
27
+
28
+ nil
29
+ end
30
+
31
+ def checkout net_http_args
32
+ stacks = Thread.current[@key] ||= {}
33
+ stack = stacks[net_http_args] ||= []
34
+
35
+ if stack.empty? then
36
+ conn = @available.pop connection_args: net_http_args
37
+ else
38
+ conn = stack.last
39
+ end
40
+
41
+ stack.push conn
42
+
43
+ conn
44
+ end
45
+
46
+ def shutdown
47
+ Thread.current[@key] = nil
48
+ super
49
+ end
50
+ end
51
+
52
+ require_relative 'timed_stack_multi'
53
+
@@ -0,0 +1,79 @@
1
+ class Net::HTTP::Persistent::TimedStackMulti < ConnectionPool::TimedStack # :nodoc:
2
+
3
+ ##
4
+ # Returns a new hash that has arrays for keys
5
+ #
6
+ # Using a class method to limit the bindings referenced by the hash's
7
+ # default_proc
8
+
9
+ def self.hash_of_arrays # :nodoc:
10
+ Hash.new { |h,k| h[k] = [] }
11
+ end
12
+
13
+ def initialize(size = 0, &block)
14
+ super
15
+
16
+ @enqueued = 0
17
+ @ques = self.class.hash_of_arrays
18
+ @lru = {}
19
+ @key = :"connection_args-#{object_id}"
20
+ end
21
+
22
+ def empty?
23
+ (@created - @enqueued) >= @max
24
+ end
25
+
26
+ def length
27
+ @max - @created + @enqueued
28
+ end
29
+
30
+ private
31
+
32
+ def connection_stored? options = {} # :nodoc:
33
+ !@ques[options[:connection_args]].empty?
34
+ end
35
+
36
+ def fetch_connection options = {} # :nodoc:
37
+ connection_args = options[:connection_args]
38
+
39
+ @enqueued -= 1
40
+ lru_update connection_args
41
+ @ques[connection_args].pop
42
+ end
43
+
44
+ def lru_update connection_args # :nodoc:
45
+ @lru.delete connection_args
46
+ @lru[connection_args] = true
47
+ end
48
+
49
+ def shutdown_connections # :nodoc:
50
+ @ques.each_key do |key|
51
+ super connection_args: key
52
+ end
53
+ end
54
+
55
+ def store_connection obj, options = {} # :nodoc:
56
+ @ques[options[:connection_args]].push obj
57
+ @enqueued += 1
58
+ end
59
+
60
+ def try_create options = {} # :nodoc:
61
+ connection_args = options[:connection_args]
62
+
63
+ if @created >= @max && @enqueued >= 1
64
+ oldest, = @lru.first
65
+ @lru.delete oldest
66
+ @ques[oldest].pop
67
+
68
+ @created -= 1
69
+ end
70
+
71
+ if @created < @max
72
+ @created += 1
73
+ lru_update connection_args
74
+ return @create_block.call(connection_args)
75
+ end
76
+ end
77
+
78
+ end
79
+
@@ -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,162 @@ 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
411
365
  skip 'OpenSSL is missing' unless HAVE_OPENSSL
412
366
 
413
367
  uri = URI.parse 'https://example.com/path'
414
- c = @http.connection_for uri
415
368
 
416
- assert c.started?
417
- assert c.use_ssl?
369
+ @http.connection_for uri do |c|
370
+ assert c.http.started?
371
+ assert c.http.use_ssl?
418
372
 
419
- @http.finish c
373
+ @http.finish c
420
374
 
421
- refute c.started?
375
+ refute c.http.started?
376
+ end
422
377
 
423
- c2 = @http.connection_for uri
378
+ @http.connection_for uri do |c2|
379
+ assert c2.http.started?
380
+ end
381
+ end
424
382
 
425
- assert c2.started?
383
+ def test_connection_for_ipv6
384
+ @http.connection_for @uri_v6 do |c|
385
+ assert_equal '2001:db8::1', c.http.address
386
+ end
426
387
  end
427
388
 
428
389
  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
390
+ c = basic_connection
391
+ def (c.http).start; raise Errno::EHOSTDOWN end
392
+ def (c.http).started?; false end
433
393
 
434
394
  e = assert_raises Net::HTTP::Persistent::Error do
435
- @http.connection_for @uri
395
+ @http.connection_for @uri do end
436
396
  end
437
397
 
438
398
  assert_equal 'host down: example.com:80', e.message
@@ -440,8 +400,10 @@ class TestNetHttpPersistent < Minitest::Test
440
400
 
441
401
  def test_connection_for_http_class_with_fakeweb
442
402
  Object.send :const_set, :FakeWeb, nil
443
- c = @http.connection_for @uri
444
- assert_instance_of Net::HTTP, c
403
+
404
+ @http.connection_for @uri do |c|
405
+ assert_instance_of Net::HTTP, c.http
406
+ end
445
407
  ensure
446
408
  if Object.const_defined?(:FakeWeb) then
447
409
  Object.send :remove_const, :FakeWeb
@@ -450,8 +412,9 @@ class TestNetHttpPersistent < Minitest::Test
450
412
 
451
413
  def test_connection_for_http_class_with_webmock
452
414
  Object.send :const_set, :WebMock, nil
453
- c = @http.connection_for @uri
454
- assert_instance_of Net::HTTP, c
415
+ @http.connection_for @uri do |c|
416
+ assert_instance_of Net::HTTP, c.http
417
+ end
455
418
  ensure
456
419
  if Object.const_defined?(:WebMock) then
457
420
  Object.send :remove_const, :WebMock
@@ -460,8 +423,9 @@ class TestNetHttpPersistent < Minitest::Test
460
423
 
461
424
  def test_connection_for_http_class_with_artifice
462
425
  Object.send :const_set, :Artifice, nil
463
- c = @http.connection_for @uri
464
- assert_instance_of Net::HTTP, c
426
+ @http.connection_for @uri do |c|
427
+ assert_instance_of Net::HTTP, c.http
428
+ end
465
429
  ensure
466
430
  if Object.const_defined?(:Artifice) then
467
431
  Object.send :remove_const, :Artifice
@@ -469,23 +433,12 @@ class TestNetHttpPersistent < Minitest::Test
469
433
  end
470
434
 
471
435
  def test_connection_for_name
472
- http = Net::HTTP::Persistent.new 'name'
436
+ http = Net::HTTP::Persistent.new name: 'name'
473
437
  uri = URI.parse 'http://example/'
474
438
 
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
439
+ http.connection_for uri do |c|
440
+ assert c.http.started?
441
+ end
489
442
  end
490
443
 
491
444
  def test_connection_for_proxy
@@ -493,16 +446,20 @@ class TestNetHttpPersistent < Minitest::Test
493
446
  uri.user = 'johndoe'
494
447
  uri.password = 'muffins'
495
448
 
496
- http = Net::HTTP::Persistent.new nil, uri
449
+ http = Net::HTTP::Persistent.new proxy: uri
497
450
 
498
- c = http.connection_for @uri
451
+ used = http.connection_for @uri do |c|
452
+ assert c.http.started?
453
+ assert c.http.proxy?
499
454
 
500
- assert c.started?
501
- assert c.proxy?
455
+ c
456
+ end
502
457
 
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']
458
+ stored = http.pool.checkout ['example.com', 80,
459
+ 'proxy.example', 80,
460
+ 'johndoe', 'muffins']
461
+
462
+ assert_same used, stored
506
463
  end
507
464
 
508
465
  def test_connection_for_proxy_unescaped
@@ -511,25 +468,28 @@ class TestNetHttpPersistent < Minitest::Test
511
468
  uri.password = 'muf%3Afins'
512
469
  uri.freeze
513
470
 
514
- http = Net::HTTP::Persistent.new nil, uri
515
- c = http.connection_for @uri
471
+ http = Net::HTTP::Persistent.new proxy: uri
472
+
473
+ http.connection_for @uri do end
474
+
475
+ stored = http.pool.checkout ['example.com', 80,
476
+ 'proxy.example', 80,
477
+ 'john@doe', 'muf:fins']
516
478
 
517
- assert_includes conns[1].keys,
518
- 'example.com:80:proxy.example:80:john@doe:muf:fins'
479
+ assert stored
519
480
  end
520
481
 
521
482
  def test_connection_for_proxy_host_down
522
483
  Net::HTTP.use_connect :host_down_connect
523
- Net::HTTP::Persistent::SSLReuse.use_connect :host_down_connect
524
484
 
525
485
  uri = URI.parse 'http://proxy.example'
526
486
  uri.user = 'johndoe'
527
487
  uri.password = 'muffins'
528
488
 
529
- http = Net::HTTP::Persistent.new nil, uri
489
+ http = Net::HTTP::Persistent.new proxy: uri
530
490
 
531
491
  e = assert_raises Net::HTTP::Persistent::Error do
532
- http.connection_for @uri
492
+ http.connection_for @uri do end
533
493
  end
534
494
 
535
495
  assert_equal 'host down: proxy.example:80', e.message
@@ -537,16 +497,15 @@ class TestNetHttpPersistent < Minitest::Test
537
497
 
538
498
  def test_connection_for_proxy_refused
539
499
  Net::HTTP.use_connect :refused_connect
540
- Net::HTTP::Persistent::SSLReuse.use_connect :refused_connect
541
500
 
542
501
  uri = URI.parse 'http://proxy.example'
543
502
  uri.user = 'johndoe'
544
503
  uri.password = 'muffins'
545
504
 
546
- http = Net::HTTP::Persistent.new nil, uri
505
+ http = Net::HTTP::Persistent.new proxy: uri
547
506
 
548
507
  e = assert_raises Net::HTTP::Persistent::Error do
549
- http.connection_for @uri
508
+ http.connection_for @uri do end
550
509
  end
551
510
 
552
511
  assert_equal 'connection refused: proxy.example:80', e.message
@@ -558,38 +517,52 @@ class TestNetHttpPersistent < Minitest::Test
558
517
  uri.password = 'muffins'
559
518
  uri.query = 'no_proxy=example.com'
560
519
 
561
- http = Net::HTTP::Persistent.new nil, uri
520
+ http = Net::HTTP::Persistent.new proxy: uri
562
521
 
563
- c = http.connection_for @uri
522
+ http.connection_for @uri do |c|
523
+ assert c.http.started?
524
+ refute c.http.proxy?
525
+ end
564
526
 
565
- assert c.started?
566
- refute c.proxy?
527
+ stored = http.pool.checkout ['example.com', 80]
567
528
 
568
- assert_includes conns[1].keys, 'example.com:80'
569
- assert_same c, conns[1]['example.com:80']
529
+ assert stored
530
+ end
531
+
532
+ def test_connection_for_no_proxy_from_env
533
+ ENV['http_proxy'] = 'proxy.example'
534
+ ENV['no_proxy'] = 'localhost, example.com,'
535
+ ENV['proxy_user'] = 'johndoe'
536
+ ENV['proxy_password'] = 'muffins'
537
+
538
+ http = Net::HTTP::Persistent.new proxy: :ENV
539
+
540
+ http.connection_for @uri do |c|
541
+ assert c.http.started?
542
+ refute c.http.proxy?
543
+ refute c.http.proxy_from_env?
544
+ end
570
545
  end
571
546
 
572
547
  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
548
+ Net::HTTP.use_connect :refused_connect
577
549
 
578
550
  e = assert_raises Net::HTTP::Persistent::Error do
579
- @http.connection_for @uri
551
+ @http.connection_for @uri do end
580
552
  end
581
553
 
582
- assert_match %r%connection refused%, e.message
554
+ assert_equal 'connection refused: example.com:80', e.message
583
555
  end
584
556
 
585
557
  def test_connection_for_ssl
586
558
  skip 'OpenSSL is missing' unless HAVE_OPENSSL
587
559
 
588
560
  uri = URI.parse 'https://example.com/path'
589
- c = @http.connection_for uri
590
561
 
591
- assert c.started?
592
- assert c.use_ssl?
562
+ @http.connection_for uri do |c|
563
+ assert c.http.started?
564
+ assert c.http.use_ssl?
565
+ end
593
566
  end
594
567
 
595
568
  def test_connection_for_ssl_cached
@@ -597,11 +570,11 @@ class TestNetHttpPersistent < Minitest::Test
597
570
 
598
571
  @uri = URI.parse 'https://example.com/path'
599
572
 
600
- cached = ssl_connection 0
601
-
602
- c = @http.connection_for @uri
573
+ cached = ssl_connection
603
574
 
604
- assert_same cached, c
575
+ @http.connection_for @uri do |c|
576
+ assert_same cached, c
577
+ end
605
578
  end
606
579
 
607
580
  def test_connection_for_ssl_cached_reconnect
@@ -611,46 +584,38 @@ class TestNetHttpPersistent < Minitest::Test
611
584
 
612
585
  cached = ssl_connection
613
586
 
614
- @http.reconnect_ssl
587
+ ssl_generation = @http.ssl_generation
615
588
 
616
- c = @http.connection_for @uri
589
+ @http.reconnect_ssl
617
590
 
618
- refute_same cached, c
591
+ @http.connection_for @uri do |c|
592
+ assert_same cached, c
593
+ refute_equal ssl_generation, c.ssl_generation
594
+ end
619
595
  end
620
596
 
621
597
  def test_connection_for_ssl_case
622
598
  skip 'OpenSSL is missing' unless HAVE_OPENSSL
623
599
 
624
600
  uri = URI.parse 'HTTPS://example.com/path'
625
- c = @http.connection_for uri
626
-
627
- assert c.started?
628
- assert c.use_ssl?
601
+ @http.connection_for uri do |c|
602
+ assert c.http.started?
603
+ assert c.http.use_ssl?
604
+ end
629
605
  end
630
606
 
631
607
  def test_connection_for_timeout
632
608
  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
609
+ cached.http.start
610
+ cached.requests = 10
611
+ cached.last_use = Time.now - 6
637
612
 
638
- c = @http.connection_for @uri
639
-
640
- assert c.started?
641
- assert_equal 0, reqs[c.object_id]
642
-
643
- assert_same cached, c
644
- end
613
+ @http.connection_for @uri do |c|
614
+ assert c.http.started?
615
+ assert_equal 0, c.requests
645
616
 
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
617
+ assert_same cached, c
618
+ end
654
619
  end
655
620
 
656
621
  def test_escape
@@ -667,8 +632,8 @@ class TestNetHttpPersistent < Minitest::Test
667
632
 
668
633
  def test_expired_eh
669
634
  c = basic_connection
670
- reqs[c.object_id] = 0
671
- touts[c.object_id] = Time.now - 11
635
+ c.requests = 0
636
+ c.last_use = Time.now - 11
672
637
 
673
638
  @http.idle_timeout = 0
674
639
  assert @http.expired? c
@@ -688,41 +653,59 @@ class TestNetHttpPersistent < Minitest::Test
688
653
 
689
654
  def test_expired_due_to_max_requests
690
655
  c = basic_connection
691
- reqs[c.object_id] = 0
692
- touts[c.object_id] = Time.now
656
+ c.requests = 0
657
+ c.last_use = Time.now
693
658
 
694
659
  refute @http.expired? c
695
660
 
696
- reqs[c.object_id] = 10
661
+ c.requests = 10
697
662
  refute @http.expired? c
698
663
 
699
664
  @http.max_requests = 10
700
665
  assert @http.expired? c
701
666
 
702
- reqs[c.object_id] = 9
667
+ c.requests = 9
703
668
  refute @http.expired? c
704
669
  end
705
670
 
706
671
  def test_finish
707
672
  c = basic_connection
708
- reqs[c.object_id] = 5
673
+ c.requests = 5
674
+ c.http.instance_variable_set(:@last_communicated, Process.clock_gettime(Process::CLOCK_MONOTONIC))
709
675
 
710
676
  @http.finish c
711
677
 
712
- refute c.started?
713
- assert c.finished?
714
- assert_equal 0, reqs[c.object_id]
678
+ refute c.http.started?
679
+ assert c.http.finished?
680
+
681
+ assert_equal 0, c.requests
682
+ assert_equal Net::HTTP::Persistent::EPOCH, c.last_use
683
+ assert_nil c.http.instance_variable_get(:@last_communicated)
715
684
  end
716
685
 
717
686
  def test_finish_io_error
718
687
  c = basic_connection
719
- def c.finish; @finished += 1; raise IOError end
720
- reqs[c.object_id] = 5
688
+ def (c.http).finish; @finished += 1; raise IOError end
689
+ c.requests = 5
690
+
691
+ @http.finish c
692
+
693
+ refute c.http.started?
694
+ assert c.http.finished?
695
+ end
696
+
697
+ def test_finish_ssl_no_session_reuse
698
+ http = Net::HTTP.new 'localhost', 443, ssl: true
699
+ http.instance_variable_set :@ssl_session, :something
700
+
701
+ c = Net::HTTP::Persistent::Connection.allocate
702
+ c.instance_variable_set :@http, http
703
+
704
+ @http.reuse_ssl_sessions = false
721
705
 
722
706
  @http.finish c
723
707
 
724
- refute c.started?
725
- assert c.finished?
708
+ assert_nil c.http.instance_variable_get :@ssl_session
726
709
  end
727
710
 
728
711
  def test_http_version
@@ -735,23 +718,21 @@ class TestNetHttpPersistent < Minitest::Test
735
718
  assert_equal '1.1', @http.http_version(@uri)
736
719
  end
737
720
 
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 '/'
721
+ def test_http_version_IPv6
722
+ assert_nil @http.http_version @uri_v6
745
723
 
746
- refute @http.idempotent? Net::HTTP::Post.new '/'
747
- end
724
+ connection @uri_v6
748
725
 
749
- def test_max_age
750
- assert_in_delta Time.now - 5, @http.max_age
726
+ @http.request @uri_v6
751
727
 
752
- @http.idle_timeout = nil
728
+ assert_equal '1.1', @http.http_version(@uri_v6)
729
+ end
730
+
731
+ def test_max_retries_equals
732
+ @http.max_retries = 5
753
733
 
754
- assert_in_delta Time.now + 1, @http.max_age
734
+ assert_equal 5, @http.max_retries
735
+ assert_equal 1, @http.generation
755
736
  end
756
737
 
757
738
  def test_normalize_uri
@@ -774,8 +755,7 @@ class TestNetHttpPersistent < Minitest::Test
774
755
  skip 'net-http-pipeline not installed' unless defined?(Net::HTTP::Pipeline)
775
756
 
776
757
  cached = basic_connection
777
- cached.start
778
- conns['example.com:80'] = cached
758
+ cached.http.start
779
759
 
780
760
  requests = [
781
761
  Net::HTTP::Get.new((@uri + '1').request_uri),
@@ -810,7 +790,7 @@ class TestNetHttpPersistent < Minitest::Test
810
790
  def test_proxy_equals_nil
811
791
  @http.proxy = nil
812
792
 
813
- assert_equal nil, @http.proxy_uri
793
+ assert_nil @http.proxy_uri
814
794
 
815
795
  assert_equal 1, @http.generation, 'generation'
816
796
  assert_equal 1, @http.ssl_generation, 'ssl_generation'
@@ -824,6 +804,14 @@ class TestNetHttpPersistent < Minitest::Test
824
804
  assert_equal proxy_uri, @http.proxy_uri
825
805
  end
826
806
 
807
+ def test_proxy_equals_uri_IPv6
808
+ proxy_uri = @uri_v6
809
+
810
+ @http.proxy = proxy_uri
811
+
812
+ assert_equal proxy_uri, @http.proxy_uri
813
+ end
814
+
827
815
  def test_proxy_from_env
828
816
  ENV['http_proxy'] = 'proxy.example'
829
817
  ENV['http_proxy_user'] = 'johndoe'
@@ -935,18 +923,47 @@ class TestNetHttpPersistent < Minitest::Test
935
923
  end
936
924
 
937
925
  def test_reconnect_ssl
938
- result = @http.reconnect_ssl
926
+ skip 'OpenSSL is missing' unless HAVE_OPENSSL
939
927
 
940
- assert_equal 1, result
928
+ @uri = URI 'https://example.com'
929
+ now = Time.now
930
+
931
+ ssl_http = ssl_connection
932
+
933
+ def (ssl_http.http).finish
934
+ @started = 0
935
+ end
936
+
937
+ used1 = @http.connection_for @uri do |c|
938
+ c.requests = 1
939
+ c.last_use = now
940
+ c
941
+ end
942
+
943
+ assert_equal OpenSSL::SSL::VERIFY_PEER, used1.http.verify_mode
944
+
945
+ @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
946
+ @http.reconnect_ssl
947
+
948
+ used2 = @http.connection_for @uri do |c|
949
+ c
950
+ end
951
+
952
+ assert_same used1, used2
953
+
954
+ assert_equal OpenSSL::SSL::VERIFY_NONE, used2.http.verify_mode,
955
+ 'verify mode must change'
956
+ assert_equal 0, used2.requests
957
+ assert_equal Net::HTTP::Persistent::EPOCH, used2.last_use
941
958
  end
942
959
 
943
- def test_request
960
+ def test_requestx
944
961
  @http.override_headers['user-agent'] = 'test ua'
945
962
  @http.headers['accept'] = 'text/*'
946
963
  c = connection
947
964
 
948
965
  res = @http.request @uri
949
- req = c.req
966
+ req = c.http.req
950
967
 
951
968
  assert_kind_of Net::HTTPResponse, res
952
969
 
@@ -959,86 +976,9 @@ class TestNetHttpPersistent < Minitest::Test
959
976
  assert_equal 'keep-alive', req['connection']
960
977
  assert_equal '30', req['keep-alive']
961
978
 
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?
1009
- 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
979
+ assert_in_delta Time.now, c.last_use
1020
980
 
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
981
+ assert_equal 1, c.requests
1042
982
  end
1043
983
 
1044
984
  def test_request_block
@@ -1050,7 +990,7 @@ class TestNetHttpPersistent < Minitest::Test
1050
990
  body = r.read_body
1051
991
  end
1052
992
 
1053
- req = c.req
993
+ req = c.http.req
1054
994
 
1055
995
  assert_kind_of Net::HTTPResponse, res
1056
996
  refute_nil body
@@ -1061,17 +1001,17 @@ class TestNetHttpPersistent < Minitest::Test
1061
1001
  assert_equal '30', req['keep-alive']
1062
1002
  assert_match %r%test ua%, req['user-agent']
1063
1003
 
1064
- assert_equal 1, reqs[c.object_id]
1004
+ assert_equal 1, c.requests
1065
1005
  end
1066
1006
 
1067
1007
  def test_request_close_1_0
1068
1008
  c = connection
1069
1009
 
1070
- class << c
1010
+ class << c.http
1071
1011
  remove_method :request
1072
1012
  end
1073
1013
 
1074
- def c.request req
1014
+ def (c.http).request req
1075
1015
  @req = req
1076
1016
  r = Net::HTTPResponse.allocate
1077
1017
  r.instance_variable_set :@header, {}
@@ -1084,7 +1024,7 @@ class TestNetHttpPersistent < Minitest::Test
1084
1024
  request = Net::HTTP::Get.new @uri.request_uri
1085
1025
 
1086
1026
  res = @http.request @uri, request
1087
- req = c.req
1027
+ req = c.http.req
1088
1028
 
1089
1029
  assert_kind_of Net::HTTPResponse, res
1090
1030
 
@@ -1093,7 +1033,7 @@ class TestNetHttpPersistent < Minitest::Test
1093
1033
  assert_equal 'keep-alive', req['connection']
1094
1034
  assert_equal '30', req['keep-alive']
1095
1035
 
1096
- assert c.finished?
1036
+ assert c.http.finished?
1097
1037
  end
1098
1038
 
1099
1039
  def test_request_connection_close_request
@@ -1103,26 +1043,26 @@ class TestNetHttpPersistent < Minitest::Test
1103
1043
  request['connection'] = 'close'
1104
1044
 
1105
1045
  res = @http.request @uri, request
1106
- req = c.req
1046
+ req = c.http.req
1107
1047
 
1108
1048
  assert_kind_of Net::HTTPResponse, res
1109
1049
 
1110
1050
  assert_kind_of Net::HTTP::Get, req
1111
1051
  assert_equal '/path', req.path
1112
1052
  assert_equal 'close', req['connection']
1113
- assert_equal nil, req['keep-alive']
1053
+ assert_nil req['keep-alive']
1114
1054
 
1115
- assert c.finished?
1055
+ assert c.http.finished?
1116
1056
  end
1117
1057
 
1118
1058
  def test_request_connection_close_response
1119
1059
  c = connection
1120
1060
 
1121
- class << c
1061
+ class << c.http
1122
1062
  remove_method :request
1123
1063
  end
1124
1064
 
1125
- def c.request req
1065
+ def (c.http).request req
1126
1066
  @req = req
1127
1067
  r = Net::HTTPResponse.allocate
1128
1068
  r.instance_variable_set :@header, {}
@@ -1136,7 +1076,7 @@ class TestNetHttpPersistent < Minitest::Test
1136
1076
  request = Net::HTTP::Get.new @uri.request_uri
1137
1077
 
1138
1078
  res = @http.request @uri, request
1139
- req = c.req
1079
+ req = c.http.req
1140
1080
 
1141
1081
  assert_kind_of Net::HTTPResponse, res
1142
1082
 
@@ -1145,53 +1085,33 @@ class TestNetHttpPersistent < Minitest::Test
1145
1085
  assert_equal 'keep-alive', req['connection']
1146
1086
  assert_equal '30', req['keep-alive']
1147
1087
 
1148
- assert c.finished?
1088
+ assert c.http.finished?
1149
1089
  end
1150
1090
 
1151
1091
  def test_request_exception
1152
1092
  c = basic_connection
1153
- def c.request(*a) raise Exception, "very bad things happened" end
1093
+ def (c.http).request(*a)
1094
+ raise Exception, "very bad things happened"
1095
+ end
1154
1096
 
1155
1097
  assert_raises Exception do
1156
1098
  @http.request @uri
1157
1099
  end
1158
1100
 
1159
- assert_equal 0, reqs[c.object_id]
1160
- assert c.finished?
1101
+ assert_equal 0, c.requests
1102
+ assert c.http.finished?
1161
1103
  end
1162
1104
 
1163
1105
  def test_request_invalid
1164
1106
  c = basic_connection
1165
- def c.request(*a) raise Errno::EINVAL, "write" end
1107
+ def (c.http).request(*a) raise Errno::EINVAL, "write" end
1166
1108
 
1167
- e = assert_raises Net::HTTP::Persistent::Error do
1109
+ e = assert_raises Errno::EINVAL do
1168
1110
  @http.request @uri
1169
1111
  end
1170
1112
 
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?
1113
+ assert_equal 0, c.requests
1114
+ assert_match %r%Invalid argument - write%, e.message
1195
1115
  end
1196
1116
 
1197
1117
  def test_request_post
@@ -1200,96 +1120,11 @@ class TestNetHttpPersistent < Minitest::Test
1200
1120
  post = Net::HTTP::Post.new @uri.path
1201
1121
 
1202
1122
  @http.request @uri, post
1203
- req = c.req
1123
+ req = c.http.req
1204
1124
 
1205
1125
  assert_same post, req
1206
1126
  end
1207
1127
 
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
1128
  def test_request_setup
1294
1129
  @http.override_headers['user-agent'] = 'test ua'
1295
1130
  @http.headers['accept'] = 'text/*'
@@ -1308,59 +1143,51 @@ class TestNetHttpPersistent < Minitest::Test
1308
1143
  assert_equal '30', req['keep-alive']
1309
1144
  end
1310
1145
 
1311
- def test_request_setup_uri
1312
- uri = @uri + '?a=b'
1313
-
1314
- req = @http.request_setup uri
1146
+ def test_request_string
1147
+ @http.override_headers['user-agent'] = 'test ua'
1148
+ @http.headers['accept'] = 'text/*'
1149
+ c = connection
1315
1150
 
1316
- assert_kind_of Net::HTTP::Get, req
1317
- assert_equal '/path?a=b', req.path
1318
- end
1151
+ res = @http.request @uri.to_s
1152
+ req = c.http.req
1319
1153
 
1320
- def test_request_failed
1321
- c = basic_connection
1322
- reqs[c.object_id] = 1
1323
- touts[c.object_id] = Time.now
1154
+ assert_kind_of Net::HTTPResponse, res
1324
1155
 
1325
- original = nil
1156
+ assert_kind_of Net::HTTP::Get, req
1157
+ assert_equal '/path', req.path
1326
1158
 
1327
- begin
1328
- raise 'original'
1329
- rescue => original
1330
- end
1159
+ assert_equal 1, c.requests
1160
+ end
1331
1161
 
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
1162
+ def test_request_setup_uri
1163
+ uri = @uri + '?a=b'
1337
1164
 
1338
- assert_match "too many connection resets (due to original - RuntimeError)",
1339
- e.message
1165
+ req = @http.request_setup uri
1340
1166
 
1341
- assert_equal original.backtrace, e.backtrace
1167
+ assert_kind_of Net::HTTP::Get, req
1168
+ assert_equal '/path?a=b', req.path
1342
1169
  end
1343
1170
 
1344
1171
  def test_reset
1345
1172
  c = basic_connection
1346
- c.start
1347
- touts[c.object_id] = Time.now
1348
- reqs[c.object_id] = 5
1173
+ c.http.start
1174
+ c.last_use = Time.now
1175
+ c.requests = 5
1349
1176
 
1350
1177
  @http.reset c
1351
1178
 
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]
1179
+ assert c.http.started?
1180
+ assert c.http.finished?
1181
+ assert c.http.reset?
1182
+ assert_equal 0, c.requests
1183
+ assert_equal Net::HTTP::Persistent::EPOCH, c.last_use
1357
1184
  end
1358
1185
 
1359
1186
  def test_reset_host_down
1360
1187
  c = basic_connection
1361
- touts[c.object_id] = Time.now
1362
- def c.start; raise Errno::EHOSTDOWN end
1363
- reqs[c.object_id] = 5
1188
+ c.last_use = Time.now
1189
+ def (c.http).start; raise Errno::EHOSTDOWN end
1190
+ c.requests = 5
1364
1191
 
1365
1192
  e = assert_raises Net::HTTP::Persistent::Error do
1366
1193
  @http.reset c
@@ -1372,20 +1199,20 @@ class TestNetHttpPersistent < Minitest::Test
1372
1199
 
1373
1200
  def test_reset_io_error
1374
1201
  c = basic_connection
1375
- touts[c.object_id] = Time.now
1376
- reqs[c.object_id] = 5
1202
+ c.last_use = Time.now
1203
+ c.requests = 5
1377
1204
 
1378
1205
  @http.reset c
1379
1206
 
1380
- assert c.started?
1381
- assert c.finished?
1207
+ assert c.http.started?
1208
+ assert c.http.finished?
1382
1209
  end
1383
1210
 
1384
1211
  def test_reset_refused
1385
1212
  c = basic_connection
1386
- touts[c.object_id] = Time.now
1387
- def c.start; raise Errno::ECONNREFUSED end
1388
- reqs[c.object_id] = 5
1213
+ c.last_use = Time.now
1214
+ def (c.http).start; raise Errno::ECONNREFUSED end
1215
+ c.requests = 5
1389
1216
 
1390
1217
  e = assert_raises Net::HTTP::Persistent::Error do
1391
1218
  @http.reset c
@@ -1395,167 +1222,39 @@ class TestNetHttpPersistent < Minitest::Test
1395
1222
  assert_match __FILE__, e.backtrace.first
1396
1223
  end
1397
1224
 
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
1225
  def test_shutdown
1427
- ssl_conns
1428
1226
  c = connection
1429
- rs = reqs
1430
- ts = touts
1431
1227
 
1432
1228
  orig = @http
1433
- @http = Net::HTTP::Persistent.new 'name'
1229
+ @http = Net::HTTP::Persistent.new name: 'name'
1434
1230
  c2 = connection
1435
1231
 
1436
1232
  orig.shutdown
1437
1233
 
1438
1234
  @http = orig
1439
1235
 
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]
1236
+ assert c.http.finished?, 'last-generation connection must be finished'
1237
+ refute c2.http.finished?, 'present generation connection must not be finished'
1513
1238
  end
1514
1239
 
1515
- def test_shutdown_ssl
1240
+ def test_ssl
1516
1241
  skip 'OpenSSL is missing' unless HAVE_OPENSSL
1517
1242
 
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
1243
+ @http.verify_callback = :callback
1244
+ c = Net::HTTP.new 'localhost', 80
1545
1245
 
1546
- refute c.finished?
1246
+ @http.ssl c
1547
1247
 
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]
1248
+ assert c.use_ssl?
1249
+ assert_equal OpenSSL::SSL::VERIFY_PEER, c.verify_mode
1250
+ assert_kind_of OpenSSL::X509::Store, c.cert_store
1251
+ assert_nil c.verify_callback
1554
1252
  end
1555
1253
 
1556
- def test_ssl
1254
+ def test_ssl_ca_file
1557
1255
  skip 'OpenSSL is missing' unless HAVE_OPENSSL
1558
1256
 
1257
+ @http.ca_file = 'ca_file'
1559
1258
  @http.verify_callback = :callback
1560
1259
  c = Net::HTTP.new 'localhost', 80
1561
1260
 
@@ -1563,14 +1262,13 @@ class TestNetHttpPersistent < Minitest::Test
1563
1262
 
1564
1263
  assert c.use_ssl?
1565
1264
  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
1265
+ assert_equal :callback, c.verify_callback
1568
1266
  end
1569
1267
 
1570
- def test_ssl_ca_file
1268
+ def test_ssl_ca_path
1571
1269
  skip 'OpenSSL is missing' unless HAVE_OPENSSL
1572
1270
 
1573
- @http.ca_file = 'ca_file'
1271
+ @http.ca_path = 'ca_path'
1574
1272
  @http.verify_callback = :callback
1575
1273
  c = Net::HTTP.new 'localhost', 80
1576
1274
 
@@ -1667,34 +1365,37 @@ class TestNetHttpPersistent < Minitest::Test
1667
1365
  end
1668
1366
  end
1669
1367
 
1670
- def test_ssl_cleanup
1671
- skip 'OpenSSL is missing' unless HAVE_OPENSSL
1672
-
1673
- uri1 = URI.parse 'https://one.example'
1368
+ def test_ssl_timeout_equals
1369
+ @http.ssl_timeout = :ssl_timeout
1674
1370
 
1675
- c1 = @http.connection_for uri1
1371
+ assert_equal :ssl_timeout, @http.ssl_timeout
1372
+ assert_equal 1, @http.ssl_generation
1373
+ end
1676
1374
 
1677
- touts[c1.object_id] = Time.now
1678
- reqs[c1.object_id] = 5
1375
+ def test_ssl_version_equals
1376
+ @http.ssl_version = :ssl_version
1679
1377
 
1680
- @http.reconnect_ssl
1378
+ assert_equal :ssl_version, @http.ssl_version
1379
+ assert_equal 1, @http.ssl_generation
1380
+ end
1681
1381
 
1682
- @http.ssl_cleanup @http.ssl_generation
1382
+ def test_min_version_equals
1383
+ @http.min_version = :min_version
1683
1384
 
1684
- assert_empty ssl_conns
1685
- assert_empty touts
1686
- assert_empty reqs # sanity check, performed by #finish
1385
+ assert_equal :min_version, @http.min_version
1386
+ assert_equal 1, @http.ssl_generation
1687
1387
  end
1688
1388
 
1689
- def test_ssl_version_equals
1690
- @http.ssl_version = :ssl_version
1389
+ def test_max_version_equals
1390
+ @http.max_version = :max_version
1691
1391
 
1692
- assert_equal :ssl_version, @http.ssl_version
1392
+ assert_equal :max_version, @http.max_version
1693
1393
  assert_equal 1, @http.ssl_generation
1694
- end unless RUBY_1
1394
+ end
1695
1395
 
1696
1396
  def test_start
1697
1397
  c = basic_connection
1398
+ c = c.http
1698
1399
 
1699
1400
  @http.socket_options << [Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1]
1700
1401
  @http.debug_output = $stderr
@@ -1722,6 +1423,13 @@ class TestNetHttpPersistent < Minitest::Test
1722
1423
  assert_equal 1, @http.ssl_generation
1723
1424
  end
1724
1425
 
1426
+ def test_verify_depth_equals
1427
+ @http.verify_depth = :verify_depth
1428
+
1429
+ assert_equal :verify_depth, @http.verify_depth
1430
+ assert_equal 1, @http.ssl_generation
1431
+ end
1432
+
1725
1433
  def test_verify_mode_equals
1726
1434
  @http.verify_mode = :verify_mode
1727
1435