persistent_http 1.0.1 → 1.0.2

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/History.md ADDED
@@ -0,0 +1,17 @@
1
+ PersistentHttp Changelog
2
+ =====================
3
+
4
+ 1.0.2
5
+
6
+ - Allow options to request to allow changing of read_timeout and possibly other params.
7
+ - Add ECONNREFUSED as a retriable exception.
8
+
9
+ 1.0.1
10
+
11
+ - Bug fixes.
12
+ - Forgot gene_pool dependency
13
+
14
+ 1.0.0
15
+
16
+ - Initial release
17
+
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010 Eric Hodel, Aaron Patterson
1
+ Copyright (c) 2010-2012 Eric Hodel, Aaron Patterson, Brad Pardee
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -1,17 +1,35 @@
1
+ # encoding: UTF-8
1
2
  require 'rubygems'
2
- require 'rake'
3
-
4
3
  begin
5
- require 'jeweler'
6
- Jeweler::Tasks.new do |gemspec|
7
- gemspec.name = "persistent_http"
8
- gemspec.summary = "Persistent HTTP connections using a connection pool"
9
- gemspec.description = "Persistent HTTP connections using a connection pool"
10
- gemspec.email = "bradpardee@gmail.com"
11
- gemspec.homepage = "http://github.com/bpardee/persistent_http"
12
- gemspec.authors = ["Brad Pardee"]
13
- gemspec.add_dependency 'gene_pool', [">= 1.0.1"]
14
- end
4
+ require 'bundler/setup'
15
5
  rescue LoadError
16
- puts "Jeweler not available. Install it with: gem install jeweler"
6
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
7
+ end
8
+
9
+ require 'rake'
10
+ #require 'rake/dsl_definition'
11
+ require 'rdoc/task'
12
+ require 'rake/testtask'
13
+ require 'rake/clean'
14
+
15
+ desc "Build gem"
16
+ task :gem do |t|
17
+ system 'gem build persistent_http.gemspec'
18
+ end
19
+
20
+ Rake::TestTask.new(:test) do |t|
21
+ t.libs << 'lib'
22
+ t.libs << 'test'
23
+ t.pattern = 'test/**/*_test.rb'
24
+ t.verbose = false
25
+ end
26
+
27
+ task :default => :test
28
+
29
+ RDoc::Task.new(:rdoc) do |rdoc|
30
+ rdoc.rdoc_dir = 'rdoc'
31
+ rdoc.title = 'PersistentHttp'
32
+ rdoc.options << '--line-numbers' << '--inline-source'
33
+ rdoc.rdoc_files.include('README.rdoc')
34
+ rdoc.rdoc_files.include('lib/**/*.rb')
17
35
  end
@@ -258,7 +258,7 @@ class PersistentHTTP
258
258
  # If there is an error and the request is idempontent according to RFC 2616
259
259
  # it will be retried automatically.
260
260
 
261
- def request req = nil, &block
261
+ def request(req = nil, options = {}, &block)
262
262
  retried = false
263
263
  bad_response = false
264
264
 
@@ -273,12 +273,15 @@ class PersistentHTTP
273
273
 
274
274
  @pool.with_connection do |connection|
275
275
  begin
276
+ options.each do |key, value|
277
+ connection.send("#{key}=", value)
278
+ end
276
279
  response = connection.request req, &block
277
280
  @http_version ||= response.http_version
278
281
  @count_hash[connection.object_id] += 1
279
282
  return response
280
283
 
281
- rescue Timeout::Error => e
284
+ rescue Timeout::Error => e
282
285
  due_to = "(due to #{e.message} - #{e.class})"
283
286
  message = error_message connection
284
287
  @logger.info "#{name}: Removing connection #{due_to} #{message}" if @logger
@@ -298,7 +301,7 @@ class PersistentHTTP
298
301
  retry
299
302
  end
300
303
 
