Skip to content

Commit

Permalink
Add support for IO#timeout.
Browse files Browse the repository at this point in the history
  • Loading branch information
ioquatix committed Jan 13, 2024
1 parent 8aa3849 commit 17b6b94
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 2 deletions.
1 change: 1 addition & 0 deletions ext/openssl/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@

have_func("rb_io_descriptor")
have_func("rb_io_maybe_wait(0, Qnil, Qnil, Qnil)", "ruby/io.h") # Ruby 3.1
have_const("rb_eIOTimeoutError", "ruby/error.h")

Logging::message "=== Checking for system dependent stuff... ===\n"
have_library("nsl", "t_open")
Expand Down
15 changes: 13 additions & 2 deletions ext/openssl/ossl_ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1725,11 +1725,20 @@ no_exception_p(VALUE opts)
#define RUBY_IO_TIMEOUT_DEFAULT Qnil
#endif

#ifdef HAVE_CONST_RB_EIOTIMEOUTERROR
#define IO_TIMEOUT_ERROR rb_eIOTimeoutError
#else
#define IO_TIMEOUT_ERROR rb_eIOError
#endif


static void
io_wait_writable(VALUE io)
{
#ifdef HAVE_RB_IO_MAYBE_WAIT
rb_io_maybe_wait_writable(errno, io, RUBY_IO_TIMEOUT_DEFAULT);
if (!rb_io_maybe_wait_writable(errno, io, RUBY_IO_TIMEOUT_DEFAULT)) {
rb_raise(IO_TIMEOUT_ERROR, "Timed out while waiting to become writable!");
}
#else
rb_io_t *fptr;
GetOpenFile(io, fptr);
Expand All @@ -1741,7 +1750,9 @@ static void
io_wait_readable(VALUE io)
{
#ifdef HAVE_RB_IO_MAYBE_WAIT
rb_io_maybe_wait_readable(errno, io, RUBY_IO_TIMEOUT_DEFAULT);
if (!rb_io_maybe_wait_readable(errno, io, RUBY_IO_TIMEOUT_DEFAULT)) {
rb_raise(IO_TIMEOUT_ERROR, "Timed out while waiting to become readable!");
}
#else
rb_io_t *fptr;
GetOpenFile(io, fptr);
Expand Down
10 changes: 10 additions & 0 deletions lib/openssl/ssl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,16 @@ def wait_readable(*args)
def wait_writable(*args)
to_io.wait_writable(*args)
end

if IO.method_defined?(:timeout)
def timeout
to_io.timeout
end

def timeout=(value)
to_io.timeout=(value)
end
end
end

def verify_certificate_identity(cert, hostname)
Expand Down
11 changes: 11 additions & 0 deletions test/openssl/test_ssl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,17 @@ def test_sysread_and_syswrite
}
end

def test_read_with_timeout
omit "does not support timeout" unless IO.method_defined?(:timeout)

start_server do |port|
server_connect(port) do |ssl|
ssl.timeout = 0.001
assert_raise(IO::TimeoutError) {ssl.read(1)}
end
end
end

def test_getbyte
start_server { |port|
server_connect(port) { |ssl|
Expand Down

0 comments on commit 17b6b94

Please sign in to comment.