Feature #5101 » socket-tcp-connect-timeout.patch
| lib/net/http.rb (working copy) | ||
|---|---|---|
|
def connect
|
||
|
D "opening connection to #{conn_address()}..."
|
||
|
s = timeout(@open_timeout) { TCPSocket.open(conn_address(), conn_port()) }
|
||
|
s = timeout(@open_timeout) { Socket.tcp(conn_address(), conn_port()) }
|
||
|
D "opened"
|
||
|
if use_ssl?
|
||
|
ssl_parameters = Hash.new
|
||
| ext/socket/lib/socket.rb (working copy) | ||
|---|---|---|
|
#
|
||
|
# If a block is given the created socket is yielded for each address.
|
||
|
#
|
||
|
def connect_internal(local_addrinfo) # :yields: socket
|
||
|
def connect_internal(local_addrinfo, timeout=nil) # :yields: socket
|
||
|
sock = Socket.new(self.pfamily, self.socktype, self.protocol)
|
||
|
begin
|
||
|
sock.ipv6only! if self.ipv6?
|
||
|
sock.bind local_addrinfo if local_addrinfo
|
||
|
sock.connect(self)
|
||
|
if timeout
|
||
|
begin
|
||
|
sock.connect_nonblock(self)
|
||
|
rescue IO::WaitWritable
|
||
|
if !IO.select(nil, [sock], nil, timeout)
|
||
|
raise Errno::ETIMEDOUT, 'user specified timeout'
|
||
|
end
|
||
|
begin
|
||
|
sock.connect_nonblock(self) # check connection failure
|
||
|
rescue Errno::EISCONN
|
||
|
end
|
||
|
end
|
||
|
else
|
||
|
sock.connect(self)
|
||
|
end
|
||
|
if block_given?
|
||
|
yield sock
|
||
|
else
|
||
| ... | ... | |
|
# puts s.read
|
||
|
# }
|
||
|
#
|
||
|
def connect_from(*local_addr_args, &block)
|
||
|
connect_internal(family_addrinfo(*local_addr_args), &block)
|
||
|
def connect_from(*args, &block)
|
||
|
opts = Hash === args.last ? args.pop : {}
|
||
|
local_addr_args = args
|
||
|
connect_internal(family_addrinfo(*local_addr_args), opts[:timeout], &block)
|
||
|
end
|
||
|
# creates a socket connected to the address of self.
|
||
| ... | ... | |
|
# puts s.read
|
||
|
# }
|
||
|
#
|
||
|
def connect(&block)
|
||
|
connect_internal(nil, &block)
|
||
|
def connect(opts={}, &block)
|
||
|
connect_internal(nil, opts[:timeout], &block)
|
||
|
end
|
||
|
# creates a socket connected to _remote_addr_args_ and bound to self.
|
||
| ... | ... | |
|
# puts s.read
|
||
|
# }
|
||
|
#
|
||
|
def connect_to(*remote_addr_args, &block)
|
||
|
def connect_to(*args, &block)
|
||
|
opts = Hash === args.last ? args.pop : {}
|
||
|
remote_addr_args = args
|
||
|
remote_addrinfo = family_addrinfo(*remote_addr_args)
|
||
|
remote_addrinfo.send(:connect_internal, self, &block)
|
||
|
remote_addrinfo.send(:connect_internal, self, opts[:timeout], &block)
|
||
|
end
|
||
|
# creates a socket bound to self.
|
||
| ... | ... | |
|
# puts sock.read
|
||
|
# }
|
||
|
#
|
||
|
def self.tcp(host, port, local_host=nil, local_port=nil) # :yield: socket
|
||
|
def self.tcp(host, port, *rest) # :yield: socket
|
||
|
opts = Hash === rest.last ? rest.pop : {}
|
||
|
local_host, local_port = rest
|
||
|
last_error = nil
|
||
|
ret = nil
|
||
|
connect_timeout = opts[:connect_timeout]
|
||
|
local_addr_list = nil
|
||
|
if local_host != nil || local_port != nil
|
||
|
local_addr_list = Addrinfo.getaddrinfo(local_host, local_port, nil, :STREAM, nil)
|
||
| ... | ... | |
|
local_addr = nil
|
||
|
end
|
||
|
begin
|
||
|
sock = local_addr ? ai.connect_from(local_addr) : ai.connect
|
||
|
sock = local_addr ?
|
||
|
ai.connect_from(local_addr, :timeout => connect_timeout) :
|
||
|
ai.connect(:timeout => connect_timeout)
|
||
|
rescue SystemCallError
|
||
|
last_error = $!
|
||
|
next
|
||