301
- rescue IOError, EOFError, Errno::ECONNABORTED, Errno::ECONNRESET, Errno::EPIPE => e
304
+ rescue IOError, EOFError, Errno::ECONNABORTED, Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::EPIPE => e
302
305
  due_to = "(due to #{e.message} - #{e.class})"
303
306
  message = error_message connection
304
307
  if retried or not (idempotent? req or @force_retry)
metadata CHANGED
@@ -1,85 +1,62 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: persistent_http
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 1
7
- - 0
8
- - 1
9
- version: 1.0.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.2
5
+ prerelease:
10
6
  platform: ruby
11
- authors:
12
- - Brad Pardee
7
+ authors:
8
+ - Brad Pardee
13
9
  autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
-
17
- date: 2010-10-04 00:00:00 -04:00
18
- default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
21
- name: gene_pool
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
- requirements:
25
- - - ">="
26
- - !ruby/object:Gem::Version
27
- segments:
28
- - 1
29
- - 0
30
- - 1
31
- version: 1.0.1
32
- type: :runtime
33
- version_requirements: *id001
12
+ date: 2012-02-03 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: gene_pool
16
+ requirement: &70318434795540 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.0.1
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70318434795540
34
25
  description: Persistent HTTP connections using a connection pool
35
- email: bradpardee@gmail.com
26
+ email:
27
+ - bradpardee@gmail.com
36
28
  executables: []
37
-
38
29
  extensions: []
39
-
40
- extra_rdoc_files:
41
- - LICENSE
42
- - README.rdoc
43
- files:
44
- - .gitignore
45
- - History.txt
46
- - LICENSE
47
- - README.rdoc
48
- - Rakefile
49
- - VERSION
50
- - lib/persistent_http.rb
51
- - lib/persistent_http/faster.rb
52
- - persistent_http.gemspec
53
- - test/persistent_http_test.rb
54
- has_rdoc: true
30
+ extra_rdoc_files: []
31
+ files:
32
+ - lib/persistent_http/faster.rb
33
+ - lib/persistent_http.rb
34
+ - LICENSE
35
+ - Rakefile
36
+ - History.md
37
+ - README.rdoc
55
38
  homepage: http://github.com/bpardee/persistent_http
56
39
  licenses: []
57
-
58
40
  post_install_message:
59
- rdoc_options:
60
- - --charset=UTF-8
61
- require_paths:
62
- - lib
63
- required_ruby_version: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - ">="
66
- - !ruby/object:Gem::Version
67
- segments:
68
- - 0
69
- version: "0"
70
- required_rubygems_version: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - ">="
73
- - !ruby/object:Gem::Version
74
- segments:
75
- - 0
76
- version: "0"
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ! '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
77
56
  requirements: []
78
-
79
57
  rubyforge_project:
80
- rubygems_version: 1.3.6
58
+ rubygems_version: 1.8.10
81
59
  signing_key:
82
60
  specification_version: 3
83
61
  summary: Persistent HTTP connections using a connection pool
