net-http-persistent 3.0.1 → 4.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -56,7 +56,8 @@ class TestNetHttpPersistent < Minitest::Test
56
56
  def setup
57
57
  @http = Net::HTTP::Persistent.new
58
58
 
59
- @uri = URI.parse 'http://example.com/path'
59
+ @uri = URI 'http://example.com/path'
60
+ @uri_v6 = URI 'http://[2001:db8::1]/path'
60
61
 
61
62
  ENV.delete 'http_proxy'
62
63
  ENV.delete 'HTTP_PROXY'
@@ -120,7 +121,7 @@ class TestNetHttpPersistent < Minitest::Test
120
121
  def basic_connection
121
122
  raise "#{@uri} is not HTTP" unless @uri.scheme.downcase == 'http'
122
123
 
123
- net_http_args = [@uri.host, @uri.port]
124
+ net_http_args = [@uri.hostname, @uri.port, nil, nil, nil, nil]
124
125
 
125
126
  connection = Net::HTTP::Persistent::Connection.allocate
126
127
  connection.ssl_generation = @http.ssl_generation
@@ -132,7 +133,9 @@ class TestNetHttpPersistent < Minitest::Test
132
133
  connection
133
134
  end
134
135
 
135
- def connection
136
+ def connection uri = @uri
137
+ @uri = uri
138
+
136
139
  connection = basic_connection
137
140
  connection.last_use = Time.now
138
141
 
@@ -152,7 +155,7 @@ class TestNetHttpPersistent < Minitest::Test
152
155
  def ssl_connection
153
156
  raise "#{@uri} is not HTTPS" unless @uri.scheme.downcase == 'https'
154
157
 
155
- net_http_args = [@uri.host, @uri.port]
158
+ net_http_args = [@uri.hostname, @uri.port, nil, nil, nil, nil]
156
159
 
157
160
  connection = Net::HTTP::Persistent::Connection.allocate
158
161
  connection.ssl_generation = @http.ssl_generation
@@ -220,26 +223,6 @@ class TestNetHttpPersistent < Minitest::Test
220
223
  assert_equal 1, @http.ssl_generation
221
224
  end
222
225
 
223
- def test_can_retry_eh_change_requests
224
- post = Net::HTTP::Post.new '/'
225
-
226
- refute @http.can_retry? post
227
-
228
- @http.retry_change_requests = true
229
-
230
- assert @http.can_retry? post
231
- end
232
-
233
- def test_can_retry_eh_idempotent
234
- head = Net::HTTP::Head.new '/'
235
-
236
- refute @http.can_retry? head
237
-
238
- post = Net::HTTP::Post.new '/'
239
-
240
- refute @http.can_retry? post
241
- end
242
-
243
226
  def test_cert_store_equals
244
227
  @http.cert_store = :cert_store
245
228
 
@@ -265,6 +248,7 @@ class TestNetHttpPersistent < Minitest::Test
265
248
  @http.open_timeout = 123
266
249
  @http.read_timeout = 321
267
250
  @http.idle_timeout = 42
251
+ @http.max_retries = 5
268
252
 
269
253
  used = @http.connection_for @uri do |c|
270
254
  assert_kind_of Net::HTTP, c.http
@@ -275,11 +259,12 @@ class TestNetHttpPersistent < Minitest::Test
275
259
  assert_equal 123, c.http.open_timeout
276
260
  assert_equal 321, c.http.read_timeout
277
261
  assert_equal 42, c.http.keep_alive_timeout
262
+ assert_equal 5, c.http.max_retries if c.http.respond_to?(:max_retries)
278
263
 
279
264
  c
280
265
  end
281
266
 
282
- stored = @http.pool.checkout ['example.com', 80]
267
+ stored = @http.pool.checkout ['example.com', 80, nil, nil, nil, nil]
283
268
 
284
269
  assert_same used, stored
285
270
  end
@@ -377,6 +362,7 @@ class TestNetHttpPersistent < Minitest::Test
377
362
  end
378
363
 
