lib/httpx/io/tcp.rb in httpx-0.18.7 vs lib/httpx/io/tcp.rb in httpx-0.19.0
- old
+ new
@@ -13,10 +13,11 @@
alias_method :host, :ip
def initialize(origin, addresses, options)
@state = :idle
+ @addresses = []
@hostname = origin.host
@options = Options.new(options)
@fallback_protocol = @options.fallback_protocol
@port = origin.port
@interests = :w
@@ -28,21 +29,35 @@
@options.io
end
raise Error, "Given IO objects do not match the request authority" unless @io
_, _, _, @ip = @io.addr
- @addresses ||= [@ip]
- @ip_index = @addresses.size - 1
+ @addresses << @ip
@keep_open = true
@state = :connected
else
- @addresses = addresses.map { |addr| addr.is_a?(IPAddr) ? addr : IPAddr.new(addr) }
+ add_addresses(addresses)
end
@ip_index = @addresses.size - 1
- @io ||= build_socket
+ # @io ||= build_socket
end
+ def add_addresses(addrs)
+ return if addrs.empty?
+
+ addrs = addrs.map { |addr| addr.is_a?(IPAddr) ? addr : IPAddr.new(addr) }
+
+ ip_index = @ip_index || (@addresses.size - 1)
+ if addrs.first.ipv6?
+ # should be the next in line
+ @addresses = [*@addresses[0, ip_index], *addrs, *@addresses[ip_index..-1]]
+ else
+ @addresses.unshift(*addrs)
+ @ip_index += addrs.size if @ip_index
+ end
+ end
+
def to_io
@io.to_io
end
def protocol
@@ -50,25 +65,29 @@
end
def connect
return unless closed?
- if @io.closed?
+ if !@io || @io.closed?
transition(:idle)
@io = build_socket
end
try_connect
rescue Errno::ECONNREFUSED,
Errno::EADDRNOTAVAIL,
Errno::EHOSTUNREACH => e
raise e if @ip_index <= 0
+ log { "failed connecting to #{@ip} (#{e.message}), trying next..." }
@ip_index -= 1
+ @io = build_socket
retry
rescue Errno::ETIMEDOUT => e
raise ConnectTimeoutError.new(@options.timeout[:connect_timeout], e.message) if @ip_index <= 0
+ log { "failed connecting to #{@ip} (#{e.message}), trying next..." }
@ip_index -= 1
+ @io = build_socket
retry
end
if RUBY_VERSION < "2.3"
# :nocov: