Skip to content

Commit f9ab934

Browse files
joshcooperhsbt
authored andcommitted
[ruby/net-http] Use nonblocking IO to detect eof
The call to `@socket.eof?` can block when attempting to reuse a persistent connection and there are SSL Handshake messages ready to be read, but no Application Data, such as when the server sends an updated NewSessionTicket in TLS 1.3. Instead call `OpenSSL::SSL::SSLSocket#read_nonblocking`, which will read and process the SSL Handshake message, but return `nil` on EOF or an empty string if no data is available. It may also return `:wait_readable` or `:wait_writable` which indicates the socket is reusable.
1 parent cf29594 commit f9ab934

1 file changed

Lines changed: 9 additions & 1 deletion

File tree

‎lib/net/http.rb‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2467,7 +2467,7 @@ def begin_transport(req)
24672467
debug 'Conn close because of keep_alive_timeout'
24682468
@socket.close
24692469
connect
2470-
elsif @socket.io.to_io.wait_readable(0) && @socket.eof?
2470+
elsif eof?
24712471
debug "Conn close because of EOF"
24722472
@socket.close
24732473
connect
@@ -2482,6 +2482,14 @@ def begin_transport(req)
24822482
req['host'] ||= addr_port()
24832483
end
24842484

2485+
def eof?
2486+
if defined?(OpenSSL::SSL) && @socket.io.is_a?(OpenSSL::SSL::SSLSocket)
2487+
@socket.io.read_nonblock(0, exception: false).nil?
2488+
else
2489+
@socket.io.to_io.wait_readable(0) && @socket.eof?
2490+
end
2491+
end
2492+
24852493
def end_transport(req, res)
24862494
@curr_http_version = res.http_version
24872495
@last_communicated = nil

0 commit comments

Comments
 (0)