class HTTPX::TCP

  1. lib/httpx/io/tcp.rb
Superclass: Object

Included modules

  1. Loggable

Attributes

addresses [R]
host [R]
interests [R]
ip [R]
port [R]
state [R]

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
protocol()
[show source]
   # File lib/httpx/io/tcp.rb
77 def protocol
78   @fallback_protocol
79 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
socket()
[show source]
   # File lib/httpx/io/tcp.rb
43 def socket
44   @io
45 end
to_io()
[show source]
   # File lib/httpx/io/tcp.rb
73 def to_io
74   @io.to_io
75 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