From 37ac08ebfac81e73a22f51a103e653ca43fb7cc4 Mon Sep 17 00:00:00 2001 From: Will Jordan Date: Thu, 20 Feb 2020 13:42:11 -0800 Subject: [PATCH 1/2] Add test for waiting with an open client connection --- test/test_puma_server.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/test_puma_server.rb b/test/test_puma_server.rb index a43a3c974a..eb55f110e6 100644 --- a/test/test_puma_server.rb +++ b/test/test_puma_server.rb @@ -754,4 +754,17 @@ def test_request_body_wait_chunked # it is set to a reasonable number. assert_operator request_body_wait, :>=, 900 end + + def test_open_connection_wait + server_run app: ->(_) { [200, {}, ["Hello"]] } + s = send_http nil + sleep 0.1 + s << "GET / HTTP/1.0\r\n\r\n" + assert_equal 'Hello', s.readlines.last + end + + def test_open_connection_wait_no_queue + @server = Puma::Server.new @app, @events, queue_requests: false + test_open_connection_wait + end end From 3304499c7dd51e4f3200d353e75e243d6661b236 Mon Sep 17 00:00:00 2001 From: Will Jordan Date: Thu, 20 Feb 2020 13:46:27 -0800 Subject: [PATCH 2/2] Rescue IO::WaitReadable instead of EAGAIN for blocking read On Windows, `read_nonblock` raises `Errno::EWOULDBLOCK` if a blocking read would occur, which is a different value from `Errno::EAGAIN`. Both of these errors are extended by `IO::WaitReadable` which is Ruby's recommended exception class for retrying `read_nonblock`. --- History.md | 1 + lib/puma/client.rb | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/History.md b/History.md index 142e8068d6..9a38780c9a 100644 --- a/History.md +++ b/History.md @@ -13,6 +13,7 @@ * Windows update extconf.rb for use with ssp and varied Ruby/MSYS2 combinations (#2069) * Preserve `BUNDLE_GEMFILE` env var when using `prune_bundler` (#1893) * Send 408 request timeout even when queue requests is disabled (#2119) + * Rescue IO::WaitReadable instead of EAGAIN for blocking read (#2121) * Refactor * Remove unused loader argument from Plugin initializer (#2095) diff --git a/lib/puma/client.rb b/lib/puma/client.rb index 8a37736aaf..7b013732ab 100644 --- a/lib/puma/client.rb +++ b/lib/puma/client.rb @@ -153,7 +153,7 @@ def try_to_finish begin data = @io.read_nonblock(CHUNK_SIZE) - rescue Errno::EAGAIN + rescue IO::WaitReadable return false rescue SystemCallError, IOError, EOFError raise ConnectionError, "Connection error detected during read" @@ -349,7 +349,7 @@ def read_body begin chunk = @io.read_nonblock(want) - rescue Errno::EAGAIN + rescue IO::WaitReadable return false rescue SystemCallError, IOError raise ConnectionError, "Connection error detected during read"