84
- test_files:
85
- - test/persistent_http_test.rb
62
+ test_files: []
data/.gitignore DELETED
@@ -1,4 +0,0 @@
1
- /TAGS
2
- /pkg
3
- /doc
4
- *.swp
data/History.txt DELETED
@@ -1,4 +0,0 @@
1
- === 1.0.0 / 2010-09-16
2
-
3
- * Major Enhancements
4
- * Based on drbrain/net-http-persistent but uses a connection pool instead of connection/thread
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 1.0.1
@@ -1,53 +0,0 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
- # -*- encoding: utf-8 -*-
5
-
6
- Gem::Specification.new do |s|
7
- s.name = %q{persistent_http}
8
- s.version = "1.0.1"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Brad Pardee"]
12
- s.date = %q{2010-10-04}
13
- s.description = %q{Persistent HTTP connections using a connection pool}
14
- s.email = %q{bradpardee@gmail.com}
15
- s.extra_rdoc_files = [
16
- "LICENSE",
17
- "README.rdoc"
18
- ]
19
- s.files = [
20
- ".gitignore",
21
- "History.txt",
22
- "LICENSE",
23
- "README.rdoc",
24
- "Rakefile",
25
- "VERSION",
26
- "lib/persistent_http.rb",
27
- "lib/persistent_http/faster.rb",
28
- "persistent_http.gemspec",
29
- "test/persistent_http_test.rb"
30
- ]
31
- s.homepage = %q{http://github.com/bpardee/persistent_http}
32
- s.rdoc_options = ["--charset=UTF-8"]
33
- s.require_paths = ["lib"]
34
- s.rubygems_version = %q{1.3.6}
35
- s.summary = %q{Persistent HTTP connections using a connection pool}
36
- s.test_files = [
37
- "test/persistent_http_test.rb"
38
- ]
39
-
40
- if s.respond_to? :specification_version then
41
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
42
- s.specification_version = 3
43
-
44
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
45
- s.add_runtime_dependency(%q<gene_pool>, [">= 1.0.1"])
46
- else
47
- s.add_dependency(%q<gene_pool>, [">= 1.0.1"])
48
- end
49
- else
50
- s.add_dependency(%q<gene_pool>, [">= 1.0.1"])
51
- end
52
- end
53
-
@@ -1,647 +0,0 @@
1
- require 'rubygems'
2
- require 'test/unit'
3
- require 'shoulda'
4
- require 'persistent_http'
5
- require 'openssl'
6
- require 'stringio'
7
- require 'logger'
8
-
9
- CMD_SUCCESS = 'success'
10
- CMD_SLEEP = 'sleep'
11
- CMD_BAD_RESPONSE = 'bad_response'
12
- CMD_EOF_ERROR = 'eof_error'
13
- CMD_CONNRESET = 'connreset'
14
- CMD_ECHO = 'echo'
15
-
16
- PASS = 'pass'
17
- FAIL = 'fail'
18
-
19
- DUMMY_OPEN_TIMEOUT_FOR_HOSTDOWN = 9000
20
- DUMMY_OPEN_TIMEOUT_FOR_CONNREFUSED = 9001
21
-
22
- $debug = false
23
- $count = -1
24
-
25
- class Net::HTTP
26
- def connect
27
- raise Errno::EHOSTDOWN if open_timeout == DUMMY_OPEN_TIMEOUT_FOR_HOSTDOWN
28
- raise Errno::ECONNREFUSED if open_timeout == DUMMY_OPEN_TIMEOUT_FOR_CONNREFUSED
29
- end
30
-
31
- def successful_response
32
- r = Net::HTTPResponse.allocate
33
- def r.http_version() '1.1'; end
34
- def r.read_body() :read_body; end
35
- yield r if block_given?
36
- r
37
- end
38
-
39
- def request(req, &block)
40
- $count += 1
41
- puts "path=#{req.path} count=#{$count}" if $debug
42
- args = req.path[1..-1].split('/')
43
- cmd = args.shift
44
- i = $count % args.size if args.size > 0
45
- puts "i=#{i}" if $debug
46
- if cmd == CMD_ECHO
47
- res = successful_response(&block)
48
- eval "def res.body() \"#{req.body}\" end"
49
- return res
50
- elsif cmd == CMD_SUCCESS || args[i] == PASS
51
- return successful_response(&block)
52
- end
53
- case cmd
54
- when CMD_SLEEP
55
- sleep args[i].to_i
56
- return successful_response(&block)
57
- when CMD_BAD_RESPONSE
58
- raise Net::HTTPBadResponse.new('Dummy bad response')
59
- when CMD_EOF_ERROR
60
- raise EOFError.new('Dummy EOF error')
61
- when CMD_CONNRESET
62
- raise Errno::ECONNRESET
63
- else
64
- return successful_response(&block)
65
- end
66
- end
67
- end
68
-
69
- class PersistentHTTP
70
- attr_reader :pool
71
-
72
- # Make private methods public
73
- send(:public, *(self.private_instance_methods - Object.private_instance_methods))
74
- end
75
-
76
- class PersistentHTTPTest < Test::Unit::TestCase
77
-
78
- def clear_proxy_env
79
- ENV.delete 'http_proxy'
80
- ENV.delete 'HTTP_PROXY'
81
- ENV.delete 'http_proxy_user'
82
- ENV.delete 'HTTP_PROXY_USER'
83
- ENV.delete 'http_proxy_pass'
84
- ENV.delete 'HTTP_PROXY_PASS'
85
- end
86
-
87
- def uri_for(*args)
88
- '/' + args.join('/')
89
- end
90
-
91
- def get_request(*args)
92
- puts "uri=#{uri_for(args)}" if $debug
93
- $count = -1
94
- return Net::HTTP::Get.new(uri_for(args))
95
- end
96
-
97
- def post_request(*args)
98
- puts "uri=#{uri_for(args)}" if $debug
99
- $count = -1
100
- return Net::HTTP::Post.new(uri_for(args))
101
- end
102
-
103
- def http_and_io(options={})
104
- io = StringIO.new
105
- logger = Logger.new(io)
106
- logger.level = Logger::INFO
107
- default_options = {:name => 'TestNetHTTPPersistent', :logger => logger, :pool_size => 1}
108
- http = PersistentHTTP.new(default_options.merge(options))
109
- [http, io]
110
- end
111
-
112
- context 'simple setup' do
113
- setup do
114
- @io = StringIO.new
115
- logger = Logger.new(@io)
116
- logger.level = Logger::INFO
117
- @http = PersistentHTTP.new(:host => 'example.com', :name => 'TestNetHTTPPersistent', :logger => logger)
118
- @http.headers['user-agent'] = 'test ua'
119
- end
120
-
121
- should 'have options set' do
122
- assert_equal @http.proxy_uri, nil
123
- assert_equal 'TestNetHTTPPersistent', @http.name
124
- end
125
-
126
- should 'handle escape' do
127
- assert_equal nil, @http.escape(nil)
128
- assert_equal '%20', @http.escape(' ')
129
- end
130
-
131
- should 'handle error' do
132
- req = get_request CMD_EOF_ERROR, PASS, PASS, PASS, PASS, FAIL, PASS, PASS
133
- 6.times do
134
- @http.request(req)
135
- end
136
- assert_match "after 4 requests on", @io.string
137
- end
138
-
139
- should 'handle finish' do
140
- c = Object.new
141
- def c.finish; @finished = true end
142
- def c.finished?; @finished end
143
- def c.start; @started = true end
144
- def c.started?; @started end
145
-
146
- @http.finish c
147
-
148
- assert !c.started?
149
- assert c.finished?
150
- end
151
-
152
- should 'handle finish io error' do
153
- c = Object.new
154
- def c.finish; @finished = true; raise IOError end
155
- def c.finished?; @finished end
156
- def c.start; @started = true end
157
- def c.started?; @started end
158
-
159
- @http.finish c
160
-
161
- assert !c.started?
162
- assert c.finished?
163
- end
164
-
165
- should 'fill in http version' do
166
- assert_nil @http.http_version
167
- @http.request(get_request(CMD_SUCCESS))
168
- assert_equal '1.1', @http.http_version
169
- end
170
-
171
- should 'handle idempotent' do
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
- assert !@http.idempotent?(Net::HTTP::Post.new '/')
180
- end
181
-
182
- should 'handle normalize_uri' do
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
- should 'handle simple request' do
189
- req = get_request(CMD_SUCCESS)
190
- res = @http.request(req)
191
-
192
- assert_kind_of Net::HTTPResponse, res
193
-
194
- assert_kind_of Net::HTTP::Get, req
195
- assert_equal uri_for(CMD_SUCCESS), req.path
196
- assert_equal 'keep-alive', req['connection']
197
- assert_equal '30', req['keep-alive']
198
- assert_match %r%test ua%, req['user-agent']
199
- end
200
-
201
- should 'handle request with block' do
202
- body = nil
203
-
204
- req = get_request(CMD_SUCCESS)
205
- res = @http.request(req) do |r|
206
- body = r.read_body
207
- end
208
-
209
- assert_kind_of Net::HTTPResponse, res
210
- assert !body.nil?
211
-
212
- assert_kind_of Net::HTTP::Get, req
213
- assert_equal uri_for(CMD_SUCCESS), req.path
214
- assert_equal 'keep-alive', req['connection']
215
- assert_equal '30', req['keep-alive']
216
- assert_match %r%test ua%, req['user-agent']
217
- end
218
-
219
- should 'handle bad response' do
220
- req = get_request(CMD_BAD_RESPONSE, FAIL, FAIL)
221
- e = assert_raises PersistentHTTP::Error do
222
- @http.request req
223
- end
224
- assert_match %r%too many bad responses%, e.message
225
- assert_match %r%Renewing connection because of bad response%, @io.string
226
- assert_match %r%Removing connection because of too many bad responses%, @io.string
227
-
228
- res = @http.request(get_request(CMD_SUCCESS))
229
- assert_kind_of Net::HTTPResponse, res
230
- end
231
-
232
- should 'handle connection reset' do
233
- req = get_request(CMD_CONNRESET, FAIL, FAIL)
234
- e = assert_raises PersistentHTTP::Error do
235
- @http.request req
236
- end
237
-
238
- assert_match %r%too many connection resets%, e.message
239
- assert_match %r%Renewing connection %, @io.string
240
- assert_match %r%Removing connection %, @io.string
241
-
242
- res = @http.request(get_request(CMD_SUCCESS))
243
- assert_kind_of Net::HTTPResponse, res
244
- end
245
-
246
- should 'retry on bad response' do
247
- res = @http.request(get_request(CMD_BAD_RESPONSE, FAIL, PASS))
248
- assert_match %r%Renewing connection because of bad response%, @io.string
249
- assert_kind_of Net::HTTPResponse, res
250
- end
251
-
252
- should 'retry on connection reset' do
253
- res = @http.request(get_request(CMD_CONNRESET, FAIL, PASS))
254
- assert_match %r%Renewing connection %, @io.string
255
- assert_kind_of Net::HTTPResponse, res
256
- end
257
-
258
- should 'not retry on bad response from post' do
259
- post = post_request(CMD_BAD_RESPONSE, FAIL, PASS)
260
- e = assert_raises PersistentHTTP::Error do
261
- @http.request(post)
262
- end
263
- assert_match %r%too many bad responses%, e.message
264
- assert_match %r%Removing connection because of too many bad responses%, @io.string
265
-
266
- res = @http.request(get_request(CMD_SUCCESS))
267
- assert_kind_of Net::HTTPResponse, res
268
- end
269
-
270
- should 'not retry on connection reset from post' do
271
- post = post_request(CMD_CONNRESET, FAIL, PASS)
272
- e = assert_raises PersistentHTTP::Error do
273
- @http.request(post)
274
- end
275
- assert_match %r%too many connection resets%, e.message
276
- assert_match %r%Removing connection %, @io.string
277
-
278
- res = @http.request(get_request(CMD_SUCCESS))
279
- assert_kind_of Net::HTTPResponse, res
280
- end
281
-
282
- should 'retry on bad response from post when force_retry set' do
283
- @http.force_retry = true
284
- post = post_request(CMD_BAD_RESPONSE, FAIL, PASS)
285
- res = @http.request post
286
- assert_match %r%Renewing connection because of bad response%, @io.string
287
- assert_kind_of Net::HTTPResponse, res
288
- end
289
-
290
- should 'retry on connection reset from post when force_retry set' do
291
- @http.force_retry = true
292
- post = post_request(CMD_CONNRESET, FAIL, PASS)
293
- res = @http.request post
294
- assert_match %r%Renewing connection %, @io.string
295
- assert_kind_of Net::HTTPResponse, res
296
- end
297
-
298
- should 'allow post' do
299
- post = Net::HTTP::Post.new(uri_for CMD_ECHO)
300
- post.body = 'hello PersistentHTTP'
301
- res = @http.request(post)
302
- assert_kind_of Net::HTTPResponse, res
303
- assert_equal post.body, res.body
304
- end
305
-
306
- should 'allow ssl' do
307
- @http.verify_callback = :callback
308
- c = Net::HTTP.new('localhost', 80)
309
-
310
- @http.ssl c
311
-
312
- assert c.use_ssl?
313
- assert_equal OpenSSL::SSL::VERIFY_NONE, c.verify_mode
314
- assert_nil c.verify_callback
315
- end
316
-
317
- should 'allow ssl ca_file' do
318
- @http.ca_file = 'ca_file'
319
- @http.verify_callback = :callback
320
- c = Net::HTTP.new('localhost', 80)
321
-
322
- @http.ssl c
323
-
324
- assert c.use_ssl?
325
- assert_equal OpenSSL::SSL::VERIFY_PEER, c.verify_mode
326
- assert_equal :callback, c.verify_callback
327
- end
328
-
329
- should 'allow ssl certificate' do
330
- @http.certificate = :cert
331
- @http.private_key = :key
332
- c = Net::HTTP.new('localhost', 80)
333
-
334
- @http.ssl c
335
-
336
- assert c.use_ssl?
337
- assert_equal :cert, c.cert
338
- assert_equal :key, c.key
339
- end
340
-
341
- should 'allow ssl verify_mode' do
342
- @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
343
- c = Net::HTTP.new('localhost', 80)
344
-
345
- @http.ssl c
346
-
347
- assert c.use_ssl?
348
- assert_equal OpenSSL::SSL::VERIFY_NONE, c.verify_mode
349
- end
350
- end
351
-
352
- context 'initialize proxy by env' do
353
- setup do
354
- clear_proxy_env
355
- ENV['HTTP_PROXY'] = 'proxy.example'
356
- @http = PersistentHTTP.new(:host => 'foobar', :proxy => :ENV)
357
- end
358
-
359
- should 'match HTTP_PROXY' do
360
- assert_equal URI.parse('http://proxy.example'), @http.proxy_uri
361
- assert_equal 'foobar', @http.host
362
- end
363
- end
364
-
365
- context 'initialize proxy by uri' do
366
- setup do
367
- @proxy_uri = URI.parse 'http://proxy.example'
368
- @proxy_uri.user = 'johndoe'
369
- @proxy_uri.password = 'muffins'
370
- @http = PersistentHTTP.new(:url => 'https://zulu.com/foobar', :proxy => @proxy_uri)
371
- end
372
-
373
- should 'match proxy_uri and have proxy connection' do
374
- assert_equal @proxy_uri, @http.proxy_uri
375
- assert_equal true, @http.use_ssl
376
- assert_equal 'zulu.com', @http.host
377
- assert_equal '/foobar', @http.default_path
378
-
379
- @http.pool.with_connection do |c|
380
- assert c.started?
381
- assert c.proxy?
382
- end
383
- end
384
- end
385
-
386
- context 'initialize proxy by env' do
387
- setup do
388
- clear_proxy_env
389
- ENV['HTTP_PROXY'] = 'proxy.example'
390
- ENV['HTTP_PROXY_USER'] = 'johndoe'
391
- ENV['HTTP_PROXY_PASS'] = 'muffins'
392
- @http = PersistentHTTP.new(:url => 'https://zulu.com/foobar', :proxy => :ENV)
393
- end
394
-
395
- should 'create proxy_uri from env' do
396
- expected = URI.parse 'http://proxy.example'
397
- expected.user = 'johndoe'
398
- expected.password = 'muffins'
399
-
400
- assert_equal expected, @http.proxy_uri
401
- end
402
- end
403
-
404
- context 'initialize proxy by env lower' do
405
- setup do
406
- clear_proxy_env
407
- ENV['http_proxy'] = 'proxy.example'
408
- ENV['http_proxy_user'] = 'johndoe'
409
- ENV['http_proxy_pass'] = 'muffins'
410
- @http = PersistentHTTP.new(:url => 'https://zulu.com/foobar', :proxy => :ENV)
411
- end
412
-
413
- should 'create proxy_uri from env' do
414
- expected = URI.parse 'http://proxy.example'
415
- expected.user = 'johndoe'
416
- expected.password = 'muffins'
417
-
418
- assert_equal expected, @http.proxy_uri
419
- end
420
- end
421
-
422
- context 'with timeouts set' do
423
- setup do
424
- @http = PersistentHTTP.new(:url => 'http://example.com')
425
- @http.open_timeout = 123
426
- @http.read_timeout = 321
427
- end
428
-
429
- should 'have timeouts set' do
430
- @http.pool.with_connection do |c|
431
- assert c.started?
432
- assert !c.proxy?
433
-
434
- assert_equal 123, c.open_timeout
435
- assert_equal 321, c.read_timeout
436
-
437
- assert_equal 'example.com', c.address
438
- assert_equal 80, c.port
439
- assert !@http.use_ssl
440
- end
441
- end
442
-
443
- should 'reuse same connection' do
444
- c1, c2 = nil, nil
445
- @http.pool.with_connection do |c|
446
- c1 = c
447
- assert c.started?
448
- end
449
- @http.pool.with_connection do |c|
450
- c2 = c
451
- assert c.started?
452
- end
453
- assert_same c1,c2
454
- end
455
- end
456
-
457
- context 'with debug_output' do
458
- setup do
459
- @io = StringIO.new
460
- @http = PersistentHTTP.new(:url => 'http://example.com', :debug_output => @io)
461
- end
462
-
463
- should 'have debug_output set' do
464
- @http.pool.with_connection do |c|
465
- assert c.started?
466
- assert_equal @io, c.instance_variable_get(:@debug_output)
467
- assert_equal 'example.com', c.address
468
- assert_equal 80, c.port
469
- end
470
- end
471
- end
472
-
473
- context 'with host down' do
474
- setup do
475
- @http = PersistentHTTP.new(:url => 'http://example.com', :open_timeout => DUMMY_OPEN_TIMEOUT_FOR_HOSTDOWN)
476
- end
477
-
478
- should 'assert error' do
479
- e = assert_raises PersistentHTTP::Error do
480
- @http.request(get_request(CMD_SUCCESS))
481
- end
482
- assert_match %r%host down%, e.message
483
- end
484
- end
485
-
486
- context 'with connection refused' do
487
- setup do
488
- @http = PersistentHTTP.new(:url => 'http://example.com', :open_timeout => DUMMY_OPEN_TIMEOUT_FOR_CONNREFUSED)
489
- end
490
-
491
- should 'assert error' do
492
- e = assert_raises PersistentHTTP::Error do
493
- @http.request(get_request(CMD_SUCCESS))
494
- end
495
- assert_match %r%connection refused%, e.message
496
- end
497
- end
498
-
499
- context 'with pool size of 3' do
500
- setup do
501
- @http = PersistentHTTP.new(:url => 'http://example.com', :pool_size => 3)
502
- end
503
-
504
- should 'only allow 3 connections checked out at a time' do
505
- @http.request(get_request(CMD_SUCCESS))
506
- pool = @http.pool
507
- 2.times do
508
- conns = []
509
- pool.with_connection do |c1|
510
- pool.with_connection do |c2|
511
- conns << c2
512
- pool.with_connection do |c3|
513
- conns << c3
514
- begin
515
- Timeout.timeout(2) do
516
- pool.with_connection { |c4| }
517
- assert false, 'should NOT have been able to get 4th connection'
518
- end
519
- rescue Timeout::Error => e
520
- # successfully failed to get a connection
521
- end
522
- @http.remove(c1)
523
- Timeout.timeout(1) do
524
- begin
525
- pool.with_connection do |c4|
526
- conns << c4
527
- end
528
- rescue Timeout::Error => e
529
- assert false, 'should have been able to get 4th connection'
530
- end
531
- end
532
- end
533
- end
534
- end
535
- pool.with_connection do |c1|
536
- pool.with_connection do |c2|
537
- pool.with_connection do |c3|
538
- assert_equal conns, [c1,c2,c3]
539
- end
540
- end
541
- end
542
- # Do it a 2nd time with finish returning an IOError
543
- c1 = conns[0]
544
- def c1.finish
545
- super
546
- raise IOError
547
- end
548
- end
549
- end
550
-
551
- should 'handle renew' do
552
- @http.request(get_request(CMD_SUCCESS))
553
- pool = @http.pool
554
- 2.times do
555
- conns = []
556
- pool.with_connection do |c1|
557
- pool.with_connection do |c2|
558
- conns << c2
559
- pool.with_connection do |c3|
560
- conns << c3
561
- new_c1 = @http.renew(c1)
562
- assert c1 != new_c1
563
- conns.unshift(new_c1)
564
- end
565
- end
566
- end
567
- pool.with_connection do |c1|
568
- pool.with_connection do |c2|
569
- pool.with_connection do |c3|
570
- assert_equal conns, [c1,c2,c3]
571
- end
572
- end
573
- end
574
- # Do it a 2nd time with finish returning an IOError
575
- c1 = conns[0]
576
- def c1.finish
577
- super
578
- raise IOError
579
- end
580
- end
581
- end
582
-
583
- should 'handle renew with exception' do
584
- pool = @http.pool
585
- [[DUMMY_OPEN_TIMEOUT_FOR_HOSTDOWN, %r%host down%], [DUMMY_OPEN_TIMEOUT_FOR_CONNREFUSED, %r%connection refused%]].each do |pair|
586
- dummy_open_timeout = pair.first
587
- error_message = pair.last
588
- pool.with_connection do |c|
589
- old_c = c
590
- @http.open_timeout = dummy_open_timeout
591
- e = assert_raises PersistentHTTP::Error do
592
- new_c = @http.renew c
593
- end
594
- assert_match error_message, e.message
595
-
596
- # Make sure our pool is still in good shape
597
- @http.open_timeout = 5 # Any valid timeout will do
598
- pool.with_connection do |c1|
599
- assert old_c != c1
600
- pool.with_connection do |c2|
601
- assert old_c != c2
602
- end
603
- end
604
- end
605
- end
606
- end
607
- end
608
- #
609
- # # def test_shutdown
610
- # # c = connection
611
- # # cs = conns
612
- # # rs = reqs
613
- # #
614
- # # orig = @http
615
- # # @http = PersistentHTTP.new 'name'
616
- # # c2 = connection
617
- # #
618
- # # orig.shutdown
619
- # #
620
- # # assert c.finished?
621
- # # refute c2.finished?
622
- # #
623
- # # refute_same cs, conns
624
- # # refute_same rs, reqs
625
- # # end
626
- # #
627
- # # def test_shutdown_not_started
628
- # # c = Object.new
629
- # # def c.finish() raise IOError end
630
- # #
631
- # # conns["#{@uri.host}:#{@uri.port}"] = c
632
- # #
633
- # # @http.shutdown
634
- # #
635
- # # assert_nil Thread.current[@http.connection_key]
636
- # # assert_nil Thread.current[@http.request_key]
637
- # # end
638
- # #
639
- # # def test_shutdown_no_connections
640
- # # @http.shutdown
641
- # #
642
- # # assert_nil Thread.current[@http.connection_key]
643
- # # assert_nil Thread.current[@http.request_key]
644
- # # end
645
- #
646
- end
647
-