tcp-client 0.10.0 → 0.10.1
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/lib/tcp-client/default_configuration.rb +1 -1
- data/lib/tcp-client/mixin/io_with_deadline.rb +119 -111
- data/lib/tcp-client/ssl_socket.rb +1 -1
- data/lib/tcp-client/version.rb +1 -1
- data/lib/tcp-client.rb +1 -1
- data/spec/tcp_client_spec.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 02440fe17a1480ba18bec8b6918cea6420a065d997c423a6602e165e0f316564
|
4
|
+
data.tar.gz: 73e315f2c80a2f0f1cf0cb57b24f2f2cd45e10caffebd83dd47510ea85de1f25
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb22bb974aacd8cfc9d4a1ebcc66393172ec949db8038ecbc37c1a4187bb8a1d703206625f25fb7dba5e336217d2de31475220aa4147bc20df26a5deff7bd7b7
|
7
|
+
data.tar.gz: 0fd048dda8d10ba76659276cd7f5c09e1fba73560d482a5cbbb35ba6db034192137552531dcd294d45a50a10a211839b318015d0546ded7df28c8f55246fe7fd
|
@@ -1,141 +1,149 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
module IOWithDeadlineMixin
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
3
|
+
class TCPClient
|
4
|
+
module IOWithDeadlineMixin
|
5
|
+
def self.included(mod)
|
6
|
+
methods = mod.instance_methods
|
7
|
+
if methods.index(:wait_writable) && methods.index(:wait_readable)
|
8
|
+
mod.include(ViaWaitMethod)
|
9
|
+
elsif methods.index(:to_io)
|
10
|
+
mod.include(ViaIOWaitMethod)
|
11
|
+
else
|
12
|
+
mod.include(ViaSelect)
|
13
|
+
end
|
13
14
|
end
|
14
|
-
end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
16
|
+
def read_with_deadline(nbytes, deadline, exception)
|
17
|
+
raise(exception) unless deadline.remaining_time
|
18
|
+
return fetch_avail(deadline, exception) if nbytes.nil?
|
19
|
+
return ''.b if nbytes.zero?
|
20
|
+
@buf ||= ''.b
|
21
|
+
while @buf.bytesize < nbytes
|
22
|
+
read = fetch_next(deadline, exception) and next @buf << read
|
23
|
+
close
|
24
|
+
break
|
25
|
+
end
|
26
|
+
fetch_buffer_slice(nbytes)
|
25
27
|
end
|
26
|
-
fetch_buffer_slice(nbytes)
|
27
|
-
end
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
29
|
+
def readto_with_deadline(sep, deadline, exception)
|
30
|
+
raise(exception) unless deadline.remaining_time
|
31
|
+
@buf ||= ''.b
|
32
|
+
while (index = @buf.index(sep)).nil?
|
33
|
+
read = fetch_next(deadline, exception) and next @buf << read
|
34
|
+
close
|
35
|
+
break
|
36
|
+
end
|
37
|
+
index = @buf.index(sep)
|
38
|
+
return fetch_buffer_slice(index + sep.bytesize) if index
|
39
|
+
result = @buf
|
40
|
+
@buf = nil
|
41
|
+
result
|
36
42
|
end
|
37
|
-
index = @buf.index(sep) and return fetch_buffer_slice(index + sep.bytesize)
|
38
|
-
result = @buf
|
39
|
-
@buf = nil
|
40
|
-
result
|
41
|
-
end
|
42
43
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
44
|
+
def write_with_deadline(data, deadline, exception)
|
45
|
+
raise(exception) unless deadline.remaining_time
|
46
|
+
return 0 if (size = data.bytesize).zero?
|
47
|
+
result = 0
|
48
|
+
loop do
|
49
|
+
written =
|
50
|
+
with_deadline(deadline, exception) do
|
51
|
+
write_nonblock(data, exception: false)
|
52
|
+
end
|
53
|
+
(result += written) >= size and return result
|
54
|
+
data = data.byteslice(written, data.bytesize - written)
|
55
|
+
end
|
54
56
|
end
|
55
|
-
end
|
56
57
|
|
57
|
-
|
58
|
+
private
|
58
59
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
60
|
+
def fetch_avail(deadline, exception)
|
61
|
+
if @buf.nil?
|
62
|
+
result = fetch_next(deadline, exception) and return result
|
63
|
+
close
|
64
|
+
return ''.b
|
65
|
+
end
|
66
|
+
result = @buf
|
67
|
+
@buf = nil
|
68
|
+
result
|
64
69
|
end
|
65
|
-
result = @buf
|
66
|
-
@buf = nil
|
67
|
-
result
|
68
|
-
end
|
69
70
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
71
|
+
def fetch_buffer_slice(size)
|
72
|
+
result = @buf.byteslice(0, size)
|
73
|
+
rest = @buf.bytesize - result.bytesize
|
74
|
+
@buf = rest.zero? ? nil : @buf.byteslice(size, rest)
|
75
|
+
result
|
76
|
+
end
|
76
77
|
|
77
|
-
|
78
|
-
|
79
|
-
|
78
|
+
def fetch_next(deadline, exception)
|
79
|
+
with_deadline(deadline, exception) do
|
80
|
+
read_nonblock(65_536, exception: false)
|
81
|
+
end
|
80
82
|
end
|
81
|
-
end
|
82
83
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
84
|
+
module ViaWaitMethod
|
85
|
+
private def with_deadline(deadline, exception)
|
86
|
+
loop do
|
87
|
+
case ret = yield
|
88
|
+
when :wait_writable
|
89
|
+
remaining_time = deadline.remaining_time or raise(exception)
|
90
|
+
raise(exception) if wait_writable(remaining_time).nil?
|
91
|
+
when :wait_readable
|
92
|
+
remaining_time = deadline.remaining_time or raise(exception)
|
93
|
+
raise(exception) if wait_readable(remaining_time).nil?
|
94
|
+
else
|
95
|
+
return ret
|
96
|
+
end
|
95
97
|
end
|
98
|
+
rescue Errno::ETIMEDOUT
|
99
|
+
raise(exception)
|
96
100
|
end
|
97
|
-
rescue Errno::ETIMEDOUT
|
98
|
-
raise(exception)
|
99
101
|
end
|
100
|
-
end
|
101
102
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
103
|
+
module ViaIOWaitMethod
|
104
|
+
private def with_deadline(deadline, exception)
|
105
|
+
loop do
|
106
|
+
case ret = yield
|
107
|
+
when :wait_writable
|
108
|
+
remaining_time = deadline.remaining_time or raise(exception)
|
109
|
+
raise(exception) if to_io.wait_writable(remaining_time).nil?
|
110
|
+
when :wait_readable
|
111
|
+
remaining_time = deadline.remaining_time or raise(exception)
|
112
|
+
raise(exception) if to_io.wait_readable(remaining_time).nil?
|
113
|
+
else
|
114
|
+
return ret
|
115
|
+
end
|
114
116
|
end
|
117
|
+
rescue Errno::ETIMEDOUT
|
118
|
+
raise(exception)
|
115
119
|
end
|
116
|
-
rescue Errno::ETIMEDOUT
|
117
|
-
raise(exception)
|
118
120
|
end
|
119
|
-
end
|
120
121
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
122
|
+
module ViaSelect
|
123
|
+
private def with_deadline(deadline, exception)
|
124
|
+
loop do
|
125
|
+
case ret = yield
|
126
|
+
when :wait_writable
|
127
|
+
remaining_time = deadline.remaining_time or raise(exception)
|
128
|
+
if ::IO.select(nil, [self], nil, remaining_time).nil?
|
129
|
+
raise(exception)
|
130
|
+
end
|
131
|
+
when :wait_readable
|
132
|
+
remaining_time = deadline.remaining_time or raise(exception)
|
133
|
+
if ::IO.select([self], nil, nil, remaining_time).nil?
|
134
|
+
raise(exception)
|
135
|
+
end
|
136
|
+
else
|
137
|
+
return ret
|
138
|
+
end
|
133
139
|
end
|
140
|
+
rescue Errno::ETIMEDOUT
|
141
|
+
raise(exception)
|
134
142
|
end
|
135
|
-
rescue Errno::ETIMEDOUT
|
136
|
-
raise(exception)
|
137
143
|
end
|
144
|
+
|
145
|
+
private_constant(:ViaWaitMethod, :ViaIOWaitMethod, :ViaSelect)
|
138
146
|
end
|
139
147
|
|
140
|
-
private_constant(:
|
148
|
+
private_constant(:IOWithDeadlineMixin)
|
141
149
|
end
|
@@ -30,7 +30,7 @@ class TCPClient
|
|
30
30
|
::OpenSSL::SSL::SSLContext.new.tap do |ctx|
|
31
31
|
ctx.set_params(ssl_params)
|
32
32
|
ctx.session_cache_mode = CONTEXT_CACHE_MODE
|
33
|
-
ctx.session_new_cb = proc { |_,
|
33
|
+
ctx.session_new_cb = proc { |_, session| @new_session = session }
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
data/lib/tcp-client/version.rb
CHANGED
data/lib/tcp-client.rb
CHANGED
@@ -13,7 +13,7 @@ require_relative 'tcp-client/version'
|
|
13
13
|
# Client class to communicate with a server via TCP w/o SSL.
|
14
14
|
#
|
15
15
|
# All connect/read/write actions can be monitored to ensure that all actions
|
16
|
-
# terminate before given time
|
16
|
+
# terminate before given time limit - or raise an exception.
|
17
17
|
#
|
18
18
|
# @example request to Google.com and limit network interactions to 1.5 seconds
|
19
19
|
# # create a configuration to use at least TLS 1.2
|
data/spec/tcp_client_spec.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tcp-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.
|
4
|
+
version: 0.10.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Blumtritt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-03-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -129,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
129
129
|
- !ruby/object:Gem::Version
|
130
130
|
version: '0'
|
131
131
|
requirements: []
|
132
|
-
rubygems_version: 3.3.
|
132
|
+
rubygems_version: 3.3.7
|
133
133
|
signing_key:
|
134
134
|
specification_version: 4
|
135
135
|
summary: A TCP client implementation with working timeout support.
|