tcp-client 0.9.3 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 75811fed2b0735c2cac6a4e9671e138df88e6b8ada2be03a0d86b4b83b37b863
4
- data.tar.gz: 9c715081912711178a0038d9af9832cf6c45e2620c2cff6dad899565de86be02
3
+ metadata.gz: 02440fe17a1480ba18bec8b6918cea6420a065d997c423a6602e165e0f316564
4
+ data.tar.gz: 73e315f2c80a2f0f1cf0cb57b24f2f2cd45e10caffebd83dd47510ea85de1f25
5
5
  SHA512:
6
- metadata.gz: d2842f5bd4fa2806c15bb94d6c1da9a897be40959a5db9033f404f1c980648a997daee0d49ad1fb75e4cf680644f72dfb04e880eb0c9e9ba9207d6ee3dd75240
7
- data.tar.gz: 174878bab1414b1ef49bd67a1f296d21e463bd7d817442340192aace8af88e56d941b647ad43ff0ed5126e2c2ab16e0159c0467dd7a08289d93c423ca520e2cb
6
+ metadata.gz: bb22bb974aacd8cfc9d4a1ebcc66393172ec949db8038ecbc37c1a4187bb8a1d703206625f25fb7dba5e336217d2de31475220aa4147bc20df26a5deff7bd7b7
7
+ data.tar.gz: 0fd048dda8d10ba76659276cd7f5c09e1fba73560d482a5cbbb35ba6db034192137552531dcd294d45a50a10a211839b318015d0546ded7df28c8f55246fe7fd
data/README.md CHANGED
@@ -27,11 +27,14 @@ cfg = TCPClient::Configuration.create(
27
27
  # - limit all network interactions to 1.5 seconds
28
28
  # - use the Configuration cfg
29
29
  # - send a simple HTTP get request
30
- # - read 12 byte: "HTTP/1.1 " + 3 byte HTTP status code
31
- TCPClient.with_deadline(1.5, 'www.google.com:443', cfg) do |client|
32
- client.write("GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n") # >= 40
33
- client.read(12) # => "HTTP/1.1 200"
34
- end
30
+ # - read the returned message and headers
31
+ response =
32
+ TCPClient.with_deadline(1.5, 'www.google.com:443', cfg) do |client|
33
+ client.write("GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n") #=> 40
34
+ client.readline("\r\n\r\n") #=> see response
35
+ end
36
+
37
+ puts(response)
35
38
  ```
36
39
 
37
40
  For more samples see [the samples dir](https://github.com/mblumtritt/tcp-client/tree/main/sample)
@@ -41,7 +41,7 @@ class TCPClient
41
41
  # @param addrinfo [Addrinfo] containing the addressed host and port
42
42
  #
43
43
  # @overload initialize(port)
44
- # Adresses the port on the local machine.
44
+ # Addresses the port on the local machine.
45
45
  #
46
46
  # @example create an Address for localhost on port 80
47
47
  # Address.new(80)
@@ -62,19 +62,28 @@ class TCPClient
62
62
  @addrinfo.freeze
63
63
  end
64
64
 
65
+ #
66
+ # @attribute [r] port
67
+ # @return [Integer] the port number
68
+ #
69
+ def port
70
+ @addrinfo.ip_port
71
+ end
72
+
65
73
  #
66
74
  # @return [String] text representation of self as "host:port"
67
75
  #
68
76
  def to_s
69
- return "[#{@hostname}]:#{@addrinfo.ip_port}" if @hostname.index(':') # IP6
70
- "#{@hostname}:#{@addrinfo.ip_port}"
77
+ hostname.index(':') ? "[#{hostname}]:#{port}" : "#{hostname}:#{port}"
71
78
  end
72
79
 
73
80
  #
74
- # @return [Hash] containing the host and port
81
+ # Convert `self` to a Hash containing host and port attribute.
82
+ #
83
+ # @return [Hash] host and port
75
84
  #
76
85
  def to_h
77
- { host: @hostname, port: @addrinfo.ip_port }
86
+ { host: hostname, port: port }
78
87
  end
79
88
 
80
89
  # @!visibility private
@@ -96,7 +105,7 @@ class TCPClient
96
105
  end
97
106
 
98
107
  def init_from_addrinfo(addrinfo)
99
- @hostname, _port = addrinfo.getnameinfo(Socket::NI_NUMERICSERV)
108
+ @hostname = addrinfo.getnameinfo(Socket::NI_NUMERICSERV).first
100
109
  @addrinfo = addrinfo
101
110
  end
102
111
 
@@ -109,7 +118,7 @@ class TCPClient
109
118
  def from_string(str)
110
119
  idx = str.rindex(':') or return nil, str.to_i
111
120
  name = str[0, idx].delete_prefix('[').delete_suffix(']')
112
- [name, str[idx + 1, str.size - idx].to_i]
121
+ [name.empty? ? nil : name, str[idx + 1, str.size - idx].to_i]
113
122
  end
114
123
  end
115
124
  end
@@ -6,24 +6,14 @@ class TCPClient
6
6
  #
7
7
  # A Configuration is used to configure the behavior of a {TCPClient} instance.
8
8
  #
9
- # It allows to specify to monitor timeout, how to handle exceptions, if SSL
9
+ # It allows to specify the monitor timeout, how to handle exceptions, if SSL
10
10
  # should be used and to setup the underlying Socket.
11
11
  #
12
12
  class Configuration
13
13
  #
14
- # @overload create(options)
15
- # Shorthand to create a new configuration with given options.
16
- #
17
- # @example
18
- # config = TCPClient::Configuration.create(buffered: false)
19
- #
20
- # @param options [Hash] see {#initialize} for details
21
- #
22
- # @return [Configuration] the initialized configuration
23
- #
24
- # @overload create(&block)
25
- # Shorthand to create a new configuration within a code block.
14
+ # Shorthand to create a new configuration.
26
15
  #
16
+ # @overload create()
27
17
  # @example
28
18
  # config = TCPClient::Configuration.create do |cfg|
29
19
  # cfg.buffered = false
@@ -32,7 +22,13 @@ class TCPClient
32
22
  #
33
23
  # @yieldparam configuration {Configuration}
34
24
  #
35
- # @return [Configuration] the initialized configuration
25
+ # @overload create(options)
26
+ # @example
27
+ # config = TCPClient::Configuration.create(buffered: false)
28
+ #
29
+ # @param options [{Symbol => Object}] see {#initialize} for details
30
+ #
31
+ # @return [Configuration] the initialized configuration
36
32
  #
37
33
  def self.create(options = {})
38
34
  configuration = new(options)
@@ -41,25 +37,25 @@ class TCPClient
41
37
  end
42
38
 
43
39
  #
44
- # Intializes the instance with given options.
40
+ # Initializes the instance with given options.
45
41
  #
46
- # @param options [Hash]
42
+ # @param options [{Symbol => Object}]
47
43
  # @option options [Boolean] :buffered, see {#buffered}
48
44
  # @option options [Boolean] :keep_alive, see {#keep_alive}
49
45
  # @option options [Boolean] :reverse_lookup, see {#reverse_lookup}
50
- # @option options [Hash<Symbol, Object>] :ssl_params, see {#ssl_params}
46
+ # @option options [{Symbol => Object}] :ssl_params, see {#ssl_params}
51
47
  # @option options [Numeric] :connect_timeout, see {#connect_timeout}
52
- # @option options [Exception] :connect_timeout_error, see
48
+ # @option options [Class<Exception>] :connect_timeout_error, see
53
49
  # {#connect_timeout_error}
54
50
  # @option options [Numeric] :read_timeout, see {#read_timeout}
55
- # @option options [Exception] :read_timeout_error, see {#read_timeout_error}
51
+ # @option options [Class<Exception>] :read_timeout_error, see
52
+ # {#read_timeout_error}
56
53
  # @option options [Numeric] :write_timeout, see {#write_timeout}
57
- # @option options [Exception] :write_timeout_error, see
54
+ # @option options [Class<Exception>] :write_timeout_error, see
58
55
  # {#write_timeout_error}
59
56
  # @option options [Boolean] :normalize_network_errors, see
60
57
  # {#normalize_network_errors}
61
58
  #
62
- #
63
59
  def initialize(options = {})
64
60
  @buffered = @keep_alive = @reverse_lookup = true
65
61
  self.timeout = @ssl_params = nil
@@ -75,9 +71,8 @@ class TCPClient
75
71
  #
76
72
  # Enables/disables use of Socket-level buffering
77
73
  #
78
- # @return [true] if the connection is allowed to use internal buffers
79
- # (default)
80
- # @return [false] if buffering is not allowed
74
+ # @return [Boolean] whether the connection is allowed to use internal
75
+ # buffers (default) or not
81
76
  #
82
77
  attr_reader :buffered
83
78
 
@@ -88,9 +83,8 @@ class TCPClient
88
83
  #
89
84
  # Enables/disables use of Socket-level keep alive handling.
90
85
  #
91
- # @return [true] if the connection is allowed to use keep alive signals
92
- # (default)
93
- # @return [false] if the connection should not check keep alive
86
+ # @return [Boolean] whether the connection is allowed to use keep alive
87
+ # signals (default) or not
94
88
  #
95
89
  attr_reader :keep_alive
96
90
 
@@ -101,9 +95,8 @@ class TCPClient
101
95
  #
102
96
  # Enables/disables address lookup.
103
97
  #
104
- # @return [true] if the connection is allowed to lookup the address
105
- # (default)
106
- # @return [false] if the address lookup is not required
98
+ # @return [Boolean] whether the connection is allowed to lookup the address
99
+ # (default) or not
107
100
  #
108
101
  attr_reader :reverse_lookup
109
102
 
@@ -113,16 +106,17 @@ class TCPClient
113
106
 
114
107
  #
115
108
  # @!parse attr_reader :ssl?
116
- # @return [Boolean] wheter SSL is configured, see {#ssl_params}
109
+ # @return [Boolean] whether SSL is configured, see {#ssl_params}
117
110
  #
118
111
  def ssl?
119
112
  @ssl_params ? true : false
120
113
  end
121
114
 
122
115
  #
123
- # Parameters used to initialize a SSL context.
116
+ # Parameters used to initialize a SSL context. SSL/TLS will only be used if
117
+ # this attribute is not `nil`.
124
118
  #
125
- # @return [Hash<Symbol, Object>] SSL parameters for the SSL context
119
+ # @return [{Symbol => Object}] SSL parameters for the SSL context
126
120
  # @return [nil] if no SSL should be used (default)
127
121
  #
128
122
  attr_reader :ssl_params
@@ -161,7 +155,7 @@ class TCPClient
161
155
  # The exception class which will be raised if {TCPClient#connect} can not
162
156
  # be finished in time.
163
157
  #
164
- # @return [Class] exception class raised
158
+ # @return [Class<Exception>] exception class raised
165
159
  # @raise [NotAnExceptionError] if given argument is not an Exception class
166
160
  #
167
161
  attr_reader :connect_timeout_error
@@ -189,7 +183,7 @@ class TCPClient
189
183
  # The exception class which will be raised if {TCPClient#read} can not be
190
184
  # finished in time.
191
185
  #
192
- # @return [Class] exception class raised
186
+ # @return [Class<Exception>] exception class raised
193
187
  # @raise [NotAnExceptionError] if given argument is not an Exception class
194
188
  #
195
189
  attr_reader :read_timeout_error
@@ -217,7 +211,7 @@ class TCPClient
217
211
  # The exception class which will be raised if {TCPClient#write} can not be
218
212
  # finished in time.
219
213
  #
220
- # @return [Class] exception class raised
214
+ # @return [Class<Exception>] exception class raised
221
215
  # @raise [NotAnExceptionError] if given argument is not an Exception class
222
216
  #
223
217
  attr_reader :write_timeout_error
@@ -231,7 +225,7 @@ class TCPClient
231
225
  # @attribute [w] timeout
232
226
  # Shorthand to set maximum time in seconds for all timeout monitoring.
233
227
  #
234
- # @return [Numeric] maximum time in seconds for any actwion
228
+ # @return [Numeric] maximum time in seconds for any action
235
229
  # @return [nil] if all timeout monitoring should be disabled (default)
236
230
  #
237
231
  # @see #connect_timeout
@@ -244,9 +238,10 @@ class TCPClient
244
238
 
245
239
  #
246
240
  # @attribute [w] timeout_error
247
- # Shorthand to set the exception class wich will by raised by any timeout.
241
+ # Shorthand to set the exception class which will by raised by any reached
242
+ # timeout.
248
243
  #
249
- # @return [Class] exception class raised
244
+ # @return [Class<Exception>] exception class raised
250
245
  #
251
246
  # @raise [NotAnExceptionError] if given argument is not an Exception class
252
247
  #
@@ -270,9 +265,8 @@ class TCPClient
270
265
  # manner. If this option is set to true all these error cases are raised as
271
266
  # {NetworkError} and can be easily captured.
272
267
  #
273
- # @return [true] if all network exceptions should be raised as
274
- # {NetworkError}
275
- # @return [false] if socket/system errors should not be normalzed (default)
268
+ # @return [Boolean] whether all network exceptions should be raised as
269
+ # {NetworkError}, or not (default)
276
270
  #
277
271
  attr_reader :normalize_network_errors
278
272
 
@@ -281,9 +275,7 @@ class TCPClient
281
275
  end
282
276
 
283
277
  #
284
- # Convert `self` to a Hash containing all attributes.
285
- #
286
- # @return [Hash<Symbol, Object>]
278
+ # @return [{Symbol => Object}] Hash containing all attributes
287
279
  #
288
280
  # @see #initialize
289
281
  #
@@ -2,8 +2,6 @@
2
2
 
3
3
  class TCPClient
4
4
  class Deadline
5
- MONOTONIC = defined?(Process::CLOCK_MONOTONIC) ? true : false
6
-
7
5
  def initialize(timeout)
8
6
  timeout = timeout&.to_f
9
7
  @deadline = timeout&.positive? ? now + timeout : 0
@@ -19,7 +17,7 @@ class TCPClient
19
17
 
20
18
  private
21
19
 
22
- if MONOTONIC
20
+ if defined?(Process::CLOCK_MONOTONIC)
23
21
  def now
24
22
  Process.clock_gettime(Process::CLOCK_MONOTONIC)
25
23
  end
@@ -41,7 +41,7 @@ class TCPClient
41
41
  #
42
42
  # @!parse attr_reader :default
43
43
  # @return [Configuration] used by default if no dedicated configuration
44
- # was specified
44
+ # was specified
45
45
  #
46
46
  # @see TCPClient.open
47
47
  # @see TCPClient.with_deadline
@@ -2,7 +2,8 @@
2
2
 
3
3
  class TCPClient
4
4
  #
5
- # Raised when a SSL connection should be establshed but the OpenSSL gem is not available.
5
+ # Raised when a SSL connection should be established but the OpenSSL gem is
6
+ # not available.
6
7
  #
7
8
  class NoOpenSSLError < RuntimeError
8
9
  def initialize
@@ -11,7 +12,8 @@ class TCPClient
11
12
  end
12
13
 
13
14
  #
14
- # Raised when a method requires a callback block but no such block is specified.
15
+ # Raised when a method requires a callback block but no such block is
16
+ # specified.
15
17
  #
16
18
  class NoBlockGivenError < ArgumentError
17
19
  def initialize
@@ -36,7 +38,7 @@ class TCPClient
36
38
  #
37
39
  class UnknownAttributeError < ArgumentError
38
40
  #
39
- # @param attribute [Object] the undefined atttribute
41
+ # @param attribute [Object] the undefined attribute
40
42
  #
41
43
  def initialize(attribute)
42
44
  super("unknown attribute - #{attribute}")
@@ -58,15 +60,18 @@ class TCPClient
58
60
  #
59
61
  # Base exception class for all network related errors.
60
62
  #
61
- # Will be raised for any system level network error when {Configuration.normalize_network_errors} is configured.
63
+ # Will be raised for any system level network error when
64
+ # {Configuration.normalize_network_errors} is configured.
62
65
  #
63
- # You should catch this exception class when you like to handle any relevant {TCPClient} error.
66
+ # You should catch this exception class when you like to handle any relevant
67
+ # {TCPClient} error.
64
68
  #
65
69
  class NetworkError < StandardError
66
70
  end
67
71
 
68
72
  #
69
- # Raised when a {TCPClient} instance should read/write from/to the network but is not connected.
73
+ # Raised when a {TCPClient} instance should read/write from/to the network
74
+ # but is not connected.
70
75
  #
71
76
  class NotConnectedError < NetworkError
72
77
  def initialize
@@ -77,7 +82,8 @@ class TCPClient
77
82
  #
78
83
  # Base exception class for a detected timeout.
79
84
  #
80
- # You should catch this exception class when you like to handle any timeout error.
85
+ # You should catch this exception class when you like to handle any timeout
86
+ # error.
81
87
  #
82
88
  class TimeoutError < NetworkError
83
89
  #
@@ -1,111 +1,149 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # @!visibility private
4
- module IOWithDeadlineMixin # :nodoc:
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)
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
- def read_with_deadline(bytes_to_read, deadline, exception)
17
- raise(exception) unless deadline.remaining_time
18
- if bytes_to_read.nil?
19
- return(
20
- with_deadline(deadline, exception) do
21
- read_nonblock(65_536, exception: false)
22
- end
23
- )
24
- end
25
- result = ''.b
26
- while result.bytesize < bytes_to_read
27
- read =
28
- with_deadline(deadline, exception) do
29
- read_nonblock(bytes_to_read - result.bytesize, exception: false)
30
- end
31
- next result += read if read
32
- close
33
- break
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)
34
27
  end
35
- result
36
- end
37
28
 
38
- def write_with_deadline(data, deadline, exception)
39
- raise(exception) unless deadline.remaining_time
40
- return 0 if (size = data.bytesize).zero?
41
- result = 0
42
- loop do
43
- written =
44
- with_deadline(deadline, exception) do
45
- write_nonblock(data, exception: false)
46
- end
47
- result += written
48
- return result if result >= size
49
- data = data.byteslice(written, data.bytesize - written)
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
50
42
  end
51
- end
52
43
 
53
- module ViaWaitMethod
54
- private def with_deadline(deadline, exception)
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
55
48
  loop do
56
- case ret = yield
57
- when :wait_writable
58
- remaining_time = deadline.remaining_time or raise(exception)
59
- raise(exception) if wait_writable(remaining_time).nil?
60
- when :wait_readable
61
- remaining_time = deadline.remaining_time or raise(exception)
62
- raise(exception) if wait_readable(remaining_time).nil?
63
- else
64
- return ret
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
56
+ end
57
+
58
+ private
59
+
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
69
+ end
70
+
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
77
+
78
+ def fetch_next(deadline, exception)
79
+ with_deadline(deadline, exception) do
80
+ read_nonblock(65_536, exception: false)
81
+ end
82
+ end
83
+
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
65
97
  end
98
+ rescue Errno::ETIMEDOUT
99
+ raise(exception)
66
100
  end
67
- rescue Errno::ETIMEDOUT
68
- raise(exception)
69
101
  end
70
- end
71
102
 
72
- module ViaIOWaitMethod
73
- private def with_deadline(deadline, exception)
74
- loop do
75
- case ret = yield
76
- when :wait_writable
77
- remaining_time = deadline.remaining_time or raise(exception)
78
- raise(exception) if to_io.wait_writable(remaining_time).nil?
79
- when :wait_readable
80
- remaining_time = deadline.remaining_time or raise(exception)
81
- raise(exception) if to_io.wait_readable(remaining_time).nil?
82
- else
83
- return ret
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
84
116
  end
117
+ rescue Errno::ETIMEDOUT
118
+ raise(exception)
85
119
  end
86
- rescue Errno::ETIMEDOUT
87
- raise(exception)
88
120
  end
89
- end
90
121
 
91
- module ViaSelect
92
- private def with_deadline(deadline, exception)
93
- loop do
94
- case ret = yield
95
- when :wait_writable
96
- remaining_time = deadline.remaining_time or raise(exception)
97
- raise(exception) if ::IO.select(nil, [self], nil, remaining_time).nil?
98
- when :wait_readable
99
- remaining_time = deadline.remaining_time or raise(exception)
100
- raise(exception) if ::IO.select([self], nil, nil, remaining_time).nil?
101
- else
102
- return ret
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
103
139
  end
140
+ rescue Errno::ETIMEDOUT
141
+ raise(exception)
104
142
  end
105
- rescue Errno::ETIMEDOUT
106
- raise(exception)
107
143
  end
144
+
145
+ private_constant(:ViaWaitMethod, :ViaIOWaitMethod, :ViaSelect)
108
146
  end
109
147
 
110
- private_constant(:ViaWaitMethod, :ViaIOWaitMethod, :ViaSelect)
148
+ private_constant(:IOWithDeadlineMixin)
111
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 { |_, sess| @new_session = sess }
33
+ ctx.session_new_cb = proc { |_, session| @new_session = session }
34
34
  end
35
35
  end
36
36
 
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class TCPClient
4
- VERSION = '0.9.3'
4
+ # The current version number.
5
+ VERSION = '0.10.1'
5
6
  end