persistent_http 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
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
-