Skip to content
Open
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
39 changes: 31 additions & 8 deletions lib/net/http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1179,6 +1179,7 @@ def initialize(address, port = nil) # :nodoc:
@debug_output = options[:debug_output]
@response_body_encoding = options[:response_body_encoding]
@ignore_eof = options[:ignore_eof]
@tcpsocket_supports_open_timeout = nil

@proxy_from_env = false
@proxy_uri = nil
Expand Down Expand Up @@ -1654,14 +1655,36 @@ def connect
end

debug "opening connection to #{conn_addr}:#{conn_port}..."
s = Timeout.timeout(@open_timeout, Net::OpenTimeout) {
begin
TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
rescue => e
raise e, "Failed to open TCP connection to " +
"#{conn_addr}:#{conn_port} (#{e.message})"
end
}
begin
s =
case @tcpsocket_supports_open_timeout
when nil, true
begin
# Use built-in timeout in TCPSocket.open if available
sock = TCPSocket.open(conn_addr, conn_port, @local_host, @local_port, open_timeout: @open_timeout)
@tcpsocket_supports_open_timeout = true
sock
rescue ArgumentError => e
raise if !(e.message.include?('unknown keyword: :open_timeout') || e.message.include?('wrong number of arguments (given 5, expected 2..4)'))
@tcpsocket_supports_open_timeout = false

# Fallback to Timeout.timeout if TCPSocket.open does not support open_timeout
Timeout.timeout(@open_timeout, Net::OpenTimeout) {
TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
}
end
when false
# The current Ruby is known to not support TCPSocket(open_timeout:).
# Directly fall back to Timeout.timeout to avoid performance penalty incured by rescue.
Timeout.timeout(@open_timeout, Net::OpenTimeout) {
TCPSocket.open(conn_addr, conn_port, @local_host, @local_port)
}
end
rescue => e
e = Net::OpenTimeout.new(e) if e.is_a?(Errno::ETIMEDOUT) # for compatibility with previous versions
raise e, "Failed to open TCP connection to " +
"#{conn_addr}:#{conn_port} (#{e.message})"
end
s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
debug "opened"
if use_ssl?
Expand Down