tcp-client 0.0.6 → 0.0.8

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: 9a5a96328918c653aaec2296d19a7434b65c8801f3a1132a152dcd66326bc9ce
4
- data.tar.gz: 5add4cd9d2607a90522b14c04a8b9d60a27bcad30c0f56212aba5df6c5036ac9
3
+ metadata.gz: f139f1f90fcb6d8c32a0d0fab85b4c96eab70b2a08845e9cdb26c5de8acfd184
4
+ data.tar.gz: f703e1c0c6f5edb4d732284ba983e31820c1e116cff1329cb7458a642b4ec1af
5
5
  SHA512:
6
- metadata.gz: 859acc902ed173236fac760ce2edbbda4353bf7fb438ecdb3856bdba3076a464a34f542458abc5b1fb2ec157b4f3ab007e0eb67123c551f1b6abedc6f810d978
7
- data.tar.gz: 36b9c267842f00e2d6181d2523b84b776528b7d754fb4eb378fbdb4fc8d33fbb43ac7b9faf5ff613cf34c4687cc2eab74eaff04601fa72196efe3787d622dc7d
6
+ metadata.gz: a19cf4e0ba023fd6a52a7470d1304b6718250c1dc28b49cefa07dc6c1fca6c52d35797bd6e769a80cd9d96feba09d48ebfcbc45273b2718f2fea8fda1de6d749
7
+ data.tar.gz: 1e0444b2cf3169b4d3e31af9ea072f0c44a98c88983f8f657f7917e1d4ee7d245599d7a640183acbb7bcbded8a319f2eed677c4f3aca8bdd15138c04acd13895
@@ -15,7 +15,7 @@ class TCPClient
15
15
 
16
16
  class NotConnected < SocketError
17
17
  def self.raise!(which)
18
- raise(self, format('client not connected - %s', which), caller(1))
18
+ raise(self, "client not connected - #{which}", caller(1))
19
19
  end
20
20
  end
21
21
 
@@ -25,11 +25,9 @@ class TCPClient
25
25
  addr = Address.new(addr)
26
26
  client = new
27
27
  client.connect(addr, configuration)
28
- return yield(client) if block_given?
29
- client, ret = nil, client
30
- ret
28
+ block_given? ? yield(client) : client
31
29
  ensure
32
- client.close if client
30
+ client&.close if block_given?
33
31
  end
34
32
 
35
33
  attr_reader :address
@@ -47,7 +45,9 @@ class TCPClient
47
45
  NoOpenSSL.raise! if configuration.ssl? && !defined?(SSLSocket)
48
46
  @address = Address.new(addr)
49
47
  @socket = TCPSocket.new(@address, configuration, Timeout)
50
- @socket = SSLSocket.new(@socket, @address, configuration, Timeout) if configuration.ssl?
48
+ configuration.ssl? && @socket = SSLSocket.new(
49
+ @socket, @address, configuration, Timeout
50
+ )
51
51
  @write_timeout = configuration.write_timeout
52
52
  @read_timeout = configuration.read_timeout
53
53
  self
@@ -55,7 +55,7 @@ class TCPClient
55
55
 
56
56
  def close
57
57
  socket, @socket = @socket, nil
58
- socket.close if socket
58
+ socket&.close
59
59
  self
60
60
  rescue IOError
61
61
  self
@@ -66,11 +66,13 @@ class TCPClient
66
66
  end
67
67
 
68
68
  def read(nbytes, timeout: @read_timeout)
69
- closed? ? NotConnected.raise!(self) : @socket.read(nbytes, timeout: timeout, exception: Timeout)
69
+ NotConnected.raise!(self) if closed?
70
+ @socket.read(nbytes, timeout: timeout, exception: Timeout)
70
71
  end
71
72
 
72
73
  def write(*msg, timeout: @write_timeout)
73
- closed? ? NotConnected.raise!(self) : @socket.write(*msg, timeout: timeout, exception: Timeout)
74
+ NotConnected.raise!(self) if closed?
75
+ @socket.write(*msg, timeout: timeout, exception: Timeout)
74
76
  end
75
77
 
76
78
  def flush
@@ -68,7 +68,7 @@ class TCPClient
68
68
  private
69
69
 
70
70
  def seconds(value)
71
- value && value > 0 ? value : nil
71
+ value&.positive? ? value : nil
72
72
  end
