net-http-persistent 2.4 → 2.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/History.txt +10 -0
- data/lib/net/http/persistent.rb +133 -23
- data/test/test_net_http_persistent.rb +261 -108
- data/test/test_net_http_persistent_ssl_reuse.rb +1 -0
- metadata +4 -3
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/History.txt
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
=== 2.4.1 / 2012-02-03
|
2
|
+
|
3
|
+
* Bug fix
|
4
|
+
* When FakeWeb or WebMock are loaded SSL sessions will not be reused to
|
5
|
+
prevent breakage of testing frameworks. Issue #13 by Matt Brictson, pull
|
6
|
+
request #14 by Zachary Scott
|
7
|
+
* SSL connections are reset when the SSL parameters change.
|
8
|
+
Mechanize issue #194 by dsisnero
|
9
|
+
* Last-use times are now cleaned up in #shutdown.
|
10
|
+
|
1
11
|
=== 2.4 / 2012-01-31
|
2
12
|
|
3
13
|
* Minor Enhancement
|
data/lib/net/http/persistent.rb
CHANGED
@@ -149,7 +149,7 @@ class Net::HTTP::Persistent
|
|
149
149
|
##
|
150
150
|
# The version of Net::HTTP::Persistent you are using
|
151
151
|
|
152
|
-
VERSION = '2.4'
|
152
|
+
VERSION = '2.4.1'
|
153
153
|
|
154
154
|
##
|
155
155
|
# Error class for errors raised by Net::HTTP::Persistent. Various
|
@@ -161,19 +161,19 @@ class Net::HTTP::Persistent
|
|
161
161
|
##
|
162
162
|
# This client's OpenSSL::X509::Certificate
|
163
163
|
|
164
|
-
|
164
|
+
attr_reader :certificate
|
165
165
|
|
166
166
|
##
|
167
167
|
# An SSL certificate authority. Setting this will set verify_mode to
|
168
168
|
# VERIFY_PEER.
|
169
169
|
|
170
|
-
|
170
|
+
attr_reader :ca_file
|
171
171
|
|
172
172
|
##
|
173
|
-
# An SSL certificate store.
|
174
|
-
# certificate store.
|
173
|
+
# An SSL certificate store. Setting this will override the default
|
174
|
+
# certificate store. See verify_mode for more information.
|
175
175
|
|
176
|
-
|
176
|
+
attr_reader :cert_store
|
177
177
|
|
178
178
|
##
|
179
179
|
# Where this instance's connections live in the thread local variables
|
@@ -230,7 +230,7 @@ class Net::HTTP::Persistent
|
|
230
230
|
##
|
231
231
|
# This client's SSL private key
|
232
232
|
|
233
|
-
|
233
|
+
attr_reader :private_key
|
234
234
|
|
235
235
|
##
|
236
236
|
# The URL through which requests will be proxied
|
@@ -267,6 +267,11 @@ class Net::HTTP::Persistent
|
|
267
267
|
|
268
268
|
attr_reader :socket_options
|
269
269
|
|
270
|
+
##
|
271
|
+
# Where this instance's SSL connections live in the thread local variables
|
272
|
+
|
273
|
+
attr_reader :ssl_generation_key # :nodoc:
|
274
|
+
|
270
275
|
##
|
271
276
|
# Where this instance's last-use times live in the thread local variables
|
272
277
|
|
@@ -275,21 +280,18 @@ class Net::HTTP::Persistent
|
|
275
280
|
##
|
276
281
|
# SSL verification callback. Used when ca_file is set.
|
277
282
|
|
278
|
-
|
283
|
+
attr_reader :verify_callback
|
279
284
|
|
280
285
|
##
|
281
286
|
# HTTPS verify mode. Defaults to OpenSSL::SSL::VERIFY_PEER which verifies
|
282
287
|
# the server certificate.
|
283
288
|
#
|
284
|
-
# If no
|
285
|
-
#
|
286
|
-
#
|
287
|
-
# To disable server certificate validation set to OpenSSL::SSL::VERIFY_NONE,
|
288
|
-
# but this is a bad idea as it disables SSL protections.
|
289
|
+
# If no ca_file or cert_store is set the default system certificate store is
|
290
|
+
# used.
|
289
291
|
#
|
290
292
|
# You can use +verify_mode+ to override any default values.
|
291
293
|
|
292
|
-
|
294
|
+
attr_reader :verify_mode
|
293
295
|
|
294
296
|
##
|
295
297
|
# Enable retries of non-idempotent requests that change data (e.g. POST
|
@@ -302,6 +304,8 @@ class Net::HTTP::Persistent
|
|
302
304
|
|
303
305
|
attr_accessor :retry_change_requests
|
304
306
|
|
307
|
+
attr_reader :ssl_generation # :nodoc:
|
308
|
+
|
305
309
|
##
|
306
310
|
# Creates a new Net::HTTP::Persistent.
|
307
311
|
#
|
@@ -353,9 +357,10 @@ class Net::HTTP::Persistent
|
|
353
357
|
Socket.const_defined? :TCP_NODELAY
|
354
358
|
|
355
359
|
key = ['net_http_persistent', name].compact
|
356
|
-
@connection_key
|
357
|
-
@
|
358
|
-
@
|
360
|
+
@connection_key = [key, 'connections' ].join('_').intern
|
361
|
+
@ssl_generation_key = [key, 'ssl_generations'].join('_').intern
|
362
|
+
@request_key = [key, 'requests' ].join('_').intern
|
363
|
+
@timeout_key = [key, 'timeouts' ].join('_').intern
|
359
364
|
|
360
365
|
@certificate = nil
|
361
366
|
@ca_file = nil
|
@@ -363,20 +368,61 @@ class Net::HTTP::Persistent
|
|
363
368
|
@verify_callback = nil
|
364
369
|
@verify_mode = OpenSSL::SSL::VERIFY_PEER
|
365
370
|
@cert_store = nil
|
371
|
+
|
372
|
+
@ssl_generation = 0 # incremented when SSL session variables change
|
366
373
|
@reuse_ssl_sessions = true
|
367
374
|
|
368
375
|
@retry_change_requests = false
|
369
376
|
end
|
370
377
|
|
378
|
+
##
|
379
|
+
# Sets this client's OpenSSL::X509::Certificate
|
380
|
+
|
381
|
+
def certificate= certificate
|
382
|
+
@certificate = certificate
|
383
|
+
|
384
|
+
reconnect_ssl
|
385
|
+
end
|
386
|
+
|
387
|
+
##
|
388
|
+
# Sets the SSL certificate authority file.
|
389
|
+
|
390
|
+
def ca_file= file
|
391
|
+
@ca_file = file
|
392
|
+
|
393
|
+
reconnect_ssl
|
394
|
+
end
|
395
|
+
|
396
|
+
##
|
397
|
+
# Overrides the default SSL certificate store used for verifying
|
398
|
+
# connections.
|
399
|
+
|
400
|
+
def cert_store= store
|
401
|
+
@cert_store = store
|
402
|
+
|
403
|
+
reconnect_ssl
|
404
|
+
end
|
405
|
+
|
371
406
|
##
|
372
407
|
# Creates a new connection for +uri+
|
373
408
|
|
374
409
|
def connection_for uri
|
375
|
-
Thread.current[@
|
376
|
-
Thread.current[@
|
377
|
-
Thread.current[@
|
410
|
+
Thread.current[@ssl_generation_key] ||= Hash.new { |h,k| h[k] = {} }
|
411
|
+
Thread.current[@connection_key] ||= {}
|
412
|
+
Thread.current[@request_key] ||= Hash.new 0
|
413
|
+
Thread.current[@timeout_key] ||= Hash.new EPOCH
|
414
|
+
|
415
|
+
use_ssl = uri.scheme.downcase == 'https'
|
378
416
|
|
379
|
-
|
417
|
+
if use_ssl then
|
418
|
+
ssl_generation = @ssl_generation
|
419
|
+
|
420
|
+
ssl_cleanup ssl_generation
|
421
|
+
|
422
|
+
connections = Thread.current[@ssl_generation_key][ssl_generation]
|
423
|
+
else
|
424
|
+
connections = Thread.current[@connection_key]
|
425
|
+
end
|
380
426
|
|
381
427
|
net_http_args = [uri.host, uri.port]
|
382
428
|
connection_id = net_http_args.join ':'
|
@@ -391,7 +437,7 @@ class Net::HTTP::Persistent
|
|
391
437
|
unless connection = connections[connection_id] then
|
392
438
|
connections[connection_id] = http_class.new(*net_http_args)
|
393
439
|
connection = connections[connection_id]
|
394
|
-
ssl connection if
|
440
|
+
ssl connection if use_ssl
|
395
441
|
else
|
396
442
|
last_used = Thread.current[@timeout_key][connection.object_id]
|
397
443
|
reset connection unless last_used > max_age
|
@@ -452,7 +498,12 @@ class Net::HTTP::Persistent
|
|
452
498
|
end
|
453
499
|
|
454
500
|
def http_class # :nodoc:
|
455
|
-
|
501
|
+
if [:FakeWeb, :WebMock].any? { |klass| Object.const_defined?(klass) } or
|
502
|
+
not @reuse_ssl_sessions then
|
503
|
+
Net::HTTP
|
504
|
+
else
|
505
|
+
Net::HTTP::Persistent::SSLReuse
|
506
|
+
end
|
456
507
|
end
|
457
508
|
|
458
509
|
##
|
@@ -543,6 +594,15 @@ class Net::HTTP::Persistent
|
|
543
594
|
connection.pipeline requests, &block
|
544
595
|
end
|
545
596
|
|
597
|
+
##
|
598
|
+
# Sets this client's SSL private key
|
599
|
+
|
600
|
+
def private_key= key
|
601
|
+
@private_key = key
|
602
|
+
|
603
|
+
reconnect_ssl
|
604
|
+
end
|
605
|
+
|
546
606
|
##
|
547
607
|
# Creates a URI for an HTTP proxy server from ENV variables.
|
548
608
|
#
|
@@ -570,6 +630,13 @@ class Net::HTTP::Persistent
|
|
570
630
|
uri
|
571
631
|
end
|
572
632
|
|
633
|
+
##
|
634
|
+
# Forces reconnection of SSL connections.
|
635
|
+
|
636
|
+
def reconnect_ssl
|
637
|
+
@ssl_generation += 1
|
638
|
+
end
|
639
|
+
|
573
640
|
##
|
574
641
|
# Finishes then restarts the Net::HTTP +connection+
|
575
642
|
|
@@ -685,8 +752,13 @@ class Net::HTTP::Persistent
|
|
685
752
|
end
|
686
753
|
end if connections
|
687
754
|
|
755
|
+
ssl_generation = reconnect_ssl
|
756
|
+
|
757
|
+
ssl_cleanup ssl_generation
|
758
|
+
|
688
759
|
thread[@connection_key] = nil
|
689
760
|
thread[@request_key] = nil
|
761
|
+
thread[@timeout_key] = nil
|
690
762
|
end
|
691
763
|
|
692
764
|
##
|
@@ -762,6 +834,44 @@ application:
|
|
762
834
|
end
|
763
835
|
end
|
764
836
|
|
837
|
+
##
|
838
|
+
# Finishes all connections that existed before the given SSL parameter
|
839
|
+
# +generation+.
|
840
|
+
|
841
|
+
def ssl_cleanup generation
|
842
|
+
(0...ssl_generation).each do |generation|
|
843
|
+
ssl_conns = Thread.current[@ssl_generation_key].delete generation
|
844
|
+
|
845
|
+
ssl_conns.each_value do |ssl_conn|
|
846
|
+
finish ssl_conn
|
847
|
+
|
848
|
+
Thread.current[@timeout_key].delete ssl_conn.object_id
|
849
|
+
end if ssl_conns
|
850
|
+
end
|
851
|
+
end
|
852
|
+
|
853
|
+
##
|
854
|
+
# Sets the HTTPS verify mode. Defaults to OpenSSL::SSL::VERIFY_PEER.
|
855
|
+
#
|
856
|
+
# Setting this to VERIFY_NONE is a VERY BAD IDEA and should NEVER be used.
|
857
|
+
# Securely transfer the correct certificate and update the default
|
858
|
+
# certificate store or set the ca file instead.
|
859
|
+
|
860
|
+
def verify_mode= verify_mode
|
861
|
+
@verify_mode = verify_mode
|
862
|
+
|
863
|
+
reconnect_ssl
|
864
|
+
end
|
865
|
+
|
866
|
+
##
|
867
|
+
# SSL verification callback.
|
868
|
+
|
869
|
+
def verify_callback= callback
|
870
|
+
@verify_callback = callback
|
871
|
+
|
872
|
+
reconnect_ssl
|
873
|
+
end
|
874
|
+
|
765
875
|
end
|
766
876
|
|
767
877
|
require 'net/http/persistent/ssl_reuse'
|
@@ -92,6 +92,8 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
92
92
|
end
|
93
93
|
|
94
94
|
def basic_connection
|
95
|
+
raise "#{@uri} is not HTTP" unless @uri.scheme.downcase == 'http'
|
96
|
+
|
95
97
|
c = BasicConnection.new
|
96
98
|
conns["#{@uri.host}:#{@uri.port}"] = c
|
97
99
|
c
|
@@ -122,6 +124,17 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
122
124
|
Thread.current[@http.request_key] ||= {}
|
123
125
|
end
|
124
126
|
|
127
|
+
def ssl_conns
|
128
|
+
Thread.current[@http.ssl_generation_key] ||= Hash.new { |h,k| h[k] = {} }
|
129
|
+
end
|
130
|
+
|
131
|
+
def ssl_connection generation = 0
|
132
|
+
raise "#{@uri} is not HTTPS" unless @uri.scheme.downcase == 'https'
|
133
|
+
c = BasicConnection.new
|
134
|
+
ssl_conns[generation]["#{@uri.host}:#{@uri.port}"] = c
|
135
|
+
c
|
136
|
+
end
|
137
|
+
|
125
138
|
def touts
|
126
139
|
Thread.current[@http.timeout_key] ||= Hash.new Net::HTTP::Persistent::EPOCH
|
127
140
|
end
|
@@ -150,6 +163,27 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
150
163
|
assert_equal proxy_uri, http.proxy_uri
|
151
164
|
end
|
152
165
|
|
166
|
+
def test_ca_file_equals
|
167
|
+
@http.ca_file = :ca_file
|
168
|
+
|
169
|
+
assert_equal :ca_file, @http.ca_file
|
170
|
+
assert_equal 1, @http.ssl_generation
|
171
|
+
end
|
172
|
+
|
173
|
+
def test_cert_store_equals
|
174
|
+
@http.cert_store = :cert_store
|
175
|
+
|
176
|
+
assert_equal :cert_store, @http.cert_store
|
177
|
+
assert_equal 1, @http.ssl_generation
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_certificate_equals
|
181
|
+
@http.certificate = :cert
|
182
|
+
|
183
|
+
assert_equal :cert, @http.certificate
|
184
|
+
assert_equal 1, @http.ssl_generation
|
185
|
+
end
|
186
|
+
|
153
187
|
def test_connection_for
|
154
188
|
@http.open_timeout = 123
|
155
189
|
@http.read_timeout = 321
|
@@ -253,6 +287,26 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
253
287
|
assert_match %r%host down%, e.message
|
254
288
|
end
|
255
289
|
|
290
|
+
def test_connection_for_http_class_with_fakeweb
|
291
|
+
Object.send :const_set, :FakeWeb, nil
|
292
|
+
c = @http.connection_for @uri
|
293
|
+
assert_instance_of Net::HTTP, c
|
294
|
+
ensure
|
295
|
+
if Object.const_defined?(:FakeWeb) then
|
296
|
+
Object.send :remove_const, :FakeWeb
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
def test_connection_for_http_class_with_webmock
|
301
|
+
Object.send :const_set, :WebMock, nil
|
302
|
+
c = @http.connection_for @uri
|
303
|
+
assert_instance_of Net::HTTP, c
|
304
|
+
ensure
|
305
|
+
if Object.const_defined?(:WebMock) then
|
306
|
+
Object.send :remove_const, :WebMock
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
256
310
|
def test_connection_for_name
|
257
311
|
http = Net::HTTP::Persistent.new 'name'
|
258
312
|
uri = URI.parse 'http://example/'
|
@@ -325,6 +379,28 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
325
379
|
assert c.use_ssl?
|
326
380
|
end
|
327
381
|
|
382
|
+
def test_connection_for_ssl_cached
|
383
|
+
@uri = URI.parse 'https://example.com/path'
|
384
|
+
|
385
|
+
cached = ssl_connection 0
|
386
|
+
|
387
|
+
c = @http.connection_for @uri
|
388
|
+
|
389
|
+
assert_same cached, c
|
390
|
+
end
|
391
|
+
|
392
|
+
def test_connection_for_ssl_cached_reconnect
|
393
|
+
@uri = URI.parse 'https://example.com/path'
|
394
|
+
|
395
|
+
cached = ssl_connection
|
396
|
+
|
397
|
+
@http.reconnect_ssl
|
398
|
+
|
399
|
+
c = @http.connection_for @uri
|
400
|
+
|
401
|
+
refute_same cached, c
|
402
|
+
end
|
403
|
+
|
328
404
|
def test_connection_for_ssl_case
|
329
405
|
uri = URI.parse 'HTTPS://example.com/path'
|
330
406
|
c = @http.connection_for uri
|
@@ -407,16 +483,16 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
407
483
|
refute @http.idempotent? Net::HTTP::Post.new '/'
|
408
484
|
end
|
409
485
|
|
486
|
+
def test_max_age
|
487
|
+
assert_in_delta Time.now - 5, @http.max_age
|
488
|
+
end
|
489
|
+
|
410
490
|
def test_normalize_uri
|
411
491
|
assert_equal 'http://example', @http.normalize_uri('example')
|
412
492
|
assert_equal 'http://example', @http.normalize_uri('http://example')
|
413
493
|
assert_equal 'https://example', @http.normalize_uri('https://example')
|
414
494
|
end
|
415
495
|
|
416
|
-
def test_max_age
|
417
|
-
assert_in_delta Time.now - 5, @http.max_age
|
418
|
-
end
|
419
|
-
|
420
496
|
def test_pipeline
|
421
497
|
skip 'net-http-pipeline not installed' unless defined?(Net::HTTP::Pipeline)
|
422
498
|
|
@@ -436,6 +512,13 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
436
512
|
assert_equal '/2', responses.last
|
437
513
|
end
|
438
514
|
|
515
|
+
def test_private_key_equals
|
516
|
+
@http.private_key = :private_key
|
517
|
+
|
518
|
+
assert_equal :private_key, @http.private_key
|
519
|
+
assert_equal 1, @http.ssl_generation
|
520
|
+
end
|
521
|
+
|
439
522
|
def test_proxy_from_env
|
440
523
|
ENV['HTTP_PROXY'] = 'proxy.example'
|
441
524
|
ENV['HTTP_PROXY_USER'] = 'johndoe'
|
@@ -476,69 +559,10 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
476
559
|
assert_nil uri
|
477
560
|
end
|
478
561
|
|
479
|
-
def
|
480
|
-
|
481
|
-
c.start
|
482
|
-
touts[c.object_id] = Time.now
|
483
|
-
reqs[c.object_id] = 5
|
484
|
-
|
485
|
-
@http.reset c
|
562
|
+
def test_reconnect_ssl
|
563
|
+
result = @http.reconnect_ssl
|
486
564
|
|
487
|
-
|
488
|
-
assert c.finished?
|
489
|
-
assert c.reset?
|
490
|
-
assert_nil reqs[c.object_id]
|
491
|
-
assert_equal Net::HTTP::Persistent::EPOCH, touts[c.object_id]
|
492
|
-
end
|
493
|
-
|
494
|
-
def test_reset_io_error
|
495
|
-
c = basic_connection
|
496
|
-
touts[c.object_id] = Time.now
|
497
|
-
reqs[c.object_id] = 5
|
498
|
-
|
499
|
-
@http.reset c
|
500
|
-
|
501
|
-
assert c.started?
|
502
|
-
assert c.finished?
|
503
|
-
end
|
504
|
-
|
505
|
-
def test_reset_host_down
|
506
|
-
c = basic_connection
|
507
|
-
touts[c.object_id] = Time.now
|
508
|
-
def c.start; raise Errno::EHOSTDOWN end
|
509
|
-
reqs[c.object_id] = 5
|
510
|
-
|
511
|
-
e = assert_raises Net::HTTP::Persistent::Error do
|
512
|
-
@http.reset c
|
513
|
-
end
|
514
|
-
|
515
|
-
assert_match %r%host down%, e.message
|
516
|
-
end
|
517
|
-
|
518
|
-
def test_reset_refused
|
519
|
-
c = basic_connection
|
520
|
-
touts[c.object_id] = Time.now
|
521
|
-
def c.start; raise Errno::ECONNREFUSED end
|
522
|
-
reqs[c.object_id] = 5
|
523
|
-
|
524
|
-
e = assert_raises Net::HTTP::Persistent::Error do
|
525
|
-
@http.reset c
|
526
|
-
end
|
527
|
-
|
528
|
-
assert_match %r%connection refused%, e.message
|
529
|
-
end
|
530
|
-
|
531
|
-
def test_ssl_error
|
532
|
-
uri = URI.parse 'https://example.com/path'
|
533
|
-
c = @http.connection_for uri
|
534
|
-
def c.request(*)
|
535
|
-
raise OpenSSL::SSL::SSLError, "SSL3_WRITE_PENDING:bad write retry"
|
536
|
-
end
|
537
|
-
|
538
|
-
e = assert_raises Net::HTTP::Persistent::Error do
|
539
|
-
@http.request uri
|
540
|
-
end
|
541
|
-
assert_match %r%bad write retry%, e.message
|
565
|
+
assert_equal 1, result
|
542
566
|
end
|
543
567
|
|
544
568
|
def test_request
|
@@ -744,6 +768,17 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
744
768
|
assert c.finished?
|
745
769
|
end
|
746
770
|
|
771
|
+
def test_request_post
|
772
|
+
c = connection
|
773
|
+
|
774
|
+
post = Net::HTTP::Post.new @uri.path
|
775
|
+
|
776
|
+
@http.request @uri, post
|
777
|
+
req = c.req
|
778
|
+
|
779
|
+
assert_same post, req
|
780
|
+
end
|
781
|
+
|
747
782
|
def test_request_reset
|
748
783
|
c = basic_connection
|
749
784
|
def c.request(*a) raise Errno::ECONNRESET end
|
@@ -796,21 +831,94 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
796
831
|
assert_match %r%too many connection resets%, e.message
|
797
832
|
end
|
798
833
|
|
799
|
-
def
|
800
|
-
|
834
|
+
def test_request_ssl_error
|
835
|
+
uri = URI.parse 'https://example.com/path'
|
836
|
+
c = @http.connection_for uri
|
837
|
+
def c.request(*)
|
838
|
+
raise OpenSSL::SSL::SSLError, "SSL3_WRITE_PENDING:bad write retry"
|
839
|
+
end
|
801
840
|
|
802
|
-
|
841
|
+
e = assert_raises Net::HTTP::Persistent::Error do
|
842
|
+
@http.request uri
|
843
|
+
end
|
844
|
+
assert_match %r%bad write retry%, e.message
|
845
|
+
end
|
803
846
|
|
804
|
-
|
805
|
-
|
847
|
+
def test_reset
|
848
|
+
c = basic_connection
|
849
|
+
c.start
|
850
|
+
touts[c.object_id] = Time.now
|
851
|
+
reqs[c.object_id] = 5
|
806
852
|
|
807
|
-
|
853
|
+
@http.reset c
|
854
|
+
|
855
|
+
assert c.started?
|
856
|
+
assert c.finished?
|
857
|
+
assert c.reset?
|
858
|
+
assert_nil reqs[c.object_id]
|
859
|
+
assert_equal Net::HTTP::Persistent::EPOCH, touts[c.object_id]
|
860
|
+
end
|
861
|
+
|
862
|
+
def test_reset_host_down
|
863
|
+
c = basic_connection
|
864
|
+
touts[c.object_id] = Time.now
|
865
|
+
def c.start; raise Errno::EHOSTDOWN end
|
866
|
+
reqs[c.object_id] = 5
|
867
|
+
|
868
|
+
e = assert_raises Net::HTTP::Persistent::Error do
|
869
|
+
@http.reset c
|
870
|
+
end
|
871
|
+
|
872
|
+
assert_match %r%host down%, e.message
|
873
|
+
end
|
874
|
+
|
875
|
+
def test_reset_io_error
|
876
|
+
c = basic_connection
|
877
|
+
touts[c.object_id] = Time.now
|
878
|
+
reqs[c.object_id] = 5
|
879
|
+
|
880
|
+
@http.reset c
|
881
|
+
|
882
|
+
assert c.started?
|
883
|
+
assert c.finished?
|
884
|
+
end
|
885
|
+
|
886
|
+
def test_reset_refused
|
887
|
+
c = basic_connection
|
888
|
+
touts[c.object_id] = Time.now
|
889
|
+
def c.start; raise Errno::ECONNREFUSED end
|
890
|
+
reqs[c.object_id] = 5
|
891
|
+
|
892
|
+
e = assert_raises Net::HTTP::Persistent::Error do
|
893
|
+
@http.reset c
|
894
|
+
end
|
895
|
+
|
896
|
+
assert_match %r%connection refused%, e.message
|
897
|
+
end
|
898
|
+
|
899
|
+
def test_retry_change_requests_equals
|
900
|
+
get = Net::HTTP::Get.new('/')
|
901
|
+
post = Net::HTTP::Post.new('/')
|
902
|
+
|
903
|
+
refute @http.retry_change_requests
|
904
|
+
|
905
|
+
assert @http.can_retry?(get)
|
906
|
+
refute @http.can_retry?(post)
|
907
|
+
|
908
|
+
@http.retry_change_requests = true
|
909
|
+
|
910
|
+
assert @http.retry_change_requests
|
911
|
+
|
912
|
+
assert @http.can_retry?(get)
|
913
|
+
assert @http.can_retry?(post)
|
808
914
|
end
|
809
915
|
|
810
916
|
def test_shutdown
|
917
|
+
ssl_conns
|
811
918
|
c = connection
|
812
919
|
cs = conns
|
813
920
|
rs = reqs
|
921
|
+
ts = touts
|
814
922
|
|
815
923
|
orig = @http
|
816
924
|
@http = Net::HTTP::Persistent.new 'name'
|
@@ -818,35 +926,25 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
818
926
|
|
819
927
|
orig.shutdown
|
820
928
|
|
929
|
+
@http = orig
|
930
|
+
|
821
931
|
assert c.finished?
|
822
932
|
refute c2.finished?
|
823
933
|
|
824
934
|
refute_same cs, conns
|
825
935
|
refute_same rs, reqs
|
826
|
-
|
827
|
-
|
828
|
-
def test_shutdown_not_started
|
829
|
-
c = basic_connection
|
830
|
-
def c.finish() raise IOError end
|
831
|
-
|
832
|
-
conns["#{@uri.host}:#{@uri.port}"] = c
|
833
|
-
|
834
|
-
@http.shutdown
|
936
|
+
refute_same ts, touts
|
835
937
|
|
836
|
-
|
837
|
-
|
938
|
+
assert_empty reqs
|
939
|
+
assert_empty touts
|
838
940
|
end
|
839
941
|
|
840
|
-
def
|
841
|
-
|
842
|
-
|
843
|
-
assert_nil Thread.current[@http.connection_key]
|
844
|
-
assert_nil Thread.current[@http.request_key]
|
845
|
-
end
|
942
|
+
def test_shutdown_in_all_threads
|
943
|
+
ssl_conns
|
846
944
|
|
847
|
-
def test_shutdown_thread
|
848
945
|
t = Thread.new do
|
849
946
|
c = connection
|
947
|
+
ssl_conns
|
850
948
|
conns
|
851
949
|
reqs
|
852
950
|
|
@@ -859,9 +957,11 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
859
957
|
|
860
958
|
c = connection
|
861
959
|
|
862
|
-
@http.
|
960
|
+
assert_nil @http.shutdown_in_all_threads
|
863
961
|
|
864
|
-
|
962
|
+
assert c.finished?
|
963
|
+
assert_nil Thread.current[@http.connection_key]
|
964
|
+
assert_nil Thread.current[@http.request_key]
|
865
965
|
|
866
966
|
t.run
|
867
967
|
assert t.value.finished?
|
@@ -869,7 +969,42 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
869
969
|
assert_nil t[@http.request_key]
|
870
970
|
end
|
871
971
|
|
872
|
-
def
|
972
|
+
def test_shutdown_no_connections
|
973
|
+
ssl_conns
|
974
|
+
|
975
|
+
@http.shutdown
|
976
|
+
|
977
|
+
assert_nil Thread.current[@http.connection_key]
|
978
|
+
assert_nil Thread.current[@http.request_key]
|
979
|
+
end
|
980
|
+
|
981
|
+
def test_shutdown_not_started
|
982
|
+
ssl_conns
|
983
|
+
|
984
|
+
c = basic_connection
|
985
|
+
def c.finish() raise IOError end
|
986
|
+
|
987
|
+
conns["#{@uri.host}:#{@uri.port}"] = c
|
988
|
+
|
989
|
+
@http.shutdown
|
990
|
+
|
991
|
+
assert_nil Thread.current[@http.connection_key]
|
992
|
+
assert_nil Thread.current[@http.request_key]
|
993
|
+
end
|
994
|
+
|
995
|
+
def test_shutdown_ssl
|
996
|
+
@uri = URI 'https://example'
|
997
|
+
|
998
|
+
@http.connection_for @uri
|
999
|
+
|
1000
|
+
@http.shutdown
|
1001
|
+
|
1002
|
+
assert_empty ssl_conns
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
def test_shutdown_thread
|
1006
|
+
ssl_conns
|
1007
|
+
|
873
1008
|
t = Thread.new do
|
874
1009
|
c = connection
|
875
1010
|
conns
|
@@ -884,11 +1019,9 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
884
1019
|
|
885
1020
|
c = connection
|
886
1021
|
|
887
|
-
|
1022
|
+
@http.shutdown t
|
888
1023
|
|
889
|
-
|
890
|
-
assert_nil Thread.current[@http.connection_key]
|
891
|
-
assert_nil Thread.current[@http.request_key]
|
1024
|
+
refute c.finished?
|
892
1025
|
|
893
1026
|
t.run
|
894
1027
|
assert t.value.finished?
|
@@ -932,7 +1065,7 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
932
1065
|
assert_equal store, c.cert_store
|
933
1066
|
end
|
934
1067
|
|
935
|
-
def
|
1068
|
+
def test_ssl_cert_store_default
|
936
1069
|
@http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
937
1070
|
|
938
1071
|
c = Net::HTTP.new 'localhost', 80
|
@@ -994,16 +1127,36 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
994
1127
|
end
|
995
1128
|
end
|
996
1129
|
|
997
|
-
def
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1130
|
+
def test_ssl_cleanup
|
1131
|
+
uri1 = URI.parse 'https://one.example'
|
1132
|
+
uri2 = URI.parse 'https://two.example'
|
1133
|
+
|
1134
|
+
c1 = @http.connection_for uri1
|
1135
|
+
|
1136
|
+
touts[c1.object_id] = Time.now
|
1137
|
+
reqs[c1.object_id] = 5
|
1138
|
+
|
1139
|
+
@http.reconnect_ssl
|
1140
|
+
|
1141
|
+
@http.ssl_cleanup @http.ssl_generation
|
1142
|
+
|
1143
|
+
assert_empty ssl_conns
|
1144
|
+
assert_empty touts
|
1145
|
+
assert_empty reqs # sanity check, performed by #finish
|
1146
|
+
end
|
1147
|
+
|
1148
|
+
def test_verify_callback_equals
|
1149
|
+
@http.verify_callback = :verify_callback
|
1150
|
+
|
1151
|
+
assert_equal :verify_callback, @http.verify_callback
|
1152
|
+
assert_equal 1, @http.ssl_generation
|
1153
|
+
end
|
1154
|
+
|
1155
|
+
def test_verify_mode_equals
|
1156
|
+
@http.verify_mode = :verify_mode
|
1157
|
+
|
1158
|
+
assert_equal :verify_mode, @http.verify_mode
|
1159
|
+
assert_equal 1, @http.ssl_generation
|
1007
1160
|
end
|
1008
1161
|
|
1009
1162
|
end
|
@@ -75,6 +75,7 @@ class TestNetHttpPersistentSSLReuse < MiniTest::Unit::TestCase
|
|
75
75
|
def test_ssl_connection_reuse
|
76
76
|
@http = Net::HTTP::Persistent::SSLReuse.new @host, @port
|
77
77
|
@http.use_ssl = true
|
78
|
+
@http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
78
79
|
@http.verify_callback = proc do |_, store_ctx|
|
79
80
|
store_ctx.current_cert.to_der == @cert.to_der
|
80
81
|
end
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: net-http-persistent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 29
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 4
|
9
|
-
|
9
|
+
- 1
|
10
|
+
version: 2.4.1
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Eric Hodel
|
@@ -35,7 +36,7 @@ cert_chain:
|
|
35
36
|
YJY7T/W2n+eWy8WuPhzVUkyzguj0bQe27NDeabgCh2mHd4Hynk2AkYh8MQ==
|
36
37
|
-----END CERTIFICATE-----
|
37
38
|
|
38
|
-
date: 2012-
|
39
|
+
date: 2012-02-04 00:00:00 Z
|
39
40
|
dependencies:
|
40
41
|
- !ruby/object:Gem::Dependency
|
41
42
|
name: minitest
|
metadata.gz.sig
CHANGED
Binary file
|