net-http-persistent 1.0

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 ADDED
Binary file
data/.autotest ADDED
@@ -0,0 +1,7 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'autotest/restart'
4
+
5
+ Autotest.add_hook :initialize do |at|
6
+ at.testlib = 'minitest/unit'
7
+ end
data/History.txt ADDED
@@ -0,0 +1,6 @@
1
+ === 1.0.0 / 2010-05-04
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
data/Manifest.txt ADDED
@@ -0,0 +1,8 @@
1
+ .autotest
2
+ History.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ lib/net/http/faster.rb
7
+ lib/net/http/persistent.rb
8
+ test/test_net_http_persistent.rb
data/README.txt ADDED
@@ -0,0 +1,44 @@
1
+ = net_http_persistent
2
+
3
+ * http://seattlerb.rubyforge.org/net-http-persistent
4
+
5
+ == DESCRIPTION:
6
+
7
+ Persistent connections using Net::HTTP plus a speed fix for 1.8. It's
8
+ thread-safe too!
9
+
10
+ == FEATURES/PROBLEMS:
11
+
12
+ * Supports SSL
13
+ * Thread-safe
14
+ * Pure ruby
15
+ * Timeout-less speed boost for 1.8 (by Aaron Patterson)
16
+
17
+ == INSTALL:
18
+
19
+ gem install net-http-persistent
20
+
21
+ == LICENSE:
22
+
23
+ (The MIT License)
24
+
25
+ Copyright (c) 2010 Eric Hodel, Aaron Patterson
26
+
27
+ Permission is hereby granted, free of charge, to any person obtaining
28
+ a copy of this software and associated documentation files (the
29
+ 'Software'), to deal in the Software without restriction, including
30
+ without limitation the rights to use, copy, modify, merge, publish,
31
+ distribute, sublicense, and/or sell copies of the Software, and to
32
+ permit persons to whom the Software is furnished to do so, subject to
33
+ the following conditions:
34
+
35
+ The above copyright notice and this permission notice shall be
36
+ included in all copies or substantial portions of the Software.
37
+
38
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
39
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
40
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
41
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
42
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
43
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
44
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+
6
+ Hoe.plugin :git
7
+
8
+ Hoe.spec 'net-http-persistent' do |p|
9
+ self.rubyforge_name = 'seattlerb'
10
+ developer 'Eric Hodel', 'drbrain@segment7.net'
11
+ end
12
+
13
+ # vim: syntax=Ruby
@@ -0,0 +1,27 @@
1
+ require 'net/protocol'
2
+
3
+ ##
4
+ # Aaron Patterson's monkeypatch (accepted into 1.9.1) to fix Net::HTTP's speed
5
+ # problems.
6
+ #
7
+ # http://gist.github.com/251244
8
+
9
+ class Net::BufferedIO #:nodoc:
10
+ alias :old_rbuf_fill :rbuf_fill
11
+
12
+ def rbuf_fill
13
+ if @io.respond_to? :read_nonblock then
14
+ begin
15
+ @rbuf << @io.read_nonblock(65536)
16
+ rescue Errno::EWOULDBLOCK => e
17
+ retry if IO.select [@io], nil, nil, @read_timeout
18
+ raise Timeout::Error, e.message
19
+ end
20
+ else # SSL sockets do not have read_nonblock
21
+ timeout @read_timeout do
22
+ @rbuf << @io.sysread(65536)
23
+ end
24
+ end
25
+ end
26
+ end
27
+
@@ -0,0 +1,215 @@
1
+ require 'net/http'
2
+ require 'net/http/faster'
3
+ require 'uri'
4
+
5
+ ##
6
+ # Persistent connections for Net::HTTP
7
+ #
8
+ # Net::HTTP::Persistent maintains persistent connections across all the
9
+ # servers you wish to talk to. For each host:port you communicate with a
10
+ # single persistent connection is created.
11
+ #
12
+ # Multiple Net::HTTP::Persistent objects will share the same set of
13
+ # connections.
14
+ #
15
+ # Example:
16
+ #
17
+ # uri = URI.parse 'http://example.com/awesome/web/service'
18
+ # http = Net::HTTP::Persistent
19
+ # stuff = http.request uri # performs a GET
20
+ #
21
+ # # perform a POST
22
+ # post_uri = uri + 'create'
23
+ # post = Net::HTTP::Post.new uri.path
24
+ # post.set_form_data 'some' => 'cool data'
25
+ # http.request post_uri, post # URI is always required
26
+
27
+ class Net::HTTP::Persistent
28
+
29
+ ##
30
+ # The version of Net::HTTP::Persistent use are using
31
+
32
+ VERSION = '1.0'
33
+
34
+ ##
35
+ # Error class for errors raised by Net::HTTP::Persistent. Various
36
+ # SystemCallErrors are re-raised with a human-readable message under this
37
+ # class.
38
+
39
+ class Error < StandardError; end
40
+
41
+ ##
42
+ # This client's OpenSSL::X509::Certificate
43
+
44
+ attr_accessor :certificate
45
+
46
+ ##
47
+ # An SSL certificate authority. Setting this will set verify_mode to
48
+ # VERIFY_PEER.
49
+
50
+ attr_accessor :ca_file
51
+
52
+ ##
53
+ # Headers that are added to every request
54
+
55
+ attr_reader :headers
56
+
57
+ ##
58
+ # The value sent in the Keep-Alive header. Defaults to 30 seconds
59
+
60
+ attr_accessor :keep_alive
61
+
62
+ ##
63
+ # This client's SSL private key
64
+
65
+ attr_accessor :private_key
66
+
67
+ ##
68
+ # SSL verification callback. Used when ca_file is set.
69
+
70
+ attr_accessor :verify_callback
71
+
72
+ ##
73
+ # HTTPS verify mode. Set to OpenSSL::SSL::VERIFY_NONE to ignore certificate
74
+ # problems.
75
+ #
76
+ # You can use +verify_mode+ to override any default values.
77
+
78
+ attr_accessor :verify_mode
79
+
80
+ def initialize # :nodoc:
81
+ @keep_alive = 30
82
+ @headers = {}
83
+
84
+ @certificate = nil
85
+ @ca_file = nil
86
+ @private_key = nil
87
+ @verify_callback = nil
88
+ @verify_mode = nil
89
+ end
90
+
91
+ ##
92
+ # Creates a new connection for +uri+
93
+
94
+ def connection_for uri
95
+ Thread.current[:net_http_persistent_connections] ||= {}
96
+ connections = Thread.current[:net_http_persistent_connections]
97
+
98
+ connection_id = [uri.host, uri.port].join ':'
99
+
100
+ connections[connection_id] ||= Net::HTTP.new uri.host, uri.port
101
+ connection = connections[connection_id]
102
+
103
+ ssl connection if uri.scheme == 'https' and not connection.started?
104
+
105
+ connection.start unless connection.started?
106
+
107
+ connection
108
+ rescue Errno::ECONNREFUSED
109
+ raise Error, "connection refused: #{connection.address}:#{connection.port}"
110
+ end
111
+
112
+ ##
113
+ # Returns an error message containing the number of requests performed on
114
+ # this connection
115
+
116
+ def error_message connection
117
+ requests =
118
+ Thread.current[:net_http_persistent_requests][connection.object_id]
119
+
120
+ "after #{requests} requests on #{connection.object_id}"
121
+ end
122
+
123
+ ##
124
+ # Finishes then restarts the Net::HTTP +connection+
125
+
126
+ def reset connection
127
+ Thread.current[:net_http_persistent_requests].delete connection.object_id
128
+
129
+ begin
130
+ connection.finish
131
+ rescue IOError
132
+ end
133
+
134
+ connection.start
135
+ rescue Errno::ECONNREFUSED
136
+ raise Error, "connection refused: #{connection.address}:#{connection.port}"
137
+ rescue Errno::EHOSTDOWN
138
+ raise Error, "host down: #{connection.address}:#{connection.port}"
139
+ end
140
+
141
+ ##
142
+ # Makes a request on +uri+. If +req+ is nil a Net::HTTP::Get is performed
143
+ # against +uri+.
144
+ #
145
+ # +req+ must be a Net::HTTPRequest subclass (see Net::HTTP for a list).
146
+
147
+ def request uri, req = nil
148
+ Thread.current[:net_http_persistent_requests] ||= Hash.new 0
149
+ retried = false
150
+ bad_response = false
151
+
152
+ req = Net::HTTP::Get.new uri.request_uri unless req
153
+
154
+ headers.each do |pair|
155
+ req.add_field(*pair)
156
+ end
157
+
158
+ req.add_field 'Connection', 'keep-alive'
159
+ req.add_field 'Keep-Alive', @keep_alive
160
+
161
+ connection = connection_for uri
162
+ connection_id = connection.object_id
163
+
164
+ begin
165
+ count = Thread.current[:net_http_persistent_requests][connection_id] += 1
166
+ response = connection.request req
167
+
168
+ rescue Net::HTTPBadResponse => e
169
+ message = error_message connection
170
+
171
+ reset connection
172
+
173
+ raise Error, "too many bad responses #{message}" if bad_response
174
+
175
+ bad_response = true
176
+ retry
177
+ rescue IOError, EOFError, Timeout::Error,
178
+ Errno::ECONNABORTED, Errno::ECONNRESET, Errno::EPIPE => e
179
+ due_to = "(due to #{e.message} - #{e.class})"
180
+ message = error_message connection
181
+
182
+ reset connection
183
+
184
+ raise Error, "too many connection resets #{due_to} #{message}" if retried
185
+
186
+ retried = true
187
+ retry
188
+ end
189
+
190
+ response
191
+ end
192
+
193
+ ##
194
+ # Enables SSL on +connection+
195
+
196
+ def ssl connection
197
+ require 'net/https'
198
+ connection.use_ssl = true
199
+
200
+ if @ca_file then
201
+ connection.ca_file = @ca_file
202
+ connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
203
+ connection.verify_callback = @verify_callback if @verify_callback
204
+ end
205
+
206
+ if @certificate and @private_key then
207
+ connection.cert = @certificate
208
+ connection.key = @private_key
209
+ end
210
+
211
+ connection.verify_mode = @verify_mode if @verify_mode
212
+ end
213
+
214
+ end
215
+
@@ -0,0 +1,244 @@
1
+ require 'minitest/autorun'
2
+ require 'net/http/persistent'
3
+ require 'openssl'
4
+
5
+ class TestNetHttpPersistent < MiniTest::Unit::TestCase
6
+
7
+ def setup
8
+ @http = Net::HTTP::Persistent.new
9
+ @uri = URI.parse 'http://example.com/path'
10
+ end
11
+
12
+ def teardown
13
+ Thread.current[:net_http_persistent_connections] = nil
14
+ Thread.current[:net_http_persistent_requests] = nil
15
+ end
16
+
17
+ def connection
18
+ c = Object.new
19
+ # Net::HTTP
20
+ def c.finish; @finish = true end
21
+ def c.request(req) @req = req; :response end
22
+ def c.reset; @reset = true end
23
+ def c.start; end
24
+
25
+ # util
26
+ def c.req() @req; end
27
+ def c.reset?; @reset end
28
+ def c.started?; true end
29
+ conns["#{@uri.host}:#{@uri.port}"] = c
30
+ c
31
+ end
32
+
33
+ def conns
34
+ Thread.current[:net_http_persistent_connections] ||= {}
35
+ end
36
+
37
+ def reqs
38
+ Thread.current[:net_http_persistent_requests] ||= {}
39
+ end
40
+
41
+ def test_connection_for
42
+ c = @http.connection_for @uri
43
+
44
+ assert c.started?
45
+
46
+ assert_includes conns.keys, 'example.com:80'
47
+ assert_same c, conns['example.com:80']
48
+ end
49
+
50
+ def test_connection_for_cached
51
+ cached = Object.new
52
+ def cached.started?; true end
53
+ conns['example.com:80'] = cached
54
+
55
+ c = @http.connection_for @uri
56
+
57
+ assert c.started?
58
+
59
+ assert_same cached, c
60
+ end
61
+
62
+ def test_connection_for_refused
63
+ cached = Object.new
64
+ def cached.address; 'example.com' end
65
+ def cached.port; 80 end
66
+ def cached.start; raise Errno::ECONNREFUSED end
67
+ def cached.started?; false end
68
+ conns['example.com:80'] = cached
69
+
70
+ e = assert_raises Net::HTTP::Persistent::Error do
71
+ @http.connection_for @uri
72
+ end
73
+
74
+ assert_match %r%connection refused%, e
75
+ end
76
+
77
+ def test_error_message
78
+ c = Object.new
79
+ reqs[c.object_id] = 5
80
+
81
+ assert_equal "after 5 requests on #{c.object_id}", @http.error_message(c)
82
+ end
83
+
84
+ def test_reset
85
+ c = Object.new
86
+ def c.finish; @finished = true end
87
+ def c.finished?; @finished end
88
+ def c.start; @started = true end
89
+ def c.started?; @started end
90
+ reqs[c.object_id] = 5
91
+
92
+ @http.reset c
93
+
94
+ assert c.started?
95
+ assert c.finished?
96
+ assert_nil reqs[c.object_id]
97
+ end
98
+
99
+ def test_reset_io_error
100
+ c = Object.new
101
+ def c.finish; @finished = true; raise IOError end
102
+ def c.finished?; @finished end
103
+ def c.start; @started = true end
104
+ def c.started?; @started end
105
+ reqs[c.object_id] = 5
106
+
107
+ @http.reset c
108
+
109
+ assert c.started?
110
+ assert c.finished?
111
+ end
112
+
113
+ def test_reset_host_down
114
+ c = Object.new
115
+ def c.address; 'example.com' end
116
+ def c.finish; end
117
+ def c.port; 80 end
118
+ def c.start; raise Errno::EHOSTDOWN end
119
+ reqs[c.object_id] = 5
120
+
121
+ e = assert_raises Net::HTTP::Persistent::Error do
122
+ @http.reset c
123
+ end
124
+
125
+ assert_match %r%host down%, e
126
+ end
127
+
128
+ def test_reset_refused
129
+ c = Object.new
130
+ def c.address; 'example.com' end
131
+ def c.finish; end
132
+ def c.port; 80 end
133
+ def c.start; raise Errno::ECONNREFUSED end
134
+ reqs[c.object_id] = 5
135
+
136
+ e = assert_raises Net::HTTP::Persistent::Error do
137
+ @http.reset c
138
+ end
139
+
140
+ assert_match %r%connection refused%, e
141
+ end
142
+
143
+ def test_request
144
+ @http.headers['user-agent'] = 'test ua'
145
+ c = connection
146
+
147
+ res = @http.request @uri
148
+ req = c.req
149
+
150
+ assert_equal :response, res
151
+
152
+ assert_kind_of Net::HTTP::Get, req
153
+ assert_equal '/path', req.path
154
+ assert_equal 'keep-alive', req['connection']
155
+ assert_equal '30', req['keep-alive']
156
+ assert_equal 'test ua', req['user-agent']
157
+
158
+ assert_equal 1, reqs[c.object_id]
159
+ end
160
+
161
+ def test_request_bad_response
162
+ c = connection
163
+ def c.request(*a) raise Net::HTTPBadResponse end
164
+
165
+ e = assert_raises Net::HTTP::Persistent::Error do
166
+ @http.request @uri
167
+ end
168
+
169
+ assert_equal 0, reqs[c.object_id]
170
+ assert_match %r%too many bad responses%, e.message
171
+ end
172
+
173
+ def test_request_reset
174
+ c = connection
175
+ def c.request(*a) raise Errno::ECONNRESET end
176
+
177
+ e = assert_raises Net::HTTP::Persistent::Error do
178
+ @http.request @uri
179
+ end
180
+
181
+ assert_equal 0, reqs[c.object_id]
182
+ assert_match %r%too many connection resets%, e.message
183
+ end
184
+
185
+ def test_request_post
186
+ c = connection
187
+
188
+ post = Net::HTTP::Post.new @uri.path
189
+
190
+ res = @http.request @uri, post
191
+ req = c.req
192
+
193
+ assert_equal :response, res
194
+
195
+ assert_same post, req
196
+ end
197
+
198
+ def test_ssl
199
+ @http.verify_callback = :callback
200
+ c = Net::HTTP.new 'localhost', 80
201
+
202
+ @http.ssl c
203
+
204
+ assert c.use_ssl?
205
+ assert_nil c.verify_mode
206
+ assert_nil c.verify_callback
207
+ end
208
+
209
+ def test_ssl_ca_file
210
+ @http.ca_file = 'ca_file'
211
+ @http.verify_callback = :callback
212
+ c = Net::HTTP.new 'localhost', 80
213
+
214
+ @http.ssl c
215
+
216
+ assert c.use_ssl?
217
+ assert_equal OpenSSL::SSL::VERIFY_PEER, c.verify_mode
218
+ assert_equal :callback, c.verify_callback
219
+ end
220
+
221
+ def test_ssl_certificate
222
+ @http.certificate = :cert
223
+ @http.private_key = :key
224
+ c = Net::HTTP.new 'localhost', 80
225
+
226
+ @http.ssl c
227
+
228
+ assert c.use_ssl?
229
+ assert_equal :cert, c.cert
230
+ assert_equal :key, c.key
231
+ end
232
+
233
+ def test_ssl_verify_mode
234
+ @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
235
+ c = Net::HTTP.new 'localhost', 80
236
+
237
+ @http.ssl c
238
+
239
+ assert c.use_ssl?
240
+ assert_equal OpenSSL::SSL::VERIFY_NONE, c.verify_mode
241
+ end
242
+
243
+ end
244
+
metadata ADDED
@@ -0,0 +1,147 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: net-http-persistent
3
+ version: !ruby/object:Gem::Version
4
+ hash: 15
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ version: "1.0"
10
+ platform: ruby
11
+ authors:
12
+ - Eric Hodel
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain:
16
+ - |
17
+ -----BEGIN CERTIFICATE-----
18
+ MIIDNjCCAh6gAwIBAgIBADANBgkqhkiG9w0BAQUFADBBMRAwDgYDVQQDDAdkcmJy
19
+ YWluMRgwFgYKCZImiZPyLGQBGRYIc2VnbWVudDcxEzARBgoJkiaJk/IsZAEZFgNu
20
+ ZXQwHhcNMDcxMjIxMDIwNDE0WhcNMDgxMjIwMDIwNDE0WjBBMRAwDgYDVQQDDAdk
21
+ cmJyYWluMRgwFgYKCZImiZPyLGQBGRYIc2VnbWVudDcxEzARBgoJkiaJk/IsZAEZ
22
+ FgNuZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbbgLrGLGIDE76
23
+ LV/cvxdEzCuYuS3oG9PrSZnuDweySUfdp/so0cDq+j8bqy6OzZSw07gdjwFMSd6J
24
+ U5ddZCVywn5nnAQ+Ui7jMW54CYt5/H6f2US6U0hQOjJR6cpfiymgxGdfyTiVcvTm
25
+ Gj/okWrQl0NjYOYBpDi+9PPmaH2RmLJu0dB/NylsDnW5j6yN1BEI8MfJRR+HRKZY
26
+ mUtgzBwF1V4KIZQ8EuL6I/nHVu07i6IkrpAgxpXUfdJQJi0oZAqXurAV3yTxkFwd
27
+ g62YrrW26mDe+pZBzR6bpLE+PmXCzz7UxUq3AE0gPHbiMXie3EFE0oxnsU3lIduh
28
+ sCANiQ8BAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
29
+ BBS5k4Z75VSpdM0AclG2UvzFA/VW5DANBgkqhkiG9w0BAQUFAAOCAQEAHagT4lfX
30
+ kP/hDaiwGct7XPuVGbrOsKRVD59FF5kETBxEc9UQ1clKWngf8JoVuEoKD774dW19
31
+ bU0GOVWO+J6FMmT/Cp7nuFJ79egMf/gy4gfUfQMuvfcr6DvZUPIs9P/TlK59iMYF
32
+ DIOQ3DxdF3rMzztNUCizN4taVscEsjCcgW6WkUJnGdqlu3OHWpQxZBJkBTjPCoc6
33
+ UW6on70SFPmAy/5Cq0OJNGEWBfgD9q7rrs/X8GGwUWqXb85RXnUVi/P8Up75E0ag
34
+ 14jEc90kN+C7oI/AGCBN0j6JnEtYIEJZibjjDJTSMWlUKKkj30kq7hlUC2CepJ4v
35
+ x52qPcexcYZR7w==
36
+ -----END CERTIFICATE-----
37
+
38
+ date: 2010-05-04 00:00:00 -07:00
39
+ default_executable:
40
+ dependencies:
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubyforge
43
+ prerelease: false
44
+ requirement: &id001 !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ hash: 9
50
+ segments:
51
+ - 2
52
+ - 0
53
+ - 3
54
+ version: 2.0.3
55
+ type: :development
56
+ version_requirements: *id001
57
+ - !ruby/object:Gem::Dependency
58
+ name: gemcutter
59
+ prerelease: false
60
+ requirement: &id002 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ hash: 11
66
+ segments:
67
+ - 0
68
+ - 5
69
+ - 0
70
+ version: 0.5.0
71
+ type: :development
72
+ version_requirements: *id002
73
+ - !ruby/object:Gem::Dependency
74
+ name: hoe
75
+ prerelease: false
76
+ requirement: &id003 !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ hash: 27
82
+ segments:
83
+ - 2
84
+ - 5
85
+ - 0
86
+ version: 2.5.0
87
+ type: :development
88
+ version_requirements: *id003
89
+ description: |-
90
+ Persistent connections using Net::HTTP plus a speed fix for 1.8. It's
91
+ thread-safe too!
92
+ email:
93
+ - drbrain@segment7.net
94
+ executables: []
95
+
96
+ extensions: []
97
+
98
+ extra_rdoc_files:
99
+ - History.txt
100
+ - Manifest.txt
101
+ - README.txt
102
+ files:
103
+ - .autotest
104
+ - History.txt
105
+ - Manifest.txt
106
+ - README.txt
107
+ - Rakefile
108
+ - lib/net/http/faster.rb
109
+ - lib/net/http/persistent.rb
110
+ - test/test_net_http_persistent.rb
111
+ has_rdoc: true
112
+ homepage: http://seattlerb.rubyforge.org/net-http-persistent
113
+ licenses: []
114
+
115
+ post_install_message:
116
+ rdoc_options:
117
+ - --main
118
+ - README.txt
119
+ require_paths:
120
+ - lib
121
+ required_ruby_version: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ hash: 3
127
+ segments:
128
+ - 0
129
+ version: "0"
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ hash: 3
136
+ segments:
137
+ - 0
138
+ version: "0"
139
+ requirements: []
140
+
141
+ rubyforge_project: seattlerb
142
+ rubygems_version: 1.3.7.pre.1
143
+ signing_key:
144
+ specification_version: 3
145
+ summary: Persistent connections using Net::HTTP plus a speed fix for 1.8
146
+ test_files:
147
+ - test/test_net_http_persistent.rb
metadata.gz.sig ADDED
Binary file