73
73
  end
74
74
  end
@@ -3,7 +3,11 @@ IOTimeoutError = Class.new(IOError) unless defined?(IOTimeoutError)
3
3
  module IOTimeoutMixin
4
4
  def self.included(mod)
5
5
  im = mod.instance_methods
6
- mod.include(im.index(:wait_writable) && im.index(:wait_readable) ? WithDeadlineMethods : WidthDeadlineIO)
6
+ if im.index(:wait_writable) && im.index(:wait_readable)
7
+ mod.include(DeadlineMethods)
8
+ else
9
+ mod.include(DeadlineIO)
10
+ end
7
11
  end
8
12
 
9
13
  def read(nbytes, timeout: nil, exception: IOTimeoutError)
@@ -11,7 +15,9 @@ module IOTimeoutMixin
11
15
  return read_all(nbytes){ |junk_size| super(junk_size) } if timeout <= 0
12
16
  deadline = Time.now + timeout
13
17
  read_all(nbytes) do |junk_size|
14
- with_deadline(deadline, exception){ read_nonblock(junk_size, exception: false) }
18
+ with_deadline(deadline, exception) do
19
+ read_nonblock(junk_size, exception: false)
20
+ end
15
21
  end
16
22
  end
17
23
 
@@ -20,7 +26,9 @@ module IOTimeoutMixin
20
26
  return write_all(msgs.join){ |junk| super(junk) } if timeout <= 0
21
27
  deadline = Time.now + timeout
22
28
  write_all(msgs.join) do |junk|
23
- with_deadline(deadline, exception){ write_nonblock(junk, exception: false) }
29
+ with_deadline(deadline, exception) do
30
+ write_nonblock(junk, exception: false)
31
+ end
24
32
  end
25
33
  end
26
34
 
@@ -50,18 +58,18 @@ module IOTimeoutMixin
50
58
  end
51
59
  end
52
60
 
53
- module WithDeadlineMethods
61
+ module DeadlineMethods
54
62
  private
55
63
 
56
64
  def with_deadline(deadline, exclass)
57
65
  loop do
58
66
  case ret = yield
59
67
  when :wait_writable
60
- remaining_time = deadline - Time.now
61
- raise(exclass) if remaining_time <= 0 || wait_writable(remaining_time).nil?
68
+ raise(exclass) if (remaining_time = deadline - Time.now) <= 0
69
+ raise(exclass) if wait_writable(remaining_time).nil?
62
70
  when :wait_readable
63
- remaining_time = deadline - Time.now
64
- raise(exclass) if remaining_time <= 0 || wait_readable(remaining_time).nil?
71
+ raise(exclass) if (remaining_time = deadline - Time.now) <= 0
72
+ raise(exclass) if wait_readable(remaining_time).nil?
65
73
  else
66
74
  return ret
67
75
  end
@@ -69,18 +77,18 @@ module IOTimeoutMixin
69
77
  end
70
78
  end
71
79
 
72
- module WidthDeadlineIO
80
+ module DeadlineIO
73
81
  private
74
82
 
75
83
  def with_deadline(deadline, exclass)
76
84
  loop do
77
85
  case ret = yield
78
86
  when :wait_writable
79
- remaining_time = deadline - Time.now
80
- raise(exclass) if remaining_time <= 0 || ::IO.select(nil, [self], nil, remaining_time).nil?
87
+ raise(exclass) if (remaining_time = deadline - Time.now) <= 0
88
+ raise(exclass) if ::IO.select(nil, [self], nil, remaining_time).nil?
81
89
  when :wait_readable
82
- remaining_time = deadline - Time.now
83
- raise(exclass) if remaining_time <= 0 || ::IO.select([self], nil, nil, remaining_time).nil?
90
+ raise(exclass) if (remaining_time = deadline - Time.now) <= 0
91
+ raise(exclass) if ::IO.select([self], nil, nil, remaining_time).nil?
84
92
  else
85
93
  return ret
86
94
  end
@@ -88,5 +96,5 @@ module IOTimeoutMixin
88
96
  end
89
97
  end
90
98
 
91
- private_constant :WithDeadlineMethods, :WidthDeadlineIO
99
+ private_constant :DeadlineMethods, :DeadlineIO
92
100
  end
@@ -31,7 +31,13 @@ class TCPClient
31
31
 
