Methods
Public Class
Public Instance
Included modules
Public Class methods
new(origin, addresses, options)
[show source]
# File lib/httpx/io/tcp.rb 15 def initialize(origin, addresses, options) 16 @state = :idle 17 @addresses = [] 18 @hostname = origin.host 19 @options = options 20 @fallback_protocol = @options.fallback_protocol 21 @port = origin.port 22 @interests = :w 23 if @options.io 24 @io = case @options.io 25 when Hash 26 @options.io[origin.authority] 27 else 28 @options.io 29 end 30 raise Error, "Given IO objects do not match the request authority" unless @io 31 32 _, _, _, ip = @io.addr 33 @ip = Resolver::Entry.new(ip) 34 @addresses << @ip 35 @keep_open = true 36 @state = :connected 37 else 38 add_addresses(addresses) 39 end 40 @ip_index = @addresses.size - 1 41 end
Public Instance methods
add_addresses(addrs)
[show source]
# File lib/httpx/io/tcp.rb 47 def add_addresses(addrs) 48 return if addrs.empty? 49 50 ip_index = @ip_index || (@addresses.size - 1) 51 if addrs.first.ipv6? 52 # should be the next in line 53 @addresses = [*@addresses[0, ip_index], *addrs, *@addresses[ip_index..-1]] 54 else 55 @addresses.unshift(*addrs) 56 @ip_index += addrs.size if @ip_index 57 end 58 end
addresses?()
eliminates expired entries and returns whether there are still any left.
[show source]
# File lib/httpx/io/tcp.rb 61 def addresses? 62 prev_addr_size = @addresses.size 63 64 @addresses.delete_if(&:expired?) 65 66 unless (decr = prev_addr_size - @addresses.size).zero? 67 @ip_index = @addresses.size - decr 68 end 69 70 @addresses.any? 71 end
close()
[show source]
# File lib/httpx/io/tcp.rb 159 def close 160 return if @keep_open || closed? 161 162 begin 163 @io.close 164 ensure 165 transition(:closed) 166 end 167 end
closed?()
[show source]
# File lib/httpx/io/tcp.rb 173 def closed? 174 @state == :idle || @state == :closed 175 end
connect()
[show source]
# File lib/httpx/io/tcp.rb 81 def connect 82 return unless closed? 83 84 if !@io || @io.closed? 85 transition(:idle) 86 @io = build_socket 87 end 88 try_connect 89 rescue Errno::EHOSTUNREACH, 90 Errno::ENETUNREACH => e 91 raise e if @ip_index <= 0 92 93 log { "failed connecting to #{@ip} (#{e.message}), evict from cache and trying next..." } 94 Resolver.cached_lookup_evict(@hostname, @ip) 95 96 @ip_index -= 1 97 @io = build_socket 98 retry 99 rescue Errno::ECONNREFUSED, 100 Errno::EADDRNOTAVAIL, 101 SocketError, 102 IOError => e 103 raise e if @ip_index <= 0 104 105 log { "failed connecting to #{@ip} (#{e.message}), trying next..." } 106 @ip_index -= 1 107 @io = build_socket 108 retry 109 rescue Errno::ETIMEDOUT => e 110 raise ConnectTimeoutError.new(@options.timeout[:connect_timeout], e.message) if @ip_index <= 0 111 112 log { "failed connecting to #{@ip} (#{e.message}), trying next..." } 113 @ip_index -= 1 114 @io = build_socket 115 retry 116 end
connected?()
[show source]
# File lib/httpx/io/tcp.rb 169 def connected? 170 @state == :connected 171 end
inspect()
:nocov:
[show source]
# File lib/httpx/io/tcp.rb 178 def inspect 179 "#<#{self.class}:#{object_id} " \ 180 "#{@ip}:#{@port} " \ 181 "@state=#{@state} " \ 182 "@hostname=#{@hostname} " \ 183 "@addresses=#{@addresses} " \ 184 "@state=#{@state}>" 185 end
read(size, buffer)
[show source]
# File lib/httpx/io/tcp.rb 136 def read(size, buffer) 137 ret = @io.read_nonblock(size, buffer, exception: false) 138 if ret == :wait_readable 139 buffer.clear 140 return 0 141 end 142 return if ret.nil? 143 144 log { "READ: #{buffer.bytesize} bytes..." } 145 buffer.bytesize 146 end
write(buffer)
[show source]
# File lib/httpx/io/tcp.rb 148 def write(buffer) 149 siz = @io.write_nonblock(buffer, exception: false) 150 return 0 if siz == :wait_writable 151 return if siz.nil? 152 153 log { "WRITE: #{siz} bytes..." } 154 155 buffer.shift!(siz) 156 siz 157 end