|
|
|
@ -191,6 +191,9 @@ class Request |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
socks = [] |
|
|
|
|
addr_by_socket = {} |
|
|
|
|
|
|
|
|
|
addresses.each do |address| |
|
|
|
|
begin |
|
|
|
|
check_private_address(address) |
|
|
|
@ -200,30 +203,45 @@ class Request |
|
|
|
|
|
|
|
|
|
sock.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1) |
|
|
|
|
|
|
|
|
|
begin |
|
|
|
|
sock.connect_nonblock(sockaddr) |
|
|
|
|
rescue IO::WaitWritable |
|
|
|
|
if IO.select(nil, [sock], nil, Request::TIMEOUT[:connect]) |
|
|
|
|
begin |
|
|
|
|
sock.connect_nonblock(sockaddr) |
|
|
|
|
rescue Errno::EISCONN |
|
|
|
|
# Yippee! |
|
|
|
|
rescue |
|
|
|
|
sock.close |
|
|
|
|
raise |
|
|
|
|
end |
|
|
|
|
else |
|
|
|
|
sock.close |
|
|
|
|
raise HTTP::TimeoutError, "Connect timed out after #{Request::TIMEOUT[:connect]} seconds" |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
sock.connect_nonblock(sockaddr) |
|
|
|
|
|
|
|
|
|
# If that hasn't raised an exception, we somehow managed to connect |
|
|
|
|
# immediately, close pending sockets and return immediately |
|
|
|
|
socks.each(&:close) |
|
|
|
|
return sock |
|
|
|
|
rescue IO::WaitWritable |
|
|
|
|
socks << sock |
|
|
|
|
addr_by_socket[sock] = sockaddr |
|
|
|
|
rescue => e |
|
|
|
|
outer_e = e |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
until socks.empty? |
|
|
|
|
_, available_socks, = IO.select(nil, socks, nil, Request::TIMEOUT[:connect]) |
|
|
|
|
|
|
|
|
|
if available_socks.nil? |
|
|
|
|
socks.each(&:close) |
|
|
|
|
raise HTTP::TimeoutError, "Connect timed out after #{Request::TIMEOUT[:connect]} seconds" |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
available_socks.each do |sock| |
|
|
|
|
socks.delete(sock) |
|
|
|
|
|
|
|
|
|
begin |
|
|
|
|
sock.connect_nonblock(addr_by_socket[sock]) |
|
|
|
|
rescue Errno::EISCONN |
|
|
|
|
rescue => e |
|
|
|
|
sock.close |
|
|
|
|
outer_e = e |
|
|
|
|
next |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
socks.each(&:close) |
|
|
|
|
return sock |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
if outer_e |
|
|
|
|
raise outer_e |
|
|
|
|
else |
|
|
|
|