Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions lib/net/http/persistent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -205,20 +205,20 @@ class Error < StandardError; end
# NOTE: This may not work on ruby > 1.9.

def self.detect_idle_timeout uri, max = 10
sleep_time = 0
http = nil
uri = URI uri unless URI::Generic === uri
uri += '/'

req = Net::HTTP::Head.new uri.request_uri

http = new 'net-http-persistent detect_idle_timeout'
http = new name: 'net-http-persistent detect_idle_timeout'

http.connection_for uri do |connection|
sleep_time = 0

http = connection.http
connection_http = connection.http

loop do
response = http.request req
response = connection_http.request req

$stderr.puts "HEAD #{uri} => #{response.code}" if $DEBUG

Expand All @@ -237,6 +237,7 @@ def self.detect_idle_timeout uri, max = 10
rescue
# ignore StandardErrors, we've probably found the idle timeout.
ensure
http.shutdown if http
return sleep_time unless $!
end

Expand Down
45 changes: 45 additions & 0 deletions test/test_net_http_persistent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,51 @@ def teardown
Net::HTTP.use_connect :orig_connect
end

def detect_idle_timeout_with responses, max
sleeps = []
closed = false
raw_http = Object.new
raw_http.define_singleton_method :request do |request|
response = responses.shift
raise response if Exception === response
response
end
connection = Struct.new(:http).new(raw_http)
client = Class.new(Net::HTTP::Persistent) do
define_method :connection_for do |uri, &block|
block.call connection
end
define_method :shutdown do
closed = true
super()
end
end
client.define_singleton_method(:sleep) { |duration| sleeps << duration }

result = client.detect_idle_timeout 'http://example.com/path', max
[result, sleeps, closed]
end

def test_detect_idle_timeout_max
ok = Net::HTTPOK.new '1.1', '200', 'OK'
assert_equal [2, [1, 2], true], detect_idle_timeout_with([ok, ok, ok], 2)
end

def test_detect_idle_timeout_zero
ok = Net::HTTPOK.new '1.1', '200', 'OK'
assert_equal [0, [], true], detect_idle_timeout_with([ok], 0)
end

def test_detect_idle_timeout_connection_closed
ok = Net::HTTPOK.new '1.1', '200', 'OK'
assert_equal [1, [1], true], detect_idle_timeout_with([ok, EOFError.new], 10)
end

def test_detect_idle_timeout_bad_response
bad = Net::HTTPServiceUnavailable.new '1.1', '503', 'Unavailable'
assert_equal [0, [], true], detect_idle_timeout_with([bad], 10)
end

class BasicConnection
attr_accessor :started, :finished, :address, :port, :use_ssl,
:read_timeout, :open_timeout, :keep_alive_timeout
Expand Down