Skip to content

Commit

Permalink
Merge 1a74391 into af7f456
Browse files Browse the repository at this point in the history
  • Loading branch information
olleolleolle committed Mar 17, 2019
2 parents af7f456 + 1a74391 commit 3b1663b
Show file tree
Hide file tree
Showing 13 changed files with 43 additions and 18 deletions.
11 changes: 11 additions & 0 deletions .travis.yml
Expand Up @@ -16,6 +16,17 @@ rvm:
matrix:
fast_finish: true

jobs:
include:
- stage: linting
rvm: ruby-2.4.1 # Pre-installed on TravisCI
install: true # Do not bundle install
script: gem install rubocop --no-document && rubocop

stages:
- linting
- test

branches:
only:
- master
2 changes: 1 addition & 1 deletion Gemfile
Expand Up @@ -12,7 +12,7 @@ end
group :test do
gem "coveralls", require: false
gem "rspec", "~> 3.7", require: false
gem "rubocop", "0.52.1", require: false
gem "rubocop", "= 0.65.0", require: false
end

group :development, :test do
Expand Down
5 changes: 1 addition & 4 deletions Rakefile
Expand Up @@ -5,7 +5,4 @@ require "bundler/gem_tasks"
require "rspec/core/rake_task"
RSpec::Core::RakeTask.new

require "rubocop/rake_task"
RuboCop::RakeTask.new

task default: %w[spec rubocop]
task default: %w[spec]
3 changes: 2 additions & 1 deletion lib/socketry/resolver/resolv.rb
Expand Up @@ -39,7 +39,8 @@ def initialize(*args)
# @raise [Socketry::AddressError] the name was resolved to an unsupported address
def resolve(hostname, timeout: nil)
raise TypeError, "expected String, got #{hostname.class}" unless hostname.is_a?(String)
return IPAddr.new(@hosts.getaddress(hostname).sub(/%.*$/, ""))

IPAddr.new(@hosts.getaddress(hostname).sub(/%.*$/, ""))
rescue ::Resolv::ResolvError
case timeout
when Integer, Float
Expand Down
8 changes: 4 additions & 4 deletions lib/socketry/ssl/server.rb
Expand Up @@ -39,11 +39,11 @@ def accept(timeout: nil, **args)
tcp_socket = super(timeout: timeout, **args)

ssl_socket = Socketry::SSL::Socket.new(
read_timeout: @read_timeout,
write_timeout: @write_timeout,
resolver: @resolver,
read_timeout: @read_timeout,
write_timeout: @write_timeout,
resolver: @resolver,
ssl_socket_class: @ssl_socket_class,
ssl_params: @ssl_params
ssl_params: @ssl_params
)

