From 8c81ab2c2a0ffc5694e9f5edcb09e5e262e843a9 Mon Sep 17 00:00:00 2001 From: Jeremy Stanley Date: Thu, 8 Dec 2022 05:43:24 -0700 Subject: [PATCH 1/2] don't invoke response block more than once due to retry If a socket error occurs while performing a streaming download via the response block provided to transport_request, avoid calling the response block again as this would result in duplicate data received by the client. fixes #86 --- lib/net/http.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/net/http.rb b/lib/net/http.rb index 8ac80a4f..101a669d 100644 --- a/lib/net/http.rb +++ b/lib/net/http.rb @@ -2350,7 +2350,10 @@ def transport_request(req) res } res.reading_body(@socket, req.response_body_permitted?) { - yield res if block_given? + if block_given? + count = max_retries # Don't restart in the middle of a download + yield res + end } rescue Net::OpenTimeout raise From f37128d2fb57100d290050e446414f0b0466e9af Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Fri, 5 Jan 2024 08:37:30 -0800 Subject: [PATCH 2/2] Add test for not retrying request block --- test/net/http/test_http.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/net/http/test_http.rb b/test/net/http/test_http.rb index 53092ee0..f0f1bc2d 100644 --- a/test/net/http/test_http.rb +++ b/test/net/http/test_http.rb @@ -1234,6 +1234,16 @@ def test_http_retry_failed } end + def test_http_retry_failed_with_block + start {|http| + http.max_retries = 10 + called = 0 + assert_raise(Errno::ECONNRESET){ http.get('/'){called += 1; raise Errno::ECONNRESET} } + assert_equal 1, called + } + @log_tester = nil + end + def test_keep_alive_server_close def @server.run(sock) sock.close