tcp-client 0.9.3 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
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