net-http-persistent 2.7 → 2.8
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 +23 -0
- data/lib/net/http/persistent.rb +143 -23
- data/test/test_net_http_persistent.rb +208 -37
- data/test/test_net_http_persistent_ssl_reuse.rb +10 -5
- metadata +105 -101
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/History.txt
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
=== 2.8 / 2012-10-17
|
2
|
+
|
3
|
+
* Minor enhancements
|
4
|
+
* Added Net::HTTP::Persistent::detect_idle_timeout which can be used to
|
5
|
+
determine the idle timeout for a host.
|
6
|
+
* The read timeout may now be updated for every request. Issue #33 by
|
7
|
+
Mislav Marohnić
|
8
|
+
* Added NO_PROXY support. Pull Request #31 by Laurence Rowe.
|
9
|
+
* Added #cert and #key aliases for Net::HTTP compatibility. Pull request
|
10
|
+
#26 by dlee.
|
11
|
+
* The artifice gem now disables SSL session reuse to prevent breakage of
|
12
|
+
testing frameworks. Pull Request #29 by Christopher Cooke.
|
13
|
+
* Disabled Net::HTTP::Persistent::SSLReuse on Ruby 2+. This feature is now
|
14
|
+
built-in to Net::HTTP.
|
15
|
+
* Bug fixes
|
16
|
+
* Socket options are set again following connection reset. Pull request #28
|
17
|
+
by cmaion.
|
18
|
+
* #shutdown now works even if no connections were made. Pull Request #24 by
|
19
|
+
James Tucker.
|
20
|
+
* Updated test RSA key size to 1024 bits. Bug #25 by Gunnar Wolf.
|
21
|
+
* The correct host:port are shown in the exception when a proxy connection
|
22
|
+
fails. Bug #30 by glebtv.
|
23
|
+
|
1
24
|
=== 2.7 / 2012-06-06
|
2
25
|
|
3
26
|
* Minor enhancement
|
data/lib/net/http/persistent.rb
CHANGED
@@ -176,7 +176,7 @@ class Net::HTTP::Persistent
|
|
176
176
|
##
|
177
177
|
# The version of Net::HTTP::Persistent you are using
|
178
178
|
|
179
|
-
VERSION = '2.
|
179
|
+
VERSION = '2.8'
|
180
180
|
|
181
181
|
##
|
182
182
|
# Error class for errors raised by Net::HTTP::Persistent. Various
|
@@ -185,11 +185,61 @@ class Net::HTTP::Persistent
|
|
185
185
|
|
186
186
|
class Error < StandardError; end
|
187
187
|
|
188
|
+
##
|
189
|
+
# Use this method to detect the idle timeout of the host at +uri+. The
|
190
|
+
# value returned can be used to configure #idle_timeout. +max+ controls the
|
191
|
+
# maximum idle timeout to detect.
|
192
|
+
#
|
193
|
+
# After
|
194
|
+
#
|
195
|
+
# Idle timeout detection is performed by creating a connection then
|
196
|
+
# performing a HEAD request in a loop until the connection terminates
|
197
|
+
# waiting one additional second per loop.
|
198
|
+
#
|
199
|
+
# NOTE: This may not work on ruby > 1.9.
|
200
|
+
|
201
|
+
def self.detect_idle_timeout uri, max = 10
|
202
|
+
uri = URI uri unless URI::Generic === uri
|
203
|
+
uri += '/'
|
204
|
+
|
205
|
+
req = Net::HTTP::Head.new uri.request_uri
|
206
|
+
|
207
|
+
http = new 'net-http-persistent detect_idle_timeout'
|
208
|
+
|
209
|
+
connection = http.connection_for uri
|
210
|
+
|
211
|
+
sleep_time = 0
|
212
|
+
|
213
|
+
loop do
|
214
|
+
response = connection.request req
|
215
|
+
|
216
|
+
$stderr.puts "HEAD #{uri} => #{response.code}" if $DEBUG
|
217
|
+
|
218
|
+
unless Net::HTTPOK === response then
|
219
|
+
raise Error, "bad response code #{response.code} detecting idle timeout"
|
220
|
+
end
|
221
|
+
|
222
|
+
break if sleep_time >= max
|
223
|
+
|
224
|
+
sleep_time += 1
|
225
|
+
|
226
|
+
$stderr.puts "sleeping #{sleep_time}" if $DEBUG
|
227
|
+
sleep sleep_time
|
228
|
+
end
|
229
|
+
ensure
|
230
|
+
http.shutdown
|
231
|
+
|
232
|
+
return sleep_time unless $!
|
233
|
+
end
|
234
|
+
|
188
235
|
##
|
189
236
|
# This client's OpenSSL::X509::Certificate
|
190
237
|
|
191
238
|
attr_reader :certificate
|
192
239
|
|
240
|
+
# For Net::HTTP parity
|
241
|
+
alias cert certificate
|
242
|
+
|
193
243
|
##
|
194
244
|
# An SSL certificate authority. Setting this will set verify_mode to
|
195
245
|
# VERIFY_PEER.
|
@@ -269,11 +319,19 @@ class Net::HTTP::Persistent
|
|
269
319
|
|
270
320
|
attr_reader :private_key
|
271
321
|
|
322
|
+
# For Net::HTTP parity
|
323
|
+
alias key private_key
|
324
|
+
|
272
325
|
##
|
273
326
|
# The URL through which requests will be proxied
|
274
327
|
|
275
328
|
attr_reader :proxy_uri
|
276
329
|
|
330
|
+
##
|
331
|
+
# List of host suffixes which will not be proxied
|
332
|
+
|
333
|
+
attr_reader :no_proxy
|
334
|
+
|
277
335
|
##
|
278
336
|
# Seconds to wait until reading one block. See Net::HTTP#read_timeout
|
279
337
|
|
@@ -376,6 +434,7 @@ class Net::HTTP::Persistent
|
|
376
434
|
|
377
435
|
@debug_output = nil
|
378
436
|
@proxy_uri = nil
|
437
|
+
@no_proxy = []
|
379
438
|
@headers = {}
|
380
439
|
@override_headers = {}
|
381
440
|
@http_versions = {}
|
@@ -420,6 +479,9 @@ class Net::HTTP::Persistent
|
|
420
479
|
reconnect_ssl
|
421
480
|
end
|
422
481
|
|
482
|
+
# For Net::HTTP parity
|
483
|
+
alias cert= certificate=
|
484
|
+
|
423
485
|
##
|
424
486
|
# Sets the SSL certificate authority file.
|
425
487
|
|
@@ -450,6 +512,8 @@ class Net::HTTP::Persistent
|
|
450
512
|
timeouts = thread[@timeout_key]
|
451
513
|
|
452
514
|
(0...generation).each do |old_generation|
|
515
|
+
next unless thread[generation_key]
|
516
|
+
|
453
517
|
conns = thread[generation_key].delete old_generation
|
454
518
|
|
455
519
|
conns.each_value do |conn|
|
@@ -488,7 +552,7 @@ class Net::HTTP::Persistent
|
|
488
552
|
net_http_args = [uri.host, uri.port]
|
489
553
|
connection_id = net_http_args.join ':'
|
490
554
|
|
491
|
-
if @proxy_uri then
|
555
|
+
if @proxy_uri and not proxy_bypass? uri.host, uri.port then
|
492
556
|
connection_id << @proxy_connection_id
|
493
557
|
net_http_args.concat @proxy_args
|
494
558
|
end
|
@@ -503,27 +567,21 @@ class Net::HTTP::Persistent
|
|
503
567
|
reset connection if expired? connection
|
504
568
|
end
|
505
569
|
|
506
|
-
unless connection.started?
|
507
|
-
connection.set_debug_output @debug_output if @debug_output
|
508
|
-
connection.open_timeout = @open_timeout if @open_timeout
|
509
|
-
connection.read_timeout = @read_timeout if @read_timeout
|
570
|
+
start connection unless connection.started?
|
510
571
|
|
511
|
-
|
512
|
-
|
513
|
-
socket = connection.instance_variable_get :@socket
|
514
|
-
|
515
|
-
if socket then # for fakeweb
|
516
|
-
@socket_options.each do |option|
|
517
|
-
socket.io.setsockopt(*option)
|
518
|
-
end
|
519
|
-
end
|
520
|
-
end
|
572
|
+
connection.read_timeout = @read_timeout if @read_timeout
|
521
573
|
|
522
574
|
connection
|
523
575
|
rescue Errno::ECONNREFUSED
|
524
|
-
|
576
|
+
address = connection.proxy_address || connection.address
|
577
|
+
port = connection.proxy_port || connection.port
|
578
|
+
|
579
|
+
raise Error, "connection refused: #{address}:#{port}"
|
525
580
|
rescue Errno::EHOSTDOWN
|
526
|
-
|
581
|
+
address = connection.proxy_address || connection.address
|
582
|
+
port = connection.proxy_port || connection.port
|
583
|
+
|
584
|
+
raise Error, "host down: #{address}:#{port}"
|
527
585
|
end
|
528
586
|
|
529
587
|
##
|
@@ -560,6 +618,24 @@ class Net::HTTP::Persistent
|
|
560
618
|
Time.now - last_used > @idle_timeout
|
561
619
|
end
|
562
620
|
|
621
|
+
##
|
622
|
+
# Starts the Net::HTTP +connection+
|
623
|
+
|
624
|
+
def start connection
|
625
|
+
connection.set_debug_output @debug_output if @debug_output
|
626
|
+
connection.open_timeout = @open_timeout if @open_timeout
|
627
|
+
|
628
|
+
connection.start
|
629
|
+
|
630
|
+
socket = connection.instance_variable_get :@socket
|
631
|
+
|
632
|
+
if socket then # for fakeweb
|
633
|
+
@socket_options.each do |option|
|
634
|
+
socket.io.setsockopt(*option)
|
635
|
+
end
|
636
|
+
end
|
637
|
+
end
|
638
|
+
|
563
639
|
##
|
564
640
|
# Finishes the Net::HTTP +connection+
|
565
641
|
|
@@ -573,8 +649,11 @@ class Net::HTTP::Persistent
|
|
573
649
|
end
|
574
650
|
|
575
651
|
def http_class # :nodoc:
|
576
|
-
if
|
577
|
-
|
652
|
+
if RUBY_VERSION > '2.0' then
|
653
|
+
Net::HTTP
|
654
|
+
elsif [:Artifice, :FakeWeb, :WebMock].any? { |klass|
|
655
|
+
Object.const_defined?(klass)
|
656
|
+
} or not @reuse_ssl_sessions then
|
578
657
|
Net::HTTP
|
579
658
|
else
|
580
659
|
Net::HTTP::Persistent::SSLReuse
|
@@ -680,6 +759,9 @@ class Net::HTTP::Persistent
|
|
680
759
|
reconnect_ssl
|
681
760
|
end
|
682
761
|
|
762
|
+
# For Net::HTTP parity
|
763
|
+
alias key= private_key=
|
764
|
+
|
683
765
|
##
|
684
766
|
# Sets the proxy server. The +proxy+ may be the URI of the proxy server,
|
685
767
|
# the symbol +:ENV+ which will read the proxy from the environment or nil to
|
@@ -689,8 +771,10 @@ class Net::HTTP::Persistent
|
|
689
771
|
# If the proxy URI is set after requests have been made, the next request
|
690
772
|
# will shut-down and re-open all connections.
|
691
773
|
#
|
692
|
-
#
|
693
|
-
#
|
774
|
+
# The +no_proxy+ query parameter can be used to specify hosts which shouldn't
|
775
|
+
# be reached via proxy; if set it should be a comma separated list of
|
776
|
+
# hostname suffixes, optionally with +:port+ appended, for example
|
777
|
+
# <tt>example.com,some.host:8080</tt>.
|
694
778
|
|
695
779
|
def proxy= proxy
|
696
780
|
@proxy_uri = case proxy
|
@@ -700,6 +784,8 @@ class Net::HTTP::Persistent
|
|
700
784
|
else raise ArgumentError, 'proxy must be :ENV or a URI::HTTP'
|
701
785
|
end
|
702
786
|
|
787
|
+
@no_proxy.clear
|
788
|
+
|
703
789
|
if @proxy_uri then
|
704
790
|
@proxy_args = [
|
705
791
|
@proxy_uri.host,
|
@@ -709,6 +795,10 @@ class Net::HTTP::Persistent
|
|
709
795
|
]
|
710
796
|
|
711
797
|
@proxy_connection_id = [nil, *@proxy_args].join ':'
|
798
|
+
|
799
|
+
if @proxy_uri.query then
|
800
|
+
@no_proxy = CGI.parse(@proxy_uri.query)['no_proxy'].join(',').downcase.split(',').map { |x| x.strip }.reject { |x| x.empty? }
|
801
|
+
end
|
712
802
|
end
|
713
803
|
|
714
804
|
reconnect
|
@@ -724,6 +814,12 @@ class Net::HTTP::Persistent
|
|
724
814
|
# indicated user and password unless HTTP_PROXY contains either of these in
|
725
815
|
# the URI.
|
726
816
|
#
|
817
|
+
# The +NO_PROXY+ ENV variable can be used to specify hosts which shouldn't
|
818
|
+
# be reached via proxy; if set it should be a comma separated list of
|
819
|
+
# hostname suffixes, optionally with +:port+ appended, for example
|
820
|
+
# <tt>example.com,some.host:8080</tt>. When set to <tt>*</tt> no proxy will
|
821
|
+
# be returned.
|
822
|
+
#
|
727
823
|
# For Windows users, lowercase ENV variables are preferred over uppercase ENV
|
728
824
|
# variables.
|
729
825
|
|
@@ -734,6 +830,15 @@ class Net::HTTP::Persistent
|
|
734
830
|
|
735
831
|
uri = URI normalize_uri env_proxy
|
736
832
|
|
833
|
+
env_no_proxy = ENV['no_proxy'] || ENV['NO_PROXY']
|
834
|
+
|
835
|
+
# '*' is special case for always bypass
|
836
|
+
return nil if env_no_proxy == '*'
|
837
|
+
|
838
|
+
if env_no_proxy then
|
839
|
+
uri.query = "no_proxy=#{escape(env_no_proxy)}"
|
840
|
+
end
|
841
|
+
|
737
842
|
unless uri.user or uri.password then
|
738
843
|
uri.user = escape ENV['http_proxy_user'] || ENV['HTTP_PROXY_USER']
|
739
844
|
uri.password = escape ENV['http_proxy_pass'] || ENV['HTTP_PROXY_PASS']
|
@@ -742,6 +847,21 @@ class Net::HTTP::Persistent
|
|
742
847
|
uri
|
743
848
|
end
|
744
849
|
|
850
|
+
##
|
851
|
+
# Returns true when proxy should by bypassed for host.
|
852
|
+
|
853
|
+
def proxy_bypass? host, port
|
854
|
+
host = host.downcase
|
855
|
+
host_port = [host, port].join ':'
|
856
|
+
|
857
|
+
@no_proxy.each do |name|
|
858
|
+
return true if host[-name.length, name.length] == name or
|
859
|
+
host_port[-name.length, name.length] == name
|
860
|
+
end
|
861
|
+
|
862
|
+
false
|
863
|
+
end
|
864
|
+
|
745
865
|
##
|
746
866
|
# Forces reconnection of HTTP connections.
|
747
867
|
|
@@ -765,7 +885,7 @@ class Net::HTTP::Persistent
|
|
765
885
|
|
766
886
|
finish connection
|
767
887
|
|
768
|
-
connection
|
888
|
+
start connection
|
769
889
|
rescue Errno::ECONNREFUSED
|
770
890
|
raise Error, "connection refused: #{connection.address}:#{connection.port}"
|
771
891
|
rescue Errno::EHOSTDOWN
|
@@ -4,8 +4,19 @@ require 'net/http/persistent'
|
|
4
4
|
require 'openssl'
|
5
5
|
require 'stringio'
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
module Net::HTTP::Persistent::TestConnect
|
8
|
+
def self.included mod
|
9
|
+
mod.send :alias_method, :orig_connect, :connect
|
10
|
+
|
11
|
+
def mod.use_connect which
|
12
|
+
self.send :remove_method, :connect
|
13
|
+
self.send :alias_method, :connect, which
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def host_down_connect
|
18
|
+
raise Errno::EHOSTDOWN
|
19
|
+
end
|
9
20
|
|
10
21
|
def test_connect
|
11
22
|
unless use_ssl? then
|
@@ -30,16 +41,30 @@ class Net::HTTP::Persistent::SSLReuse
|
|
30
41
|
@socket = Net::BufferedIO.new s
|
31
42
|
end
|
32
43
|
|
33
|
-
def
|
34
|
-
|
35
|
-
self.send :alias_method, :connect, which
|
44
|
+
def refused_connect
|
45
|
+
raise Errno::ECONNREFUSED
|
36
46
|
end
|
37
47
|
end
|
38
48
|
|
49
|
+
class Net::HTTP
|
50
|
+
include Net::HTTP::Persistent::TestConnect
|
51
|
+
end
|
52
|
+
|
53
|
+
class Net::HTTP::Persistent::SSLReuse
|
54
|
+
include Net::HTTP::Persistent::TestConnect
|
55
|
+
end
|
56
|
+
|
39
57
|
class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
40
58
|
|
41
59
|
def setup
|
60
|
+
@http_class = if RUBY_VERSION > '2.0' then
|
61
|
+
Net::HTTP
|
62
|
+
else
|
63
|
+
Net::HTTP::Persistent::SSLReuse
|
64
|
+
end
|
65
|
+
|
42
66
|
@http = Net::HTTP::Persistent.new
|
67
|
+
|
43
68
|
@uri = URI.parse 'http://example.com/path'
|
44
69
|
|
45
70
|
ENV.delete 'http_proxy'
|
@@ -48,7 +73,10 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
48
73
|
ENV.delete 'HTTP_PROXY_USER'
|
49
74
|
ENV.delete 'http_proxy_pass'
|
50
75
|
ENV.delete 'HTTP_PROXY_PASS'
|
76
|
+
ENV.delete 'no_proxy'
|
77
|
+
ENV.delete 'NO_PROXY'
|
51
78
|
|
79
|
+
Net::HTTP.use_connect :test_connect
|
52
80
|
Net::HTTP::Persistent::SSLReuse.use_connect :test_connect
|
53
81
|
end
|
54
82
|
|
@@ -57,12 +85,14 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
57
85
|
Thread.current[key] = nil
|
58
86
|
end
|
59
87
|
|
88
|
+
Net::HTTP.use_connect :orig_connect
|
60
89
|
Net::HTTP::Persistent::SSLReuse.use_connect :orig_connect
|
61
90
|
end
|
62
91
|
|
63
92
|
class BasicConnection
|
64
|
-
attr_accessor :started, :finished, :address, :port
|
65
|
-
|
93
|
+
attr_accessor :started, :finished, :address, :port,
|
94
|
+
:read_timeout, :open_timeout
|
95
|
+
attr_reader :req, :debug_output
|
66
96
|
def initialize
|
67
97
|
@started, @finished = 0, 0
|
68
98
|
@address, @port = 'example.com', 80
|
@@ -80,6 +110,9 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
80
110
|
def reset?
|
81
111
|
@started == @finished + 1
|
82
112
|
end
|
113
|
+
def set_debug_output io
|
114
|
+
@debug_output = io
|
115
|
+
end
|
83
116
|
def start
|
84
117
|
@started += 1
|
85
118
|
io = Object.new
|
@@ -142,6 +175,8 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
142
175
|
def test_initialize
|
143
176
|
assert_nil @http.proxy_uri
|
144
177
|
|
178
|
+
assert_empty @http.no_proxy
|
179
|
+
|
145
180
|
ssl_session_exists = OpenSSL::SSL.const_defined? :Session
|
146
181
|
|
147
182
|
assert_equal ssl_session_exists, @http.reuse_ssl_sessions
|
@@ -201,7 +236,7 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
201
236
|
@http.read_timeout = 321
|
202
237
|
c = @http.connection_for @uri
|
203
238
|
|
204
|
-
assert_kind_of
|
239
|
+
assert_kind_of @http_class, c
|
205
240
|
|
206
241
|
assert c.started?
|
207
242
|
refute c.proxy?
|
@@ -211,15 +246,6 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
211
246
|
|
212
247
|
assert_includes conns[0].keys, 'example.com:80'
|
213
248
|
assert_same c, conns[0]['example.com:80']
|
214
|
-
|
215
|
-
socket = c.instance_variable_get :@socket
|
216
|
-
expected = if Socket.const_defined? :TCP_NODELAY then
|
217
|
-
[[Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1]]
|
218
|
-
else
|
219
|
-
[]
|
220
|
-
end
|
221
|
-
|
222
|
-
assert_equal expected, socket.io.instance_variable_get(:@setsockopts)
|
223
249
|
end
|
224
250
|
|
225
251
|
def test_connection_for_cached
|
@@ -227,10 +253,14 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
227
253
|
cached.start
|
228
254
|
conns[0]['example.com:80'] = cached
|
229
255
|
|
256
|
+
@http.read_timeout = 5
|
257
|
+
|
230
258
|
c = @http.connection_for @uri
|
231
259
|
|
232
260
|
assert c.started?
|
233
261
|
|
262
|
+
assert_equal 5, c.read_timeout
|
263
|
+
|
234
264
|
assert_same cached, c
|
235
265
|
end
|
236
266
|
|
@@ -324,6 +354,17 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
324
354
|
'connection not reset due to timeout'
|
325
355
|
end
|
326
356
|
|
357
|
+
def test_connection_for_refused
|
358
|
+
Net::HTTP.use_connect :refused_connect
|
359
|
+
Net::HTTP::Persistent::SSLReuse.use_connect :refused_connect
|
360
|
+
|
361
|
+
e = assert_raises Net::HTTP::Persistent::Error do
|
362
|
+
@http.connection_for @uri
|
363
|
+
end
|
364
|
+
|
365
|
+
assert_equal 'connection refused: example.com:80', e.message
|
366
|
+
end
|
367
|
+
|
327
368
|
def test_connection_for_finished_ssl
|
328
369
|
uri = URI.parse 'https://example.com/path'
|
329
370
|
c = @http.connection_for uri
|
@@ -350,7 +391,7 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
350
391
|
@http.connection_for @uri
|
351
392
|
end
|
352
393
|
|
353
|
-
|
394
|
+
assert_equal 'host down: example.com:80', e.message
|
354
395
|
end
|
355
396
|
|
356
397
|
def test_connection_for_http_class_with_fakeweb
|
@@ -373,6 +414,16 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
373
414
|
end
|
374
415
|
end
|
375
416
|
|
417
|
+
def test_connection_for_http_class_with_artifice
|
418
|
+
Object.send :const_set, :Artifice, nil
|
419
|
+
c = @http.connection_for @uri
|
420
|
+
assert_instance_of Net::HTTP, c
|
421
|
+
ensure
|
422
|
+
if Object.const_defined?(:Artifice) then
|
423
|
+
Object.send :remove_const, :Artifice
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
376
427
|
def test_connection_for_name
|
377
428
|
http = Net::HTTP::Persistent.new 'name'
|
378
429
|
uri = URI.parse 'http://example/'
|
@@ -410,6 +461,57 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
410
461
|
assert_same c, conns[1]['example.com:80:proxy.example:80:johndoe:muffins']
|
411
462
|
end
|
412
463
|
|
464
|
+
def test_connection_for_proxy_host_down
|
465
|
+
Net::HTTP.use_connect :host_down_connect
|
466
|
+
Net::HTTP::Persistent::SSLReuse.use_connect :host_down_connect
|
467
|
+
|
468
|
+
uri = URI.parse 'http://proxy.example'
|
469
|
+
uri.user = 'johndoe'
|
470
|
+
uri.password = 'muffins'
|
471
|
+
|
472
|
+
http = Net::HTTP::Persistent.new nil, uri
|
473
|
+
|
474
|
+
e = assert_raises Net::HTTP::Persistent::Error do
|
475
|
+
http.connection_for @uri
|
476
|
+
end
|
477
|
+
|
478
|
+
assert_equal 'host down: proxy.example:80', e.message
|
479
|
+
end
|
480
|
+
|
481
|
+
def test_connection_for_proxy_refused
|
482
|
+
Net::HTTP.use_connect :refused_connect
|
483
|
+
Net::HTTP::Persistent::SSLReuse.use_connect :refused_connect
|
484
|
+
|
485
|
+
uri = URI.parse 'http://proxy.example'
|
486
|
+
uri.user = 'johndoe'
|
487
|
+
uri.password = 'muffins'
|
488
|
+
|
489
|
+
http = Net::HTTP::Persistent.new nil, uri
|
490
|
+
|
491
|
+
e = assert_raises Net::HTTP::Persistent::Error do
|
492
|
+
http.connection_for @uri
|
493
|
+
end
|
494
|
+
|
495
|
+
assert_equal 'connection refused: proxy.example:80', e.message
|
496
|
+
end
|
497
|
+
|
498
|
+
def test_connection_for_no_proxy
|
499
|
+
uri = URI.parse 'http://proxy.example'
|
500
|
+
uri.user = 'johndoe'
|
501
|
+
uri.password = 'muffins'
|
502
|
+
uri.query = 'no_proxy=example.com'
|
503
|
+
|
504
|
+
http = Net::HTTP::Persistent.new nil, uri
|
505
|
+
|
506
|
+
c = http.connection_for @uri
|
507
|
+
|
508
|
+
assert c.started?
|
509
|
+
refute c.proxy?
|
510
|
+
|
511
|
+
assert_includes conns[1].keys, 'example.com:80'
|
512
|
+
assert_same c, conns[1]['example.com:80']
|
513
|
+
end
|
514
|
+
|
413
515
|
def test_connection_for_refused
|
414
516
|
cached = basic_connection
|
415
517
|
def cached.start; raise Errno::ECONNREFUSED end
|
@@ -423,20 +525,6 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
423
525
|
assert_match %r%connection refused%, e.message
|
424
526
|
end
|
425
527
|
|
426
|
-
def test_connection_for_socket_options
|
427
|
-
@http.socket_options << [Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1]
|
428
|
-
c = @http.connection_for @uri
|
429
|
-
|
430
|
-
socket = c.instance_variable_get :@socket
|
431
|
-
|
432
|
-
expected = []
|
433
|
-
expected << [Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1] if
|
434
|
-
Socket.const_defined? :TCP_NODELAY
|
435
|
-
expected << [Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1]
|
436
|
-
|
437
|
-
assert_equal expected, socket.io.instance_variable_get(:@setsockopts)
|
438
|
-
end
|
439
|
-
|
440
528
|
def test_connection_for_ssl
|
441
529
|
uri = URI.parse 'https://example.com/path'
|
442
530
|
c = @http.connection_for uri
|
@@ -642,12 +730,14 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
642
730
|
ENV['HTTP_PROXY'] = 'proxy.example'
|
643
731
|
ENV['HTTP_PROXY_USER'] = 'johndoe'
|
644
732
|
ENV['HTTP_PROXY_PASS'] = 'muffins'
|
733
|
+
ENV['NO_PROXY'] = 'localhost,example.com'
|
645
734
|
|
646
735
|
uri = @http.proxy_from_env
|
647
736
|
|
648
737
|
expected = URI.parse 'http://proxy.example'
|
649
738
|
expected.user = 'johndoe'
|
650
739
|
expected.password = 'muffins'
|
740
|
+
expected.query = 'no_proxy=localhost%2Cexample.com'
|
651
741
|
|
652
742
|
assert_equal expected, uri
|
653
743
|
end
|
@@ -656,12 +746,14 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
656
746
|
ENV['http_proxy'] = 'proxy.example'
|
657
747
|
ENV['http_proxy_user'] = 'johndoe'
|
658
748
|
ENV['http_proxy_pass'] = 'muffins'
|
749
|
+
ENV['no_proxy'] = 'localhost,example.com'
|
659
750
|
|
660
751
|
uri = @http.proxy_from_env
|
661
752
|
|
662
753
|
expected = URI.parse 'http://proxy.example'
|
663
754
|
expected.user = 'johndoe'
|
664
755
|
expected.password = 'muffins'
|
756
|
+
expected.query = 'no_proxy=localhost%2Cexample.com'
|
665
757
|
|
666
758
|
assert_equal expected, uri
|
667
759
|
end
|
@@ -678,6 +770,66 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
678
770
|
assert_nil uri
|
679
771
|
end
|
680
772
|
|
773
|
+
def test_proxy_from_env_no_proxy_star
|
774
|
+
uri = @http.proxy_from_env
|
775
|
+
|
776
|
+
assert_nil uri
|
777
|
+
|
778
|
+
ENV['HTTP_PROXY'] = 'proxy.example'
|
779
|
+
ENV['NO_PROXY'] = '*'
|
780
|
+
|
781
|
+
uri = @http.proxy_from_env
|
782
|
+
|
783
|
+
assert_nil uri
|
784
|
+
end
|
785
|
+
|
786
|
+
def test_proxy_bypass
|
787
|
+
ENV['HTTP_PROXY'] = 'proxy.example'
|
788
|
+
ENV['NO_PROXY'] = 'localhost,example.com:80'
|
789
|
+
|
790
|
+
@http.proxy = :ENV
|
791
|
+
|
792
|
+
assert @http.proxy_bypass? 'localhost', 80
|
793
|
+
assert @http.proxy_bypass? 'localhost', 443
|
794
|
+
assert @http.proxy_bypass? 'LOCALHOST', 80
|
795
|
+
assert @http.proxy_bypass? 'example.com', 80
|
796
|
+
refute @http.proxy_bypass? 'example.com', 443
|
797
|
+
assert @http.proxy_bypass? 'www.example.com', 80
|
798
|
+
refute @http.proxy_bypass? 'www.example.com', 443
|
799
|
+
assert @http.proxy_bypass? 'endingexample.com', 80
|
800
|
+
refute @http.proxy_bypass? 'example.org', 80
|
801
|
+
end
|
802
|
+
|
803
|
+
def test_proxy_bypass_space
|
804
|
+
ENV['HTTP_PROXY'] = 'proxy.example'
|
805
|
+
ENV['NO_PROXY'] = 'localhost, example.com'
|
806
|
+
|
807
|
+
@http.proxy = :ENV
|
808
|
+
|
809
|
+
assert @http.proxy_bypass? 'example.com', 80
|
810
|
+
refute @http.proxy_bypass? 'example.org', 80
|
811
|
+
end
|
812
|
+
|
813
|
+
def test_proxy_bypass_trailing
|
814
|
+
ENV['HTTP_PROXY'] = 'proxy.example'
|
815
|
+
ENV['NO_PROXY'] = 'localhost,example.com,'
|
816
|
+
|
817
|
+
@http.proxy = :ENV
|
818
|
+
|
819
|
+
assert @http.proxy_bypass? 'example.com', 80
|
820
|
+
refute @http.proxy_bypass? 'example.org', 80
|
821
|
+
end
|
822
|
+
|
823
|
+
def test_proxy_bypass_double_comma
|
824
|
+
ENV['HTTP_PROXY'] = 'proxy.example'
|
825
|
+
ENV['NO_PROXY'] = 'localhost,,example.com'
|
826
|
+
|
827
|
+
@http.proxy = :ENV
|
828
|
+
|
829
|
+
assert @http.proxy_bypass? 'example.com', 80
|
830
|
+
refute @http.proxy_bypass? 'example.org', 80
|
831
|
+
end
|
832
|
+
|
681
833
|
def test_reconnect
|
682
834
|
result = @http.reconnect
|
683
835
|
|
@@ -1113,13 +1265,10 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
1113
1265
|
end
|
1114
1266
|
|
1115
1267
|
def test_shutdown_no_connections
|
1116
|
-
conns
|
1117
|
-
ssl_conns
|
1118
|
-
|
1119
1268
|
@http.shutdown
|
1120
1269
|
|
1121
|
-
|
1122
|
-
|
1270
|
+
assert_nil Thread.current[@http.generation_key]
|
1271
|
+
assert_nil Thread.current[@http.ssl_generation_key]
|
1123
1272
|
|
1124
1273
|
assert_nil Thread.current[@http.request_key]
|
1125
1274
|
assert_nil Thread.current[@http.timeout_key]
|
@@ -1303,6 +1452,28 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
1303
1452
|
assert_equal 1, @http.ssl_generation
|
1304
1453
|
end if RUBY_VERSION > '1.9'
|
1305
1454
|
|
1455
|
+
def test_start
|
1456
|
+
c = basic_connection
|
1457
|
+
|
1458
|
+
@http.socket_options << [Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1]
|
1459
|
+
@http.debug_output = $stderr
|
1460
|
+
@http.open_timeout = 6
|
1461
|
+
|
1462
|
+
@http.start c
|
1463
|
+
|
1464
|
+
assert_equal $stderr, c.debug_output
|
1465
|
+
assert_equal 6, c.open_timeout
|
1466
|
+
|
1467
|
+
socket = c.instance_variable_get :@socket
|
1468
|
+
|
1469
|
+
expected = []
|
1470
|
+
expected << [Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1] if
|
1471
|
+
Socket.const_defined? :TCP_NODELAY
|
1472
|
+
expected << [Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1]
|
1473
|
+
|
1474
|
+
assert_equal expected, socket.io.instance_variable_get(:@setsockopts)
|
1475
|
+
end
|
1476
|
+
|
1306
1477
|
def test_verify_callback_equals
|
1307
1478
|
@http.verify_callback = :verify_callback
|
1308
1479
|
|
@@ -19,9 +19,9 @@ class TestNetHttpPersistentSSLReuse < MiniTest::Unit::TestCase
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def setup
|
22
|
-
@name = OpenSSL::X509::Name.parse 'CN=localhost'
|
22
|
+
@name = OpenSSL::X509::Name.parse 'CN=localhost/DC=localdomain'
|
23
23
|
|
24
|
-
@key = OpenSSL::PKey::RSA.new
|
24
|
+
@key = OpenSSL::PKey::RSA.new 1024
|
25
25
|
|
26
26
|
@cert = OpenSSL::X509::Certificate.new
|
27
27
|
@cert.version = 2
|
@@ -30,6 +30,9 @@ class TestNetHttpPersistentSSLReuse < MiniTest::Unit::TestCase
|
|
30
30
|
@cert.not_after = Time.now + 300
|
31
31
|
@cert.public_key = @key.public_key
|
32
32
|
@cert.subject = @name
|
33
|
+
@cert.issuer = @name
|
34
|
+
|
35
|
+
@cert.sign @key, OpenSSL::Digest::SHA1.new
|
33
36
|
|
34
37
|
@host = 'localhost'
|
35
38
|
@port = 10082
|
@@ -73,12 +76,14 @@ class TestNetHttpPersistentSSLReuse < MiniTest::Unit::TestCase
|
|
73
76
|
end
|
74
77
|
|
75
78
|
def test_ssl_connection_reuse
|
79
|
+
store = OpenSSL::X509::Store.new
|
80
|
+
store.add_cert @cert
|
81
|
+
|
76
82
|
@http = Net::HTTP::Persistent::SSLReuse.new @host, @port
|
83
|
+
@http.cert_store = store
|
84
|
+
@http.ssl_version = :SSLv3 if @http.respond_to? :ssl_version=
|
77
85
|
@http.use_ssl = true
|
78
86
|
@http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
79
|
-
@http.verify_callback = proc do |_, store_ctx|
|
80
|
-
store_ctx.current_cert.to_der == @cert.to_der
|
81
|
-
end
|
82
87
|
|
83
88
|
@http.start
|
84
89
|
@http.get '/'
|
metadata
CHANGED
@@ -1,110 +1,121 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: net-http-persistent
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '2.8'
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 2
|
8
|
-
- 7
|
9
|
-
version: "2.7"
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- Eric Hodel
|
13
9
|
autorequire:
|
14
10
|
bindir: bin
|
15
|
-
cert_chain:
|
16
|
-
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
11
|
+
cert_chain:
|
12
|
+
- !binary |-
|
13
|
+
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURlRENDQW1DZ0F3SUJB
|
14
|
+
Z0lCQVRBTkJna3Foa2lHOXcwQkFRVUZBREJCTVJBd0RnWURWUVFEREFka2Nt
|
15
|
+
SnkKWVdsdU1SZ3dGZ1lLQ1pJbWlaUHlMR1FCR1JZSWMyVm5iV1Z1ZERjeEV6
|
16
|
+
QVJCZ29Ka2lhSmsvSXNaQUVaRmdOdQpaWFF3SGhjTk1USXdNakk0TVRjMU5E
|
17
|
+
STFXaGNOTVRNd01qSTNNVGMxTkRJMVdqQkJNUkF3RGdZRFZRUUREQWRrCmNt
|
18
|
+
SnlZV2x1TVJnd0ZnWUtDWkltaVpQeUxHUUJHUllJYzJWbmJXVnVkRGN4RXpB
|
19
|
+
UkJnb0praWFKay9Jc1pBRVoKRmdOdVpYUXdnZ0VpTUEwR0NTcUdTSWIzRFFF
|
20
|
+
QkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDYmJnTHJHTEdJREU3NgpMVi9jdnhk
|
21
|
+
RXpDdVl1UzNvRzlQclNabnVEd2V5U1VmZHAvc28wY0RxK2o4YnF5Nk96WlN3
|
22
|
+
MDdnZGp3Rk1TZDZKClU1ZGRaQ1Z5d241bm5BUStVaTdqTVc1NENZdDUvSDZm
|
23
|
+
MlVTNlUwaFFPakpSNmNwZml5bWd4R2RmeVRpVmN2VG0KR2ovb2tXclFsME5q
|
24
|
+
WU9ZQnBEaSs5UFBtYUgyUm1MSnUwZEIvTnlsc0RuVzVqNnlOMUJFSThNZkpS
|
25
|
+
UitIUktaWQptVXRnekJ3RjFWNEtJWlE4RXVMNkkvbkhWdTA3aTZJa3JwQWd4
|
26
|
+
cFhVZmRKUUppMG9aQXFYdXJBVjN5VHhrRndkCmc2MllyclcyNm1EZStwWkJ6
|
27
|
+
UjZicExFK1BtWEN6ejdVeFVxM0FFMGdQSGJpTVhpZTNFRkUwb3huc1UzbElk
|
28
|
+
dWgKc0NBTmlROEJBZ01CQUFHamV6QjVNQWtHQTFVZEV3UUNNQUF3Q3dZRFZS
|
29
|
+
MFBCQVFEQWdTd01CMEdBMVVkRGdRVwpCQlM1azRaNzVWU3BkTTBBY2xHMlV2
|
30
|
+
ekZBL1ZXNURBZkJnTlZIUkVFR0RBV2dSUmtjbUp5WVdsdVFITmxaMjFsCmJu
|
31
|
+
UTNMbTVsZERBZkJnTlZIUklFR0RBV2dSUmtjbUp5WVdsdVFITmxaMjFsYm5R
|
32
|
+
M0xtNWxkREFOQmdrcWhraUcKOXcwQkFRVUZBQU9DQVFFQVBlV3pGbnJjdkM2
|
33
|
+
ZVZ6ZGxobWpVdWIyczZxaWVCa29uZ0tSREhRejVNRWVRdjRMUwpTQVJub0hZ
|
34
|
+
K3VDQVZMLzF4R0FobXB6cVEzZkpHV0s5ZUJhY1cvZThFNUdGOXhRY1YzbUUx
|
35
|
+
YkEwV05haURsWDVqClUyYUkrWkdTYmxxdkhVQ3hLQkhSMXM3VU1Ic2J6MXNh
|
36
|
+
T21nZFJUeVB4MGp1SnM2OG9jYlVUZVlCTFd1OVY0S1AKemRHQUcySlhPMmdP
|
37
|
+
TmczYjR0WUR2cEJMYnJ5K0tPWDI3aUFKdWxVYUg5VGlUT1VMTDRJVEpWRnNL
|
38
|
+
MG1ZVnFtUgpROFRubzlTM2U0WEdHUDFaV2ZMclRXRUpiYXZGZmhHSHV0MmlN
|
39
|
+
UndmQzdzL1lJTEFITkFUb3BhSmRIOUROcGQxClU4MXpHSE1VQk92ei9WR1Q2
|
40
|
+
d0p3WUozZW1TMm5mQTJOT0hGZmdBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUt
|
41
|
+
LS0tLQo=
|
42
|
+
date: 2012-10-18 00:00:00.000000000 Z
|
43
|
+
dependencies:
|
44
|
+
- !ruby/object:Gem::Dependency
|
42
45
|
name: minitest
|
43
|
-
|
44
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
46
|
+
requirement: !ruby/object:Gem::Requirement
|
45
47
|
none: false
|
46
|
-
requirements:
|
48
|
+
requirements:
|
47
49
|
- - ~>
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
|
50
|
-
segments:
|
51
|
-
- 2
|
52
|
-
- 11
|
53
|
-
version: "2.11"
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '3.4'
|
54
52
|
type: :development
|
55
|
-
version_requirements: *id001
|
56
|
-
- !ruby/object:Gem::Dependency
|
57
|
-
name: rdoc
|
58
53
|
prerelease: false
|
59
|
-
|
54
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
55
|
none: false
|
61
|
-
requirements:
|
56
|
+
requirements:
|
62
57
|
- - ~>
|
63
|
-
- !ruby/object:Gem::Version
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '3.4'
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: rdoc
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ~>
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '3.10'
|
69
68
|
type: :development
|
70
|
-
version_requirements: *id002
|
71
|
-
- !ruby/object:Gem::Dependency
|
72
|
-
name: hoe
|
73
69
|
prerelease: false
|
74
|
-
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
75
71
|
none: false
|
76
|
-
requirements:
|
72
|
+
requirements:
|
77
73
|
- - ~>
|
78
|
-
- !ruby/object:Gem::Version
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.10'
|
76
|
+
- !ruby/object:Gem::Dependency
|
77
|
+
name: hoe
|
78
|
+
requirement: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ~>
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '3.0'
|
84
84
|
type: :development
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
85
|
+
prerelease: false
|
86
|
+
version_requirements: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ~>
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '3.0'
|
92
|
+
description: ! 'Manages persistent connections using Net::HTTP plus a speed fix for
|
93
|
+
Ruby 1.8.
|
94
|
+
|
95
|
+
It''s thread-safe too!
|
96
|
+
|
97
|
+
|
90
98
|
Using persistent HTTP connections can dramatically increase the speed of HTTP.
|
99
|
+
|
91
100
|
Creating a new HTTP connection for every request involves an extra TCP
|
101
|
+
|
92
102
|
round-trip and causes TCP congestion avoidance negotiation to start over.
|
93
|
-
|
103
|
+
|
104
|
+
|
94
105
|
Net::HTTP supports persistent connections with some API methods but does not
|
106
|
+
|
95
107
|
handle reconnection gracefully. Net::HTTP::Persistent supports reconnection
|
96
|
-
|
97
|
-
|
108
|
+
|
109
|
+
and retry according to RFC 2616.'
|
110
|
+
email:
|
98
111
|
- drbrain@segment7.net
|
99
112
|
executables: []
|
100
|
-
|
101
113
|
extensions: []
|
102
|
-
|
103
|
-
extra_rdoc_files:
|
114
|
+
extra_rdoc_files:
|
104
115
|
- History.txt
|
105
116
|
- Manifest.txt
|
106
117
|
- README.rdoc
|
107
|
-
files:
|
118
|
+
files:
|
108
119
|
- .autotest
|
109
120
|
- .gemtest
|
110
121
|
- History.txt
|
@@ -118,38 +129,31 @@ files:
|
|
118
129
|
- test/test_net_http_persistent_ssl_reuse.rb
|
119
130
|
homepage: http://docs.seattlerb.org/net-http-persistent
|
120
131
|
licenses: []
|
121
|
-
|
122
132
|
post_install_message:
|
123
|
-
rdoc_options:
|
133
|
+
rdoc_options:
|
124
134
|
- --main
|
125
135
|
- README.rdoc
|
126
|
-
require_paths:
|
136
|
+
require_paths:
|
127
137
|
- lib
|
128
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
138
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
129
139
|
none: false
|
130
|
-
requirements:
|
131
|
-
- -
|
132
|
-
- !ruby/object:Gem::Version
|
133
|
-
|
134
|
-
|
135
|
-
- 0
|
136
|
-
version: "0"
|
137
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
|
+
requirements:
|
141
|
+
- - ! '>='
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: '0'
|
144
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
145
|
none: false
|
139
|
-
requirements:
|
140
|
-
- -
|
141
|
-
- !ruby/object:Gem::Version
|
142
|
-
|
143
|
-
segments:
|
144
|
-
- 0
|
145
|
-
version: "0"
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
146
150
|
requirements: []
|
147
|
-
|
148
151
|
rubyforge_project: net-http-persistent
|
149
|
-
rubygems_version: 1.8.
|
152
|
+
rubygems_version: 1.8.24
|
150
153
|
signing_key:
|
151
154
|
specification_version: 3
|
152
|
-
summary: Manages persistent connections using Net::HTTP plus a speed fix for Ruby
|
153
|
-
|
155
|
+
summary: Manages persistent connections using Net::HTTP plus a speed fix for Ruby
|
156
|
+
1.8
|
157
|
+
test_files:
|
154
158
|
- test/test_net_http_persistent.rb
|
155
159
|
- test/test_net_http_persistent_ssl_reuse.rb
|
metadata.gz.sig
CHANGED
Binary file
|