lib/httpx/io/tcp.rb in httpx-0.1.0 vs lib/httpx/io/tcp.rb in httpx-0.2.0

- old
+ new

@@ -7,33 +7,37 @@ class TCP include Loggable attr_reader :ip, :port + attr_reader :addresses + alias_method :host, :ip - def initialize(uri, options) + def initialize(uri, addresses, options) @state = :idle @hostname = uri.host + @addresses = addresses + @ip_index = @addresses.size - 1 @options = Options.new(options) @fallback_protocol = @options.fallback_protocol @port = uri.port if @options.io @io = case @options.io when Hash - @ip = Resolv.getaddress(@hostname) + @ip = @addresses[@ip_index] @options.io[@ip] || @options.io["#{@ip}:#{@port}"] else @ip = @hostname @options.io end unless @io.nil? @keep_open = true @state = :connected end else - @ip = Resolv.getaddress(@hostname) + @ip = @addresses[@ip_index] end @io ||= build_socket end def scheme @@ -53,14 +57,18 @@ begin if @io.closed? transition(:idle) @io = build_socket end - @io.connect_nonblock(Socket.sockaddr_in(@port, @ip)) + @io.connect_nonblock(Socket.sockaddr_in(@port, @ip.to_s)) rescue Errno::EISCONN end transition(:connected) + rescue Errno::EHOSTUNREACH => e + raise e if @ip_index <= 0 + @ip_index -= 1 + retry rescue Errno::EINPROGRESS, Errno::EALREADY, ::IO::WaitReadable end @@ -123,12 +131,11 @@ end private def build_socket - addr = IPAddr.new(@ip) - Socket.new(addr.family, :STREAM, 0) + Socket.new(@ip.family, :STREAM, 0) end def transition(nextstate) case nextstate # when :idle @@ -139,10 +146,21 @@ end do_transition(nextstate) end def do_transition(nextstate) - log(level: 1, label: "#{inspect}: ") { nextstate.to_s } + log(level: 1) do + log_transition_state(nextstate) + end @state = nextstate + end + + def log_transition_state(nextstate) + case nextstate + when :connected + "Connected to #{@hostname} (#{@ip}) port #{@port} (##{@io.fileno})" + else + "#{@ip}:#{@port} #{@state} -> #{nextstate}" + end end end end