Skip to content

Commit a09ad63

Browse files
authored
V1.0.2 (#18)
- adapt license - remove deprecated error constants - optimize socket initialization - optimize socket read with read size hinting - tidy-up
1 parent ea7bbf9 commit a09ad63

File tree

10 files changed

+41
-56
lines changed

10 files changed

+41
-56
lines changed

LICENSE

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
BSD 3-Clause License
22

3-
Copyright (c) 2017-2021, Mike Blumtritt. All rights reserved.
3+
Copyright (c) 2017-2025, Mike Blumtritt. All rights reserved.
44

55
Redistribution and use in source and binary forms, with or without
66
modification, are permitted provided that the following conditions are met:
@@ -26,3 +26,4 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2626
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2727
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2828
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29+

lib/tcp-client.rb

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def closed? = @socket.nil? || @socket.closed?
125125
def close
126126
@socket&.close
127127
self
128-
rescue *NETWORK_ERRORS
128+
rescue *@@net_errors
129129
self
130130
ensure
131131
@socket = @deadline = nil
@@ -338,26 +338,24 @@ def create_socket(timeout, exception)
338338

339339
def stem_errors(except = nil)
340340
yield
341-
rescue *NETWORK_ERRORS => e
341+
rescue *@@net_errors => e
342342
raise unless @configuration.normalize_network_errors
343343
except && e.is_a?(except) ? raise : raise(NetworkError, e)
344344
end
345345

346-
NETWORK_ERRORS =
347-
[
348-
Errno::EADDRNOTAVAIL,
349-
Errno::ECONNABORTED,
350-
Errno::ECONNREFUSED,
351-
Errno::ECONNRESET,
352-
Errno::EHOSTUNREACH,
353-
Errno::EINVAL,
354-
Errno::ENETUNREACH,
355-
Errno::EPIPE,
356-
IOError,
357-
SocketError
358-
].tap do |errors|
359-
errors << ::OpenSSL::SSL::SSLError if defined?(::OpenSSL::SSL::SSLError)
360-
end
361-
.freeze
362-
private_constant(:NETWORK_ERRORS)
346+
@@net_errors = [
347+
Errno::EADDRNOTAVAIL,
348+
Errno::ECONNABORTED,
349+
Errno::ECONNREFUSED,
350+
Errno::EHOSTUNREACH,
351+
Errno::ENETUNREACH,
352+
Errno::ECONNRESET,
353+
Errno::EINVAL,
354+
Errno::EPIPE,
355+
Errno::EPERM,
356+
SocketError,
357+
IOError
358+
]
359+
@@net_errors << ::OpenSSL::SSL::SSLError if defined?(::OpenSSL::SSL::SSLError)
360+
@@net_errors.freeze
363361
end

lib/tcp-client/address.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,11 @@ def to_s = host.index(':') ? "[#{host}]:#{port}" : "#{host}:#{port}"
100100
# @return [Address] itself
101101
#
102102
def freeze
103-
return super if frozen?
104-
solve
105-
@addrinfo.freeze
106-
@host.freeze
103+
unless frozen?
104+
solve
105+
@addrinfo.freeze
106+
@host.freeze
107+
end
107108
super
108109
end
109110

lib/tcp-client/configuration.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ def self.create(options = nil)
4343
#
4444
def initialize(options = nil)
4545
@buffered = @keep_alive = @reverse_lookup = true
46-
self.timeout = @ssl_params = nil
4746
@connect_timeout_error = ConnectTimeoutError
4847
@read_timeout_error = ReadTimeoutError
4948
@write_timeout_error = WriteTimeoutError
@@ -107,7 +106,7 @@ def ssl? = @ssl_params ? true : false
107106
def ssl_params=(value)
108107
@ssl_params =
109108
if value.respond_to?(:to_hash)
110-
Hash[value.to_hash]
109+
value.to_hash.dup
111110
elsif value.respond_to?(:to_h)
112111
value.nil? ? nil : value.to_h.dup
113112
else

lib/tcp-client/errors.rb

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -129,19 +129,4 @@ class WriteTimeoutError < TimeoutError
129129
#
130130
def action = :write
131131
end
132-
133-
NoOpenSSL = NoOpenSSLError # @!visibility private
134-
NoBlockGiven = NoBlockGivenError # @!visibility private
135-
InvalidDeadLine = InvalidDeadLineError # @!visibility private
136-
UnknownAttribute = UnknownAttributeError # @!visibility private
137-
NotAnException = NotAnExceptionError # @!visibility private
138-
NotConnected = NotConnectedError # @!visibility private
139-
deprecate_constant(
140-
:NoOpenSSL,
141-
:NoBlockGiven,
142-
:InvalidDeadLine,
143-
:UnknownAttribute,
144-
:NotAnException,
145-
:NotConnected
146-
)
147132
end

lib/tcp-client/ssl_socket.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ def should_verify?(ssl_params)
5353
CONTEXT_CACHE_MODE =
5454
::OpenSSL::SSL::SSLContext::SESSION_CACHE_CLIENT |
5555
::OpenSSL::SSL::SSLContext::SESSION_CACHE_NO_INTERNAL_STORE
56+
57+
private_constant(:CONTEXT_CACHE_MODE)
5658
end
5759

5860
private_constant(:SSLSocket)

lib/tcp-client/tcp_socket.rb

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,17 @@ class TCPSocket < ::Socket
99
include WithDeadline
1010

1111
def initialize(address, configuration, deadline)
12-
super(address.addrinfo.ipv6? ? :INET6 : :INET, :STREAM)
12+
addrinfo = address.addrinfo
13+
super(addrinfo.ipv6? ? :INET6 : :INET, :STREAM)
1314
configure(configuration)
14-
connect_to(as_addr_in(address), deadline)
15+
connect_to(
16+
::Socket.pack_sockaddr_in(addrinfo.ip_port, addrinfo.ip_address),
17+
deadline
18+
)
1519
end
1620

1721
private
1822

19-
def as_addr_in(address)
20-
addrinfo = address.addrinfo
21-
::Socket.pack_sockaddr_in(addrinfo.ip_port, addrinfo.ip_address)
22-
end
23-
2423
def connect_to(addr, deadline)
2524
return connect(addr) unless deadline.valid?
2625
with_deadline(deadline) { connect_nonblock(addr, exception: false) }

lib/tcp-client/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
class TCPClient
44
# The current version number.
5-
VERSION = '1.0.1'
5+
VERSION = '1.0.2'
66
end

lib/tcp-client/with_deadline.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ def read_with_deadline(nbytes, deadline)
66
deadline.remaining_time
77
return fetch_avail(deadline) if nbytes.nil?
88
@read_buffer ||= ''.b
9-
while @read_buffer.bytesize < nbytes
10-
read = fetch_next(deadline)
9+
while (diff = nbytes - @read_buffer.bytesize) > 0
10+
read = fetch_next(deadline, diff)
1111
read ? @read_buffer << read : (break close)
1212
end
1313
fetch_slice(nbytes)
@@ -57,8 +57,8 @@ def fetch_slice(size)
5757
result
5858
end
5959

60-
def fetch_next(deadline)
61-
with_deadline(deadline) { read_nonblock(65_536, exception: false) }
60+
def fetch_next(deadline, size = 65_536)
61+
with_deadline(deadline) { read_nonblock(size, exception: false) }
6262
end
6363

6464
def with_deadline(deadline)

spec/lib/tcp-client_spec.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
TCPClient::Configuration.create(buffered: false, reverse_lookup: false)
77
end
88

9-
describe 'a new instance' do
9+
context 'with a new instance' do
1010
subject(:client) { TCPClient.new }
1111

1212
it { is_expected.to be_closed }
@@ -34,7 +34,7 @@
3434
end
3535
end
3636

37-
describe 'a connected instance' do
37+
context 'with a connected instance' do
3838
before { allow_any_instance_of(Socket).to receive(:connect) }
3939

4040
it { is_expected.not_to be_closed }
@@ -75,7 +75,7 @@
7575
end
7676
end
7777

78-
describe 'an instance after #connect failed' do
78+
context 'with an instance after #connect failed' do
7979
subject(:client) do
8080
TCPClient.new.tap do |instance|
8181
instance.connect('', configuration)

0 commit comments

Comments
 (0)