libuv 0.11.22 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +19 -17
- data/.gitmodules +3 -3
- data/.rspec +1 -1
- data/.travis.yml +16 -16
- data/Gemfile +4 -4
- data/LICENSE +23 -23
- data/README.md +89 -89
- data/Rakefile +31 -31
- data/lib/libuv.rb +54 -54
- data/lib/libuv/async.rb +47 -47
- data/lib/libuv/check.rb +55 -55
- data/lib/libuv/dns.rb +85 -85
- data/lib/libuv/error.rb +78 -74
- data/lib/libuv/ext/ext.rb +260 -258
- data/lib/libuv/ext/platform/darwin_x64.rb +23 -23
- data/lib/libuv/ext/platform/linux.rb +7 -7
- data/lib/libuv/ext/platform/unix.rb +29 -29
- data/lib/libuv/ext/platform/windows.rb +40 -40
- data/lib/libuv/ext/tasks.rb +31 -31
- data/lib/libuv/ext/tasks/mac.rb +23 -23
- data/lib/libuv/ext/tasks/unix.rb +23 -23
- data/lib/libuv/ext/tasks/win.rb +14 -14
- data/lib/libuv/ext/types.rb +238 -238
- data/lib/libuv/file.rb +281 -269
- data/lib/libuv/filesystem.rb +232 -232
- data/lib/libuv/fs_event.rb +31 -31
- data/lib/libuv/handle.rb +85 -85
- data/lib/libuv/idle.rb +56 -56
- data/lib/libuv/loop.rb +412 -412
- data/lib/libuv/mixins/assertions.rb +23 -23
- data/lib/libuv/mixins/fs_checks.rb +60 -58
- data/lib/libuv/mixins/listener.rb +34 -34
- data/lib/libuv/mixins/net.rb +40 -40
- data/lib/libuv/mixins/resource.rb +27 -27
- data/lib/libuv/mixins/stream.rb +153 -154
- data/lib/libuv/pipe.rb +184 -203
- data/lib/libuv/prepare.rb +56 -56
- data/lib/libuv/signal.rb +51 -51
- data/lib/libuv/tcp.rb +334 -334
- data/lib/libuv/timer.rb +85 -85
- data/lib/libuv/tty.rb +37 -37
- data/lib/libuv/udp.rb +240 -240
- data/lib/libuv/version.rb +3 -3
- data/lib/libuv/work.rb +75 -75
- data/libuv.gemspec +56 -56
- data/spec/async_spec.rb +61 -60
- data/spec/cpu_spec.rb +10 -10
- data/spec/defer_spec.rb +980 -980
- data/spec/dns_spec.rb +96 -90
- data/spec/filesystem_spec.rb +270 -261
- data/spec/idle_spec.rb +56 -56
- data/spec/pipe_spec.rb +160 -160
- data/spec/tcp_spec.rb +271 -267
- metadata +64 -51
data/lib/libuv/signal.rb
CHANGED
@@ -1,51 +1,51 @@
|
|
1
|
-
module Libuv
|
2
|
-
class Signal < Handle
|
3
|
-
|
4
|
-
|
5
|
-
SIGNALS = {
|
6
|
-
:HUP => 1,
|
7
|
-
:SIGHUP => 1,
|
8
|
-
:INT => 2,
|
9
|
-
:SIGINT => 2,
|
10
|
-
:BREAK => 21,
|
11
|
-
:SIGBREAK => 21,
|
12
|
-
:WINCH => 28,
|
13
|
-
:SIGWINCH => 28
|
14
|
-
}
|
15
|
-
|
16
|
-
|
17
|
-
# @param loop [::Libuv::Loop] loop this signal handler will be associated
|
18
|
-
# @param callback [Proc] callback to be called when the signal is triggered
|
19
|
-
def initialize(loop)
|
20
|
-
@loop = loop
|
21
|
-
|
22
|
-
signal_ptr = ::Libuv::Ext.create_handle(:uv_signal)
|
23
|
-
error = check_result(::Libuv::Ext.signal_init(loop.handle, signal_ptr))
|
24
|
-
|
25
|
-
super(signal_ptr, error)
|
26
|
-
end
|
27
|
-
|
28
|
-
# Enables the signal handler.
|
29
|
-
def start(signal)
|
30
|
-
return if @closed
|
31
|
-
signal = SIGNALS[signal] if signal.is_a? Symbol
|
32
|
-
error = check_result ::Libuv::Ext.signal_start(handle, callback(:on_sig), signal)
|
33
|
-
reject(error) if error
|
34
|
-
end
|
35
|
-
|
36
|
-
# Disables the signal handler.
|
37
|
-
def stop
|
38
|
-
return if @closed
|
39
|
-
error = check_result ::Libuv::Ext.signal_stop(handle)
|
40
|
-
reject(error) if error
|
41
|
-
end
|
42
|
-
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
|
47
|
-
def on_sig(handle, signal)
|
48
|
-
defer.notify(signal) # notify of a call
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
1
|
+
module Libuv
|
2
|
+
class Signal < Handle
|
3
|
+
|
4
|
+
|
5
|
+
SIGNALS = {
|
6
|
+
:HUP => 1,
|
7
|
+
:SIGHUP => 1,
|
8
|
+
:INT => 2,
|
9
|
+
:SIGINT => 2,
|
10
|
+
:BREAK => 21,
|
11
|
+
:SIGBREAK => 21,
|
12
|
+
:WINCH => 28,
|
13
|
+
:SIGWINCH => 28
|
14
|
+
}
|
15
|
+
|
16
|
+
|
17
|
+
# @param loop [::Libuv::Loop] loop this signal handler will be associated
|
18
|
+
# @param callback [Proc] callback to be called when the signal is triggered
|
19
|
+
def initialize(loop)
|
20
|
+
@loop = loop
|
21
|
+
|
22
|
+
signal_ptr = ::Libuv::Ext.create_handle(:uv_signal)
|
23
|
+
error = check_result(::Libuv::Ext.signal_init(loop.handle, signal_ptr))
|
24
|
+
|
25
|
+
super(signal_ptr, error)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Enables the signal handler.
|
29
|
+
def start(signal)
|
30
|
+
return if @closed
|
31
|
+
signal = SIGNALS[signal] if signal.is_a? Symbol
|
32
|
+
error = check_result ::Libuv::Ext.signal_start(handle, callback(:on_sig), signal)
|
33
|
+
reject(error) if error
|
34
|
+
end
|
35
|
+
|
36
|
+
# Disables the signal handler.
|
37
|
+
def stop
|
38
|
+
return if @closed
|
39
|
+
error = check_result ::Libuv::Ext.signal_stop(handle)
|
40
|
+
reject(error) if error
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
|
47
|
+
def on_sig(handle, signal)
|
48
|
+
defer.notify(signal) # notify of a call
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/libuv/tcp.rb
CHANGED
@@ -1,335 +1,335 @@
|
|
1
|
-
require 'ipaddr'
|
2
|
-
require 'ruby-tls'
|
3
|
-
|
4
|
-
|
5
|
-
module Libuv
|
6
|
-
class TCP < Handle
|
7
|
-
include Stream, Net
|
8
|
-
|
9
|
-
|
10
|
-
TLS_ERROR = "TLS write failed".freeze
|
11
|
-
|
12
|
-
|
13
|
-
attr_reader :connected
|
14
|
-
# Check if tls active on the socket
|
15
|
-
def tls?; !@tls.nil?; end
|
16
|
-
|
17
|
-
|
18
|
-
def initialize(loop, acceptor = nil)
|
19
|
-
@loop = loop
|
20
|
-
|
21
|
-
tcp_ptr = ::Libuv::Ext.create_handle(:uv_tcp)
|
22
|
-
error = check_result(::Libuv::Ext.tcp_init(loop.handle, tcp_ptr))
|
23
|
-
|
24
|
-
if acceptor && error.nil?
|
25
|
-
error = check_result(::Libuv::Ext.accept(acceptor, tcp_ptr))
|
26
|
-
@connected = true
|
27
|
-
else
|
28
|
-
@connected = false
|
29
|
-
end
|
30
|
-
|
31
|
-
super(tcp_ptr, error)
|
32
|
-
end
|
33
|
-
|
34
|
-
|
35
|
-
#
|
36
|
-
# TLS Abstraction ----------------------
|
37
|
-
# --------------------------------------
|
38
|
-
#
|
39
|
-
def start_tls(args = {})
|
40
|
-
return unless @connected && @tls.nil?
|
41
|
-
|
42
|
-
@handshake = false
|
43
|
-
@pending_writes = []
|
44
|
-
@tls = ::RubyTls::Connection.new(self)
|
45
|
-
@tls.start(args)
|
46
|
-
end
|
47
|
-
|
48
|
-
# Push through any pending writes when handshake has completed
|
49
|
-
def handshake_cb
|
50
|
-
@handshake = true
|
51
|
-
writes = @pending_writes
|
52
|
-
@pending_writes = nil
|
53
|
-
writes.each do |deferred, data|
|
54
|
-
@pending_write = deferred
|
55
|
-
@tls.encrypt(data)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
# This is clear text data that has been decrypted
|
60
|
-
# Same as stream.rb on_read for clear text
|
61
|
-
def dispatch_cb(data)
|
62
|
-
begin
|
63
|
-
@progress.call data, self
|
64
|
-
rescue Exception => e
|
65
|
-
@loop.log :error, :stream_progress_cb, e
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
# We resolve the existing tls write promise with a the
|
70
|
-
# real writes promise (a close may have occurred)
|
71
|
-
def transmit_cb(data)
|
72
|
-
if not @pending_write.nil?
|
73
|
-
@pending_write.resolve(direct_write(data))
|
74
|
-
@pending_write = nil
|
75
|
-
else
|
76
|
-
direct_write(data)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
# Close can be called multiple times
|
81
|
-
def close_cb
|
82
|
-
if not @pending_write.nil?
|
83
|
-
@pending_write.reject(TLS_ERROR)
|
84
|
-
@pending_write = nil
|
85
|
-
end
|
86
|
-
|
87
|
-
# Shutdown the stream
|
88
|
-
close
|
89
|
-
end
|
90
|
-
|
91
|
-
# overwrite the default close to ensure
|
92
|
-
# pending writes are rejected
|
93
|
-
def close
|
94
|
-
return if @closed
|
95
|
-
|
96
|
-
@tls.cleanup if @tls # Free tls memory
|
97
|
-
@connected = false
|
98
|
-
|
99
|
-
if not @pending_writes.nil?
|
100
|
-
@pending_writes.each do |deferred, data|
|
101
|
-
deferred.reject(TLS_ERROR)
|
102
|
-
end
|
103
|
-
@pending_writes = nil
|
104
|
-
end
|
105
|
-
|
106
|
-
super
|
107
|
-
end
|
108
|
-
|
109
|
-
# Verify peers will be called for each cert in the chain
|
110
|
-
def verify_peer(&block)
|
111
|
-
@tls.verify_cb &block
|
112
|
-
end
|
113
|
-
|
114
|
-
alias_method :direct_write, :write
|
115
|
-
def write(data)
|
116
|
-
if @tls.nil?
|
117
|
-
direct_write(data)
|
118
|
-
else
|
119
|
-
deferred = @loop.defer
|
120
|
-
|
121
|
-
if @handshake == true
|
122
|
-
@pending_write = deferred
|
123
|
-
@tls.encrypt(data)
|
124
|
-
else
|
125
|
-
@pending_writes << [deferred, data]
|
126
|
-
end
|
127
|
-
|
128
|
-
deferred.promise
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
alias_method :do_shutdown, :shutdown
|
133
|
-
def shutdown
|
134
|
-
if @pending_writes && @pending_writes.length > 0
|
135
|
-
@pending_writes[-1][0].finally method(:do_shutdown)
|
136
|
-
else
|
137
|
-
do_shutdown
|
138
|
-
end
|
139
|
-
end
|
140
|
-
#
|
141
|
-
# END TLS Abstraction ------------------
|
142
|
-
# --------------------------------------
|
143
|
-
#
|
144
|
-
|
145
|
-
def bind(ip, port, callback = nil, &blk)
|
146
|
-
return if @closed
|
147
|
-
@on_listen = callback || blk
|
148
|
-
assert_type(String, ip, IP_ARGUMENT_ERROR)
|
149
|
-
assert_type(Integer, port, PORT_ARGUMENT_ERROR)
|
150
|
-
|
151
|
-
begin
|
152
|
-
@tcp_socket = create_socket(IPAddr.new(ip), port)
|
153
|
-
@tcp_socket.bind
|
154
|
-
rescue Exception => e
|
155
|
-
reject(e)
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
def open(fd, binding = true, callback = nil, &blk)
|
160
|
-
return if @closed
|
161
|
-
if binding
|
162
|
-
@on_listen = callback || blk
|
163
|
-
else
|
164
|
-
@callback = callback || blk
|
165
|
-
end
|
166
|
-
error = check_result UV.tcp_open(handle, fd)
|
167
|
-
reject(error) if error
|
168
|
-
end
|
169
|
-
|
170
|
-
def accept(callback = nil, &blk)
|
171
|
-
begin
|
172
|
-
raise RuntimeError, CLOSED_HANDLE_ERROR if @closed
|
173
|
-
tcp = TCP.new(loop, handle)
|
174
|
-
begin
|
175
|
-
(callback || blk).call(tcp)
|
176
|
-
rescue Exception => e
|
177
|
-
@loop.log :error, :tcp_accept_cb, e
|
178
|
-
end
|
179
|
-
rescue Exception => e
|
180
|
-
@loop.log :info, :tcp_accept_failed, e
|
181
|
-
end
|
182
|
-
nil
|
183
|
-
end
|
184
|
-
|
185
|
-
def connect(ip, port, callback = nil, &blk)
|
186
|
-
return if @closed
|
187
|
-
@callback = callback || blk
|
188
|
-
assert_type(String, ip, IP_ARGUMENT_ERROR)
|
189
|
-
assert_type(Integer, port, PORT_ARGUMENT_ERROR)
|
190
|
-
|
191
|
-
begin
|
192
|
-
@tcp_socket = create_socket(IPAddr.new(ip), port)
|
193
|
-
@tcp_socket.connect(callback(:on_connect))
|
194
|
-
rescue Exception => e
|
195
|
-
reject(e)
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
def sockname
|
200
|
-
return [] if @closed
|
201
|
-
sockaddr, len = get_sockaddr_and_len
|
202
|
-
check_result! ::Libuv::Ext.tcp_getsockname(handle, sockaddr, len)
|
203
|
-
get_ip_and_port(::Libuv::Ext::Sockaddr.new(sockaddr), len.get_int(0))
|
204
|
-
end
|
205
|
-
|
206
|
-
def peername
|
207
|
-
return [] if @closed
|
208
|
-
sockaddr, len = get_sockaddr_and_len
|
209
|
-
check_result! ::Libuv::Ext.tcp_getpeername(handle, sockaddr, len)
|
210
|
-
get_ip_and_port(::Libuv::Ext::Sockaddr.new(sockaddr), len.get_int(0))
|
211
|
-
end
|
212
|
-
|
213
|
-
def enable_nodelay
|
214
|
-
return if @closed
|
215
|
-
check_result ::Libuv::Ext.tcp_nodelay(handle, 1)
|
216
|
-
end
|
217
|
-
|
218
|
-
def disable_nodelay
|
219
|
-
return if @closed
|
220
|
-
check_result ::Libuv::Ext.tcp_nodelay(handle, 0)
|
221
|
-
end
|
222
|
-
|
223
|
-
def enable_keepalive(delay)
|
224
|
-
return if @closed # The to_i asserts integer
|
225
|
-
check_result ::Libuv::Ext.tcp_keepalive(handle, 1, delay.to_i)
|
226
|
-
end
|
227
|
-
|
228
|
-
def disable_keepalive
|
229
|
-
return if @closed
|
230
|
-
check_result ::Libuv::Ext.tcp_keepalive(handle, 0, 0)
|
231
|
-
end
|
232
|
-
|
233
|
-
def enable_simultaneous_accepts
|
234
|
-
return if @closed
|
235
|
-
check_result ::Libuv::Ext.tcp_simultaneous_accepts(handle, 1)
|
236
|
-
end
|
237
|
-
|
238
|
-
def disable_simultaneous_accepts
|
239
|
-
return if @closed
|
240
|
-
check_result ::Libuv::Ext.tcp_simultaneous_accepts(handle, 0)
|
241
|
-
end
|
242
|
-
|
243
|
-
|
244
|
-
private
|
245
|
-
|
246
|
-
|
247
|
-
def create_socket(ip, port)
|
248
|
-
if ip.ipv4?
|
249
|
-
Socket4.new(loop, handle, ip.to_s, port)
|
250
|
-
else
|
251
|
-
Socket6.new(loop, handle, ip.to_s, port)
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
def on_connect(req, status)
|
256
|
-
::Libuv::Ext.free(req)
|
257
|
-
e = check_result(status)
|
258
|
-
|
259
|
-
if e
|
260
|
-
reject(e)
|
261
|
-
else
|
262
|
-
@connected = true
|
263
|
-
|
264
|
-
begin
|
265
|
-
@callback.call(self)
|
266
|
-
rescue Exception => e
|
267
|
-
@loop.log :error, :connect_cb, e
|
268
|
-
end
|
269
|
-
end
|
270
|
-
end
|
271
|
-
|
272
|
-
|
273
|
-
class SocketBase
|
274
|
-
include Resource
|
275
|
-
|
276
|
-
def initialize(loop, tcp, ip, port)
|
277
|
-
@tcp, @sockaddr = tcp, ip_addr(ip, port)
|
278
|
-
@loop = loop
|
279
|
-
end
|
280
|
-
|
281
|
-
def bind
|
282
|
-
check_result!(tcp_bind)
|
283
|
-
end
|
284
|
-
|
285
|
-
def connect(callback)
|
286
|
-
check_result!(tcp_connect(callback))
|
287
|
-
end
|
288
|
-
|
289
|
-
|
290
|
-
protected
|
291
|
-
|
292
|
-
|
293
|
-
def connect_req
|
294
|
-
::Libuv::Ext.create_request(:uv_connect)
|
295
|
-
end
|
296
|
-
|
297
|
-
def tcp_connect(callback)
|
298
|
-
::Libuv::Ext.tcp_connect(
|
299
|
-
connect_req,
|
300
|
-
@tcp,
|
301
|
-
@sockaddr,
|
302
|
-
callback
|
303
|
-
)
|
304
|
-
end
|
305
|
-
|
306
|
-
def tcp_bind
|
307
|
-
::Libuv::Ext.tcp_bind(@tcp, @sockaddr)
|
308
|
-
end
|
309
|
-
end
|
310
|
-
|
311
|
-
|
312
|
-
class Socket4 < SocketBase
|
313
|
-
protected
|
314
|
-
|
315
|
-
|
316
|
-
def ip_addr(ip, port)
|
317
|
-
addr = Ext::SockaddrIn.new
|
318
|
-
check_result! ::Libuv::Ext.ip4_addr(ip, port, addr)
|
319
|
-
addr
|
320
|
-
end
|
321
|
-
end
|
322
|
-
|
323
|
-
|
324
|
-
class Socket6 < SocketBase
|
325
|
-
protected
|
326
|
-
|
327
|
-
|
328
|
-
def ip_addr(ip, port)
|
329
|
-
addr = Ext::SockaddrIn6.new
|
330
|
-
check_result! ::Libuv::Ext.ip6_addr(ip, port, addr)
|
331
|
-
addr
|
332
|
-
end
|
333
|
-
end
|
334
|
-
end
|
1
|
+
require 'ipaddr'
|
2
|
+
require 'ruby-tls'
|
3
|
+
|
4
|
+
|
5
|
+
module Libuv
|
6
|
+
class TCP < Handle
|
7
|
+
include Stream, Net
|
8
|
+
|
9
|
+
|
10
|
+
TLS_ERROR = "TLS write failed".freeze
|
11
|
+
|
12
|
+
|
13
|
+
attr_reader :connected
|
14
|
+
# Check if tls active on the socket
|
15
|
+
def tls?; !@tls.nil?; end
|
16
|
+
|
17
|
+
|
18
|
+
def initialize(loop, acceptor = nil)
|
19
|
+
@loop = loop
|
20
|
+
|
21
|
+
tcp_ptr = ::Libuv::Ext.create_handle(:uv_tcp)
|
22
|
+
error = check_result(::Libuv::Ext.tcp_init(loop.handle, tcp_ptr))
|
23
|
+
|
24
|
+
if acceptor && error.nil?
|
25
|
+
error = check_result(::Libuv::Ext.accept(acceptor, tcp_ptr))
|
26
|
+
@connected = true
|
27
|
+
else
|
28
|
+
@connected = false
|
29
|
+
end
|
30
|
+
|
31
|
+
super(tcp_ptr, error)
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
#
|
36
|
+
# TLS Abstraction ----------------------
|
37
|
+
# --------------------------------------
|
38
|
+
#
|
39
|
+
def start_tls(args = {})
|
40
|
+
return unless @connected && @tls.nil?
|
41
|
+
|
42
|
+
@handshake = false
|
43
|
+
@pending_writes = []
|
44
|
+
@tls = ::RubyTls::Connection.new(self)
|
45
|
+
@tls.start(args)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Push through any pending writes when handshake has completed
|
49
|
+
def handshake_cb
|
50
|
+
@handshake = true
|
51
|
+
writes = @pending_writes
|
52
|
+
@pending_writes = nil
|
53
|
+
writes.each do |deferred, data|
|
54
|
+
@pending_write = deferred
|
55
|
+
@tls.encrypt(data)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# This is clear text data that has been decrypted
|
60
|
+
# Same as stream.rb on_read for clear text
|
61
|
+
def dispatch_cb(data)
|
62
|
+
begin
|
63
|
+
@progress.call data, self
|
64
|
+
rescue Exception => e
|
65
|
+
@loop.log :error, :stream_progress_cb, e
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# We resolve the existing tls write promise with a the
|
70
|
+
# real writes promise (a close may have occurred)
|
71
|
+
def transmit_cb(data)
|
72
|
+
if not @pending_write.nil?
|
73
|
+
@pending_write.resolve(direct_write(data))
|
74
|
+
@pending_write = nil
|
75
|
+
else
|
76
|
+
direct_write(data)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Close can be called multiple times
|
81
|
+
def close_cb
|
82
|
+
if not @pending_write.nil?
|
83
|
+
@pending_write.reject(TLS_ERROR)
|
84
|
+
@pending_write = nil
|
85
|
+
end
|
86
|
+
|
87
|
+
# Shutdown the stream
|
88
|
+
close
|
89
|
+
end
|
90
|
+
|
91
|
+
# overwrite the default close to ensure
|
92
|
+
# pending writes are rejected
|
93
|
+
def close
|
94
|
+
return if @closed
|
95
|
+
|
96
|
+
@tls.cleanup if @tls # Free tls memory
|
97
|
+
@connected = false
|
98
|
+
|
99
|
+
if not @pending_writes.nil?
|
100
|
+
@pending_writes.each do |deferred, data|
|
101
|
+
deferred.reject(TLS_ERROR)
|
102
|
+
end
|
103
|
+
@pending_writes = nil
|
104
|
+
end
|
105
|
+
|
106
|
+
super
|
107
|
+
end
|
108
|
+
|
109
|
+
# Verify peers will be called for each cert in the chain
|
110
|
+
def verify_peer(&block)
|
111
|
+
@tls.verify_cb &block
|
112
|
+
end
|
113
|
+
|
114
|
+
alias_method :direct_write, :write
|
115
|
+
def write(data)
|
116
|
+
if @tls.nil?
|
117
|
+
direct_write(data)
|
118
|
+
else
|
119
|
+
deferred = @loop.defer
|
120
|
+
|
121
|
+
if @handshake == true
|
122
|
+
@pending_write = deferred
|
123
|
+
@tls.encrypt(data)
|
124
|
+
else
|
125
|
+
@pending_writes << [deferred, data]
|
126
|
+
end
|
127
|
+
|
128
|
+
deferred.promise
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
alias_method :do_shutdown, :shutdown
|
133
|
+
def shutdown
|
134
|
+
if @pending_writes && @pending_writes.length > 0
|
135
|
+
@pending_writes[-1][0].finally method(:do_shutdown)
|
136
|
+
else
|
137
|
+
do_shutdown
|
138
|
+
end
|
139
|
+
end
|
140
|
+
#
|
141
|
+
# END TLS Abstraction ------------------
|
142
|
+
# --------------------------------------
|
143
|
+
#
|
144
|
+
|
145
|
+
def bind(ip, port, callback = nil, &blk)
|
146
|
+
return if @closed
|
147
|
+
@on_listen = callback || blk
|
148
|
+
assert_type(String, ip, IP_ARGUMENT_ERROR)
|
149
|
+
assert_type(Integer, port, PORT_ARGUMENT_ERROR)
|
150
|
+
|
151
|
+
begin
|
152
|
+
@tcp_socket = create_socket(IPAddr.new(ip), port)
|
153
|
+
@tcp_socket.bind
|
154
|
+
rescue Exception => e
|
155
|
+
reject(e)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def open(fd, binding = true, callback = nil, &blk)
|
160
|
+
return if @closed
|
161
|
+
if binding
|
162
|
+
@on_listen = callback || blk
|
163
|
+
else
|
164
|
+
@callback = callback || blk
|
165
|
+
end
|
166
|
+
error = check_result UV.tcp_open(handle, fd)
|
167
|
+
reject(error) if error
|
168
|
+
end
|
169
|
+
|
170
|
+
def accept(callback = nil, &blk)
|
171
|
+
begin
|
172
|
+
raise RuntimeError, CLOSED_HANDLE_ERROR if @closed
|
173
|
+
tcp = TCP.new(loop, handle)
|
174
|
+
begin
|
175
|
+
(callback || blk).call(tcp)
|
176
|
+
rescue Exception => e
|
177
|
+
@loop.log :error, :tcp_accept_cb, e
|
178
|
+
end
|
179
|
+
rescue Exception => e
|
180
|
+
@loop.log :info, :tcp_accept_failed, e
|
181
|
+
end
|
182
|
+
nil
|
183
|
+
end
|
184
|
+
|
185
|
+
def connect(ip, port, callback = nil, &blk)
|
186
|
+
return if @closed
|
187
|
+
@callback = callback || blk
|
188
|
+
assert_type(String, ip, IP_ARGUMENT_ERROR)
|
189
|
+
assert_type(Integer, port, PORT_ARGUMENT_ERROR)
|
190
|
+
|
191
|
+
begin
|
192
|
+
@tcp_socket = create_socket(IPAddr.new(ip), port)
|
193
|
+
@tcp_socket.connect(callback(:on_connect))
|
194
|
+
rescue Exception => e
|
195
|
+
reject(e)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def sockname
|
200
|
+
return [] if @closed
|
201
|
+
sockaddr, len = get_sockaddr_and_len
|
202
|
+
check_result! ::Libuv::Ext.tcp_getsockname(handle, sockaddr, len)
|
203
|
+
get_ip_and_port(::Libuv::Ext::Sockaddr.new(sockaddr), len.get_int(0))
|
204
|
+
end
|
205
|
+
|
206
|
+
def peername
|
207
|
+
return [] if @closed
|
208
|
+
sockaddr, len = get_sockaddr_and_len
|
209
|
+
check_result! ::Libuv::Ext.tcp_getpeername(handle, sockaddr, len)
|
210
|
+
get_ip_and_port(::Libuv::Ext::Sockaddr.new(sockaddr), len.get_int(0))
|
211
|
+
end
|
212
|
+
|
213
|
+
def enable_nodelay
|
214
|
+
return if @closed
|
215
|
+
check_result ::Libuv::Ext.tcp_nodelay(handle, 1)
|
216
|
+
end
|
217
|
+
|
218
|
+
def disable_nodelay
|
219
|
+
return if @closed
|
220
|
+
check_result ::Libuv::Ext.tcp_nodelay(handle, 0)
|
221
|
+
end
|
222
|
+
|
223
|
+
def enable_keepalive(delay)
|
224
|
+
return if @closed # The to_i asserts integer
|
225
|
+
check_result ::Libuv::Ext.tcp_keepalive(handle, 1, delay.to_i)
|
226
|
+
end
|
227
|
+
|
228
|
+
def disable_keepalive
|
229
|
+
return if @closed
|
230
|
+
check_result ::Libuv::Ext.tcp_keepalive(handle, 0, 0)
|
231
|
+
end
|
232
|
+
|
233
|
+
def enable_simultaneous_accepts
|
234
|
+
return if @closed
|
235
|
+
check_result ::Libuv::Ext.tcp_simultaneous_accepts(handle, 1)
|
236
|
+
end
|
237
|
+
|
238
|
+
def disable_simultaneous_accepts
|
239
|
+
return if @closed
|
240
|
+
check_result ::Libuv::Ext.tcp_simultaneous_accepts(handle, 0)
|
241
|
+
end
|
242
|
+
|
243
|
+
|
244
|
+
private
|
245
|
+
|
246
|
+
|
247
|
+
def create_socket(ip, port)
|
248
|
+
if ip.ipv4?
|
249
|
+
Socket4.new(loop, handle, ip.to_s, port)
|
250
|
+
else
|
251
|
+
Socket6.new(loop, handle, ip.to_s, port)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
def on_connect(req, status)
|
256
|
+
::Libuv::Ext.free(req)
|
257
|
+
e = check_result(status)
|
258
|
+
|
259
|
+
if e
|
260
|
+
reject(e)
|
261
|
+
else
|
262
|
+
@connected = true
|
263
|
+
|
264
|
+
begin
|
265
|
+
@callback.call(self)
|
266
|
+
rescue Exception => e
|
267
|
+
@loop.log :error, :connect_cb, e
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
|
273
|
+
class SocketBase
|
274
|
+
include Resource
|
275
|
+
|
276
|
+
def initialize(loop, tcp, ip, port)
|
277
|
+
@tcp, @sockaddr = tcp, ip_addr(ip, port)
|
278
|
+
@loop = loop
|
279
|
+
end
|
280
|
+
|
281
|
+
def bind
|
282
|
+
check_result!(tcp_bind)
|
283
|
+
end
|
284
|
+
|
285
|
+
def connect(callback)
|
286
|
+
check_result!(tcp_connect(callback))
|
287
|
+
end
|
288
|
+
|
289
|
+
|
290
|
+
protected
|
291
|
+
|
292
|
+
|
293
|
+
def connect_req
|
294
|
+
::Libuv::Ext.create_request(:uv_connect)
|
295
|
+
end
|
296
|
+
|
297
|
+
def tcp_connect(callback)
|
298
|
+
::Libuv::Ext.tcp_connect(
|
299
|
+
connect_req,
|
300
|
+
@tcp,
|
301
|
+
@sockaddr,
|
302
|
+
callback
|
303
|
+
)
|
304
|
+
end
|
305
|
+
|
306
|
+
def tcp_bind
|
307
|
+
::Libuv::Ext.tcp_bind(@tcp, @sockaddr)
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
|
312
|
+
class Socket4 < SocketBase
|
313
|
+
protected
|
314
|
+
|
315
|
+
|
316
|
+
def ip_addr(ip, port)
|
317
|
+
addr = Ext::SockaddrIn.new
|
318
|
+
check_result! ::Libuv::Ext.ip4_addr(ip, port, addr)
|
319
|
+
addr
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
|
324
|
+
class Socket6 < SocketBase
|
325
|
+
protected
|
326
|
+
|
327
|
+
|
328
|
+
def ip_addr(ip, port)
|
329
|
+
addr = Ext::SockaddrIn6.new
|
330
|
+
check_result! ::Libuv::Ext.ip6_addr(ip, port, addr)
|
331
|
+
addr
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
335
335
|
end
|