32
32
  def connect_to(address, check, timeout, exception)
33
33
  self.hostname = address.hostname
34
- timeout ? with_deadline(Time.now + timeout, exception){ connect_nonblock(exception: false) } : connect
34
+ if timeout
35
+ with_deadline(Time.now + timeout, exception) do
36
+ connect_nonblock(exception: false)
37
+ end
38
+ else
39
+ connect
40
+ end
35
41
  post_connection_check(address.hostname) if check
36
42
  end
37
43
  end
@@ -14,9 +14,13 @@ class TCPClient
14
14
  private
15
15
 
16
16
  def connect_to(address, timeout, exception)
17
- addr = ::Socket.pack_sockaddr_in(address.addrinfo.ip_port, address.addrinfo.ip_address)
17
+ addr = ::Socket.pack_sockaddr_in(
18
+ address.addrinfo.ip_port, address.addrinfo.ip_address
19
+ )
18
20
  return connect(addr) unless timeout
19
- with_deadline(Time.now + timeout, exception){ connect_nonblock(addr, exception: false) }
21
+ with_deadline(Time.now + timeout, exception) do
22
+ connect_nonblock(addr, exception: false)
23
+ end
20
24
  end
21
25
 
22
26
  def configure(configuration)
@@ -1,3 +1,3 @@
1
1
  class TCPClient
2
- VERSION = '0.0.6'.freeze
2
+ VERSION = '0.0.8'.freeze
3
3
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
  require 'rake/testtask'
3
5
 
@@ -8,5 +10,5 @@ Rake::TestTask.new(:test) do |t|
8
10
  end
9
11
 
10
12
  task :default do
11
- exec('rake -T')
13
+ exec("#{$0} --tasks")
12
14
  end
@@ -1,18 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require File.expand_path('../lib/tcp-client/version', __FILE__)
3
+ require_relative './lib/tcp-client/version'
4
4
 
5
5
  GemSpec = Gem::Specification.new do |spec|
6
6
  spec.name = 'tcp-client'
7
7
  spec.version = TCPClient::VERSION
8
8
  spec.summary = 'A TCP client implementation with working timeout support.'
9
- spec.description = <<~EOS
9
+ spec.description = <<~DESCRIPTION
10
10
  This gem implements a TCP client with (optional) SSL support. The
11
11
  motivation of this project is the need to have a _really working_
12
12
  easy to use client which can handle time limits correctly. Unlike
13
13
  other implementations this client respects given/configurable time
14
14
  limits for each method (`connect`, `read`, `write`).
15
- EOS
15
+ DESCRIPTION
16
16
  spec.author = 'Mike Blumtritt'
17
17
  spec.email = 'mike.blumtritt@invision.de'
18
18
  spec.homepage = 'https://github.com/mblumtritt/tcp-client'
@@ -20,12 +20,12 @@ GemSpec = Gem::Specification.new do |spec|
20
20
  spec.rubyforge_project = spec.name
21
21
 
22
22
  spec.add_development_dependency 'bundler'
23
- spec.add_development_dependency 'rake'
24
23
  spec.add_development_dependency 'minitest'
24
+ spec.add_development_dependency 'rake'
25
25
 
26
26
  spec.platform = Gem::Platform::RUBY
27
- spec.required_rubygems_version = Gem::Requirement.new('>= 1.3.6')
28
27
  spec.required_ruby_version = '>= 2.5.0'
28
+ spec.required_rubygems_version = Gem::Requirement.new('>= 1.3.6')
29
29
 
30
30
  spec.require_paths = %w[lib]
31
31
 
@@ -33,6 +33,5 @@ GemSpec = Gem::Specification.new do |spec|
33
33
  spec.test_files = all_files.grep(%r{^(spec|test)/})
34
34
  spec.files = all_files - spec.test_files
35
35
 
36
- spec.has_rdoc = false
37
36
  spec.extra_rdoc_files = %w[README.md]
38
37
  end
@@ -40,24 +40,30 @@ class TCPClientTest < Test
40
40
  end
41
41
  end
42
42
 
43
+ def with_dummy_server(port)
44
+ # this server will never receive or send any data
45
+ server = TCPServer.new('localhost', port)
46
+ ensure
47
+ server&.close
48
+ end
49
+
43
50
  def test_connected_state