379
364
  def test_connection_for_finished_ssl
365
+ skip 'Broken on Windows' if Gem.win_platform?
380
366
  skip 'OpenSSL is missing' unless HAVE_OPENSSL
381
367
 
382
368
  uri = URI.parse 'https://example.com/path'
@@ -395,6 +381,12 @@ class TestNetHttpPersistent < Minitest::Test
395
381
  end
396
382
  end
397
383
 
384
+ def test_connection_for_ipv6
385
+ @http.connection_for @uri_v6 do |c|
386
+ assert_equal '2001:db8::1', c.http.address
387
+ end
388
+ end
389
+
398
390
  def test_connection_for_host_down
399
391
  c = basic_connection
400
392
  def (c.http).start; raise Errno::EHOSTDOWN end
@@ -538,6 +530,21 @@ class TestNetHttpPersistent < Minitest::Test
538
530
  assert stored
539
531
  end
540
532
 
533
+ def test_connection_for_no_proxy_from_env
534
+ ENV['http_proxy'] = 'proxy.example'
535
+ ENV['no_proxy'] = 'localhost, example.com,'
536
+ ENV['proxy_user'] = 'johndoe'
537
+ ENV['proxy_password'] = 'muffins'
538
+
539
+ http = Net::HTTP::Persistent.new proxy: :ENV
540
+
541
+ http.connection_for @uri do |c|
542
+ assert c.http.started?
543
+ refute c.http.proxy?
544
+ refute c.http.proxy_from_env?
545
+ end
546
+ end
547
+
541
548
  def test_connection_for_refused
542
549
  Net::HTTP.use_connect :refused_connect
543
550
 
@@ -549,6 +556,7 @@ class TestNetHttpPersistent < Minitest::Test
549
556
  end
550
557
 
551
558
  def test_connection_for_ssl
559
+ skip 'Broken on Windows' if Gem.win_platform?
552
560
  skip 'OpenSSL is missing' unless HAVE_OPENSSL
553
561
 
554
562
  uri = URI.parse 'https://example.com/path'
@@ -589,6 +597,7 @@ class TestNetHttpPersistent < Minitest::Test
589
597
  end
590
598
 
591
599
  def test_connection_for_ssl_case
600
+ skip 'Broken on Windows' if Gem.win_platform?
592
601
  skip 'OpenSSL is missing' unless HAVE_OPENSSL
593
602
 
594
603
  uri = URI.parse 'HTTPS://example.com/path'
@@ -612,16 +621,6 @@ class TestNetHttpPersistent < Minitest::Test
612
621
  end
613
622
  end
614
623
 
615
- def test_error_message
616
- c = basic_connection
617
- c.last_use = Time.now - 1
618
- c.requests = 5
619
-
620
- message = @http.error_message c
621
- assert_match %r%after 4 requests on #{c.http.object_id}%, message
622
- assert_match %r%, last used [\d.]+ seconds ago%, message
623
- end
624
-
625
624
  def test_escape
626
625
  assert_nil @http.escape nil
627
626
 
@@ -635,6 +634,7 @@ class TestNetHttpPersistent < Minitest::Test
635
634
  end
636
635
 
637
636
  def test_expired_eh
637
+ skip 'Broken on Windows' if Gem.win_platform?
638
638
  c = basic_connection
639
639
  c.requests = 0
640
640
  c.last_use = Time.now - 11
@@ -675,6 +675,7 @@ class TestNetHttpPersistent < Minitest::Test
675
675
  def test_finish
676
676
  c = basic_connection
677
677
  c.requests = 5
678
+ c.http.instance_variable_set(:@last_communicated, Process.clock_gettime(Process::CLOCK_MONOTONIC))
678
679
 
679
680
  @http.finish c
680
681
 
@@ -683,6 +684,7 @@ class TestNetHttpPersistent < Minitest::Test
683
684
 
684
685
  assert_equal 0, c.requests
685
686
  assert_equal Net::HTTP::Persistent::EPOCH, c.last_use
