Class: HTTPX::TCP
Constant Summary
Constants included
from Loggable
Loggable::COLORS, Loggable::USE_DEBUG_LOG
Instance Attribute Summary collapse
Instance Method Summary
collapse
Methods included from Loggable
#log, #log_exception
Constructor Details
#initialize(origin, addresses, options) ⇒ TCP
Returns a new instance of TCP.
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
# File 'lib/httpx/io/tcp.rb', line 16
def initialize(origin, addresses, options)
@state = :idle
@addresses = []
@hostname = origin.host
@options = options
@fallback_protocol = @options.fallback_protocol
@port = origin.port
@interests = :w
if @options.io
@io = case @options.io
when Hash
@options.io[origin.authority]
else
@options.io
end
raise Error, "Given IO objects do not match the request authority" unless @io
_, _, _, @ip = @io.addr
@addresses << @ip
@keep_open = true
@state = :connected
else
add_addresses(addresses)
end
@ip_index = @addresses.size - 1
end
|
Instance Attribute Details
#addresses ⇒ Object
Returns the value of attribute addresses.
12
13
14
|
# File 'lib/httpx/io/tcp.rb', line 12
def addresses
@addresses
end
|
#interests ⇒ Object
Returns the value of attribute interests.
12
13
14
|
# File 'lib/httpx/io/tcp.rb', line 12
def interests
@interests
end
|
#ip ⇒ Object
Also known as:
host
Returns the value of attribute ip.
12
13
14
|
# File 'lib/httpx/io/tcp.rb', line 12
def ip
@ip
end
|
#port ⇒ Object
Returns the value of attribute port.
12
13
14
|
# File 'lib/httpx/io/tcp.rb', line 12
def port
@port
end
|
#state ⇒ Object
Returns the value of attribute state.
12
13
14
|
# File 'lib/httpx/io/tcp.rb', line 12
def state
@state
end
|
Instance Method Details
#add_addresses(addrs) ⇒ Object
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
# File 'lib/httpx/io/tcp.rb', line 47
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?
@addresses = [*@addresses[0, ip_index], *addrs, *@addresses[ip_index..-1]]
else
@addresses.unshift(*addrs)
@ip_index += addrs.size if @ip_index
end
end
|
#close ⇒ Object
139
140
141
142
143
144
145
146
147
|
# File 'lib/httpx/io/tcp.rb', line 139
def close
return if @keep_open || closed?
begin
@io.close
ensure
transition(:closed)
end
end
|
#closed? ⇒ Boolean
153
154
155
|
# File 'lib/httpx/io/tcp.rb', line 153
def closed?
@state == :idle || @state == :closed
end
|
#connect ⇒ Object
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
# File 'lib/httpx/io/tcp.rb', line 70
def connect
return unless closed?
if !@io || @io.closed?
transition(:idle)
@io = build_socket
end
try_connect
rescue Errno::ECONNREFUSED,
Errno::EADDRNOTAVAIL,
Errno::EHOSTUNREACH,
SocketError,
IOError => 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
|
#connected? ⇒ Boolean
149
150
151
|
# File 'lib/httpx/io/tcp.rb', line 149
def connected?
@state == :connected
end
|
#expired? ⇒ Boolean
157
158
159
160
161
162
163
164
165
166
|
# File 'lib/httpx/io/tcp.rb', line 157
def expired?
return false if @options.io
return true unless @addresses
resolver_addresses = Resolver.nolookup_resolve(@hostname)
(Array(resolver_addresses) & @addresses).empty?
end
|
#inspect ⇒ Object
169
170
171
|
# File 'lib/httpx/io/tcp.rb', line 169
def inspect
"#<#{self.class}: #{@ip}:#{@port} (state: #{@state})>"
end
|
#protocol ⇒ Object
66
67
68
|
# File 'lib/httpx/io/tcp.rb', line 66
def protocol
@fallback_protocol
end
|
#read(size, buffer) ⇒ Object
116
117
118
119
120
121
122
123
124
125
126
|
# File 'lib/httpx/io/tcp.rb', line 116
def read(size, buffer)
ret = @io.read_nonblock(size, buffer, exception: false)
if ret == :wait_readable
buffer.clear
return 0
end
return if ret.nil?
log { "READ: #{buffer.bytesize} bytes..." }
buffer.bytesize
end
|
#socket ⇒ Object
43
44
45
|
# File 'lib/httpx/io/tcp.rb', line 43
def socket
@io
end
|
#to_io ⇒ Object
62
63
64
|
# File 'lib/httpx/io/tcp.rb', line 62
def to_io
@io.to_io
end
|
#write(buffer) ⇒ Object
128
129
130
131
132
133
134
135
136
137
|
# File 'lib/httpx/io/tcp.rb', line 128
def write(buffer)
siz = @io.write_nonblock(buffer, exception: false)
return 0 if siz == :wait_writable
return if siz.nil?
log { "WRITE: #{siz} bytes..." }
buffer.shift!(siz)
siz
end
|