44
- server = TCPServer.new(1234)
45
- TCPClient.open('localhost:1234', TCPClient::Configuration.new) do |subject|
46
- refute(subject.closed?)
47
- assert_equal('localhost:1234', subject.to_s)
48
- refute_nil(subject.address)
49
- address_when_opened = subject.address
50
- assert_equal('localhost:1234', subject.address.to_s)
51
- assert_equal('localhost', subject.address.hostname)
52
- assert_instance_of(Addrinfo, subject.address.addrinfo)
53
- assert_same(1234, subject.address.addrinfo.ip_port)
51
+ with_dummy_server(1234) do
52
+ TCPClient.open('localhost:1234') do |subject|
53
+ refute(subject.closed?)
54
+ assert_equal('localhost:1234', subject.to_s)
55
+ refute_nil(subject.address)
56
+ address_when_opened = subject.address
57
+ assert_equal('localhost:1234', subject.address.to_s)
58
+ assert_equal('localhost', subject.address.hostname)
59
+ assert_instance_of(Addrinfo, subject.address.addrinfo)
60
+ assert_same(1234, subject.address.addrinfo.ip_port)
54
61
 
55
- subject.close
56
- assert(subject.closed?)
57
- assert_same(address_when_opened, subject.address)
62
+ subject.close
63
+ assert(subject.closed?)
64
+ assert_same(address_when_opened, subject.address)
65
+ end
58
66
  end
59
- ensure
60
- server.close if server
61
67
  end
62
68
 
63
69
  def check_read_write_timeout(addr, timeout)
@@ -66,7 +72,7 @@ class TCPClientTest < Test
66
72
  start_time = nil
67
73
  assert_raises(TCPClient::Timeout) do
68
74
  start_time = Time.now
69
- # we need to send 1MB to avoid any TCP stack buffering
75
+ # send 1MB to avoid any TCP stack buffering
70
76
  subject.write('?' * (1024 * 1024), timeout: timeout)
71
77
  end
72
78
  assert_in_delta(timeout, Time.now - start_time, 0.02)
@@ -79,32 +85,30 @@ class TCPClientTest < Test
79
85
  end
80
86
 
81
87
  def test_read_write_timeout
82
- server = TCPServer.new(1235) # this server will never read/write client data
83
- [0.5, 1, 1.5].each do |timeout|
84
- check_read_write_timeout(':1235', timeout)
88
+ with_dummy_server(1235) do
89
+ [0.5, 1, 1.5].each do |timeout|
90
+ check_read_write_timeout('localhost:1235', timeout)
91
+ end
85
92
  end
86
- ensure
87
- server.close if server
88
93
  end
89
94
 
90
- def check_connect_timeout(addr, config, timeout)
95
+ def check_connect_timeout(addr, config)
91
96
  start_time = nil
92
97
  assert_raises(TCPClient::Timeout) do
93
98
  start_time = Time.now
94
99
  TCPClient.new.connect(addr, config)
95
100
  end
96
- assert_in_delta(timeout, Time.now - start_time, 0.02)
101
+ assert_in_delta(config.connect_timeout, Time.now - start_time, 0.02)
97
102
  end
98
103
 
99
104
  def test_connect_ssl_timeout
100
- server = TCPServer.new(1236)
101
- config = TCPClient::Configuration.new
102
- config.ssl = true
103
- [0.5, 1, 1.5].each do |timeout|
104
- config.timeout = timeout
105
- check_connect_timeout('localhost:1236', config, timeout)
105
+ with_dummy_server(1236) do
106
+ config = TCPClient::Configuration.new
107
+ config.ssl = true
108
+ [0.5, 1, 1.5].each do |timeout|
109
+ config.timeout = timeout
110
+ check_connect_timeout('localhost:1236', config)
111
+ end
106
112
  end
107
- ensure
108
- server.close if server
109
113
  end
110
114
  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.0.6
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Blumtritt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-21 00:00:00.000000000 Z
11
+ date: 2018-10-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: minitest
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: minitest
42
+ name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -104,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
104
  version: 1.3.6
105
105
  requirements: []
106
106
  rubyforge_project: tcp-client
107
- rubygems_version: 2.7.3
107
+ rubygems_version: 2.7.7
108
108
  signing_key:
109
109
  specification_version: 4
110
110
  summary: A TCP client implementation with working timeout support.