From c5119a4a528e6aa1c2cdbe3ebc2cc155907c5415 Mon Sep 17 00:00:00 2001 From: AC Date: Sat, 10 Oct 2026 14:47:50 +0800 Subject: [PATCH] Restore detect_idle_timeout client setup and cleanup Signed-off-by: AC --- lib/net/http/persistent.rb | 11 ++++---- test/test_net_http_persistent.rb | 45 ++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/lib/net/http/persistent.rb b/lib/net/http/persistent.rb index 8392676..1ae6524 100644 --- a/lib/net/http/persistent.rb +++ b/lib/net/http/persistent.rb @@ -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 @@ -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 diff --git a/test/test_net_http_persistent.rb b/test/test_net_http_persistent.rb index 85e5ea8..f97fa43 100644 --- a/test/test_net_http_persistent.rb +++ b/test/test_net_http_persistent.rb @@ -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