net-http-persistent 2.9.4 → 4.0.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.
- checksums.yaml +5 -5
- data/.travis.yml +23 -0
- data/Gemfile +15 -0
- data/History.txt +101 -0
- data/Manifest.txt +6 -3
- data/README.rdoc +10 -10
- data/Rakefile +11 -4
- data/lib/net/http/persistent.rb +282 -425
- data/lib/net/http/persistent/connection.rb +40 -0
- data/lib/net/http/persistent/pool.rb +53 -0
- data/lib/net/http/persistent/timed_stack_multi.rb +79 -0
- data/test/test_net_http_persistent.rb +399 -691
- data/test/test_net_http_persistent_timed_stack_multi.rb +151 -0
- metadata +85 -51
- checksums.yaml.gz.sig +0 -2
- data.tar.gz.sig +0 -0
- data/lib/net/http/faster.rb +0 -27
- data/lib/net/http/persistent/ssl_reuse.rb +0 -129
- data/test/test_net_http_persistent_ssl_reuse.rb +0 -112
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 776350367e44e2bf8c4e4fd84b1fd1c03eca4c785462c3dd58c8f214fc9b74ab
|
4
|
+
data.tar.gz: f79c075c1a091389c030137bdcbcf5ef3079fbb66702a7ebf6ef8e8bfb75146d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 10ec9cc95f92954730b37ea924ef4eea9491b7fa5f5b913e9dea762e19381a8f9516caa4201aafe33f8028984c0aed429f6d7533d2056375f49558882fcc67dc
|
7
|
+
data.tar.gz: cd107612612cb1f70513bfe858dd75b6d8aeb2a5415b892e1fa98158b126152820c0b7c3b6a4ba2f0b6da42157da230182f49ffd0453c5b9779c6db29f088958
|
data/.travis.yml
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
---
|
2
|
+
after_script:
|
3
|
+
- rake travis:after -t
|
4
|
+
before_script:
|
5
|
+
- gem install hoe-travis --no-document
|
6
|
+
- rake travis:before -t
|
7
|
+
language: ruby
|
8
|
+
notifications:
|
9
|
+
email:
|
10
|
+
- drbrain@segment7.net
|
11
|
+
rvm:
|
12
|
+
- 2.3
|
13
|
+
- 2.4
|
14
|
+
- 2.5
|
15
|
+
- 2.6
|
16
|
+
- 2.7
|
17
|
+
script: rake travis
|
18
|
+
install: "" # avoid running default bundler install
|
19
|
+
|
20
|
+
matrix:
|
21
|
+
include:
|
22
|
+
- rvm: "2.7"
|
23
|
+
env: TRAVIS_MATRIX=pipeline
|
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
# DO NOT EDIT THIS FILE. Instead, edit Rakefile, and run `rake bundler:gemfile`.
|
4
|
+
|
5
|
+
source "https://rubygems.org/"
|
6
|
+
|
7
|
+
gem "connection_pool", "~>2.2"
|
8
|
+
|
9
|
+
gem "minitest", "~>5.11", :group => [:development, :test]
|
10
|
+
gem "hoe-bundler", "~>1.5", :group => [:development, :test]
|
11
|
+
gem "hoe-travis", "~>1.4", ">=1.4.1", :group => [:development, :test]
|
12
|
+
gem "rdoc", ">=4.0", "<7", :group => [:development, :test]
|
13
|
+
gem "hoe", "~>3.17", :group => [:development, :test]
|
14
|
+
|
15
|
+
# vim: syntax=ruby
|
data/History.txt
CHANGED
@@ -1,3 +1,104 @@
|
|
1
|
+
=== 4.0.1 / 2021-01-12
|
2
|
+
|
3
|
+
Bug fixes:
|
4
|
+
|
5
|
+
* Loosen Ruby version requirement so Ruby 3.0 will work.
|
6
|
+
|
7
|
+
=== 4.0.0 / 2020-04-30
|
8
|
+
|
9
|
+
Breaking changes:
|
10
|
+
|
11
|
+
* Removed built-in support for retrying failed requests as Net::HTTP has this
|
12
|
+
built-in for all supported versions. Pull request #100 by Michael Grosser.
|
13
|
+
* Dropped support for EoL ruby versions (< 2.4). Future feature releases may
|
14
|
+
drop support for ruby versions that are at end-of-life or in security-only
|
15
|
+
maintenance mode with any release. Pull request #113 by David Rodríguez
|
16
|
+
|
17
|
+
New features:
|
18
|
+
|
19
|
+
* Added Net::HTTP::Persistent#max_retries= to configure the number of retries
|
20
|
+
performed on a request for ruby versions that support it (2.5+).
|
21
|
+
* URI-ness is determined through #respond_to? to allow compatibility with
|
22
|
+
Addressable::URI. Pull request #67 by Ryan McKern.
|
23
|
+
* Use require_relative to reduce patch burden for vendored versions. Pull
|
24
|
+
Request #106 by David Rodríguez
|
25
|
+
|
26
|
+
Bug fixes:
|
27
|
+
|
28
|
+
* Stop wasting a connection when the keep-alive timeout is less than the idle
|
29
|
+
timeout. Pull request #115 by Yap Sok Ann.
|
30
|
+
* Improved use of URI#hostname for IPv6 connections. Pull request #76 by
|
31
|
+
Tomas Koutsky.
|
32
|
+
* Improved check for Process::RLIMIT_NOFILE support. Pull request #109 by Vít
|
33
|
+
Ondruch.
|
34
|
+
* Fix namespace in comments for escape/unescape wrappers. Pull request #114
|
35
|
+
by David Rodríguez.
|
36
|
+
* Fix History.txt timestamp for 3.0.0 release. Pull request #107 by Joe Van
|
37
|
+
Dyk.
|
38
|
+
* Fix link to PR #98 in 3.1.0 release notes. Pull request #110 by Justin
|
39
|
+
Reid.
|
40
|
+
|
41
|
+
Other:
|
42
|
+
|
43
|
+
* Updated Net::HTTP::Persistent#reconnect documentation to indicate that all
|
44
|
+
connections are reset. Issue #117 by Taisuke Miyazaki.
|
45
|
+
|
46
|
+
=== 3.1.0 / 2019-07-24
|
47
|
+
|
48
|
+
New features:
|
49
|
+
* Support ruby 2.6 Net::HTTP#write_timeout=. Pull request #99 by Víctor
|
50
|
+
Roldán Betancort.
|
51
|
+
* Support setting TLS min/max version. Pull request #94 by Bart.
|
52
|
+
|
53
|
+
Bug fixes:
|
54
|
+
* Reduce potential for memory leak through Hash default proc bindings. Pull
|
55
|
+
request #64 by Dominic Metzger.
|
56
|
+
* Test proxy auto detection from no_proxy in ENV. Pull request #60 by
|
57
|
+
HINOHARA Hiroshi.
|
58
|
+
* Add missing timestamp for 3.0 release. Pull request #78 by Joe Van Dyk.
|
59
|
+
* Support IPv6 URLs in proxy checks. Pull request #82 by Nicolás Sanguinetti.
|
60
|
+
* Use Net::HTTPGenericRequest#method to check idempotence for improved
|
61
|
+
compatibility. Pull request #83 by Fotos Georgiadis.
|
62
|
+
* Run net-http-pipeline tests in travis. Pull request #86 by T.J. Schuck.
|
63
|
+
* Correct +no_proxy+ support to override Net::HTTP proxy fallback. Pull
|
64
|
+
request #88 by Jared Kauppila.
|
65
|
+
* Mitigate memory leak when combined with faraday. Pull request #105 by Yohei
|
66
|
+
Kitamura.
|
67
|
+
* Set default connection pool size for Windows. Pull request #90 by Jared
|
68
|
+
Kauppila.
|
69
|
+
* Fix missing +name:+ argument in documentation. Pull requests #85 by T.J.
|
70
|
+
Schuck, #84 by James White.
|
71
|
+
* Fix memory leak from connection pooling. Pull request #98 by Aaron
|
72
|
+
Patterson.
|
73
|
+
* Update tests for minitest assert_equal deprecation. Pull request #92 by
|
74
|
+
Olle Jonsson.
|
75
|
+
* Fix typo in Net::HTTP::Persistent#pipeline. Pull request #91 by Kazuma
|
76
|
+
Furuhashi.
|
77
|
+
|
78
|
+
Other:
|
79
|
+
* Added bundler hoe plugin. Pull request #103 by Michael Grosser.
|
80
|
+
* Updated ruby versions in Travis CI. Pull request #93 by Olle Jonsson. Pull
|
81
|
+
request #103 by Michael Grosser.
|
82
|
+
|
83
|
+
=== 3.0 / 2016-10-05
|
84
|
+
|
85
|
+
Breaking changes:
|
86
|
+
|
87
|
+
* No longer supports ruby 2.0 and earlier
|
88
|
+
* Net::HTTP::Persistent::new now uses keyword arguments for +name+ and
|
89
|
+
+proxy+.
|
90
|
+
* Removed #max_age, use #expired?
|
91
|
+
|
92
|
+
New features:
|
93
|
+
|
94
|
+
* Uses connection_pool to manage all connections for a Net::HTTP::Persistent
|
95
|
+
instance.
|
96
|
+
|
97
|
+
Bug fixes:
|
98
|
+
|
99
|
+
* Add missing SSL options ca_path, ciphers, ssl_timeout, verify_depth.
|
100
|
+
Issue #63 by Johnneylee Jack Rollins.
|
101
|
+
|
1
102
|
=== 2.9.4 / 2014-02-10
|
2
103
|
|
3
104
|
* Bug fixes
|
data/Manifest.txt
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
.autotest
|
2
2
|
.gemtest
|
3
|
+
.travis.yml
|
4
|
+
Gemfile
|
3
5
|
History.txt
|
4
6
|
Manifest.txt
|
5
7
|
README.rdoc
|
6
8
|
Rakefile
|
7
|
-
lib/net/http/faster.rb
|
8
9
|
lib/net/http/persistent.rb
|
9
|
-
lib/net/http/persistent/
|
10
|
+
lib/net/http/persistent/connection.rb
|
11
|
+
lib/net/http/persistent/pool.rb
|
12
|
+
lib/net/http/persistent/timed_stack_multi.rb
|
10
13
|
test/test_net_http_persistent.rb
|
11
|
-
test/
|
14
|
+
test/test_net_http_persistent_timed_stack_multi.rb
|
data/README.rdoc
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
= net-http-persistent
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
home :: https://github.com/drbrain/net-http-persistent
|
4
|
+
rdoc :: http://docs.seattlerb.org/net-http-persistent
|
5
5
|
|
6
6
|
== DESCRIPTION:
|
7
7
|
|
8
|
-
Manages persistent connections using Net::HTTP
|
9
|
-
|
8
|
+
Manages persistent connections using Net::HTTP including a thread pool for
|
9
|
+
connecting to multiple hosts.
|
10
10
|
|
11
11
|
Using persistent HTTP connections can dramatically increase the speed of HTTP.
|
12
12
|
Creating a new HTTP connection for every request involves an extra TCP
|
13
13
|
round-trip and causes TCP congestion avoidance negotiation to start over.
|
14
14
|
|
15
15
|
Net::HTTP supports persistent connections with some API methods but does not
|
16
|
-
|
17
|
-
and
|
16
|
+
make setting up a single persistent connection or managing multiple
|
17
|
+
connections easy. Net::HTTP::Persistent wraps Net::HTTP and allows you to
|
18
|
+
focus on how to make HTTP requests.
|
18
19
|
|
19
20
|
== FEATURES/PROBLEMS:
|
20
21
|
|
21
|
-
* Supports
|
22
|
+
* Supports TLS with secure defaults
|
22
23
|
* Thread-safe
|
23
24
|
* Pure ruby
|
24
|
-
* Timeout-less speed boost for Ruby 1.8 (by Aaron Patterson)
|
25
25
|
|
26
26
|
== SYNOPSIS
|
27
27
|
|
@@ -32,7 +32,7 @@ connection is kept alive between requests:
|
|
32
32
|
|
33
33
|
uri = URI 'http://example.com/awesome/web/service'
|
34
34
|
|
35
|
-
http = Net::HTTP::Persistent.new 'my_app_name'
|
35
|
+
http = Net::HTTP::Persistent.new name: 'my_app_name'
|
36
36
|
|
37
37
|
# perform a GET
|
38
38
|
response = http.request uri
|
@@ -60,7 +60,7 @@ including SSL connection verification, header handling and tunable options.
|
|
60
60
|
|
61
61
|
(The MIT License)
|
62
62
|
|
63
|
-
Copyright (c)
|
63
|
+
Copyright (c) Eric Hodel, Aaron Patterson
|
64
64
|
|
65
65
|
Permission is hereby granted, free of charge, to any person obtaining
|
66
66
|
a copy of this software and associated documentation files (the
|
data/Rakefile
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# -*- ruby -*-
|
2
2
|
|
3
|
-
require 'rubygems'
|
4
3
|
require 'hoe'
|
5
4
|
|
5
|
+
Hoe.plugin :bundler
|
6
6
|
Hoe.plugin :git
|
7
7
|
Hoe.plugin :minitest
|
8
8
|
Hoe.plugin :travis
|
@@ -13,12 +13,19 @@ Hoe.spec 'net-http-persistent' do
|
|
13
13
|
self.readme_file = 'README.rdoc'
|
14
14
|
self.extra_rdoc_files += Dir['*.rdoc']
|
15
15
|
|
16
|
+
self.require_ruby_version '>= 2.3'
|
17
|
+
|
16
18
|
license 'MIT'
|
17
19
|
|
18
20
|
rdoc_locations <<
|
19
|
-
'docs.seattlerb.org:/data/www/docs.seattlerb.org/net-http-persistent/'
|
20
|
-
|
21
|
-
dependency '
|
21
|
+
'docs-push.seattlerb.org:/data/www/docs.seattlerb.org/net-http-persistent/'
|
22
|
+
|
23
|
+
dependency 'connection_pool', '~> 2.2'
|
24
|
+
dependency 'minitest', '~> 5.2', :development
|
25
|
+
dependency 'hoe-bundler', '~> 1.5', :development
|
26
|
+
dependency 'hoe-travis', ['~> 1.4', '>= 1.4.1'], :development
|
27
|
+
dependency 'net-http-pipeline', '~> 1.0' if
|
28
|
+
ENV['TRAVIS_MATRIX'] == 'pipeline'
|
22
29
|
end
|
23
30
|
|
24
31
|
# vim: syntax=Ruby
|
data/lib/net/http/persistent.rb
CHANGED
@@ -1,12 +1,7 @@
|
|
1
1
|
require 'net/http'
|
2
|
-
begin
|
3
|
-
require 'net/https'
|
4
|
-
rescue LoadError
|
5
|
-
# net/https or openssl
|
6
|
-
end if RUBY_VERSION < '1.9' # but only for 1.8
|
7
|
-
require 'net/http/faster'
|
8
2
|
require 'uri'
|
9
3
|
require 'cgi' # for escaping
|
4
|
+
require 'connection_pool'
|
10
5
|
|
11
6
|
begin
|
12
7
|
require 'net/http/pipeline'
|
@@ -22,15 +17,11 @@ autoload :OpenSSL, 'openssl'
|
|
22
17
|
# servers you wish to talk to. For each host:port you communicate with a
|
23
18
|
# single persistent connection is created.
|
24
19
|
#
|
25
|
-
#
|
26
|
-
# connections.
|
20
|
+
# Connections will be shared across threads through a connection pool to
|
21
|
+
# increase reuse of connections.
|
27
22
|
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
# You can shut down the HTTP connections when done by calling #shutdown. You
|
32
|
-
# should name your Net::HTTP::Persistent object if you intend to call this
|
33
|
-
# method.
|
23
|
+
# You can shut down any remaining HTTP connections when done by calling
|
24
|
+
# #shutdown.
|
34
25
|
#
|
35
26
|
# Example:
|
36
27
|
#
|
@@ -38,7 +29,7 @@ autoload :OpenSSL, 'openssl'
|
|
38
29
|
#
|
39
30
|
# uri = URI 'http://example.com/awesome/web/service'
|
40
31
|
#
|
41
|
-
# http = Net::HTTP::Persistent.new
|
32
|
+
# http = Net::HTTP::Persistent.new
|
42
33
|
#
|
43
34
|
# # perform a GET
|
44
35
|
# response = http.request uri
|
@@ -60,23 +51,27 @@ autoload :OpenSSL, 'openssl'
|
|
60
51
|
# to use URI#request_uri not URI#path. The request_uri contains the query
|
61
52
|
# params which are sent in the body for other requests.
|
62
53
|
#
|
63
|
-
# == SSL
|
54
|
+
# == TLS/SSL
|
64
55
|
#
|
65
|
-
#
|
66
|
-
# URI.
|
56
|
+
# TLS connections are automatically created depending upon the scheme of the
|
57
|
+
# URI. TLS connections are automatically verified against the default
|
67
58
|
# certificate store for your computer. You can override this by changing
|
68
59
|
# verify_mode or by specifying an alternate cert_store.
|
69
60
|
#
|
70
|
-
# Here are the
|
61
|
+
# Here are the TLS settings, see the individual methods for documentation:
|
71
62
|
#
|
72
63
|
# #certificate :: This client's certificate
|
73
|
-
# #ca_file :: The certificate-
|
64
|
+
# #ca_file :: The certificate-authorities
|
65
|
+
# #ca_path :: Directory with certificate-authorities
|
74
66
|
# #cert_store :: An SSL certificate store
|
67
|
+
# #ciphers :: List of SSl ciphers allowed
|
75
68
|
# #private_key :: The client's SSL private key
|
76
69
|
# #reuse_ssl_sessions :: Reuse a previously opened SSL session for a new
|
77
70
|
# connection
|
71
|
+
# #ssl_timeout :: Session lifetime
|
78
72
|
# #ssl_version :: Which specific SSL version to use
|
79
73
|
# #verify_callback :: For server certificate verification
|
74
|
+
# #verify_depth :: Depth of certificate verification
|
80
75
|
# #verify_mode :: How connections should be verified
|
81
76
|
#
|
82
77
|
# == Proxies
|
@@ -102,14 +97,15 @@ autoload :OpenSSL, 'openssl'
|
|
102
97
|
#
|
103
98
|
# === Segregation
|
104
99
|
#
|
105
|
-
#
|
106
|
-
#
|
100
|
+
# Each Net::HTTP::Persistent instance has its own pool of connections. There
|
101
|
+
# is no sharing with other instances (as was true in earlier versions).
|
107
102
|
#
|
108
103
|
# === Idle Timeout
|
109
104
|
#
|
110
|
-
# If a connection hasn't been used for this number of seconds it will
|
111
|
-
# reset upon the next use to avoid attempting to send to a
|
112
|
-
# The default value is 5 seconds. nil means no timeout.
|
105
|
+
# If a connection hasn't been used for this number of seconds it will
|
106
|
+
# automatically be reset upon the next use to avoid attempting to send to a
|
107
|
+
# closed connection. The default value is 5 seconds. nil means no timeout.
|
108
|
+
# Set through #idle_timeout.
|
113
109
|
#
|
114
110
|
# Reducing this value may help avoid the "too many connection resets" error
|
115
111
|
# when sending non-idempotent requests while increasing this value will cause
|
@@ -124,8 +120,9 @@ autoload :OpenSSL, 'openssl'
|
|
124
120
|
#
|
125
121
|
# The number of requests that should be made before opening a new connection.
|
126
122
|
# Typically many keep-alive capable servers tune this to 100 or less, so the
|
127
|
-
# 101st request will fail with ECONNRESET. If unset (default), this value has
|
128
|
-
# effect, if set, connections will be reset on the request after
|
123
|
+
# 101st request will fail with ECONNRESET. If unset (default), this value has
|
124
|
+
# no effect, if set, connections will be reset on the request after
|
125
|
+
# max_requests.
|
129
126
|
#
|
130
127
|
# === Open Timeout
|
131
128
|
#
|
@@ -137,45 +134,6 @@ autoload :OpenSSL, 'openssl'
|
|
137
134
|
# Socket options may be set on newly-created connections. See #socket_options
|
138
135
|
# for details.
|
139
136
|
#
|
140
|
-
# === Non-Idempotent Requests
|
141
|
-
#
|
142
|
-
# By default non-idempotent requests will not be retried per RFC 2616. By
|
143
|
-
# setting retry_change_requests to true requests will automatically be retried
|
144
|
-
# once.
|
145
|
-
#
|
146
|
-
# Only do this when you know that retrying a POST or other non-idempotent
|
147
|
-
# request is safe for your application and will not create duplicate
|
148
|
-
# resources.
|
149
|
-
#
|
150
|
-
# The recommended way to handle non-idempotent requests is the following:
|
151
|
-
#
|
152
|
-
# require 'net/http/persistent'
|
153
|
-
#
|
154
|
-
# uri = URI 'http://example.com/awesome/web/service'
|
155
|
-
# post_uri = uri + 'create'
|
156
|
-
#
|
157
|
-
# http = Net::HTTP::Persistent.new 'my_app_name'
|
158
|
-
#
|
159
|
-
# post = Net::HTTP::Post.new post_uri.path
|
160
|
-
# # ... fill in POST request
|
161
|
-
#
|
162
|
-
# begin
|
163
|
-
# response = http.request post_uri, post
|
164
|
-
# rescue Net::HTTP::Persistent::Error
|
165
|
-
#
|
166
|
-
# # POST failed, make a new request to verify the server did not process
|
167
|
-
# # the request
|
168
|
-
# exists_uri = uri + '...'
|
169
|
-
# response = http.get exists_uri
|
170
|
-
#
|
171
|
-
# # Retry if it failed
|
172
|
-
# retry if response.code == '404'
|
173
|
-
# end
|
174
|
-
#
|
175
|
-
# The method of determining if the resource was created or not is unique to
|
176
|
-
# the particular service you are using. Of course, you will want to add
|
177
|
-
# protection from infinite looping.
|
178
|
-
#
|
179
137
|
# === Connection Termination
|
180
138
|
#
|
181
139
|
# If you are done using the Net::HTTP::Persistent instance you may shut down
|
@@ -201,24 +159,20 @@ class Net::HTTP::Persistent
|
|
201
159
|
HAVE_OPENSSL = defined? OpenSSL::SSL # :nodoc:
|
202
160
|
|
203
161
|
##
|
204
|
-
# The
|
162
|
+
# The default connection pool size is 1/4 the allowed open files
|
163
|
+
# (<code>ulimit -n</code>) or 256 if your OS does not support file handle
|
164
|
+
# limits (typically windows).
|
205
165
|
|
206
|
-
|
166
|
+
if Process.const_defined? :RLIMIT_NOFILE
|
167
|
+
DEFAULT_POOL_SIZE = Process.getrlimit(Process::RLIMIT_NOFILE).first / 4
|
168
|
+
else
|
169
|
+
DEFAULT_POOL_SIZE = 256
|
170
|
+
end
|
207
171
|
|
208
172
|
##
|
209
|
-
#
|
210
|
-
# the exception list for ruby 1.x.
|
173
|
+
# The version of Net::HTTP::Persistent you are using
|
211
174
|
|
212
|
-
|
213
|
-
(Net::ReadTimeout if Net.const_defined? :ReadTimeout),
|
214
|
-
IOError,
|
215
|
-
EOFError,
|
216
|
-
Errno::ECONNRESET,
|
217
|
-
Errno::ECONNABORTED,
|
218
|
-
Errno::EPIPE,
|
219
|
-
(OpenSSL::SSL::SSLError if HAVE_OPENSSL),
|
220
|
-
Timeout::Error,
|
221
|
-
].compact
|
175
|
+
VERSION = '4.0.1'
|
222
176
|
|
223
177
|
##
|
224
178
|
# Error class for errors raised by Net::HTTP::Persistent. Various
|
@@ -248,31 +202,31 @@ class Net::HTTP::Persistent
|
|
248
202
|
|
249
203
|
http = new 'net-http-persistent detect_idle_timeout'
|
250
204
|
|
251
|
-
|
205
|
+
http.connection_for uri do |connection|
|
206
|
+
sleep_time = 0
|
252
207
|
|
253
|
-
|
208
|
+
http = connection.http
|
254
209
|
|
255
|
-
|
256
|
-
|
210
|
+
loop do
|
211
|
+
response = http.request req
|
257
212
|
|
258
|
-
|
213
|
+
$stderr.puts "HEAD #{uri} => #{response.code}" if $DEBUG
|
259
214
|
|
260
|
-
|
261
|
-
|
262
|
-
|
215
|
+
unless Net::HTTPOK === response then
|
216
|
+
raise Error, "bad response code #{response.code} detecting idle timeout"
|
217
|
+
end
|
263
218
|
|
264
|
-
|
219
|
+
break if sleep_time >= max
|
265
220
|
|
266
|
-
|
221
|
+
sleep_time += 1
|
267
222
|
|
268
|
-
|
269
|
-
|
223
|
+
$stderr.puts "sleeping #{sleep_time}" if $DEBUG
|
224
|
+
sleep sleep_time
|
225
|
+
end
|
270
226
|
end
|
271
227
|
rescue
|
272
228
|
# ignore StandardErrors, we've probably found the idle timeout.
|
273
229
|
ensure
|
274
|
-
http.shutdown
|
275
|
-
|
276
230
|
return sleep_time unless $!
|
277
231
|
end
|
278
232
|
|
@@ -281,7 +235,9 @@ class Net::HTTP::Persistent
|
|
281
235
|
|
282
236
|
attr_reader :certificate
|
283
237
|
|
238
|
+
##
|
284
239
|
# For Net::HTTP parity
|
240
|
+
|
285
241
|
alias cert certificate
|
286
242
|
|
287
243
|
##
|
@@ -290,12 +246,23 @@ class Net::HTTP::Persistent
|
|
290
246
|
|
291
247
|
attr_reader :ca_file
|
292
248
|
|
249
|
+
##
|
250
|
+
# A directory of SSL certificates to be used as certificate authorities.
|
251
|
+
# Setting this will set verify_mode to VERIFY_PEER.
|
252
|
+
|
253
|
+
attr_reader :ca_path
|
254
|
+
|
293
255
|
##
|
294
256
|
# An SSL certificate store. Setting this will override the default
|
295
257
|
# certificate store. See verify_mode for more information.
|
296
258
|
|
297
259
|
attr_reader :cert_store
|
298
260
|
|
261
|
+
##
|
262
|
+
# The ciphers allowed for SSL connections
|
263
|
+
|
264
|
+
attr_reader :ciphers
|
265
|
+
|
299
266
|
##
|
300
267
|
# Sends debug_output to this IO via Net::HTTP#set_debug_output.
|
301
268
|
#
|
@@ -309,11 +276,6 @@ class Net::HTTP::Persistent
|
|
309
276
|
|
310
277
|
attr_reader :generation # :nodoc:
|
311
278
|
|
312
|
-
##
|
313
|
-
# Where this instance's connections live in the thread local variables
|
314
|
-
|
315
|
-
attr_reader :generation_key # :nodoc:
|
316
|
-
|
317
279
|
##
|
318
280
|
# Headers that are added to every request using Net::HTTP#add_field
|
319
281
|
|
@@ -337,6 +299,13 @@ class Net::HTTP::Persistent
|
|
337
299
|
|
338
300
|
attr_accessor :max_requests
|
339
301
|
|
302
|
+
##
|
303
|
+
# Number of retries to perform if a request fails.
|
304
|
+
#
|
305
|
+
# See also #max_retries=, Net::HTTP#max_retries=.
|
306
|
+
|
307
|
+
attr_reader :max_retries
|
308
|
+
|
340
309
|
##
|
341
310
|
# The value sent in the Keep-Alive header. Defaults to 30. Not needed for
|
342
311
|
# HTTP/1.1 servers.
|
@@ -349,8 +318,7 @@ class Net::HTTP::Persistent
|
|
349
318
|
attr_accessor :keep_alive
|
350
319
|
|
351
320
|
##
|
352
|
-
#
|
353
|
-
# from everybody else's.
|
321
|
+
# The name for this collection of persistent connections.
|
354
322
|
|
355
323
|
attr_reader :name
|
356
324
|
|
@@ -369,7 +337,9 @@ class Net::HTTP::Persistent
|
|
369
337
|
|
370
338
|
attr_reader :private_key
|
371
339
|
|
340
|
+
##
|
372
341
|
# For Net::HTTP parity
|
342
|
+
|
373
343
|
alias key private_key
|
374
344
|
|
375
345
|
##
|
@@ -382,15 +352,20 @@ class Net::HTTP::Persistent
|
|
382
352
|
|
383
353
|
attr_reader :no_proxy
|
384
354
|
|
355
|
+
##
|
356
|
+
# Test-only accessor for the connection pool
|
357
|
+
|
358
|
+
attr_reader :pool # :nodoc:
|
359
|
+
|
385
360
|
##
|
386
361
|
# Seconds to wait until reading one block. See Net::HTTP#read_timeout
|
387
362
|
|
388
363
|
attr_accessor :read_timeout
|
389
364
|
|
390
365
|
##
|
391
|
-
#
|
366
|
+
# Seconds to wait until writing one block. See Net::HTTP#write_timeout
|
392
367
|
|
393
|
-
|
368
|
+
attr_accessor :write_timeout
|
394
369
|
|
395
370
|
##
|
396
371
|
# By default SSL sessions are reused to avoid extra SSL handshakes. Set
|
@@ -418,17 +393,33 @@ class Net::HTTP::Persistent
|
|
418
393
|
attr_reader :ssl_generation # :nodoc:
|
419
394
|
|
420
395
|
##
|
421
|
-
#
|
396
|
+
# SSL session lifetime
|
422
397
|
|
423
|
-
attr_reader :
|
398
|
+
attr_reader :ssl_timeout
|
424
399
|
|
425
400
|
##
|
426
401
|
# SSL version to use.
|
427
402
|
#
|
428
403
|
# By default, the version will be negotiated automatically between client
|
429
|
-
# and server. Ruby 1.9 and newer only.
|
404
|
+
# and server. Ruby 1.9 and newer only. Deprecated since Ruby 2.5.
|
430
405
|
|
431
|
-
attr_reader :ssl_version
|
406
|
+
attr_reader :ssl_version
|
407
|
+
|
408
|
+
##
|
409
|
+
# Minimum SSL version to use, e.g. :TLS1_1
|
410
|
+
#
|
411
|
+
# By default, the version will be negotiated automatically between client
|
412
|
+
# and server. Ruby 2.5 and newer only.
|
413
|
+
|
414
|
+
attr_reader :min_version
|
415
|
+
|
416
|
+
##
|
417
|
+
# Maximum SSL version to use, e.g. :TLS1_2
|
418
|
+
#
|
419
|
+
# By default, the version will be negotiated automatically between client
|
420
|
+
# and server. Ruby 2.5 and newer only.
|
421
|
+
|
422
|
+
attr_reader :max_version
|
432
423
|
|
433
424
|
##
|
434
425
|
# Where this instance's last-use times live in the thread local variables
|
@@ -436,38 +427,31 @@ class Net::HTTP::Persistent
|
|
436
427
|
attr_reader :timeout_key # :nodoc:
|
437
428
|
|
438
429
|
##
|
439
|
-
# SSL verification callback. Used when ca_file is set.
|
430
|
+
# SSL verification callback. Used when ca_file or ca_path is set.
|
440
431
|
|
441
432
|
attr_reader :verify_callback
|
442
433
|
|
434
|
+
##
|
435
|
+
# Sets the depth of SSL certificate verification
|
436
|
+
|
437
|
+
attr_reader :verify_depth
|
438
|
+
|
443
439
|
##
|
444
440
|
# HTTPS verify mode. Defaults to OpenSSL::SSL::VERIFY_PEER which verifies
|
445
441
|
# the server certificate.
|
446
442
|
#
|
447
|
-
# If no ca_file or cert_store is set the default system certificate
|
448
|
-
# used.
|
443
|
+
# If no ca_file, ca_path or cert_store is set the default system certificate
|
444
|
+
# store is used.
|
449
445
|
#
|
450
446
|
# You can use +verify_mode+ to override any default values.
|
451
447
|
|
452
448
|
attr_reader :verify_mode
|
453
449
|
|
454
|
-
##
|
455
|
-
# Enable retries of non-idempotent requests that change data (e.g. POST
|
456
|
-
# requests) when the server has disconnected.
|
457
|
-
#
|
458
|
-
# This will in the worst case lead to multiple requests with the same data,
|
459
|
-
# but it may be useful for some applications. Take care when enabling
|
460
|
-
# this option to ensure it is safe to POST or perform other non-idempotent
|
461
|
-
# requests to the server.
|
462
|
-
|
463
|
-
attr_accessor :retry_change_requests
|
464
|
-
|
465
450
|
##
|
466
451
|
# Creates a new Net::HTTP::Persistent.
|
467
452
|
#
|
468
|
-
# Set +name+
|
469
|
-
#
|
470
|
-
# good enough. This parameter will be required in a future version.
|
453
|
+
# Set a +name+ for fun. Your library name should be good enough, but this
|
454
|
+
# otherwise has no purpose.
|
471
455
|
#
|
472
456
|
# +proxy+ may be set to a URI::HTTP or :ENV to pick up proxy options from
|
473
457
|
# the environment. See proxy_from_env for details.
|
@@ -478,8 +462,13 @@ class Net::HTTP::Persistent
|
|
478
462
|
# proxy = URI 'http://proxy.example'
|
479
463
|
# proxy.user = 'AzureDiamond'
|
480
464
|
# proxy.password = 'hunter2'
|
465
|
+
#
|
466
|
+
# Set +pool_size+ to limit the maximum number of connections allowed.
|
467
|
+
# Defaults to 1/4 the number of allowed file handles or 256 if your OS does
|
468
|
+
# not support a limit on allowed file handles. You can have no more than
|
469
|
+
# this many threads with active HTTP transactions.
|
481
470
|
|
482
|
-
def initialize name
|
471
|
+
def initialize name: nil, proxy: nil, pool_size: DEFAULT_POOL_SIZE
|
483
472
|
@name = name
|
484
473
|
|
485
474
|
@debug_output = nil
|
@@ -491,40 +480,41 @@ class Net::HTTP::Persistent
|
|
491
480
|
@keep_alive = 30
|
492
481
|
@open_timeout = nil
|
493
482
|
@read_timeout = nil
|
483
|
+
@write_timeout = nil
|
494
484
|
@idle_timeout = 5
|
495
485
|
@max_requests = nil
|
486
|
+
@max_retries = 1
|
496
487
|
@socket_options = []
|
488
|
+
@ssl_generation = 0 # incremented when SSL session variables change
|
497
489
|
|
498
490
|
@socket_options << [Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1] if
|
499
491
|
Socket.const_defined? :TCP_NODELAY
|
500
492
|
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
@request_key = [key, 'requests' ].join('_').intern
|
505
|
-
@timeout_key = [key, 'timeouts' ].join('_').intern
|
493
|
+
@pool = Net::HTTP::Persistent::Pool.new size: pool_size do |http_args|
|
494
|
+
Net::HTTP::Persistent::Connection.new Net::HTTP, http_args, @ssl_generation
|
495
|
+
end
|
506
496
|
|
507
497
|
@certificate = nil
|
508
498
|
@ca_file = nil
|
499
|
+
@ca_path = nil
|
500
|
+
@ciphers = nil
|
509
501
|
@private_key = nil
|
502
|
+
@ssl_timeout = nil
|
510
503
|
@ssl_version = nil
|
504
|
+
@min_version = nil
|
505
|
+
@max_version = nil
|
511
506
|
@verify_callback = nil
|
507
|
+
@verify_depth = nil
|
512
508
|
@verify_mode = nil
|
513
509
|
@cert_store = nil
|
514
510
|
|
515
511
|
@generation = 0 # incremented when proxy URI changes
|
516
|
-
@ssl_generation = 0 # incremented when SSL session variables change
|
517
512
|
|
518
513
|
if HAVE_OPENSSL then
|
519
514
|
@verify_mode = OpenSSL::SSL::VERIFY_PEER
|
520
515
|
@reuse_ssl_sessions = OpenSSL::SSL.const_defined? :Session
|
521
516
|
end
|
522
517
|
|
523
|
-
@retry_change_requests = false
|
524
|
-
|
525
|
-
@ruby_1 = RUBY_VERSION < '2'
|
526
|
-
@retried_on_ruby_2 = !@ruby_1
|
527
|
-
|
528
518
|
self.proxy = proxy if proxy
|
529
519
|
end
|
530
520
|
|
@@ -549,6 +539,15 @@ class Net::HTTP::Persistent
|
|
549
539
|
reconnect_ssl
|
550
540
|
end
|
551
541
|
|
542
|
+
##
|
543
|
+
# Sets the SSL certificate authority path.
|
544
|
+
|
545
|
+
def ca_path= path
|
546
|
+
@ca_path = path
|
547
|
+
|
548
|
+
reconnect_ssl
|
549
|
+
end
|
550
|
+
|
552
551
|
##
|
553
552
|
# Overrides the default SSL certificate store used for verifying
|
554
553
|
# connections.
|
@@ -560,115 +559,74 @@ class Net::HTTP::Persistent
|
|
560
559
|
end
|
561
560
|
|
562
561
|
##
|
563
|
-
#
|
564
|
-
# the given +generation+ in the threads +generation_key+ list.
|
565
|
-
#
|
566
|
-
# See #shutdown for a bunch of scary warning about misusing this method.
|
567
|
-
|
568
|
-
def cleanup(generation, thread = Thread.current,
|
569
|
-
generation_key = @generation_key) # :nodoc:
|
570
|
-
timeouts = thread[@timeout_key]
|
562
|
+
# The ciphers allowed for SSL connections
|
571
563
|
|
572
|
-
|
573
|
-
|
564
|
+
def ciphers= ciphers
|
565
|
+
@ciphers = ciphers
|
574
566
|
|
575
|
-
|
576
|
-
|
577
|
-
conns.each_value do |conn|
|
578
|
-
finish conn, thread
|
579
|
-
|
580
|
-
timeouts.delete conn.object_id if timeouts
|
581
|
-
end if conns
|
582
|
-
end
|
567
|
+
reconnect_ssl
|
583
568
|
end
|
584
569
|
|
585
570
|
##
|
586
571
|
# Creates a new connection for +uri+
|
587
572
|
|
588
573
|
def connection_for uri
|
589
|
-
Thread.current[@generation_key] ||= Hash.new { |h,k| h[k] = {} }
|
590
|
-
Thread.current[@ssl_generation_key] ||= Hash.new { |h,k| h[k] = {} }
|
591
|
-
Thread.current[@request_key] ||= Hash.new 0
|
592
|
-
Thread.current[@timeout_key] ||= Hash.new EPOCH
|
593
|
-
|
594
574
|
use_ssl = uri.scheme.downcase == 'https'
|
595
575
|
|
596
|
-
|
597
|
-
raise Net::HTTP::Persistent::Error, 'OpenSSL is not available' unless
|
598
|
-
HAVE_OPENSSL
|
599
|
-
|
600
|
-
ssl_generation = @ssl_generation
|
576
|
+
net_http_args = [uri.hostname, uri.port]
|
601
577
|
|
602
|
-
|
603
|
-
|
604
|
-
|
578
|
+
# I'm unsure if uri.host or uri.hostname should be checked against
|
579
|
+
# the proxy bypass list.
|
580
|
+
if @proxy_uri and not proxy_bypass? uri.host, uri.port then
|
581
|
+
net_http_args.concat @proxy_args
|
605
582
|
else
|
606
|
-
|
607
|
-
|
608
|
-
cleanup generation
|
609
|
-
|
610
|
-
connections = Thread.current[@generation_key][generation]
|
583
|
+
net_http_args.concat [nil, nil, nil, nil]
|
611
584
|
end
|
612
585
|
|
613
|
-
|
614
|
-
connection_id = net_http_args.join ':'
|
586
|
+
connection = @pool.checkout net_http_args
|
615
587
|
|
616
|
-
|
617
|
-
connection_id << @proxy_connection_id
|
618
|
-
net_http_args.concat @proxy_args
|
619
|
-
end
|
588
|
+
http = connection.http
|
620
589
|
|
621
|
-
connection
|
590
|
+
connection.ressl @ssl_generation if
|
591
|
+
connection.ssl_generation != @ssl_generation
|
622
592
|
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
reset connection if expired? connection
|
593
|
+
if not http.started? then
|
594
|
+
ssl http if use_ssl
|
595
|
+
start http
|
596
|
+
elsif expired? connection then
|
597
|
+
reset connection
|
629
598
|
end
|
630
599
|
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
600
|
+
http.keep_alive_timeout = @idle_timeout if @idle_timeout
|
601
|
+
http.max_retries = @max_retries if http.respond_to?(:max_retries=)
|
602
|
+
http.read_timeout = @read_timeout if @read_timeout
|
603
|
+
http.write_timeout = @write_timeout if
|
604
|
+
@write_timeout && http.respond_to?(:write_timeout=)
|
635
605
|
|
636
|
-
connection
|
606
|
+
return yield connection
|
637
607
|
rescue Errno::ECONNREFUSED
|
638
|
-
address =
|
639
|
-
port =
|
608
|
+
address = http.proxy_address || http.address
|
609
|
+
port = http.proxy_port || http.port
|
640
610
|
|
641
611
|
raise Error, "connection refused: #{address}:#{port}"
|
642
612
|
rescue Errno::EHOSTDOWN
|
643
|
-
address =
|
644
|
-
port =
|
613
|
+
address = http.proxy_address || http.address
|
614
|
+
port = http.proxy_port || http.port
|
645
615
|
|
646
616
|
raise Error, "host down: #{address}:#{port}"
|
617
|
+
ensure
|
618
|
+
@pool.checkin net_http_args
|
647
619
|
end
|
648
620
|
|
649
621
|
##
|
650
|
-
#
|
651
|
-
# this connection
|
652
|
-
|
653
|
-
def error_message connection
|
654
|
-
requests = Thread.current[@request_key][connection.object_id] - 1 # fixup
|
655
|
-
last_use = Thread.current[@timeout_key][connection.object_id]
|
656
|
-
|
657
|
-
age = Time.now - last_use
|
658
|
-
|
659
|
-
"after #{requests} requests on #{connection.object_id}, " \
|
660
|
-
"last used #{age} seconds ago"
|
661
|
-
end
|
662
|
-
|
663
|
-
##
|
664
|
-
# URI::escape wrapper
|
622
|
+
# CGI::escape wrapper
|
665
623
|
|
666
624
|
def escape str
|
667
625
|
CGI.escape str if str
|
668
626
|
end
|
669
627
|
|
670
628
|
##
|
671
|
-
#
|
629
|
+
# CGI::unescape wrapper
|
672
630
|
|
673
631
|
def unescape str
|
674
632
|
CGI.unescape str if str
|
@@ -680,26 +638,23 @@ class Net::HTTP::Persistent
|
|
680
638
|
# maximum request count, false otherwise.
|
681
639
|
|
682
640
|
def expired? connection
|
683
|
-
requests
|
684
|
-
return true if @max_requests && requests >= @max_requests
|
641
|
+
return true if @max_requests && connection.requests >= @max_requests
|
685
642
|
return false unless @idle_timeout
|
686
643
|
return true if @idle_timeout.zero?
|
687
644
|
|
688
|
-
|
689
|
-
|
690
|
-
Time.now - last_used > @idle_timeout
|
645
|
+
Time.now - connection.last_use > @idle_timeout
|
691
646
|
end
|
692
647
|
|
693
648
|
##
|
694
649
|
# Starts the Net::HTTP +connection+
|
695
650
|
|
696
|
-
def start
|
697
|
-
|
698
|
-
|
651
|
+
def start http
|
652
|
+
http.set_debug_output @debug_output if @debug_output
|
653
|
+
http.open_timeout = @open_timeout if @open_timeout
|
699
654
|
|
700
|
-
|
655
|
+
http.start
|
701
656
|
|
702
|
-
socket =
|
657
|
+
socket = http.instance_variable_get :@socket
|
703
658
|
|
704
659
|
if socket then # for fakeweb
|
705
660
|
@socket_options.each do |option|
|
@@ -711,108 +666,48 @@ class Net::HTTP::Persistent
|
|
711
666
|
##
|
712
667
|
# Finishes the Net::HTTP +connection+
|
713
668
|
|
714
|
-
def finish connection
|
715
|
-
if requests = thread[@request_key] then
|
716
|
-
requests.delete connection.object_id
|
717
|
-
end
|
718
|
-
|
669
|
+
def finish connection
|
719
670
|
connection.finish
|
720
|
-
rescue IOError
|
721
|
-
end
|
722
671
|
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
elsif [:Artifice, :FakeWeb, :WebMock].any? { |klass|
|
727
|
-
Object.const_defined?(klass)
|
728
|
-
} or not @reuse_ssl_sessions then
|
729
|
-
Net::HTTP
|
730
|
-
else
|
731
|
-
Net::HTTP::Persistent::SSLReuse
|
732
|
-
end
|
672
|
+
connection.http.instance_variable_set :@last_communicated, nil
|
673
|
+
connection.http.instance_variable_set :@ssl_session, nil unless
|
674
|
+
@reuse_ssl_sessions
|
733
675
|
end
|
734
676
|
|
735
677
|
##
|
736
678
|
# Returns the HTTP protocol version for +uri+
|
737
679
|
|
738
680
|
def http_version uri
|
739
|
-
@http_versions["#{uri.
|
681
|
+
@http_versions["#{uri.hostname}:#{uri.port}"]
|
740
682
|
end
|
741
683
|
|
742
684
|
##
|
743
|
-
#
|
685
|
+
# Adds "http://" to the String +uri+ if it is missing.
|
744
686
|
|
745
|
-
def
|
746
|
-
|
747
|
-
when Net::HTTP::Delete, Net::HTTP::Get, Net::HTTP::Head,
|
748
|
-
Net::HTTP::Options, Net::HTTP::Put, Net::HTTP::Trace then
|
749
|
-
true
|
750
|
-
end
|
687
|
+
def normalize_uri uri
|
688
|
+
(uri =~ /^https?:/) ? uri : "http://#{uri}"
|
751
689
|
end
|
752
690
|
|
753
691
|
##
|
754
|
-
#
|
692
|
+
# Set the maximum number of retries for a request.
|
755
693
|
#
|
756
|
-
#
|
757
|
-
#
|
758
|
-
|
759
|
-
def can_retry? req, retried_on_ruby_2 = false
|
760
|
-
return @retry_change_requests && !idempotent?(req) if retried_on_ruby_2
|
761
|
-
|
762
|
-
@retry_change_requests || idempotent?(req)
|
763
|
-
end
|
764
|
-
|
765
|
-
if RUBY_VERSION > '1.9' then
|
766
|
-
##
|
767
|
-
# Workaround for missing Net::HTTPHeader#connection_close? on Ruby 1.8
|
768
|
-
|
769
|
-
def connection_close? header
|
770
|
-
header.connection_close?
|
771
|
-
end
|
772
|
-
|
773
|
-
##
|
774
|
-
# Workaround for missing Net::HTTPHeader#connection_keep_alive? on Ruby 1.8
|
775
|
-
|
776
|
-
def connection_keep_alive? header
|
777
|
-
header.connection_keep_alive?
|
778
|
-
end
|
779
|
-
else
|
780
|
-
##
|
781
|
-
# Workaround for missing Net::HTTPRequest#connection_close? on Ruby 1.8
|
782
|
-
|
783
|
-
def connection_close? header
|
784
|
-
header['connection'] =~ /close/ or header['proxy-connection'] =~ /close/
|
785
|
-
end
|
786
|
-
|
787
|
-
##
|
788
|
-
# Workaround for missing Net::HTTPRequest#connection_keep_alive? on Ruby
|
789
|
-
# 1.8
|
790
|
-
|
791
|
-
def connection_keep_alive? header
|
792
|
-
header['connection'] =~ /keep-alive/ or
|
793
|
-
header['proxy-connection'] =~ /keep-alive/
|
794
|
-
end
|
795
|
-
end
|
796
|
-
|
797
|
-
##
|
798
|
-
# Deprecated in favor of #expired?
|
694
|
+
# Defaults to one retry.
|
695
|
+
#
|
696
|
+
# Set this to 0 to disable retries.
|
799
697
|
|
800
|
-
def
|
801
|
-
|
698
|
+
def max_retries= retries
|
699
|
+
retries = retries.to_int
|
802
700
|
|
803
|
-
|
804
|
-
end
|
701
|
+
raise ArgumentError, "max_retries must be positive" if retries < 0
|
805
702
|
|
806
|
-
|
807
|
-
# Adds "http://" to the String +uri+ if it is missing.
|
703
|
+
@max_retries = retries
|
808
704
|
|
809
|
-
|
810
|
-
(uri =~ /^https?:/) ? uri : "http://#{uri}"
|
705
|
+
reconnect
|
811
706
|
end
|
812
707
|
|
813
708
|
##
|
814
709
|
# Pipelines +requests+ to the HTTP server at +uri+ yielding responses if a
|
815
|
-
# block is given. Returns all responses
|
710
|
+
# block is given. Returns all responses received.
|
816
711
|
#
|
817
712
|
# See
|
818
713
|
# Net::HTTP::Pipeline[http://docs.seattlerb.org/net-http-pipeline/Net/HTTP/Pipeline.html]
|
@@ -822,9 +717,9 @@ class Net::HTTP::Persistent
|
|
822
717
|
# <tt>net-http-persistent</tt> #pipeline will be present.
|
823
718
|
|
824
719
|
def pipeline uri, requests, &block # :yields: responses
|
825
|
-
|
826
|
-
|
827
|
-
|
720
|
+
connection_for uri do |connection|
|
721
|
+
connection.http.pipeline requests, &block
|
722
|
+
end
|
828
723
|
end
|
829
724
|
|
830
725
|
##
|
@@ -865,7 +760,7 @@ class Net::HTTP::Persistent
|
|
865
760
|
|
866
761
|
if @proxy_uri then
|
867
762
|
@proxy_args = [
|
868
|
-
@proxy_uri.
|
763
|
+
@proxy_uri.hostname,
|
869
764
|
@proxy_uri.port,
|
870
765
|
unescape(@proxy_uri.user),
|
871
766
|
unescape(@proxy_uri.password),
|
@@ -940,14 +835,15 @@ class Net::HTTP::Persistent
|
|
940
835
|
end
|
941
836
|
|
942
837
|
##
|
943
|
-
# Forces reconnection of HTTP connections
|
838
|
+
# Forces reconnection of all HTTP connections, including TLS/SSL
|
839
|
+
# connections.
|
944
840
|
|
945
841
|
def reconnect
|
946
842
|
@generation += 1
|
947
843
|
end
|
948
844
|
|
949
845
|
##
|
950
|
-
# Forces reconnection of SSL connections.
|
846
|
+
# Forces reconnection of only TLS/SSL connections.
|
951
847
|
|
952
848
|
def reconnect_ssl
|
953
849
|
@ssl_generation += 1
|
@@ -957,18 +853,17 @@ class Net::HTTP::Persistent
|
|
957
853
|
# Finishes then restarts the Net::HTTP +connection+
|
958
854
|
|
959
855
|
def reset connection
|
960
|
-
|
961
|
-
Thread.current[@timeout_key].delete connection.object_id
|
856
|
+
http = connection.http
|
962
857
|
|
963
858
|
finish connection
|
964
859
|
|
965
|
-
start
|
860
|
+
start http
|
966
861
|
rescue Errno::ECONNREFUSED
|
967
|
-
e = Error.new "connection refused: #{
|
862
|
+
e = Error.new "connection refused: #{http.address}:#{http.port}"
|
968
863
|
e.set_backtrace $@
|
969
864
|
raise e
|
970
865
|
rescue Errno::EHOSTDOWN
|
971
|
-
e = Error.new "host down: #{
|
866
|
+
e = Error.new "host down: #{http.address}:#{http.port}"
|
972
867
|
e.set_backtrace $@
|
973
868
|
raise e
|
974
869
|
end
|
@@ -980,84 +875,41 @@ class Net::HTTP::Persistent
|
|
980
875
|
# If a block is passed #request behaves like Net::HTTP#request (the body of
|
981
876
|
# the response will not have been read).
|
982
877
|
#
|
983
|
-
# +req+ must be a Net::
|
984
|
-
#
|
985
|
-
# If there is an error and the request is idempotent according to RFC 2616
|
986
|
-
# it will be retried automatically.
|
878
|
+
# +req+ must be a Net::HTTPGenericRequest subclass (see Net::HTTP for a list).
|
987
879
|
|
988
880
|
def request uri, req = nil, &block
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
881
|
+
uri = URI uri
|
882
|
+
req = request_setup req || uri
|
883
|
+
response = nil
|
884
|
+
|
885
|
+
connection_for uri do |connection|
|
886
|
+
http = connection.http
|
887
|
+
|
888
|
+
begin
|
889
|
+
connection.requests += 1
|
890
|
+
|
891
|
+
response = http.request req, &block
|
892
|
+
|
893
|
+
if req.connection_close? or
|
894
|
+
(response.http_version <= '1.0' and
|
895
|
+
not response.connection_keep_alive?) or
|
896
|
+
response.connection_close? then
|
897
|
+
finish connection
|
898
|
+
end
|
899
|
+
rescue Exception # make sure to close the connection when it was interrupted
|
900
|
+
finish connection
|
901
|
+
|
902
|
+
raise
|
903
|
+
ensure
|
904
|
+
connection.last_use = Time.now
|
1006
905
|
end
|
1007
|
-
rescue Net::HTTPBadResponse => e
|
1008
|
-
message = error_message connection
|
1009
|
-
|
1010
|
-
finish connection
|
1011
|
-
|
1012
|
-
raise Error, "too many bad responses #{message}" if
|
1013
|
-
bad_response or not can_retry? req
|
1014
|
-
|
1015
|
-
bad_response = true
|
1016
|
-
retry
|
1017
|
-
rescue *RETRIED_EXCEPTIONS => e # retried on ruby 2
|
1018
|
-
request_failed e, req, connection if
|
1019
|
-
retried or not can_retry? req, @retried_on_ruby_2
|
1020
|
-
|
1021
|
-
reset connection
|
1022
|
-
|
1023
|
-
retried = true
|
1024
|
-
retry
|
1025
|
-
rescue Errno::EINVAL, Errno::ETIMEDOUT => e # not retried on ruby 2
|
1026
|
-
request_failed e, req, connection if retried or not can_retry? req
|
1027
|
-
|
1028
|
-
reset connection
|
1029
|
-
|
1030
|
-
retried = true
|
1031
|
-
retry
|
1032
|
-
rescue Exception => e
|
1033
|
-
finish connection
|
1034
|
-
|
1035
|
-
raise
|
1036
|
-
ensure
|
1037
|
-
Thread.current[@timeout_key][connection_id] = Time.now
|
1038
906
|
end
|
1039
907
|
|
1040
|
-
@http_versions["#{uri.
|
908
|
+
@http_versions["#{uri.hostname}:#{uri.port}"] ||= response.http_version
|
1041
909
|
|
1042
910
|
response
|
1043
911
|
end
|
1044
912
|
|
1045
|
-
##
|
1046
|
-
# Raises an Error for +exception+ which resulted from attempting the request
|
1047
|
-
# +req+ on the +connection+.
|
1048
|
-
#
|
1049
|
-
# Finishes the +connection+.
|
1050
|
-
|
1051
|
-
def request_failed exception, req, connection # :nodoc:
|
1052
|
-
due_to = "(due to #{exception.message} - #{exception.class})"
|
1053
|
-
message = "too many connection resets #{due_to} #{error_message connection}"
|
1054
|
-
|
1055
|
-
finish connection
|
1056
|
-
|
1057
|
-
|
1058
|
-
raise Error, message, exception.backtrace
|
1059
|
-
end
|
1060
|
-
|
1061
913
|
##
|
1062
914
|
# Creates a GET request if +req_or_uri+ is a URI and adds headers to the
|
1063
915
|
# request.
|
@@ -1065,7 +917,7 @@ class Net::HTTP::Persistent
|
|
1065
917
|
# Returns the request.
|
1066
918
|
|
1067
919
|
def request_setup req_or_uri # :nodoc:
|
1068
|
-
req = if
|
920
|
+
req = if req_or_uri.respond_to? 'request_uri' then
|
1069
921
|
Net::HTTP::Get.new req_or_uri.request_uri
|
1070
922
|
else
|
1071
923
|
req_or_uri
|
@@ -1088,45 +940,15 @@ class Net::HTTP::Persistent
|
|
1088
940
|
end
|
1089
941
|
|
1090
942
|
##
|
1091
|
-
# Shuts down all connections
|
943
|
+
# Shuts down all connections
|
1092
944
|
#
|
1093
|
-
#
|
945
|
+
# *NOTE*: Calling shutdown for can be dangerous!
|
1094
946
|
#
|
1095
|
-
# If
|
1096
|
-
#
|
1097
|
-
#
|
1098
|
-
# *NOTE*: Calling shutdown for another thread can be dangerous!
|
1099
|
-
#
|
1100
|
-
# If the thread is still using the connection it may cause an error! It is
|
1101
|
-
# best to call #shutdown in the thread at the appropriate time instead!
|
1102
|
-
|
1103
|
-
def shutdown thread = Thread.current
|
1104
|
-
generation = reconnect
|
1105
|
-
cleanup generation, thread, @generation_key
|
947
|
+
# If any thread is still using a connection it may cause an error! Call
|
948
|
+
# #shutdown when you are completely done making requests!
|
1106
949
|
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
thread[@request_key] = nil
|
1111
|
-
thread[@timeout_key] = nil
|
1112
|
-
end
|
1113
|
-
|
1114
|
-
##
|
1115
|
-
# Shuts down all connections in all threads
|
1116
|
-
#
|
1117
|
-
# *NOTE*: THIS METHOD IS VERY DANGEROUS!
|
1118
|
-
#
|
1119
|
-
# Do not call this method if other threads are still using their
|
1120
|
-
# connections! Call #shutdown at the appropriate time instead!
|
1121
|
-
#
|
1122
|
-
# Use this method only as a last resort!
|
1123
|
-
|
1124
|
-
def shutdown_in_all_threads
|
1125
|
-
Thread.list.each do |thread|
|
1126
|
-
shutdown thread
|
1127
|
-
end
|
1128
|
-
|
1129
|
-
nil
|
950
|
+
def shutdown
|
951
|
+
@pool.shutdown { |http| http.finish }
|
1130
952
|
end
|
1131
953
|
|
1132
954
|
##
|
@@ -1135,9 +957,14 @@ class Net::HTTP::Persistent
|
|
1135
957
|
def ssl connection
|
1136
958
|
connection.use_ssl = true
|
1137
959
|
|
960
|
+
connection.ciphers = @ciphers if @ciphers
|
961
|
+
connection.ssl_timeout = @ssl_timeout if @ssl_timeout
|
1138
962
|
connection.ssl_version = @ssl_version if @ssl_version
|
963
|
+
connection.min_version = @min_version if @min_version
|
964
|
+
connection.max_version = @max_version if @max_version
|
1139
965
|
|
1140
|
-
connection.
|
966
|
+
connection.verify_depth = @verify_depth
|
967
|
+
connection.verify_mode = @verify_mode
|
1141
968
|
|
1142
969
|
if OpenSSL::SSL::VERIFY_PEER == OpenSSL::SSL::VERIFY_NONE and
|
1143
970
|
not Object.const_defined?(:I_KNOW_THAT_OPENSSL_VERIFY_PEER_EQUALS_VERIFY_NONE_IS_WRONG) then
|
@@ -1166,8 +993,10 @@ application:
|
|
1166
993
|
WARNING
|
1167
994
|
end
|
1168
995
|
|
1169
|
-
if @ca_file
|
1170
|
-
|
996
|
+
connection.ca_file = @ca_file if @ca_file
|
997
|
+
connection.ca_path = @ca_path if @ca_path
|
998
|
+
|
999
|
+
if @ca_file or @ca_path then
|
1171
1000
|
connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
1172
1001
|
connection.verify_callback = @verify_callback if @verify_callback
|
1173
1002
|
end
|
@@ -1187,11 +1016,12 @@ application:
|
|
1187
1016
|
end
|
1188
1017
|
|
1189
1018
|
##
|
1190
|
-
#
|
1191
|
-
|
1019
|
+
# SSL session lifetime
|
1020
|
+
|
1021
|
+
def ssl_timeout= ssl_timeout
|
1022
|
+
@ssl_timeout = ssl_timeout
|
1192
1023
|
|
1193
|
-
|
1194
|
-
cleanup generation, Thread.current, @ssl_generation_key
|
1024
|
+
reconnect_ssl
|
1195
1025
|
end
|
1196
1026
|
|
1197
1027
|
##
|
@@ -1201,7 +1031,34 @@ application:
|
|
1201
1031
|
@ssl_version = ssl_version
|
1202
1032
|
|
1203
1033
|
reconnect_ssl
|
1204
|
-
end
|
1034
|
+
end
|
1035
|
+
|
1036
|
+
##
|
1037
|
+
# Minimum SSL version to use
|
1038
|
+
|
1039
|
+
def min_version= min_version
|
1040
|
+
@min_version = min_version
|
1041
|
+
|
1042
|
+
reconnect_ssl
|
1043
|
+
end
|
1044
|
+
|
1045
|
+
##
|
1046
|
+
# maximum SSL version to use
|
1047
|
+
|
1048
|
+
def max_version= max_version
|
1049
|
+
@max_version = max_version
|
1050
|
+
|
1051
|
+
reconnect_ssl
|
1052
|
+
end
|
1053
|
+
|
1054
|
+
##
|
1055
|
+
# Sets the depth of SSL certificate verification
|
1056
|
+
|
1057
|
+
def verify_depth= verify_depth
|
1058
|
+
@verify_depth = verify_depth
|
1059
|
+
|
1060
|
+
reconnect_ssl
|
1061
|
+
end
|
1205
1062
|
|
1206
1063
|
##
|
1207
1064
|
# Sets the HTTPS verify mode. Defaults to OpenSSL::SSL::VERIFY_PEER.
|
@@ -1224,8 +1081,8 @@ application:
|
|
1224
1081
|
|
1225
1082
|
reconnect_ssl
|
1226
1083
|
end
|
1227
|
-
|
1228
1084
|
end
|
1229
1085
|
|
1230
|
-
|
1086
|
+
require_relative 'persistent/connection'
|
1087
|
+
require_relative 'persistent/pool'
|
1231
1088
|
|