net-http-persistent 4.0.5 → 4.0.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.
- checksums.yaml +4 -4
- data/History.txt +6 -0
- data/README.rdoc +1 -1
- data/lib/net/http/persistent/pool.rb +1 -1
- data/lib/net/http/persistent/timed_stack_multi.rb +12 -2
- data/lib/net/http/persistent.rb +65 -42
- data/test/test_net_http_persistent.rb +41 -2
- data/test/test_net_http_persistent_timed_stack_multi.rb +26 -7
- metadata +13 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3e1c40dff68b8e70cac3630ca6b19ff70679fe7462974c835bb8638ab2b5dd5b
|
|
4
|
+
data.tar.gz: 95185bc4624e14eaae5b31e65a7b8e474a07f621020a5096966ccfec200bf6f7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 32089ec62a29518f3d6b1e9f1a1a677b65b1cc3b937506a9e3f985455f8c924b0c37c80516e9adc23420f8d25932607c4975cc042ec217bbd5bed2c626c2a57b
|
|
7
|
+
data.tar.gz: 28fc74bc92b2f63f752dfc8a2e86971f76b3cb064fe3647949005f9f1d7fa41d48d26122dd6f4c9d137d5255cd1b3dedc09ed779c937d12597fb9baba6c325e7
|
data/History.txt
CHANGED
data/README.rdoc
CHANGED
|
@@ -4,7 +4,7 @@ class Net::HTTP::Persistent::Pool < ConnectionPool # :nodoc:
|
|
|
4
4
|
attr_reader :key # :nodoc:
|
|
5
5
|
|
|
6
6
|
def initialize(options = {}, &block)
|
|
7
|
-
super
|
|
7
|
+
super(**options, &block)
|
|
8
8
|
|
|
9
9
|
@available = Net::HTTP::Persistent::TimedStackMulti.new(@size, &block)
|
|
10
10
|
@key = "current-#{@available.object_id}"
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
class Net::HTTP::Persistent::TimedStackMulti < ConnectionPool::TimedStack # :nodoc:
|
|
2
2
|
|
|
3
|
+
##
|
|
4
|
+
# Detects if ConnectionPool 3.0+ is being used (needed for TimedStack subclass compatibility)
|
|
5
|
+
|
|
6
|
+
CP_USES_KEYWORD_ARGS = Gem::Version.new(ConnectionPool::VERSION) >= Gem::Version.new('3.0.0') # :nodoc:
|
|
7
|
+
|
|
3
8
|
##
|
|
4
9
|
# Returns a new hash that has arrays for keys
|
|
5
10
|
#
|
|
@@ -11,7 +16,11 @@ class Net::HTTP::Persistent::TimedStackMulti < ConnectionPool::TimedStack # :nod
|
|
|
11
16
|
end
|
|
12
17
|
|
|
13
18
|
def initialize(size = 0, &block)
|
|
14
|
-
|
|
19
|
+
if CP_USES_KEYWORD_ARGS
|
|
20
|
+
super(size: size, &block)
|
|
21
|
+
else
|
|
22
|
+
super(size, &block)
|
|
23
|
+
end
|
|
15
24
|
|
|
16
25
|
@enqueued = 0
|
|
17
26
|
@ques = self.class.hash_of_arrays
|
|
@@ -63,7 +72,8 @@ class Net::HTTP::Persistent::TimedStackMulti < ConnectionPool::TimedStack # :nod
|
|
|
63
72
|
if @created >= @max && @enqueued >= 1
|
|
64
73
|
oldest, = @lru.first
|
|
65
74
|
@lru.delete oldest
|
|
66
|
-
@ques[oldest].pop
|
|
75
|
+
connection = @ques[oldest].pop
|
|
76
|
+
connection.close if connection.respond_to?(:close)
|
|
67
77
|
|
|
68
78
|
@created -= 1
|
|
69
79
|
end
|
data/lib/net/http/persistent.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require 'net/http'
|
|
2
2
|
require 'uri'
|
|
3
|
-
require 'cgi'
|
|
3
|
+
require 'cgi/escape'
|
|
4
|
+
require 'cgi/util' unless defined?(CGI::EscapeExt)
|
|
4
5
|
require 'connection_pool'
|
|
5
6
|
|
|
6
7
|
begin
|
|
@@ -47,9 +48,8 @@ autoload :OpenSSL, 'openssl'
|
|
|
47
48
|
# # perform the POST, the URI is always required
|
|
48
49
|
# response http.request post_uri, post
|
|
49
50
|
#
|
|
50
|
-
# Note that for GET, HEAD and other requests that do not have a body
|
|
51
|
-
#
|
|
52
|
-
# params which are sent in the body for other requests.
|
|
51
|
+
# ⚠ Note that for GET, HEAD and other requests that do not have a body,
|
|
52
|
+
# it uses URI#request_uri as default to send query params
|
|
53
53
|
#
|
|
54
54
|
# == TLS/SSL
|
|
55
55
|
#
|
|
@@ -182,7 +182,7 @@ class Net::HTTP::Persistent
|
|
|
182
182
|
##
|
|
183
183
|
# The version of Net::HTTP::Persistent you are using
|
|
184
184
|
|
|
185
|
-
VERSION = '4.0.
|
|
185
|
+
VERSION = '4.0.8'
|
|
186
186
|
|
|
187
187
|
##
|
|
188
188
|
# Error class for errors raised by Net::HTTP::Persistent. Various
|
|
@@ -477,6 +477,13 @@ class Net::HTTP::Persistent
|
|
|
477
477
|
|
|
478
478
|
attr_reader :verify_hostname
|
|
479
479
|
|
|
480
|
+
|
|
481
|
+
##
|
|
482
|
+
# Sets whether to ignore end-of-file when reading a response body
|
|
483
|
+
# with Content-Length headers.
|
|
484
|
+
|
|
485
|
+
attr_accessor :ignore_eof
|
|
486
|
+
|
|
480
487
|
##
|
|
481
488
|
# Creates a new Net::HTTP::Persistent.
|
|
482
489
|
#
|
|
@@ -516,6 +523,7 @@ class Net::HTTP::Persistent
|
|
|
516
523
|
@max_retries = 1
|
|
517
524
|
@socket_options = []
|
|
518
525
|
@ssl_generation = 0 # incremented when SSL session variables change
|
|
526
|
+
@ignore_eof = nil
|
|
519
527
|
|
|
520
528
|
@socket_options << [Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1] if
|
|
521
529
|
Socket.const_defined? :TCP_NODELAY
|
|
@@ -631,47 +639,50 @@ class Net::HTTP::Persistent
|
|
|
631
639
|
|
|
632
640
|
connection = @pool.checkout net_http_args
|
|
633
641
|
|
|
634
|
-
|
|
642
|
+
begin
|
|
643
|
+
http = connection.http
|
|
635
644
|
|
|
636
|
-
|
|
637
|
-
|
|
645
|
+
connection.ressl @ssl_generation if
|
|
646
|
+
connection.ssl_generation != @ssl_generation
|
|
638
647
|
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
648
|
+
if not http.started? then
|
|
649
|
+
ssl http if use_ssl
|
|
650
|
+
start http
|
|
651
|
+
elsif expired? connection then
|
|
652
|
+
reset connection
|
|
653
|
+
end
|
|
645
654
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
655
|
+
http.ignore_eof = @ignore_eof if @ignore_eof
|
|
656
|
+
http.keep_alive_timeout = @idle_timeout if @idle_timeout
|
|
657
|
+
http.max_retries = @max_retries if http.respond_to?(:max_retries=)
|
|
658
|
+
http.read_timeout = @read_timeout if @read_timeout
|
|
659
|
+
http.write_timeout = @write_timeout if
|
|
660
|
+
@write_timeout && http.respond_to?(:write_timeout=)
|
|
661
|
+
|
|
662
|
+
return yield connection
|
|
663
|
+
rescue Errno::ECONNREFUSED
|
|
664
|
+
if http.proxy?
|
|
665
|
+
address = http.proxy_address
|
|
666
|
+
port = http.proxy_port
|
|
667
|
+
else
|
|
668
|
+
address = http.address
|
|
669
|
+
port = http.port
|
|
670
|
+
end
|
|
651
671
|
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
672
|
+
raise Error, "connection refused: #{address}:#{port}"
|
|
673
|
+
rescue Errno::EHOSTDOWN
|
|
674
|
+
if http.proxy?
|
|
675
|
+
address = http.proxy_address
|
|
676
|
+
port = http.proxy_port
|
|
677
|
+
else
|
|
678
|
+
address = http.address
|
|
679
|
+
port = http.port
|
|
680
|
+
end
|
|
661
681
|
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
address = http.proxy_address
|
|
666
|
-
port = http.proxy_port
|
|
667
|
-
else
|
|
668
|
-
address = http.address
|
|
669
|
-
port = http.port
|
|
682
|
+
raise Error, "host down: #{address}:#{port}"
|
|
683
|
+
ensure
|
|
684
|
+
@pool.checkin net_http_args
|
|
670
685
|
end
|
|
671
|
-
|
|
672
|
-
raise Error, "host down: #{address}:#{port}"
|
|
673
|
-
ensure
|
|
674
|
-
@pool.checkin net_http_args
|
|
675
686
|
end
|
|
676
687
|
|
|
677
688
|
##
|
|
@@ -825,7 +836,7 @@ class Net::HTTP::Persistent
|
|
|
825
836
|
@proxy_connection_id = [nil, *@proxy_args].join ':'
|
|
826
837
|
|
|
827
838
|
if @proxy_uri.query then
|
|
828
|
-
@no_proxy =
|
|
839
|
+
@no_proxy = URI.decode_www_form(@proxy_uri.query).filter_map { |k, v| v if k == 'no_proxy' }.join(',').downcase.split(',').map { |x| x.strip }.reject { |x| x.empty? }
|
|
829
840
|
end
|
|
830
841
|
end
|
|
831
842
|
|
|
@@ -996,7 +1007,8 @@ class Net::HTTP::Persistent
|
|
|
996
1007
|
end
|
|
997
1008
|
|
|
998
1009
|
##
|
|
999
|
-
# Shuts down all connections
|
|
1010
|
+
# Shuts down all connections. Attempting to checkout a connection after
|
|
1011
|
+
# shutdown will raise an error.
|
|
1000
1012
|
#
|
|
1001
1013
|
# *NOTE*: Calling shutdown for can be dangerous!
|
|
1002
1014
|
#
|
|
@@ -1007,6 +1019,17 @@ class Net::HTTP::Persistent
|
|
|
1007
1019
|
@pool.shutdown { |http| http.finish }
|
|
1008
1020
|
end
|
|
1009
1021
|
|
|
1022
|
+
##
|
|
1023
|
+
# Discard all existing connections. Subsequent checkouts will create
|
|
1024
|
+
# new connections as needed.
|
|
1025
|
+
#
|
|
1026
|
+
# If any thread is still using a connection it may cause an error! Call
|
|
1027
|
+
# #reload when you are completely done making requests!
|
|
1028
|
+
|
|
1029
|
+
def reload
|
|
1030
|
+
@pool.reload { |http| http.finish }
|
|
1031
|
+
end
|
|
1032
|
+
|
|
1010
1033
|
##
|
|
1011
1034
|
# Enables SSL on +connection+
|
|
1012
1035
|
|
|
@@ -80,7 +80,7 @@ class TestNetHttpPersistent < Minitest::Test
|
|
|
80
80
|
:read_timeout, :open_timeout, :keep_alive_timeout
|
|
81
81
|
attr_accessor :ciphers, :ssl_timeout, :ssl_version, :min_version,
|
|
82
82
|
:max_version, :verify_depth, :verify_mode, :cert_store,
|
|
83
|
-
:ca_file, :ca_path, :cert, :key
|
|
83
|
+
:ca_file, :ca_path, :cert, :key, :ignore_eof
|
|
84
84
|
attr_reader :req, :debug_output
|
|
85
85
|
def initialize
|
|
86
86
|
@started, @finished = 0, 0
|
|
@@ -280,6 +280,16 @@ class TestNetHttpPersistent < Minitest::Test
|
|
|
280
280
|
assert_same used, stored
|
|
281
281
|
end
|
|
282
282
|
|
|
283
|
+
def test_connection_for_exhaustion
|
|
284
|
+
@http = Net::HTTP::Persistent.new pool_size: 0
|
|
285
|
+
|
|
286
|
+
assert_raises Timeout::Error do
|
|
287
|
+
@http.connection_for @uri do |c|
|
|
288
|
+
assert_same nil, c
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
|
|
283
293
|
def test_connection_for_cached
|
|
284
294
|
cached = basic_connection
|
|
285
295
|
cached.http.start
|
|
@@ -993,7 +1003,7 @@ class TestNetHttpPersistent < Minitest::Test
|
|
|
993
1003
|
|
|
994
1004
|
# There's some roounding issue on jruby preventing this from passing
|
|
995
1005
|
unless RUBY_PLATFORM == "java"
|
|
996
|
-
assert_in_delta Time.now, c.last_use
|
|
1006
|
+
assert_in_delta Time.now, c.last_use, 0.003
|
|
997
1007
|
end
|
|
998
1008
|
|
|
999
1009
|
assert_equal 1, c.requests
|
|
@@ -1255,6 +1265,17 @@ class TestNetHttpPersistent < Minitest::Test
|
|
|
1255
1265
|
refute c2.http.finished?, 'present generation connection must not be finished'
|
|
1256
1266
|
end
|
|
1257
1267
|
|
|
1268
|
+
def test_reload
|
|
1269
|
+
c = connection
|
|
1270
|
+
|
|
1271
|
+
@http.reload
|
|
1272
|
+
|
|
1273
|
+
c2 = connection
|
|
1274
|
+
|
|
1275
|
+
assert c.http.finished?, 'last-generation connection must be finished'
|
|
1276
|
+
refute c2.http.finished?, 'present generation connection must not be finished'
|
|
1277
|
+
end
|
|
1278
|
+
|
|
1258
1279
|
def test_ssl
|
|
1259
1280
|
skip 'OpenSSL is missing' unless HAVE_OPENSSL
|
|
1260
1281
|
|
|
@@ -1509,4 +1530,22 @@ class TestNetHttpPersistent < Minitest::Test
|
|
|
1509
1530
|
connection.close
|
|
1510
1531
|
end
|
|
1511
1532
|
end
|
|
1533
|
+
|
|
1534
|
+
def test_ignore_eof
|
|
1535
|
+
@http.ignore_eof = true
|
|
1536
|
+
|
|
1537
|
+
connection
|
|
1538
|
+
|
|
1539
|
+
@http.connection_for @uri do |c|
|
|
1540
|
+
assert c.http.ignore_eof
|
|
1541
|
+
end
|
|
1542
|
+
|
|
1543
|
+
@http.ignore_eof = false
|
|
1544
|
+
|
|
1545
|
+
connection
|
|
1546
|
+
|
|
1547
|
+
@http.connection_for @uri do |c|
|
|
1548
|
+
assert !c.http.ignore_eof
|
|
1549
|
+
end
|
|
1550
|
+
end
|
|
1512
1551
|
end
|
|
@@ -4,10 +4,15 @@ require 'net/http/persistent'
|
|
|
4
4
|
class TestNetHttpPersistentTimedStackMulti < Minitest::Test
|
|
5
5
|
|
|
6
6
|
class Connection
|
|
7
|
-
attr_reader :host
|
|
7
|
+
attr_reader :host, :closed
|
|
8
8
|
|
|
9
9
|
def initialize(host)
|
|
10
10
|
@host = host
|
|
11
|
+
@closed = false
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def close
|
|
15
|
+
@closed = true
|
|
11
16
|
end
|
|
12
17
|
end
|
|
13
18
|
|
|
@@ -24,7 +29,7 @@ class TestNetHttpPersistentTimedStackMulti < Minitest::Test
|
|
|
24
29
|
|
|
25
30
|
assert_empty stack
|
|
26
31
|
|
|
27
|
-
stack.push connection_args:
|
|
32
|
+
stack.push popped, connection_args: 'default'
|
|
28
33
|
|
|
29
34
|
refute_empty stack
|
|
30
35
|
end
|
|
@@ -38,7 +43,7 @@ class TestNetHttpPersistentTimedStackMulti < Minitest::Test
|
|
|
38
43
|
|
|
39
44
|
assert_equal 0, stack.length
|
|
40
45
|
|
|
41
|
-
stack.push connection_args:
|
|
46
|
+
stack.push popped, connection_args: 'default'
|
|
42
47
|
|
|
43
48
|
assert_equal 1, stack.length
|
|
44
49
|
end
|
|
@@ -57,7 +62,7 @@ class TestNetHttpPersistentTimedStackMulti < Minitest::Test
|
|
|
57
62
|
@stack.pop timeout: 0
|
|
58
63
|
end
|
|
59
64
|
|
|
60
|
-
|
|
65
|
+
assert_includes e.message, 'Waited 0 sec'
|
|
61
66
|
end
|
|
62
67
|
|
|
63
68
|
def test_pop_full
|
|
@@ -69,6 +74,18 @@ class TestNetHttpPersistentTimedStackMulti < Minitest::Test
|
|
|
69
74
|
assert_empty stack
|
|
70
75
|
end
|
|
71
76
|
|
|
77
|
+
def test_pop_closes_extra_connections
|
|
78
|
+
stack = Net::HTTP::Persistent::TimedStackMulti.new(1) { |host| Connection.new(host) }
|
|
79
|
+
|
|
80
|
+
a_conn = stack.pop connection_args: 'a.example'
|
|
81
|
+
stack.push a_conn, connection_args: 'a.example'
|
|
82
|
+
|
|
83
|
+
b_conn = stack.pop connection_args: 'b.example'
|
|
84
|
+
|
|
85
|
+
assert a_conn.closed
|
|
86
|
+
refute b_conn.closed
|
|
87
|
+
end
|
|
88
|
+
|
|
72
89
|
def test_pop_wait
|
|
73
90
|
thread = Thread.start do
|
|
74
91
|
@stack.pop
|
|
@@ -96,7 +113,7 @@ class TestNetHttpPersistentTimedStackMulti < Minitest::Test
|
|
|
96
113
|
|
|
97
114
|
conn = stack.pop
|
|
98
115
|
|
|
99
|
-
stack.push connection_args:
|
|
116
|
+
stack.push conn, connection_args: 'default'
|
|
100
117
|
|
|
101
118
|
refute_empty stack
|
|
102
119
|
end
|
|
@@ -108,14 +125,16 @@ class TestNetHttpPersistentTimedStackMulti < Minitest::Test
|
|
|
108
125
|
called << object
|
|
109
126
|
end
|
|
110
127
|
|
|
111
|
-
|
|
128
|
+
obj = Object.new
|
|
129
|
+
@stack.push obj, connection_args: 'default'
|
|
112
130
|
|
|
113
131
|
refute_empty called
|
|
114
132
|
assert_empty @stack
|
|
115
133
|
end
|
|
116
134
|
|
|
117
135
|
def test_shutdown
|
|
118
|
-
|
|
136
|
+
obj = Object.new
|
|
137
|
+
@stack.push obj, connection_args: 'default'
|
|
119
138
|
|
|
120
139
|
called = []
|
|
121
140
|
|
metadata
CHANGED
|
@@ -1,29 +1,34 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: net-http-persistent
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.0.
|
|
4
|
+
version: 4.0.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Eric Hodel
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: connection_pool
|
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
|
16
15
|
requirements:
|
|
17
|
-
- - "
|
|
16
|
+
- - ">="
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
18
|
+
version: 2.2.4
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '4'
|
|
20
22
|
type: :runtime
|
|
21
23
|
prerelease: false
|
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
25
|
requirements:
|
|
24
|
-
- - "
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: 2.2.4
|
|
29
|
+
- - "<"
|
|
25
30
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
31
|
+
version: '4'
|
|
27
32
|
description: |-
|
|
28
33
|
Manages persistent connections using Net::HTTP including a thread pool for
|
|
29
34
|
connecting to multiple hosts.
|
|
@@ -63,7 +68,6 @@ licenses:
|
|
|
63
68
|
- MIT
|
|
64
69
|
metadata:
|
|
65
70
|
homepage_uri: https://github.com/drbrain/net-http-persistent
|
|
66
|
-
post_install_message:
|
|
67
71
|
rdoc_options:
|
|
68
72
|
- "--main"
|
|
69
73
|
- README.rdoc
|
|
@@ -80,8 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
80
84
|
- !ruby/object:Gem::Version
|
|
81
85
|
version: '0'
|
|
82
86
|
requirements: []
|
|
83
|
-
rubygems_version:
|
|
84
|
-
signing_key:
|
|
87
|
+
rubygems_version: 4.0.3
|
|
85
88
|
specification_version: 4
|
|
86
89
|
summary: Manages persistent connections using Net::HTTP including a thread pool for
|
|
87
90
|
connecting to multiple hosts
|