net-http-persistent 2.4 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|