def connect
@socket = nil
exception = nil
addrinfo = if @proxy
::Socket.getaddrinfo(@proxy[:host], @proxy[:port].to_i, ::Socket::Constants::AF_UNSPEC, ::Socket::Constants::SOCK_STREAM)
else
::Socket.getaddrinfo(@params[:host], @params[:port].to_i, ::Socket::Constants::AF_UNSPEC, ::Socket::Constants::SOCK_STREAM)
end
addrinfo.each do |_, port, _, ip, a_family, s_type|
begin
sockaddr = ::Socket.sockaddr_in(port, ip)
socket = ::Socket.new(a_family, s_type, 0)
if @params[:nonblock]
socket.connect_nonblock(sockaddr)
else
begin
Timeout.timeout(@params[:connect_timeout]) do
socket.connect(sockaddr)
end
rescue Timeout::Error
raise Excon::Errors::Timeout.new('connect timeout reached')
end
end
@socket = socket
break
rescue Errno::EINPROGRESS
unless IO.select(nil, [socket], nil, @params[:connect_timeout])
raise(Excon::Errors::Timeout.new("connect timeout reached"))
end
begin
socket.connect_nonblock(sockaddr)
@socket = socket
break
rescue Errno::EISCONN
@socket = socket
break
rescue SystemCallError => exception
socket.close
next
end
rescue SystemCallError => exception
socket.close
next
end
end
unless @socket
raise exception
end
end