687
+ assert_nil c.http.instance_variable_get(:@last_communicated)
686
688
  end
687
689
 
688
690
  def test_finish_io_error
@@ -720,15 +722,21 @@ class TestNetHttpPersistent < Minitest::Test
720
722
  assert_equal '1.1', @http.http_version(@uri)
721
723
  end
722
724
 
723
- def test_idempotent_eh
724
- assert @http.idempotent? Net::HTTP::Delete.new '/'
725
- assert @http.idempotent? Net::HTTP::Get.new '/'
726
- assert @http.idempotent? Net::HTTP::Head.new '/'
727
- assert @http.idempotent? Net::HTTP::Options.new '/'
728
- assert @http.idempotent? Net::HTTP::Put.new '/'
729
- assert @http.idempotent? Net::HTTP::Trace.new '/'
725
+ def test_http_version_IPv6
726
+ assert_nil @http.http_version @uri_v6
730
727
 
731
- refute @http.idempotent? Net::HTTP::Post.new '/'
728
+ connection @uri_v6
729
+
730
+ @http.request @uri_v6
731
+
732
+ assert_equal '1.1', @http.http_version(@uri_v6)
733
+ end
734
+
735
+ def test_max_retries_equals
736
+ @http.max_retries = 5
737
+
738
+ assert_equal 5, @http.max_retries
739
+ assert_equal 1, @http.generation
732
740
  end
733
741
 
734
742
  def test_normalize_uri
@@ -751,7 +759,7 @@ class TestNetHttpPersistent < Minitest::Test
751
759
  skip 'net-http-pipeline not installed' unless defined?(Net::HTTP::Pipeline)
752
760
 
753
761
  cached = basic_connection
754
- cached.start
762
+ cached.http.start
755
763
 
