tcp-client 0.11.4 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +10 -7
- data/lib/tcp-client/address.rb +83 -37
- data/lib/tcp-client/configuration.rb +13 -2
- data/lib/tcp-client/mixin/io_with_deadline.rb +2 -2
- data/lib/tcp-client/version.rb +1 -1
- data/lib/tcp-client.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1fc5d1bf109cf729758affe093ed44313d0e688c9c0098bf671f9c8e1250118c
|
4
|
+
data.tar.gz: 185ea5d345ecd2cceecafe6d19179a68919429df7269c5088bd89032749d6db3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b34d0fef41cafa8d915ed203a5a4a934f22d2ee37fbe4a1f992bef6278f3ebfb7715ff7b4672e01af98c81d7a39eb7d057d79499b41248db44cf4de730240b1d
|
7
|
+
data.tar.gz: 5125d264eb11b6c5358df65525ad8ac9806f69d4e3f5bccd3dc775a36ae1f49c6c3b3cb97b410e09bdc214275a3b95b0f576c3a52db77f79ef610203e29fabd9
|
data/README.md
CHANGED
@@ -18,11 +18,14 @@ require 'tcp-client'
|
|
18
18
|
|
19
19
|
# create a configuration:
|
20
20
|
# - don't use internal buffering
|
21
|
-
# - use
|
22
|
-
cfg =
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
# - use at least TLS 1.2
|
22
|
+
cfg =
|
23
|
+
TCPClient::Configuration.create(
|
24
|
+
buffered: false,
|
25
|
+
ssl_params: {
|
26
|
+
min_version: :TLS1_2
|
27
|
+
}
|
28
|
+
)
|
26
29
|
|
27
30
|
# request to Google.com:
|
28
31
|
# - limit all network interactions to 1.5 seconds
|
@@ -52,13 +55,13 @@ gem 'tcp-client'
|
|
52
55
|
|
53
56
|
and install it by running Bundler:
|
54
57
|
|
55
|
-
```
|
58
|
+
```shell
|
56
59
|
bundle
|
57
60
|
```
|
58
61
|
|
59
62
|
To install the gem globally use:
|
60
63
|
|
61
|
-
```
|
64
|
+
```shell
|
62
65
|
gem install tcp-client
|
63
66
|
```
|
64
67
|
|
data/lib/tcp-client/address.rb
CHANGED
@@ -4,21 +4,46 @@ require 'socket'
|
|
4
4
|
|
5
5
|
class TCPClient
|
6
6
|
#
|
7
|
-
# The address used by a TCPClient
|
7
|
+
# The address used by a TCPClient.
|
8
|
+
#
|
9
|
+
# @note An {Address} does not resolve the required TCP information until it is
|
10
|
+
# needed.
|
11
|
+
#
|
12
|
+
# This means that address resolution only occurs when an instance attribute
|
13
|
+
# is accessed or the address is frozen.
|
14
|
+
# To force the address resolution at a certain time, {#freeze} can be called.
|
8
15
|
#
|
9
16
|
class Address
|
10
17
|
#
|
18
|
+
# @attribute [r] addrinfo
|
19
|
+
# @return [Addrinfo] the address info
|
20
|
+
#
|
21
|
+
def addrinfo
|
22
|
+
freeze if @addrinfo.nil?
|
23
|
+
@addrinfo
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# @attribute [r] host
|
11
28
|
# @return [String] the host name
|
12
29
|
#
|
13
|
-
|
30
|
+
def host
|
31
|
+
freeze if @host.nil?
|
32
|
+
@host
|
33
|
+
end
|
34
|
+
alias hostname host
|
14
35
|
|
15
36
|
#
|
16
|
-
# @
|
37
|
+
# @attribute [r] port
|
38
|
+
# @return [Integer] the port number
|
17
39
|
#
|
18
|
-
|
40
|
+
def port
|
41
|
+
addrinfo.ip_port
|
42
|
+
end
|
19
43
|
|
20
44
|
#
|
21
45
|
# Initializes an address
|
46
|
+
#
|
22
47
|
# @overload initialize(addr)
|
23
48
|
# The addr can be specified as
|
24
49
|
#
|
@@ -49,46 +74,53 @@ class TCPClient
|
|
49
74
|
# @param port [Integer] the addressed port
|
50
75
|
#
|
51
76
|
def initialize(addr)
|
52
|
-
|
53
|
-
when self.class
|
54
|
-
init_from_selfclass(addr)
|
55
|
-
when Addrinfo
|
56
|
-
init_from_addrinfo(addr)
|
57
|
-
when Integer
|
58
|
-
init_from_addrinfo(Addrinfo.tcp(nil, addr))
|
59
|
-
else
|
60
|
-
init_from_string(addr)
|
61
|
-
end
|
62
|
-
@addrinfo.freeze
|
77
|
+
@addr = addr
|
63
78
|
end
|
64
79
|
|
65
80
|
#
|
66
|
-
#
|
67
|
-
# @return [Integer] the port number
|
81
|
+
# Convert `self` to a Hash containing host and port attribute.
|
68
82
|
#
|
69
|
-
|
70
|
-
|
83
|
+
# @return [Hash] host and port
|
84
|
+
#
|
85
|
+
def to_hash
|
86
|
+
{ host: host, port: port }
|
87
|
+
end
|
88
|
+
|
89
|
+
#
|
90
|
+
# Convert `self` to a Hash containing host and port attribute.
|
91
|
+
#
|
92
|
+
# @overload to_h
|
93
|
+
# @overload to_h(&block)
|
94
|
+
# @return [Hash] host and port
|
95
|
+
#
|
96
|
+
def to_h(&block)
|
97
|
+
block ? to_hash.to_h(&block) : to_hash
|
71
98
|
end
|
72
99
|
|
73
100
|
#
|
74
101
|
# @return [String] text representation of self as "host:port"
|
75
102
|
#
|
76
103
|
def to_s
|
77
|
-
|
104
|
+
host.index(':') ? "[#{host}]:#{port}" : "#{host}:#{port}"
|
78
105
|
end
|
79
106
|
|
80
107
|
#
|
81
|
-
#
|
108
|
+
# Force the address resolution and prevents further modifications of itself.
|
82
109
|
#
|
83
|
-
# @return [
|
110
|
+
# @return [Address] itself
|
84
111
|
#
|
85
|
-
def
|
86
|
-
|
112
|
+
def freeze
|
113
|
+
return super if frozen?
|
114
|
+
solve
|
115
|
+
@addrinfo.freeze
|
116
|
+
@host.freeze
|
117
|
+
@addr = nil
|
118
|
+
super
|
87
119
|
end
|
88
120
|
|
89
121
|
# @!visibility private
|
90
122
|
def ==(other)
|
91
|
-
|
123
|
+
to_hash == other.to_h
|
92
124
|
end
|
93
125
|
alias eql? ==
|
94
126
|
|
@@ -99,26 +131,40 @@ class TCPClient
|
|
99
131
|
|
100
132
|
private
|
101
133
|
|
102
|
-
def
|
103
|
-
@
|
134
|
+
def solve
|
135
|
+
case @addr
|
136
|
+
when self.class
|
137
|
+
from_self_class(@addr)
|
138
|
+
when Addrinfo
|
139
|
+
from_addrinfo(@addr)
|
140
|
+
when Integer
|
141
|
+
from_addrinfo(Addrinfo.tcp(nil, @addr))
|
142
|
+
else
|
143
|
+
from_string(@addr)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def from_self_class(address)
|
148
|
+
unless address.frozen?
|
149
|
+
@addr = address.instance_variable_get(:@addr)
|
150
|
+
return solve
|
151
|
+
end
|
104
152
|
@addrinfo = address.addrinfo
|
153
|
+
@host = address.host
|
105
154
|
end
|
106
155
|
|
107
|
-
def
|
108
|
-
@
|
156
|
+
def from_addrinfo(addrinfo)
|
157
|
+
@host = addrinfo.getnameinfo(Socket::NI_NUMERICSERV).first
|
109
158
|
@addrinfo = addrinfo
|
110
159
|
end
|
111
160
|
|
112
|
-
def
|
113
|
-
@
|
114
|
-
if @
|
115
|
-
|
116
|
-
else
|
117
|
-
init_from_addrinfo(Addrinfo.tcp(nil, port)) unless @hostname
|
118
|
-
end
|
161
|
+
def from_string(str)
|
162
|
+
@host, port = host_n_port(str.to_s)
|
163
|
+
return @addrinfo = Addrinfo.tcp(@host, port) if @host
|
164
|
+
from_addrinfo(Addrinfo.tcp(nil, port))
|
119
165
|
end
|
120
166
|
|
121
|
-
def
|
167
|
+
def host_n_port(str)
|
122
168
|
idx = str.rindex(':') or return nil, str.to_i
|
123
169
|
name = str[0, idx].delete_prefix('[').delete_suffix(']')
|
124
170
|
[name.empty? ? nil : name, str[idx + 1, str.size - idx].to_i]
|
@@ -268,7 +268,7 @@ class TCPClient
|
|
268
268
|
#
|
269
269
|
# @see #configure
|
270
270
|
#
|
271
|
-
def
|
271
|
+
def to_hash
|
272
272
|
{
|
273
273
|
buffered: @buffered,
|
274
274
|
keep_alive: @keep_alive,
|
@@ -284,6 +284,17 @@ class TCPClient
|
|
284
284
|
}
|
285
285
|
end
|
286
286
|
|
287
|
+
#
|
288
|
+
# @overload to_h
|
289
|
+
# @overload to_h(&block)
|
290
|
+
# @return [{Symbol => Object}] Hash containing all attributes
|
291
|
+
#
|
292
|
+
# @see #configure
|
293
|
+
#
|
294
|
+
def to_h(&block)
|
295
|
+
block ? to_hash.to_h(&block) : to_hash
|
296
|
+
end
|
297
|
+
|
287
298
|
#
|
288
299
|
# Configures the instance with given options Hash.
|
289
300
|
#
|
@@ -326,7 +337,7 @@ class TCPClient
|
|
326
337
|
|
327
338
|
# @!visibility private
|
328
339
|
def ==(other)
|
329
|
-
|
340
|
+
to_hash == other.to_h
|
330
341
|
end
|
331
342
|
alias eql? ==
|
332
343
|
|
@@ -48,7 +48,7 @@ class TCPClient
|
|
48
48
|
return 0 if (size = data.bytesize).zero?
|
49
49
|
raise(exception) unless deadline.remaining_time
|
50
50
|
result = 0
|
51
|
-
|
51
|
+
while true
|
52
52
|
written =
|
53
53
|
with_deadline(deadline, exception) do
|
54
54
|
write_nonblock(data, exception: false)
|
@@ -84,7 +84,7 @@ class TCPClient
|
|
84
84
|
end
|
85
85
|
|
86
86
|
def with_deadline(deadline, exception)
|
87
|
-
|
87
|
+
while true
|
88
88
|
case ret = yield
|
89
89
|
when :wait_writable
|
90
90
|
remaining_time = deadline.remaining_time or raise(exception)
|
data/lib/tcp-client/version.rb
CHANGED
data/lib/tcp-client.rb
CHANGED
@@ -161,7 +161,7 @@ class TCPClient
|
|
161
161
|
close if @socket
|
162
162
|
@configuration = (configuration || Configuration.default).dup
|
163
163
|
raise(NoOpenSSLError) if @configuration.ssl? && !defined?(SSLSocket)
|
164
|
-
@address =
|
164
|
+
@address = Address.new(address)
|
165
165
|
@socket = create_socket(timeout, exception)
|
166
166
|
self
|
167
167
|
end
|
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.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Blumtritt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-04-06 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
This gem implements a customizable TCP client class that gives you control
|
@@ -43,6 +43,7 @@ metadata:
|
|
43
43
|
source_code_uri: https://github.com/mblumtritt/tcp-client
|
44
44
|
bug_tracker_uri: https://github.com/mblumtritt/tcp-client/issues
|
45
45
|
documentation_uri: https://rubydoc.info/gems/tcp-client
|
46
|
+
rubygems_mfa_required: 'true'
|
46
47
|
post_install_message:
|
47
48
|
rdoc_options: []
|
48
49
|
require_paths:
|
@@ -58,7 +59,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
58
59
|
- !ruby/object:Gem::Version
|
59
60
|
version: '0'
|
60
61
|
requirements: []
|
61
|
-
rubygems_version: 3.4.
|
62
|
+
rubygems_version: 3.4.10
|
62
63
|
signing_key:
|
63
64
|
specification_version: 4
|
64
65
|
summary: Use your TCP connections with working timeout.
|