tcp-client 0.11.4 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c1aa14f6b147ad3e70a4020f9973c45682dcbe7a0d99cd4c50dbe65b2db05141
4
- data.tar.gz: 61393c3ce4e626b2299fd1a1ab74ea7f600506ca3bde690c1b128c1a9c669eb0
3
+ metadata.gz: 1fc5d1bf109cf729758affe093ed44313d0e688c9c0098bf671f9c8e1250118c
4
+ data.tar.gz: 185ea5d345ecd2cceecafe6d19179a68919429df7269c5088bd89032749d6db3
5
5
  SHA512:
6
- metadata.gz: 8831cef32985a2f41b11fd6830548badb93963df3d67a9bb0424de3e601552cc687a8b27b13433e01f88a3672bdd24df21a5bd3656b85b0ad562838b9fb2c418
7
- data.tar.gz: d636abef03299dd92f916d54eec01414985fa87375254d6e3814d6307159bac62963591f87cb176387fcdf26ae3562df6883223c6710e9572a123af8d4f6ba70
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 TLS 1.2 or TLS 1.3
22
- cfg = TCPClient::Configuration.create(
23
- buffered: false,
24
- ssl_params: {min_version: :TLS1_2, max_version: :TLS1_3}
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
- ```bash
58
+ ```shell
56
59
  bundle
57
60
  ```
58
61
 
59
62
  To install the gem globally use:
60
63
 
61
- ```bash
64
+ ```shell
62
65
  gem install tcp-client
63
66
  ```
64
67
 
@@ -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
- attr_reader :hostname
30
+ def host
31
+ freeze if @host.nil?
32
+ @host
33
+ end
34
+ alias hostname host
14
35
 
15
36
  #
16
- # @return [Addrinfo] the address info
37
+ # @attribute [r] port
38
+ # @return [Integer] the port number
17
39
  #
18
- attr_reader :addrinfo
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
- case addr
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
- # @attribute [r] port
67
- # @return [Integer] the port number
81
+ # Convert `self` to a Hash containing host and port attribute.
68
82
  #
69
- def port
70
- @addrinfo.ip_port
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
- hostname.index(':') ? "[#{hostname}]:#{port}" : "#{hostname}:#{port}"
104
+ host.index(':') ? "[#{host}]:#{port}" : "#{host}:#{port}"
78
105
  end
79
106
 
80
107
  #
81
- # Convert `self` to a Hash containing host and port attribute.
108
+ # Force the address resolution and prevents further modifications of itself.
82
109
  #
83
- # @return [Hash] host and port
110
+ # @return [Address] itself
84
111
  #
85
- def to_h
86
- { host: hostname, port: port }
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
- to_h == other.to_h
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 init_from_selfclass(address)
103
- @hostname = address.hostname
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 init_from_addrinfo(addrinfo)
108
- @hostname = addrinfo.getnameinfo(Socket::NI_NUMERICSERV).first
156
+ def from_addrinfo(addrinfo)
157
+ @host = addrinfo.getnameinfo(Socket::NI_NUMERICSERV).first
109
158
  @addrinfo = addrinfo
110
159
  end
111
160
 
112
- def init_from_string(str)
113
- @hostname, port = from_string(str.to_s)
114
- if @hostname
115
- @addrinfo = Addrinfo.tcp(@hostname, port)
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 from_string(str)
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 to_h
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
- to_h == other.to_h
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
- loop do
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
- loop do
87
+ while true
88
88
  case ret = yield
89
89
  when :wait_writable
90
90
  remaining_time = deadline.remaining_time or raise(exception)
@@ -2,5 +2,5 @@
2
2
 
3
3
  class TCPClient
4
4
  # The current version number.
5
- VERSION = '0.11.4'
5
+ VERSION = '0.12.0'
6
6
  end
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 = stem_errors { Address.new(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.11.4
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-01-15 00:00:00.000000000 Z
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.3
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.