Methods
Public Class
Public Instance
Included modules
Public Class methods
new(origin, addresses, options)
[show source]
# File lib/httpx/io/tcp.rb 16 def initialize(origin, addresses, options) 17 @state = :idle 18 @addresses = [] 19 @hostname = origin.host 20 @options = options 21 @fallback_protocol = @options.fallback_protocol 22 @port = origin.port 23 @interests = :w 24 if @options.io 25 @io = case @options.io 26 when Hash 27 @options.io[origin.authority] 28 else 29 @options.io 30 end 31 raise Error, "Given IO objects do not match the request authority" unless @io 32 33 _, _, _, @ip = @io.addr 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 addrs = addrs.map { |addr| addr.is_a?(IPAddr) ? addr : IPAddr.new(addr) } 51 52 ip_index = @ip_index || (@addresses.size - 1) 53 if addrs.first.ipv6? 54 # should be the next in line 55 @addresses = [*@addresses[0, ip_index], *addrs, *@addresses[ip_index..-1]] 56 else 57 @addresses.unshift(*addrs) 58 @ip_index += addrs.size if @ip_index 59 end 60 end
close()
[show source]
# File lib/httpx/io/tcp.rb 148 def close 149 return if @keep_open || closed? 150 151 begin 152 @io.close 153 ensure 154 transition(:closed) 155 end 156 end
closed?()
[show source]
# File lib/httpx/io/tcp.rb 162 def closed? 163 @state == :idle || @state == :closed 164 end
connect()
[show source]
# File lib/httpx/io/tcp.rb 70 def connect 71 return unless closed? 72 73 if !@io || @io.closed? 74 transition(:idle) 75 @io = build_socket 76 end 77 try_connect 78 rescue Errno::EHOSTUNREACH, 79 Errno::ENETUNREACH => e 80 raise e if @ip_index <= 0 81 82 log { "failed connecting to #{@ip} (#{e.message}), evict from cache and trying next..." } 83 Resolver.cached_lookup_evict(@hostname, @ip) 84 85 @ip_index -= 1 86 @io = build_socket 87 retry 88 rescue Errno::ECONNREFUSED, 89 Errno::EADDRNOTAVAIL, 90 SocketError, 91 IOError => e 92 raise e if @ip_index <= 0 93 94 log { "failed connecting to #{@ip} (#{e.message}), trying next..." } 95 @ip_index -= 1 96 @io = build_socket 97 retry 98 rescue Errno::ETIMEDOUT => e 99 raise ConnectTimeoutError.new(@options.timeout[:connect_timeout], e.message) if @ip_index <= 0 100 101 log { "failed connecting to #{@ip} (#{e.message}), trying next..." } 102 @ip_index -= 1 103 @io = build_socket 104 retry 105 end
connected?()
[show source]
# File lib/httpx/io/tcp.rb 158 def connected? 159 @state == :connected 160 end
expired?()
[show source]
# File lib/httpx/io/tcp.rb 166 def expired? 167 # do not mess with external sockets 168 return false if @options.io 169 170 return true unless @addresses 171 172 resolver_addresses = Resolver.nolookup_resolve(@hostname) 173 174 (Array(resolver_addresses) & @addresses).empty? 175 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 125 def read(size, buffer) 126 ret = @io.read_nonblock(size, buffer, exception: false) 127 if ret == :wait_readable 128 buffer.clear 129 return 0 130 end 131 return if ret.nil? 132 133 log { "READ: #{buffer.bytesize} bytes..." } 134 buffer.bytesize 135 end
write(buffer)
[show source]
# File lib/httpx/io/tcp.rb 137 def write(buffer) 138 siz = @io.write_nonblock(buffer, exception: false) 139 return 0 if siz == :wait_writable 140 return if siz.nil? 141 142 log { "WRITE: #{siz} bytes..." } 143 144 buffer.shift!(siz) 145 siz 146 end