756
764
  requests = [
757
765
  Net::HTTP::Get.new((@uri + '1').request_uri),
@@ -800,6 +808,14 @@ class TestNetHttpPersistent < Minitest::Test
800
808
  assert_equal proxy_uri, @http.proxy_uri
801
809
  end
802
810
 
811
+ def test_proxy_equals_uri_IPv6
812
+ proxy_uri = @uri_v6
813
+
814
+ @http.proxy = proxy_uri
815
+
816
+ assert_equal proxy_uri, @http.proxy_uri
817
+ end
818
+
803
819
  def test_proxy_from_env
804
820
  ENV['http_proxy'] = 'proxy.example'
805
821
  ENV['http_proxy_user'] = 'johndoe'
@@ -945,7 +961,7 @@ class TestNetHttpPersistent < Minitest::Test
945
961
  assert_equal Net::HTTP::Persistent::EPOCH, used2.last_use
946
962
  end
947
963
 
948
- def test_request
964
+ def test_requestx
949
965
  @http.override_headers['user-agent'] = 'test ua'
950
966
  @http.headers['accept'] = 'text/*'
951
967
  c = connection
@@ -964,65 +980,12 @@ class TestNetHttpPersistent < Minitest::Test
964
980
  assert_equal 'keep-alive', req['connection']
965
981
  assert_equal '30', req['keep-alive']
966
982
 
967
- assert_in_delta Time.now, c.last_use
968
-
969
- assert_equal 1, c.requests
970
- end
971
-
972
- def test_request_ETIMEDOUT
973
- c = basic_connection
974
- def (c.http).request(*a) raise Errno::ETIMEDOUT, "timed out" end
975
-
976
- e = assert_raises Net::HTTP::Persistent::Error do
977
- @http.request @uri
978
- end
979
-
980
- assert_equal 0, c.requests
981
- assert_match %r%too many connection resets%, e.message
982
- end
983
-
984
- def test_request_bad_response
985
- c = basic_connection
986
- def (c.http).request(*a) raise Net::HTTPBadResponse end
987
-
988
- e = assert_raises Net::HTTP::Persistent::Error do
989
- @http.request @uri
990
- end
991
-
992
- assert_equal 0, c.requests
993
- assert_match %r%too many bad responses%, e.message
994
- end
995
-
996
- def test_request_bad_response_retry
997
- c = basic_connection
998
- def (c.http).request(*a)
999
- raise Net::HTTPBadResponse
1000
- end
1001
-
1002
- assert_raises Net::HTTP::Persistent::Error do
1003
- @http.request @uri
1004
- end
1005
-
1006
- assert c.http.finished?
1007
- end
1008
-
1009
- def test_request_bad_response_unsafe
1010
- c = basic_connection
1011
- def (c.http).request(*a)
1012
- if instance_variable_defined? :@request then
1013
- raise 'POST must not be retried'
1014
- else
1015
- @request = true
1016
- raise Net::HTTPBadResponse
1017
- end
1018
- end
1019
-
1020
- e = assert_raises Net::HTTP::Persistent::Error do
1021
- @http.request @uri, Net::HTTP::Post.new(@uri.path)
983
+ # There's some roounding issue on jruby preventing this from passing
984
+ unless RUBY_PLATFORM == "java"
985
+ assert_in_delta Time.now, c.last_use
1022
986
  end
1023
987
 
1024
- assert_equal 0, c.requests
1025
- assert_match %r%too many bad responses%, e.message
988
+ assert_equal 1, c.requests
1026
989
  end
1027
990
 
1028
991
  def test_request_block
@@ -1150,12 +1113,12 @@ class TestNetHttpPersistent < Minitest::Test
1150
1113
  c = basic_connection
1151
1114
  def (c.http).request(*a) raise Errno::EINVAL, "write" end
1152
1115
 
1153
- e = assert_raises Net::HTTP::Persistent::Error do
1116
+ e = assert_raises Errno::EINVAL do
1154
1117
  @http.request @uri
1155
1118
  end
1156
1119
 
1157
1120
  assert_equal 0, c.requests
1158
- assert_match %r%too many connection resets%, e.message
1121
+ assert_match %r%Invalid argument - write%, e.message
1159
1122
  end
1160
1123
 
1161
1124
  def test_request_post
@@ -1169,69 +1132,6 @@ class TestNetHttpPersistent < Minitest::Test
1169
1132
  assert_same post, req
1170
1133
  end
1171
1134
 
1172
- def test_request_reset
1173
- c = basic_connection
1174
- def (c.http).request(*a) raise Errno::ECONNRESET end
1175
-
1176
- e = assert_raises Net::HTTP::Persistent::Error do
1177
- @http.request @uri
1178
- end
1179
-
1180
- assert_equal 0, c.requests
1181
- assert_match %r%too many connection resets%, e.message
1182
- end
1183
-
1184
- def test_request_reset_retry
1185
- c = basic_connection
1186
- c.last_use = Time.now
1187
-
1188
- def (c.http).request(*a)
1189
- raise Errno::ECONNRESET
1190
- end
1191
-
1192
- assert_raises Net::HTTP::Persistent::Error do
1193
- @http.request @uri
1194
- end
1195
-
1196
- refute (c.http).reset?
1197
- assert (c.http).finished?
1198
- end
1199
-
1200
- def test_request_reset_unsafe
1201
- c = basic_connection
1202
- def (c.http).request(*a)
1203
- if instance_variable_defined? :@request then
1204
- raise 'POST must not be retried'
1205
- else
1206
- @request = true
1207
- raise Errno::ECONNRESET
1208
- end
1209
- end
1210
-
1211
- e = assert_raises Net::HTTP::Persistent::Error do
1212
- @http.request @uri, Net::HTTP::Post.new(@uri.path)
1213
- end
1214
-
1215
- assert_equal 0, c.requests
1216
- assert_match %r%too many connection resets%, e.message
1217
- end
1218
-
1219
- def test_request_ssl_error
1220
- skip 'OpenSSL is missing' unless HAVE_OPENSSL
1221
-
1222
- uri = URI.parse 'https://example.com/path'
1223
- @http.connection_for uri do |c|
1224
- def (c.http).request(*)
1225
- raise OpenSSL::SSL::SSLError, "SSL3_WRITE_PENDING:bad write retry"
1226
- end
1227
-
1228
- e = assert_raises Net::HTTP::Persistent::Error do
1229
- @http.request uri
1230
- end
1231
- assert_match %r%bad write retry%, e.message
1232
- end
1233
- end
1234
-
1235
1135
  def test_request_setup
1236
1136
  @http.override_headers['user-agent'] = 'test ua'
1237
1137
  @http.headers['accept'] = 'text/*'
@@ -1275,30 +1175,6 @@ class TestNetHttpPersistent < Minitest::Test
1275
1175
  assert_equal '/path?a=b', req.path
1276
1176
  end
1277
1177
 
1278
- def test_request_failed
1279
- c = basic_connection
1280
- c.requests = 1
1281
- c.last_use = Time.now
1282
-
1283
- original = nil
1284
-
1285
- begin
1286
- raise 'original'
1287
- rescue => original
1288
- end
1289
-
1290
- req = Net::HTTP::Get.new '/'
1291
-
1292
- e = assert_raises Net::HTTP::Persistent::Error do
1293
- @http.request_failed original, req, c
1294
- end
1295
-
1296
- assert_match "too many connection resets (due to original - RuntimeError)",
1297
- e.message
1298
-
1299
- assert_equal original.backtrace, e.backtrace
1300
- end
1301
-
1302
1178
  def test_reset
1303
1179
  c = basic_connection
1304
1180
  c.http.start
@@ -1353,23 +1229,6 @@ class TestNetHttpPersistent < Minitest::Test
1353
1229
  assert_match __FILE__, e.backtrace.first
1354
1230
  end
1355
1231
 
1356
- def test_retry_change_requests_equals
1357
- get = Net::HTTP::Get.new('/')
1358
- post = Net::HTTP::Post.new('/')
1359
-
1360
- refute @http.retry_change_requests
1361
-
1362
- refute @http.can_retry?(get)
1363
- refute @http.can_retry?(post)
1364
-
1365
- @http.retry_change_requests = true
1366
-
1367
- assert @http.retry_change_requests
1368
-
1369
- refute @http.can_retry?(get)
1370
- assert @http.can_retry?(post)
1371
- end
1372
-
1373
1232
  def test_shutdown
1374
1233
  c = connection
1375
1234
 
@@ -1585,5 +1444,15 @@ class TestNetHttpPersistent < Minitest::Test
1585
1444
  assert_equal 1, @http.ssl_generation
1586
1445
  end
1587
1446
 
1447
+ def test_connection_pool_after_fork
1448
+ # ConnectionPool 2.4+ calls `checkin(force: true)` after fork
1449
+ @http.pool.checkin(force: true)
1450
+
1451
+ @http.pool.checkout ['example.com', 80, nil, nil, nil, nil]
1452
+ @http.pool.checkin(force: true)
1453
+ @http.pool.reload do |connection|
1454
+ connection.close
1455
+ end
1456
+ end
1588
1457
  end
1589
1458
 
@@ -57,7 +57,7 @@ class TestNetHttpPersistentTimedStackMulti < Minitest::Test
57
57
  @stack.pop timeout: 0
58
58
  end
59
59
 
60
- assert_equal 'Waited 0 sec', e.message
60
+ assert_match 'Waited 0 sec', e.message
61
61
  end
62
62
 
63
63
  def test_pop_full
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-http-persistent
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 4.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Hodel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-29 00:00:00.000000000 Z
11
+ date: 2023-03-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: connection_pool
@@ -24,65 +24,18 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.2'
27
- - !ruby/object:Gem::Dependency
28
- name: minitest
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '5.11'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '5.11'
41
- - !ruby/object:Gem::Dependency
42
- name: rdoc
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '4.0'
48
- - - "<"
49
- - !ruby/object:Gem::Version
50
- version: '7'
51
- type: :development
52
- prerelease: false
53
- version_requirements: !ruby/object:Gem::Requirement
54
- requirements:
55
- - - ">="
56
- - !ruby/object:Gem::Version
57
- version: '4.0'
58
- - - "<"
59
- - !ruby/object:Gem::Version
60
- version: '7'
61
- - !ruby/object:Gem::Dependency
62
- name: hoe
63
- requirement: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - "~>"
66
- - !ruby/object:Gem::Version
67
- version: '3.17'
68
- type: :development
69
- prerelease: false
70
- version_requirements: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - "~>"
73
- - !ruby/object:Gem::Version
74
- version: '3.17'
75
27
  description: |-
76
- Manages persistent connections using Net::HTTP plus a speed fix for Ruby 1.8.
77
- It's thread-safe too!
28
+ Manages persistent connections using Net::HTTP including a thread pool for
29
+ connecting to multiple hosts.
78
30
 
79
31
  Using persistent HTTP connections can dramatically increase the speed of HTTP.
80
32
  Creating a new HTTP connection for every request involves an extra TCP
81
33
  round-trip and causes TCP congestion avoidance negotiation to start over.
82
34
 
83
35
  Net::HTTP supports persistent connections with some API methods but does not
84
- handle reconnection gracefully. Net::HTTP::Persistent supports reconnection
85
- and retry according to RFC 2616.
36
+ make setting up a single persistent connection or managing multiple
37
+ connections easy. Net::HTTP::Persistent wraps Net::HTTP and allows you to
38
+ focus on how to make HTTP requests.
86
39
  email:
87
40
  - drbrain@segment7.net
88
41
  executables: []
@@ -94,7 +47,7 @@ extra_rdoc_files:
94
47
  files:
95
48
  - ".autotest"
96
49
  - ".gemtest"
97
- - ".travis.yml"
50
+ - Gemfile
98
51
  - History.txt
99
52
  - Manifest.txt
100
53
  - README.rdoc
@@ -105,10 +58,11 @@ files:
105
58
  - lib/net/http/persistent/timed_stack_multi.rb
106
59
  - test/test_net_http_persistent.rb
107
60
  - test/test_net_http_persistent_timed_stack_multi.rb
108
- homepage: http://docs.seattlerb.org/net-http-persistent
61
+ homepage: https://github.com/drbrain/net-http-persistent
109
62
  licenses:
110
63
  - MIT
111
- metadata: {}
64
+ metadata:
65
+ homepage_uri: https://github.com/drbrain/net-http-persistent
112
66
  post_install_message:
113
67
  rdoc_options:
114
68
  - "--main"
@@ -117,18 +71,18 @@ require_paths:
117
71
  - lib
118
72
  required_ruby_version: !ruby/object:Gem::Requirement
119
73
  requirements:
120
- - - "~>"
74
+ - - ">="
121
75
  - !ruby/object:Gem::Version
122
- version: '2.1'
76
+ version: '2.4'
123
77
  required_rubygems_version: !ruby/object:Gem::Requirement
124
78
  requirements:
125
79
  - - ">="
126
80
  - !ruby/object:Gem::Version
127
81
  version: '0'
128
82
  requirements: []
129
- rubygems_version: 3.0.1
83
+ rubygems_version: 3.0.3.1
130
84
  signing_key:
131
85
  specification_version: 4
132
- summary: Manages persistent connections using Net::HTTP plus a speed fix for Ruby
133
- 1.8
86
+ summary: Manages persistent connections using Net::HTTP including a thread pool for
87
+ connecting to multiple hosts
134
88
  test_files: []
data/.travis.yml DELETED
@@ -1,15 +0,0 @@
1
- ---
2
- after_script:
3
- - rake travis:after -t
4
- before_script:
5
- - gem install hoe-travis --no-rdoc --no-ri
6
- - rake travis:before -t
7
- language: ruby
8
- notifications:
9
- email:
10
- - drbrain@segment7.net
11
- rvm:
12
- - 2.1.10
13
- - 2.2.5
14
- - 2.3.1
15
- script: rake travis