tcp-client 0.10.0 → 0.11.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/README.md +5 -4
- data/lib/tcp-client/configuration.rb +37 -21
- data/lib/tcp-client/default_configuration.rb +3 -3
- data/lib/tcp-client/mixin/io_with_deadline.rb +78 -101
- data/lib/tcp-client/ssl_socket.rb +1 -1
- data/lib/tcp-client/version.rb +1 -1
- data/lib/tcp-client.rb +5 -4
- metadata +11 -89
- data/.gitignore +0 -6
- data/.yardopts +0 -5
- data/gems.rb +0 -4
- data/rakefile.rb +0 -18
- data/sample/google.rb +0 -21
- data/sample/google_ssl.rb +0 -28
- data/spec/helper.rb +0 -12
- data/spec/tcp-client/address_spec.rb +0 -132
- data/spec/tcp-client/configuration_spec.rb +0 -270
- data/spec/tcp-client/default_configuration_spec.rb +0 -22
- data/spec/tcp-client/version_spec.rb +0 -13
- data/spec/tcp_client_spec.rb +0 -800
- data/tcp-client.gemspec +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c5d814647f45ebfc5a5d43b6b0ae208092c36493bdc839c7e4e722c3ff4b1f0
|
4
|
+
data.tar.gz: 6187b371bb275f0cc88c63091dce51e91f45b79c5257580f881616433c581345
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c48c0b4b0b9f14545895ae489f27d2a75a2c400598a342b553f8e7bbace7f2b4d9d9874f70e85ff40fe3ff4c59e2ea1973e8f324aceacb2705c7982fb1ebb772
|
7
|
+
data.tar.gz: 9c8259dcb4b9b351224627f08a84041d2d8bdf543233d0cefc2b14ed265d67a4b7a2b128bfe75fa4fd8a6b44bab527bb81a815a1edeefafcd85a4733d0064087
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# TCPClient
|
2
2
|
|
3
|
-
|
3
|
+
Use your TCP connections with working timeout.
|
4
4
|
|
5
5
|
- Gem: [rubygems.org](https://rubygems.org/gems/tcp-client)
|
6
6
|
- Source: [github.com](https://github.com/mblumtritt/tcp-client)
|
@@ -8,7 +8,8 @@ A TCP client implementation with working timeout support.
|
|
8
8
|
|
9
9
|
## Description
|
10
10
|
|
11
|
-
This
|
11
|
+
This gem implements a customizable TCP client class that gives you control over time limits. You can set time limits for individual read or write calls or set a deadline for entire call sequences.
|
12
|
+
It has a very small footprint, no dependencies and is easily useable.
|
12
13
|
|
13
14
|
## Sample
|
14
15
|
|
@@ -37,7 +38,7 @@ response =
|
|
37
38
|
puts(response)
|
38
39
|
```
|
39
40
|
|
40
|
-
For more samples see [the
|
41
|
+
For more samples see [the examples dir](https://github.com/mblumtritt/tcp-client/tree/main/examples)
|
41
42
|
|
42
43
|
## Installation
|
43
44
|
|
@@ -61,7 +62,7 @@ To install the gem globally use:
|
|
61
62
|
gem install tcp-client
|
62
63
|
```
|
63
64
|
|
64
|
-
After that you need only a single line of code in your project to have
|
65
|
+
After that you need only a single line of code in your project to have it on board:
|
65
66
|
|
66
67
|
```ruby
|
67
68
|
require 'tcp-client'
|
@@ -30,40 +30,25 @@ class TCPClient
|
|
30
30
|
#
|
31
31
|
# @return [Configuration] the initialized configuration
|
32
32
|
#
|
33
|
-
def self.create(options =
|
33
|
+
def self.create(options = nil)
|
34
34
|
configuration = new(options)
|
35
35
|
yield(configuration) if block_given?
|
36
36
|
configuration
|
37
37
|
end
|
38
38
|
|
39
39
|
#
|
40
|
-
# Initializes the instance with given options.
|
40
|
+
# Initializes and optionally configures the instance with given options.
|
41
41
|
#
|
42
|
-
# @
|
43
|
-
# @option options [Boolean] :buffered, see {#buffered}
|
44
|
-
# @option options [Boolean] :keep_alive, see {#keep_alive}
|
45
|
-
# @option options [Boolean] :reverse_lookup, see {#reverse_lookup}
|
46
|
-
# @option options [{Symbol => Object}] :ssl_params, see {#ssl_params}
|
47
|
-
# @option options [Numeric] :connect_timeout, see {#connect_timeout}
|
48
|
-
# @option options [Class<Exception>] :connect_timeout_error, see
|
49
|
-
# {#connect_timeout_error}
|
50
|
-
# @option options [Numeric] :read_timeout, see {#read_timeout}
|
51
|
-
# @option options [Class<Exception>] :read_timeout_error, see
|
52
|
-
# {#read_timeout_error}
|
53
|
-
# @option options [Numeric] :write_timeout, see {#write_timeout}
|
54
|
-
# @option options [Class<Exception>] :write_timeout_error, see
|
55
|
-
# {#write_timeout_error}
|
56
|
-
# @option options [Boolean] :normalize_network_errors, see
|
57
|
-
# {#normalize_network_errors}
|
42
|
+
# @see #configure
|
58
43
|
#
|
59
|
-
def initialize(options =
|
44
|
+
def initialize(options = nil)
|
60
45
|
@buffered = @keep_alive = @reverse_lookup = true
|
61
46
|
self.timeout = @ssl_params = nil
|
62
47
|
@connect_timeout_error = ConnectTimeoutError
|
63
48
|
@read_timeout_error = ReadTimeoutError
|
64
49
|
@write_timeout_error = WriteTimeoutError
|
65
50
|
@normalize_network_errors = false
|
66
|
-
options
|
51
|
+
configure(options) if options
|
67
52
|
end
|
68
53
|
|
69
54
|
# @!group Instance Attributes Socket Level
|
@@ -257,6 +242,8 @@ class TCPClient
|
|
257
242
|
|
258
243
|
# @!endgroup
|
259
244
|
|
245
|
+
# @!group Other Instance Attributes
|
246
|
+
|
260
247
|
#
|
261
248
|
# Enables/disables if network exceptions should be raised as {NetworkError}.
|
262
249
|
#
|
@@ -274,10 +261,12 @@ class TCPClient
|
|
274
261
|
@normalize_network_errors = value ? true : false
|
275
262
|
end
|
276
263
|
|
264
|
+
# @!endgroup
|
265
|
+
|
277
266
|
#
|
278
267
|
# @return [{Symbol => Object}] Hash containing all attributes
|
279
268
|
#
|
280
|
-
# @see #
|
269
|
+
# @see #configure
|
281
270
|
#
|
282
271
|
def to_h
|
283
272
|
{
|
@@ -295,6 +284,33 @@ class TCPClient
|
|
295
284
|
}
|
296
285
|
end
|
297
286
|
|
287
|
+
#
|
288
|
+
# Configures the instance with given options Hash.
|
289
|
+
#
|
290
|
+
# @param options [{Symbol => Object}]
|
291
|
+
# @option options [Boolean] :buffered, see {#buffered}
|
292
|
+
# @option options [Boolean] :keep_alive, see {#keep_alive}
|
293
|
+
# @option options [Boolean] :reverse_lookup, see {#reverse_lookup}
|
294
|
+
# @option options [{Symbol => Object}] :ssl_params, see {#ssl_params}
|
295
|
+
# @option options [Numeric] :connect_timeout, see {#connect_timeout}
|
296
|
+
# @option options [Class<Exception>] :connect_timeout_error, see
|
297
|
+
# {#connect_timeout_error}
|
298
|
+
# @option options [Numeric] :read_timeout, see {#read_timeout}
|
299
|
+
# @option options [Class<Exception>] :read_timeout_error, see
|
300
|
+
# {#read_timeout_error}
|
301
|
+
# @option options [Numeric] :write_timeout, see {#write_timeout}
|
302
|
+
# @option options [Class<Exception>] :write_timeout_error, see
|
303
|
+
# {#write_timeout_error}
|
304
|
+
# @option options [Boolean] :normalize_network_errors, see
|
305
|
+
# {#normalize_network_errors}
|
306
|
+
#
|
307
|
+
# @return [Configuration] self
|
308
|
+
#
|
309
|
+
def configure(options)
|
310
|
+
options.each_pair { |attribute, value| set(attribute, value) }
|
311
|
+
self
|
312
|
+
end
|
313
|
+
|
298
314
|
# @!visibility private
|
299
315
|
def freeze
|
300
316
|
@ssl_params.freeze
|
@@ -25,13 +25,13 @@ class TCPClient
|
|
25
25
|
# cfg.ssl_params = { min_version: :TLS1_2, max_version: :TLS1_3 }
|
26
26
|
# end
|
27
27
|
#
|
28
|
-
# @param options [Hash] see {Configuration#
|
28
|
+
# @param options [Hash] see {Configuration#configure} for details
|
29
29
|
#
|
30
30
|
# @yieldparam cfg {Configuration} the new configuration
|
31
31
|
#
|
32
32
|
# @return [Configuration] the new default configuration
|
33
33
|
#
|
34
|
-
def configure(options =
|
34
|
+
def configure(options = nil, &block)
|
35
35
|
@default_configuration = Configuration.create(options, &block)
|
36
36
|
end
|
37
37
|
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
|
-
#
|
44
|
+
# was specified
|
45
45
|
#
|
46
46
|
# @see TCPClient.open
|
47
47
|
# @see TCPClient.with_deadline
|
@@ -1,87 +1,80 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
module IOWithDeadlineMixin
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
mod.include(
|
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
|
+
return if methods.index(:wait_writable) && methods.index(:wait_readable)
|
8
|
+
mod.include(methods.index(:to_io) ? WaitWithIO : WaitWithSelect)
|
13
9
|
end
|
14
|
-
end
|
15
10
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
11
|
+
def read_with_deadline(nbytes, deadline, exception)
|
12
|
+
raise(exception) unless deadline.remaining_time
|
13
|
+
return fetch_avail(deadline, exception) if nbytes.nil?
|
14
|
+
return ''.b if nbytes.zero?
|
15
|
+
@read_buffer ||= ''.b
|
16
|
+
while @read_buffer.bytesize < nbytes
|
17
|
+
read = fetch_next(deadline, exception) and next @read_buffer << read
|
18
|
+
close
|
19
|
+
break
|
20
|
+
end
|
21
|
+
fetch_slice(nbytes)
|
25
22
|
end
|
26
|
-
fetch_buffer_slice(nbytes)
|
27
|
-
end
|
28
23
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
24
|
+
def read_to_with_deadline(sep, deadline, exception)
|
25
|
+
raise(exception) unless deadline.remaining_time
|
26
|
+
@read_buffer ||= ''.b
|
27
|
+
while @read_buffer.index(sep).nil?
|
28
|
+
read = fetch_next(deadline, exception) and next @read_buffer << read
|
29
|
+
close
|
30
|
+
break
|
31
|
+
end
|
32
|
+
index = @read_buffer.index(sep)
|
33
|
+
return fetch_slice(index + sep.bytesize) if index
|
34
|
+
result = @read_buffer
|
35
|
+
@read_buffer = nil
|
36
|
+
result
|
36
37
|
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
38
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
39
|
+
def write_with_deadline(data, deadline, exception)
|
40
|
+
raise(exception) unless deadline.remaining_time
|
41
|
+
return 0 if (size = data.bytesize).zero?
|
42
|
+
result = 0
|
43
|
+
loop do
|
44
|
+
written =
|
45
|
+
with_deadline(deadline, exception) do
|
46
|
+
write_nonblock(data, exception: false)
|
47
|
+
end
|
48
|
+
(result += written) >= size and return result
|
49
|
+
data = data.byteslice(written, data.bytesize - written)
|
50
|
+
end
|
54
51
|
end
|
55
|
-
end
|
56
52
|
|
57
|
-
|
53
|
+
private
|
58
54
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
55
|
+
def fetch_avail(deadline, exception)
|
56
|
+
if (result = @read_buffer || fetch_next(deadline, exception)).nil?
|
57
|
+
close
|
58
|
+
return ''.b
|
59
|
+
end
|
60
|
+
@read_buffer = nil
|
61
|
+
result
|
64
62
|
end
|
65
|
-
result = @buf
|
66
|
-
@buf = nil
|
67
|
-
result
|
68
|
-
end
|
69
63
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
64
|
+
def fetch_slice(size)
|
65
|
+
result = @read_buffer.byteslice(0, size)
|
66
|
+
rest = @read_buffer.bytesize - result.bytesize
|
67
|
+
@read_buffer = rest.zero? ? nil : @read_buffer.byteslice(size, rest)
|
68
|
+
result
|
69
|
+
end
|
76
70
|
|
77
|
-
|
78
|
-
|
79
|
-
|
71
|
+
def fetch_next(deadline, exception)
|
72
|
+
with_deadline(deadline, exception) do
|
73
|
+
read_nonblock(65_536, exception: false)
|
74
|
+
end
|
80
75
|
end
|
81
|
-
end
|
82
76
|
|
83
|
-
|
84
|
-
private def with_deadline(deadline, exception)
|
77
|
+
def with_deadline(deadline, exception)
|
85
78
|
loop do
|
86
79
|
case ret = yield
|
87
80
|
when :wait_writable
|
@@ -97,45 +90,29 @@ module IOWithDeadlineMixin # :nodoc:
|
|
97
90
|
rescue Errno::ETIMEDOUT
|
98
91
|
raise(exception)
|
99
92
|
end
|
100
|
-
end
|
101
93
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
when :wait_readable
|
110
|
-
remaining_time = deadline.remaining_time or raise(exception)
|
111
|
-
raise(exception) if to_io.wait_readable(remaining_time).nil?
|
112
|
-
else
|
113
|
-
return ret
|
114
|
-
end
|
94
|
+
module WaitWithIO
|
95
|
+
def wait_writable(remaining_time)
|
96
|
+
to_io.wait_writable(remaining_time)
|
97
|
+
end
|
98
|
+
|
99
|
+
def wait_readable(remaining_time)
|
100
|
+
to_io.wait_readable(remaining_time)
|
115
101
|
end
|
116
|
-
rescue Errno::ETIMEDOUT
|
117
|
-
raise(exception)
|
118
102
|
end
|
119
|
-
end
|
120
103
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
when :wait_readable
|
129
|
-
remaining_time = deadline.remaining_time or raise(exception)
|
130
|
-
raise(exception) if ::IO.select([self], nil, nil, remaining_time).nil?
|
131
|
-
else
|
132
|
-
return ret
|
133
|
-
end
|
104
|
+
module WaitWithSelect
|
105
|
+
def wait_writable(remaining_time)
|
106
|
+
::IO.select(nil, [self], nil, remaining_time)
|
107
|
+
end
|
108
|
+
|
109
|
+
def wait_readable(remaining_time)
|
110
|
+
::IO.select([self], nil, nil, remaining_time)
|
134
111
|
end
|
135
|
-
rescue Errno::ETIMEDOUT
|
136
|
-
raise(exception)
|
137
112
|
end
|
113
|
+
|
114
|
+
private_constant(:WaitWithIO, :WaitWithSelect)
|
138
115
|
end
|
139
116
|
|
140
|
-
private_constant(:
|
117
|
+
private_constant(:IOWithDeadlineMixin)
|
141
118
|
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
|
@@ -231,7 +231,7 @@ class TCPClient
|
|
231
231
|
exception ||= configuration.read_timeout_error
|
232
232
|
line =
|
233
233
|
stem_errors(exception) do
|
234
|
-
@socket.
|
234
|
+
@socket.read_to_with_deadline(separator, deadline, exception)
|
235
235
|
end
|
236
236
|
chomp ? line.chomp : line
|
237
237
|
end
|
@@ -344,7 +344,8 @@ class TCPClient
|
|
344
344
|
IOError,
|
345
345
|
SocketError
|
346
346
|
].tap do |errors|
|
347
|
-
|
348
|
-
|
347
|
+
errors << ::OpenSSL::SSL::SSLError if defined?(::OpenSSL::SSL::SSLError)
|
348
|
+
end
|
349
|
+
.freeze
|
349
350
|
private_constant(:NETWORK_ERRORS)
|
350
351
|
end
|
metadata
CHANGED
@@ -1,79 +1,20 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tcp-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.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-
|
12
|
-
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: bundler
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rake
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rspec
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: yard
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
11
|
+
date: 2022-07-30 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
69
13
|
description: |
|
70
|
-
This
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
predefined/configurable time limits for each method
|
75
|
-
(`connect`, `read`, `write`). Deadlines for a sequence of read/write
|
76
|
-
actions can also be monitored.
|
14
|
+
This gem implements a customizable TCP client class that gives you control
|
15
|
+
over time limits. You can set time limits for individual read or write calls
|
16
|
+
or set a deadline for entire call sequences.
|
17
|
+
It has a very small footprint, no dependencies and is easily useable.
|
77
18
|
email:
|
78
19
|
executables: []
|
79
20
|
extensions: []
|
@@ -81,11 +22,8 @@ extra_rdoc_files:
|
|
81
22
|
- README.md
|
82
23
|
- LICENSE
|
83
24
|
files:
|
84
|
-
- ".gitignore"
|
85
|
-
- ".yardopts"
|
86
25
|
- LICENSE
|
87
26
|
- README.md
|
88
|
-
- gems.rb
|
89
27
|
- lib/tcp-client.rb
|
90
28
|
- lib/tcp-client/address.rb
|
91
29
|
- lib/tcp-client/configuration.rb
|
@@ -97,23 +35,13 @@ files:
|
|
97
35
|
- lib/tcp-client/tcp_socket.rb
|
98
36
|
- lib/tcp-client/version.rb
|
99
37
|
- lib/tcp_client.rb
|
100
|
-
- rakefile.rb
|
101
|
-
- sample/google.rb
|
102
|
-
- sample/google_ssl.rb
|
103
|
-
- spec/helper.rb
|
104
|
-
- spec/tcp-client/address_spec.rb
|
105
|
-
- spec/tcp-client/configuration_spec.rb
|
106
|
-
- spec/tcp-client/default_configuration_spec.rb
|
107
|
-
- spec/tcp-client/version_spec.rb
|
108
|
-
- spec/tcp_client_spec.rb
|
109
|
-
- tcp-client.gemspec
|
110
38
|
homepage: https://github.com/mblumtritt/tcp-client
|
111
39
|
licenses:
|
112
40
|
- BSD-3-Clause
|
113
41
|
metadata:
|
114
42
|
source_code_uri: https://github.com/mblumtritt/tcp-client
|
115
43
|
bug_tracker_uri: https://github.com/mblumtritt/tcp-client/issues
|
116
|
-
documentation_uri: https://rubydoc.info/
|
44
|
+
documentation_uri: https://rubydoc.info/gems/tcp-client
|
117
45
|
post_install_message:
|
118
46
|
rdoc_options: []
|
119
47
|
require_paths:
|
@@ -129,14 +57,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
129
57
|
- !ruby/object:Gem::Version
|
130
58
|
version: '0'
|
131
59
|
requirements: []
|
132
|
-
rubygems_version: 3.3.
|
60
|
+
rubygems_version: 3.3.7
|
133
61
|
signing_key:
|
134
62
|
specification_version: 4
|
135
|
-
summary:
|
136
|
-
test_files:
|
137
|
-
- spec/helper.rb
|
138
|
-
- spec/tcp-client/address_spec.rb
|
139
|
-
- spec/tcp-client/configuration_spec.rb
|
140
|
-
- spec/tcp-client/default_configuration_spec.rb
|
141
|
-
- spec/tcp-client/version_spec.rb
|
142
|
-
- spec/tcp_client_spec.rb
|
63
|
+
summary: Use your TCP connections with working timeout.
|
64
|
+
test_files: []
|
data/.gitignore
DELETED
data/.yardopts
DELETED
data/gems.rb
DELETED
data/rakefile.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rake/clean'
|
4
|
-
require 'bundler/gem_tasks'
|
5
|
-
require 'rspec/core/rake_task'
|
6
|
-
require 'yard'
|
7
|
-
|
8
|
-
$stdout.sync = $stderr.sync = true
|
9
|
-
|
10
|
-
CLEAN << 'prj' << 'doc'
|
11
|
-
|
12
|
-
CLOBBER << '.yardoc'
|
13
|
-
|
14
|
-
task(:default) { exec('rake --tasks') }
|
15
|
-
|
16
|
-
RSpec::Core::RakeTask.new { |task| task.ruby_opts = %w[-w] }
|
17
|
-
|
18
|
-
YARD::Rake::YardocTask.new { |task| task.stats_options = %w[--list-undoc] }
|
data/sample/google.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative '../lib/tcp-client'
|
4
|
-
|
5
|
-
# global configuration.
|
6
|
-
# - 0.5 seconds to connect the server
|
7
|
-
# - 0.25 seconds to write a single data junk
|
8
|
-
# - 0.25 seconds to read some bytes
|
9
|
-
TCPClient.configure do |cfg|
|
10
|
-
cfg.connect_timeout = 0.5
|
11
|
-
cfg.write_timeout = 0.25
|
12
|
-
cfg.read_timeout = 0.25
|
13
|
-
end
|
14
|
-
|
15
|
-
# request to Google:
|
16
|
-
# - send a simple HTTP get request
|
17
|
-
# - read 12 byte: "HTTP/1.1 " + 3 byte HTTP status code
|
18
|
-
TCPClient.open('www.google.com:80') do |client|
|
19
|
-
p client.write("GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n")
|
20
|
-
p client.read(12)
|
21
|
-
end
|
data/sample/google_ssl.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative '../lib/tcp-client'
|
4
|
-
|
5
|
-
# create a configuration:
|
6
|
-
# - don't use internal buffering
|
7
|
-
# - use TLS 1.2 or TLS 1.3
|
8
|
-
cfg =
|
9
|
-
TCPClient::Configuration.create(
|
10
|
-
buffered: false,
|
11
|
-
ssl_params: {
|
12
|
-
min_version: :TLS1_2,
|
13
|
-
max_version: :TLS1_3
|
14
|
-
}
|
15
|
-
)
|
16
|
-
|
17
|
-
# request to Google.com:
|
18
|
-
# - limit all network interactions to 1.5 seconds
|
19
|
-
# - use the Configuration cfg
|
20
|
-
# - send a simple HTTP get request
|
21
|
-
# - read the returned message and headers
|
22
|
-
response =
|
23
|
-
TCPClient.with_deadline(1.5, 'www.google.com:443', cfg) do |client|
|
24
|
-
client.write("GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n") #=> 40
|
25
|
-
client.readline("\r\n\r\n") #=> see response
|
26
|
-
end
|
27
|
-
|
28
|
-
puts(response)
|