net-http-persistent 1.0.1 → 1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data.tar.gz.sig +0 -0
- data/History.txt +15 -1
- data/lib/net/http/persistent.rb +172 -15
- data/test/test_net_http_persistent.rb +192 -6
- metadata +3 -4
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/History.txt
CHANGED
@@ -1,9 +1,23 @@
|
|
1
|
+
=== 1.1
|
2
|
+
|
3
|
+
* Minor Enhancements
|
4
|
+
* Proxy support, see Net::HTTP::Persistent::new,
|
5
|
+
Net::HTTP::Persistent#proxy_from_env
|
6
|
+
* Added +name+ parameter to Net::HTTP::Persistent::new for separation of
|
7
|
+
connection pools.
|
8
|
+
* Added Net::HTTP::Persistent#shutdown so you can clean up after yourself
|
9
|
+
* Net::HTTP::Persistent now suppresses "peer certificate won't be verified
|
10
|
+
in this SSL session" warning.
|
11
|
+
|
12
|
+
* Bug Fixes
|
13
|
+
* Net::HTTP::Persistent retries requests in accordance with RFC 2616.
|
14
|
+
|
1
15
|
=== 1.0.1 / 2010-05-05
|
2
16
|
|
3
17
|
* Minor Enhancements
|
4
18
|
* Added #debug_output
|
5
19
|
* Now uses Hoe minitest plugin
|
6
|
-
* Bug
|
20
|
+
* Bug Fixes
|
7
21
|
* Tests pass on 1.9
|
8
22
|
|
9
23
|
=== 1.0.0 / 2010-05-04
|
data/lib/net/http/persistent.rb
CHANGED
@@ -12,6 +12,13 @@ require 'uri'
|
|
12
12
|
# Multiple Net::HTTP::Persistent objects will share the same set of
|
13
13
|
# connections.
|
14
14
|
#
|
15
|
+
# For each thread you start a new connection will be created. A
|
16
|
+
# Net::HTTP::Persistent connection will not be shared across threads.
|
17
|
+
#
|
18
|
+
# You can shut down the HTTP connections when done by calling #shutdown. You
|
19
|
+
# should name your Net::HTTP::Persistent object if you intend to call this
|
20
|
+
# method.
|
21
|
+
#
|
15
22
|
# Example:
|
16
23
|
#
|
17
24
|
# uri = URI.parse 'http://example.com/awesome/web/service'
|
@@ -29,7 +36,7 @@ class Net::HTTP::Persistent
|
|
29
36
|
##
|
30
37
|
# The version of Net::HTTP::Persistent use are using
|
31
38
|
|
32
|
-
VERSION = '1.
|
39
|
+
VERSION = '1.1'
|
33
40
|
|
34
41
|
##
|
35
42
|
# Error class for errors raised by Net::HTTP::Persistent. Various
|
@@ -49,6 +56,11 @@ class Net::HTTP::Persistent
|
|
49
56
|
|
50
57
|
attr_accessor :ca_file
|
51
58
|
|
59
|
+
##
|
60
|
+
# Where this instance's connections live in the thread local variables
|
61
|
+
|
62
|
+
attr_reader :connection_key # :nodoc:
|
63
|
+
|
52
64
|
##
|
53
65
|
# Sends debug_output to this IO via Net::HTTP#set_debug_output.
|
54
66
|
#
|
@@ -63,33 +75,97 @@ class Net::HTTP::Persistent
|
|
63
75
|
attr_reader :headers
|
64
76
|
|
65
77
|
##
|
66
|
-
# The value sent in the Keep-Alive header. Defaults to 30
|
78
|
+
# The value sent in the Keep-Alive header. Defaults to 30. Not needed for
|
79
|
+
# HTTP/1.1 servers.
|
80
|
+
#
|
81
|
+
# This may not work correctly for HTTP/1.0 servers
|
82
|
+
#
|
83
|
+
# This method may be removed in a future version as RFC 2616 does not
|
84
|
+
# require this header.
|
67
85
|
|
68
86
|
attr_accessor :keep_alive
|
69
87
|
|
88
|
+
##
|
89
|
+
# A name for this connection. Allows you to keep your connections apart
|
90
|
+
# from everybody else's.
|
91
|
+
|
92
|
+
attr_reader :name
|
93
|
+
|
70
94
|
##
|
71
95
|
# This client's SSL private key
|
72
96
|
|
73
97
|
attr_accessor :private_key
|
74
98
|
|
99
|
+
##
|
100
|
+
# The URL through which requests will be proxied
|
101
|
+
|
102
|
+
attr_reader :proxy_uri
|
103
|
+
|
104
|
+
##
|
105
|
+
# Where this instance's request counts live in the thread local variables
|
106
|
+
|
107
|
+
attr_reader :request_key # :nodoc:
|
108
|
+
|
75
109
|
##
|
76
110
|
# SSL verification callback. Used when ca_file is set.
|
77
111
|
|
78
112
|
attr_accessor :verify_callback
|
79
113
|
|
80
114
|
##
|
81
|
-
# HTTPS verify mode.
|
82
|
-
# problems.
|
115
|
+
# HTTPS verify mode. Defaults to OpenSSL::SSL::VERIFY_NONE which ignores
|
116
|
+
# certificate problems.
|
83
117
|
#
|
84
118
|
# You can use +verify_mode+ to override any default values.
|
85
119
|
|
86
120
|
attr_accessor :verify_mode
|
87
121
|
|
88
|
-
|
122
|
+
##
|
123
|
+
# Creates a new Net::HTTP::Persistent.
|
124
|
+
#
|
125
|
+
# Set +name+ to keep your connections apart from everybody else's. Not
|
126
|
+
# required currently, but highly recommended. Your library name should be
|
127
|
+
# good enough. This parameter will be required in a future version.
|
128
|
+
#
|
129
|
+
# +proxy+ may be set to a URI::HTTP or :ENV to pick up proxy options from
|
130
|
+
# the environment. See proxy_from_env for details.
|
131
|
+
#
|
132
|
+
# In order to use a URI for the proxy you'll need to do some extra work
|
133
|
+
# beyond URI.parse:
|
134
|
+
#
|
135
|
+
# proxy = URI.parse 'http://proxy.example'
|
136
|
+
# proxy.user = 'AzureDiamond'
|
137
|
+
# proxy.password = 'hunter2'
|
138
|
+
|
139
|
+
def initialize name = nil, proxy = nil
|
140
|
+
@name = name
|
141
|
+
|
142
|
+
@proxy_uri = case proxy
|
143
|
+
when :ENV then proxy_from_env
|
144
|
+
when URI::HTTP then proxy
|
145
|
+
when nil then # ignore
|
146
|
+
else raise ArgumentError, 'proxy must be :ENV or a URI::HTTP'
|
147
|
+
end
|
148
|
+
|
149
|
+
if @proxy_uri then
|
150
|
+
@proxy_args = [
|
151
|
+
@proxy_uri.host,
|
152
|
+
@proxy_uri.port,
|
153
|
+
@proxy_uri.user,
|
154
|
+
@proxy_uri.password,
|
155
|
+
]
|
156
|
+
|
157
|
+
@proxy_connection_id = [nil, *@proxy_args].join ':'
|
158
|
+
end
|
159
|
+
|
89
160
|
@debug_output = nil
|
90
161
|
@headers = {}
|
91
162
|
@keep_alive = 30
|
92
163
|
|
164
|
+
key = ['net_http_persistent', name, 'connections'].compact.join '_'
|
165
|
+
@connection_key = key.intern
|
166
|
+
key = ['net_http_persistent', name, 'requests'].compact.join '_'
|
167
|
+
@request_key = key.intern
|
168
|
+
|
93
169
|
@certificate = nil
|
94
170
|
@ca_file = nil
|
95
171
|
@private_key = nil
|
@@ -101,12 +177,18 @@ class Net::HTTP::Persistent
|
|
101
177
|
# Creates a new connection for +uri+
|
102
178
|
|
103
179
|
def connection_for uri
|
104
|
-
Thread.current[
|
105
|
-
connections = Thread.current[
|
180
|
+
Thread.current[@connection_key] ||= {}
|
181
|
+
connections = Thread.current[@connection_key]
|
106
182
|
|
107
|
-
|
183
|
+
net_http_args = [uri.host, uri.port]
|
184
|
+
connection_id = net_http_args.join ':'
|
108
185
|
|
109
|
-
|
186
|
+
if @proxy_uri then
|
187
|
+
connection_id << @proxy_connection_id
|
188
|
+
net_http_args.concat @proxy_args
|
189
|
+
end
|
190
|
+
|
191
|
+
connections[connection_id] ||= Net::HTTP.new(*net_http_args)
|
110
192
|
connection = connections[connection_id]
|
111
193
|
|
112
194
|
unless connection.started? then
|
@@ -128,16 +210,68 @@ class Net::HTTP::Persistent
|
|
128
210
|
|
129
211
|
def error_message connection
|
130
212
|
requests =
|
131
|
-
Thread.current[
|
213
|
+
Thread.current[@request_key][connection.object_id]
|
132
214
|
|
133
215
|
"after #{requests} requests on #{connection.object_id}"
|
134
216
|
end
|
135
217
|
|
218
|
+
##
|
219
|
+
# URI::escape wrapper
|
220
|
+
|
221
|
+
def escape str
|
222
|
+
URI.escape str if str
|
223
|
+
end
|
224
|
+
|
225
|
+
##
|
226
|
+
# Is +req+ idempotent according to RFC 2616?
|
227
|
+
|
228
|
+
def idempotent? req
|
229
|
+
case req
|
230
|
+
when Net::HTTP::Delete, Net::HTTP::Get, Net::HTTP::Head,
|
231
|
+
Net::HTTP::Options, Net::HTTP::Put, Net::HTTP::Trace then
|
232
|
+
true
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
##
|
237
|
+
# Adds "http://" to the String +uri+ if it is missing.
|
238
|
+
|
239
|
+
def normalize_uri uri
|
240
|
+
(uri =~ /^https?:/) ? uri : "http://#{uri}"
|
241
|
+
end
|
242
|
+
|
243
|
+
##
|
244
|
+
# Creates a URI for an HTTP proxy server from ENV variables.
|
245
|
+
#
|
246
|
+
# If +HTTP_PROXY+ is set a proxy will be returned.
|
247
|
+
#
|
248
|
+
# If +HTTP_PROXY_USER+ or +HTTP_PROXY_PASS+ are set the URI is given the
|
249
|
+
# indicated user and password unless HTTP_PROXY contains either of these in
|
250
|
+
# the URI.
|
251
|
+
#
|
252
|
+
# For Windows users lowercase ENV variables are preferred over uppercase ENV
|
253
|
+
# variables.
|
254
|
+
|
255
|
+
def proxy_from_env
|
256
|
+
env_proxy = ENV['http_proxy'] || ENV['HTTP_PROXY']
|
257
|
+
|
258
|
+
return nil if env_proxy.nil? or env_proxy.empty?
|
259
|
+
|
260
|
+
uri = URI.parse normalize_uri env_proxy
|
261
|
+
|
262
|
+
unless uri.user or uri.password then
|
263
|
+
uri.user = escape ENV['http_proxy_user'] || ENV['HTTP_PROXY_USER']
|
264
|
+
uri.password = escape ENV['http_proxy_pass'] || ENV['HTTP_PROXY_PASS']
|
265
|
+
end
|
266
|
+
|
267
|
+
uri
|
268
|
+
end
|
269
|
+
|
136
270
|
##
|
137
271
|
# Finishes then restarts the Net::HTTP +connection+
|
138
272
|
|
139
273
|
def reset connection
|
140
|
-
Thread.current[
|
274
|
+
Thread.current[@request_key].delete connection.object_id
|
141
275
|
|
142
276
|
begin
|
143
277
|
connection.finish
|
@@ -156,9 +290,12 @@ class Net::HTTP::Persistent
|
|
156
290
|
# against +uri+.
|
157
291
|
#
|
158
292
|
# +req+ must be a Net::HTTPRequest subclass (see Net::HTTP for a list).
|
293
|
+
#
|
294
|
+
# If there is an error and the request is idempontent according to RFC 2616
|
295
|
+
# it will be retried automatically.
|
159
296
|
|
160
297
|
def request uri, req = nil
|
161
|
-
Thread.current[
|
298
|
+
Thread.current[@request_key] ||= Hash.new 0
|
162
299
|
retried = false
|
163
300
|
bad_response = false
|
164
301
|
|
@@ -175,7 +312,7 @@ class Net::HTTP::Persistent
|
|
175
312
|
connection_id = connection.object_id
|
176
313
|
|
177
314
|
begin
|
178
|
-
count = Thread.current[
|
315
|
+
count = Thread.current[@request_key][connection_id] += 1
|
179
316
|
response = connection.request req
|
180
317
|
|
181
318
|
rescue Net::HTTPBadResponse => e
|
@@ -183,7 +320,8 @@ class Net::HTTP::Persistent
|
|
183
320
|
|
184
321
|
reset connection
|
185
322
|
|
186
|
-
raise Error, "too many bad responses #{message}" if
|
323
|
+
raise Error, "too many bad responses #{message}" if
|
324
|
+
bad_response or not idempotent? req
|
187
325
|
|
188
326
|
bad_response = true
|
189
327
|
retry
|
@@ -194,7 +332,8 @@ class Net::HTTP::Persistent
|
|
194
332
|
|
195
333
|
reset connection
|
196
334
|
|
197
|
-
raise Error, "too many connection resets #{due_to} #{message}" if
|
335
|
+
raise Error, "too many connection resets #{due_to} #{message}" if
|
336
|
+
retried or not idempotent? req
|
198
337
|
|
199
338
|
retried = true
|
200
339
|
retry
|
@@ -203,6 +342,21 @@ class Net::HTTP::Persistent
|
|
203
342
|
response
|
204
343
|
end
|
205
344
|
|
345
|
+
##
|
346
|
+
# Shuts down all connections in this thread.
|
347
|
+
#
|
348
|
+
# If you've used Net::HTTP::Persistent across multiple threads you must call
|
349
|
+
# this in each thread.
|
350
|
+
|
351
|
+
def shutdown
|
352
|
+
Thread.current[@connection_key].each do |_, connection|
|
353
|
+
connection.finish
|
354
|
+
end
|
355
|
+
|
356
|
+
Thread.current[@connection_key] = nil
|
357
|
+
Thread.current[@request_key] = nil
|
358
|
+
end
|
359
|
+
|
206
360
|
##
|
207
361
|
# Enables SSL on +connection+
|
208
362
|
|
@@ -210,6 +364,9 @@ class Net::HTTP::Persistent
|
|
210
364
|
require 'net/https'
|
211
365
|
connection.use_ssl = true
|
212
366
|
|
367
|
+
# suppress warning but allow override
|
368
|
+
connection.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @verify_mode
|
369
|
+
|
213
370
|
if @ca_file then
|
214
371
|
connection.ca_file = @ca_file
|
215
372
|
connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
@@ -3,22 +3,35 @@ require 'net/http/persistent'
|
|
3
3
|
require 'openssl'
|
4
4
|
require 'stringio'
|
5
5
|
|
6
|
+
class Net::HTTP
|
7
|
+
def connect
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
6
11
|
class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
7
12
|
|
8
13
|
def setup
|
9
14
|
@http = Net::HTTP::Persistent.new
|
10
15
|
@uri = URI.parse 'http://example.com/path'
|
16
|
+
|
17
|
+
ENV.delete 'http_proxy'
|
18
|
+
ENV.delete 'HTTP_PROXY'
|
19
|
+
ENV.delete 'http_proxy_user'
|
20
|
+
ENV.delete 'HTTP_PROXY_USER'
|
21
|
+
ENV.delete 'http_proxy_pass'
|
22
|
+
ENV.delete 'HTTP_PROXY_PASS'
|
11
23
|
end
|
12
24
|
|
13
25
|
def teardown
|
14
|
-
Thread.current
|
15
|
-
|
26
|
+
Thread.current.keys.each do |key|
|
27
|
+
Thread.current[key] = nil
|
28
|
+
end
|
16
29
|
end
|
17
30
|
|
18
31
|
def connection
|
19
32
|
c = Object.new
|
20
33
|
# Net::HTTP
|
21
|
-
def c.finish; @
|
34
|
+
def c.finish; @finished = true end
|
22
35
|
def c.request(req) @req = req; :response end
|
23
36
|
def c.reset; @reset = true end
|
24
37
|
def c.start; end
|
@@ -27,22 +40,48 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
27
40
|
def c.req() @req; end
|
28
41
|
def c.reset?; @reset end
|
29
42
|
def c.started?; true end
|
43
|
+
def c.finished?; @finished end
|
30
44
|
conns["#{@uri.host}:#{@uri.port}"] = c
|
31
45
|
c
|
32
46
|
end
|
33
47
|
|
34
48
|
def conns
|
35
|
-
Thread.current[
|
49
|
+
Thread.current[@http.connection_key] ||= {}
|
36
50
|
end
|
37
51
|
|
38
52
|
def reqs
|
39
|
-
Thread.current[
|
53
|
+
Thread.current[@http.request_key] ||= {}
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_initialize
|
57
|
+
assert_nil @http.proxy_uri
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_initialize_name
|
61
|
+
http = Net::HTTP::Persistent.new 'name'
|
62
|
+
assert_equal 'name', http.name
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_initialize_env
|
66
|
+
ENV['HTTP_PROXY'] = 'proxy.example'
|
67
|
+
http = Net::HTTP::Persistent.new nil, :ENV
|
68
|
+
|
69
|
+
assert_equal URI.parse('http://proxy.example'), http.proxy_uri
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_initialize_uri
|
73
|
+
proxy_uri = URI.parse 'http://proxy.example'
|
74
|
+
|
75
|
+
http = Net::HTTP::Persistent.new nil, proxy_uri
|
76
|
+
|
77
|
+
assert_equal proxy_uri, http.proxy_uri
|
40
78
|
end
|
41
79
|
|
42
80
|
def test_connection_for
|
43
81
|
c = @http.connection_for @uri
|
44
82
|
|
45
83
|
assert c.started?
|
84
|
+
refute c.proxy?
|
46
85
|
|
47
86
|
assert_includes conns.keys, 'example.com:80'
|
48
87
|
assert_same c, conns['example.com:80']
|
@@ -73,6 +112,34 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
73
112
|
assert_same c, conns['example.com:80']
|
74
113
|
end
|
75
114
|
|
115
|
+
def test_connection_for_name
|
116
|
+
http = Net::HTTP::Persistent.new 'name'
|
117
|
+
uri = URI.parse 'http://example/'
|
118
|
+
|
119
|
+
c = http.connection_for uri
|
120
|
+
|
121
|
+
assert c.started?
|
122
|
+
|
123
|
+
refute_includes conns.keys, 'example:80'
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_connection_for_proxy
|
127
|
+
uri = URI.parse 'http://proxy.example'
|
128
|
+
uri.user = 'johndoe'
|
129
|
+
uri.password = 'muffins'
|
130
|
+
|
131
|
+
http = Net::HTTP::Persistent.new nil, uri
|
132
|
+
|
133
|
+
c = http.connection_for @uri
|
134
|
+
|
135
|
+
assert c.started?
|
136
|
+
assert c.proxy?
|
137
|
+
|
138
|
+
assert_includes conns.keys,
|
139
|
+
'example.com:80:proxy.example:80:johndoe:muffins'
|
140
|
+
assert_same c, conns['example.com:80:proxy.example:80:johndoe:muffins']
|
141
|
+
end
|
142
|
+
|
76
143
|
def test_connection_for_refused
|
77
144
|
cached = Object.new
|
78
145
|
def cached.address; 'example.com' end
|
@@ -95,6 +162,69 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
95
162
|
assert_equal "after 5 requests on #{c.object_id}", @http.error_message(c)
|
96
163
|
end
|
97
164
|
|
165
|
+
def test_escape
|
166
|
+
assert_nil @http.escape nil
|
167
|
+
|
168
|
+
assert_equal '%20', @http.escape(' ')
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_idempotent_eh
|
172
|
+
assert @http.idempotent? Net::HTTP::Delete.new '/'
|
173
|
+
assert @http.idempotent? Net::HTTP::Get.new '/'
|
174
|
+
assert @http.idempotent? Net::HTTP::Head.new '/'
|
175
|
+
assert @http.idempotent? Net::HTTP::Options.new '/'
|
176
|
+
assert @http.idempotent? Net::HTTP::Put.new '/'
|
177
|
+
assert @http.idempotent? Net::HTTP::Trace.new '/'
|
178
|
+
|
179
|
+
refute @http.idempotent? Net::HTTP::Post.new '/'
|
180
|
+
end
|
181
|
+
|
182
|
+
def test_normalize_uri
|
183
|
+
assert_equal 'http://example', @http.normalize_uri('example')
|
184
|
+
assert_equal 'http://example', @http.normalize_uri('http://example')
|
185
|
+
assert_equal 'https://example', @http.normalize_uri('https://example')
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_proxy_from_env
|
189
|
+
ENV['HTTP_PROXY'] = 'proxy.example'
|
190
|
+
ENV['HTTP_PROXY_USER'] = 'johndoe'
|
191
|
+
ENV['HTTP_PROXY_PASS'] = 'muffins'
|
192
|
+
|
193
|
+
uri = @http.proxy_from_env
|
194
|
+
|
195
|
+
expected = URI.parse 'http://proxy.example'
|
196
|
+
expected.user = 'johndoe'
|
197
|
+
expected.password = 'muffins'
|
198
|
+
|
199
|
+
assert_equal expected, uri
|
200
|
+
end
|
201
|
+
|
202
|
+
def test_proxy_from_env_lower
|
203
|
+
ENV['http_proxy'] = 'proxy.example'
|
204
|
+
ENV['http_proxy_user'] = 'johndoe'
|
205
|
+
ENV['http_proxy_pass'] = 'muffins'
|
206
|
+
|
207
|
+
uri = @http.proxy_from_env
|
208
|
+
|
209
|
+
expected = URI.parse 'http://proxy.example'
|
210
|
+
expected.user = 'johndoe'
|
211
|
+
expected.password = 'muffins'
|
212
|
+
|
213
|
+
assert_equal expected, uri
|
214
|
+
end
|
215
|
+
|
216
|
+
def test_proxy_from_env_nil
|
217
|
+
uri = @http.proxy_from_env
|
218
|
+
|
219
|
+
assert_nil uri
|
220
|
+
|
221
|
+
ENV['HTTP_PROXY'] = ''
|
222
|
+
|
223
|
+
uri = @http.proxy_from_env
|
224
|
+
|
225
|
+
assert_nil uri
|
226
|
+
end
|
227
|
+
|
98
228
|
def test_reset
|
99
229
|
c = Object.new
|
100
230
|
def c.finish; @finished = true end
|
@@ -184,6 +314,25 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
184
314
|
assert_match %r%too many bad responses%, e.message
|
185
315
|
end
|
186
316
|
|
317
|
+
def test_request_bad_response_unsafe
|
318
|
+
c = connection
|
319
|
+
def c.request(*a)
|
320
|
+
if instance_variable_defined? :@request then
|
321
|
+
raise 'POST must not be retried'
|
322
|
+
else
|
323
|
+
@request = true
|
324
|
+
raise Net::HTTPBadResponse
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
e = assert_raises Net::HTTP::Persistent::Error do
|
329
|
+
@http.request @uri, Net::HTTP::Post.new(@uri.path)
|
330
|
+
end
|
331
|
+
|
332
|
+
assert_equal 0, reqs[c.object_id]
|
333
|
+
assert_match %r%too many bad responses%, e.message
|
334
|
+
end
|
335
|
+
|
187
336
|
def test_request_reset
|
188
337
|
c = connection
|
189
338
|
def c.request(*a) raise Errno::ECONNRESET end
|
@@ -196,6 +345,25 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
196
345
|
assert_match %r%too many connection resets%, e.message
|
197
346
|
end
|
198
347
|
|
348
|
+
def test_request_reset_unsafe
|
349
|
+
c = connection
|
350
|
+
def c.request(*a)
|
351
|
+
if instance_variable_defined? :@request then
|
352
|
+
raise 'POST must not be retried'
|
353
|
+
else
|
354
|
+
@request = true
|
355
|
+
raise Errno::ECONNRESET
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
e = assert_raises Net::HTTP::Persistent::Error do
|
360
|
+
@http.request @uri, Net::HTTP::Post.new(@uri.path)
|
361
|
+
end
|
362
|
+
|
363
|
+
assert_equal 0, reqs[c.object_id]
|
364
|
+
assert_match %r%too many connection resets%, e.message
|
365
|
+
end
|
366
|
+
|
199
367
|
def test_request_post
|
200
368
|
c = connection
|
201
369
|
|
@@ -209,6 +377,24 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
209
377
|
assert_same post, req
|
210
378
|
end
|
211
379
|
|
380
|
+
def test_shutdown
|
381
|
+
c = connection
|
382
|
+
cs = conns
|
383
|
+
rs = reqs
|
384
|
+
|
385
|
+
orig = @http
|
386
|
+
@http = Net::HTTP::Persistent.new 'name'
|
387
|
+
c2 = connection
|
388
|
+
|
389
|
+
orig.shutdown
|
390
|
+
|
391
|
+
assert c.finished?
|
392
|
+
refute c2.finished?
|
393
|
+
|
394
|
+
refute_same cs, conns
|
395
|
+
refute_same rs, reqs
|
396
|
+
end
|
397
|
+
|
212
398
|
def test_ssl
|
213
399
|
@http.verify_callback = :callback
|
214
400
|
c = Net::HTTP.new 'localhost', 80
|
@@ -216,7 +402,7 @@ class TestNetHttpPersistent < MiniTest::Unit::TestCase
|
|
216
402
|
@http.ssl c
|
217
403
|
|
218
404
|
assert c.use_ssl?
|
219
|
-
|
405
|
+
assert_equal OpenSSL::SSL::VERIFY_NONE, c.verify_mode
|
220
406
|
assert_nil c.verify_callback
|
221
407
|
end
|
222
408
|
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: net-http-persistent
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 13
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
- 0
|
9
8
|
- 1
|
10
|
-
version: 1.
|
9
|
+
version: "1.1"
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Eric Hodel
|
@@ -36,7 +35,7 @@ cert_chain:
|
|
36
35
|
x52qPcexcYZR7w==
|
37
36
|
-----END CERTIFICATE-----
|
38
37
|
|
39
|
-
date: 2010-05-
|
38
|
+
date: 2010-05-18 00:00:00 -07:00
|
40
39
|
default_executable:
|
41
40
|
dependencies:
|
42
41
|
- !ruby/object:Gem::Dependency
|
metadata.gz.sig
CHANGED
Binary file
|