ssl_socket.accept(tcp_socket, timeout: timeout)
Expand Down
1 change: 1 addition & 0 deletions lib/socketry/ssl/socket.rb
Expand Up @@ -75,6 +75,7 @@ def connect(
raise Socketry::TimeoutError, "connection to #{remote_addr}:#{remote_port} timed out"
rescue OpenSSL::SSL::SSLError => ex
raise Socketry::SSL::CertificateVerifyError, ex.message if ex.message.include?("certificate verify failed")

raise Socketry::SSL::Error, ex.message, ex.backtrace
end

Expand Down
8 changes: 5 additions & 3 deletions lib/socketry/tcp/server.rb
Expand Up @@ -57,6 +57,7 @@ def accept(timeout: nil)
while (socket = accept_nonblock) == :wait_readable
# Ruby 2.2 has trouble using io/wait here
next if IO.select([@server], nil, nil, time_remaining(timeout))

raise Socketry::TimeoutError, "no connection received after #{timeout} seconds"
end

Expand All @@ -72,10 +73,10 @@ def accept_nonblock
# Note: `exception: false` for TCPServer#accept_nonblock is only supported in Ruby 2.3+
# TODO: Switch to `exception: false` when we drop support for Ruby 2.2.
Socketry::TCP::Socket.new(
read_timeout: @read_timeout,
read_timeout: @read_timeout,
write_timeout: @write_timeout,
resolver: @resolver,
socket_class: @socket_class
resolver: @resolver,
socket_class: @socket_class
).from_socket(@server.accept_nonblock)
rescue IO::WaitReadable, Errno::EAGAIN
:wait_readable
Expand All @@ -84,6 +85,7 @@ def accept_nonblock
# Close the server
def close
return false unless @server

@server.close rescue nil
@server = nil
true
Expand Down
7 changes: 7 additions & 0 deletions lib/socketry/tcp/socket.rb
Expand Up @@ -204,6 +204,7 @@ def reconnect(timeout: Socketry::Timeout::DEFAULT_TIMEOUTS[:connect])
def from_socket(socket)
ensure_state :disconnected
raise TypeError, "expected #{@socket_class}, got #{socket.class}" unless socket.is_a?(@socket_class)

@socket = socket
@state = :connected

Expand Down Expand Up @@ -248,6 +249,7 @@ def readpartial(size, outbuf: nil, timeout: @read_timeout)
begin
while (result = read_nonblock(size, outbuf: outbuf)) == :wait_readable
next if @socket.wait_readable(time_remaining(timeout))

raise TimeoutError, "read timed out after #{timeout} seconds"
end
ensure
Expand Down Expand Up @@ -314,6 +316,7 @@ def writepartial(data, timeout: @write_timeout)
begin
while (result = write_nonblock(data)) == :wait_writable
next if @socket.wait_writable(time_remaining(timeout))

raise TimeoutError, "write timed out after #{timeout} seconds"
end
ensure
Expand Down Expand Up @@ -344,6 +347,7 @@ def write(data, timeout: @write_timeout)
return :eof if bytes_written == :eof

break if bytes_written == data.bytesize

data = data.byteslice(bytes_written..-1)
end
end
Expand Down Expand Up @@ -432,14 +436,17 @@ def change_state(new_state)
when :connecting
raise "@socket is unset in #{@state} state" unless @socket
raise(StateError, "not in the disconnected state (actual: #{@state})") unless @state == :disconnected

@state = :connecting
when :connected
raise "@socket is unset in #{@state} state" unless @socket
raise(StateError, "not in the connecting state (actual: #{@state})") unless @state == :connecting

@state = :connected
when :disconnected
raise "@socket is still set while disconnecting (in #{@state} state)" if @socket
raise(StateError, "already in the disconnected state") if @state == :disconnected

@state = :disconnected
else raise ArgumentError, "bad state argument: #{state.inspect}"
end
Expand Down
8 changes: 6 additions & 2 deletions lib/socketry/timeout.rb
Expand Up @@ -7,8 +7,8 @@ module Timeout

# Default timeouts (in seconds)
DEFAULT_TIMEOUTS = {
read: 5,
write: 5,
read: 5,
write: 5,
connect: 5
}.freeze

Expand All @@ -33,6 +33,7 @@ def start_timer(timer = DEFAULT_TIMER.new)
# @raise [Socketry::InternalError] if timer has not been started
def lifetime
raise Socketry::InternalError, "timer not started" unless @timer

@timer.to_f
end

Expand All @@ -56,6 +57,7 @@ def set_timeout(timeout)
def clear_timeout(timeout)
return unless timeout
raise Socketry::InternalError, "no deadline set" unless @deadline

@deadline = nil
end

Expand All @@ -68,8 +70,10 @@ def clear_timeout(timeout)
def time_remaining(timeout)
return unless timeout
raise Socketry::InternalError, "no deadline set" unless @deadline

remaining = @deadline - lifetime
raise Socketry::TimeoutError, "time expired" if remaining <= 0

remaining
end
end
Expand Down
2 changes: 2 additions & 0 deletions lib/socketry/udp/socket.rb
Expand Up @@ -135,6 +135,7 @@ def recvfrom(maxlen, timeout: @read_timeout)
begin
while (result = recvfrom_nonblock(maxlen)) == :wait_readable
next if @socket.wait_readable(time_remaining(timeout))

raise Socketry::TimeoutError, "recvfrom timed out after #{timeout} seconds"
end
ensure
Expand Down Expand Up @@ -168,6 +169,7 @@ def send(msg, host: nil, port: nil)
# @return [true, false] true if the socket was open, false if closed
def close
return false if closed?

@socket.close
true
ensure
Expand Down
2 changes: 1 addition & 1 deletion socketry.gemspec
@@ -1,6 +1,6 @@
# frozen_string_literal: true

lib = File.expand_path("../lib", __FILE__)
lib = File.expand_path("lib", __dir__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require "socketry/version"

Expand Down
2 changes: 1 addition & 1 deletion spec/socketry/ssl/server_spec.rb
Expand Up @@ -14,7 +14,7 @@
let(:ssl_server_params) do
{
cert: OpenSSL::X509::Certificate.new(server_cert_file.read),
key: OpenSSL::PKey::RSA.new(server_key_file.read)
key: OpenSSL::PKey::RSA.new(server_key_file.read)
}
end

Expand Down
2 changes: 1 addition & 1 deletion spec/spec_helper.rb
Expand Up @@ -3,7 +3,7 @@
require "coveralls"
Coveralls.wear!

$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
require "socketry"

RSpec.configure(&:disable_monkey_patching!)
Expand Down

0 comments on commit 3b1663b

Please sign in to comment.