summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSharon Rosner <sharon@noteflakes.com>2026-01-19 09:15:41 +0100
committergit <svn-admin@ruby-lang.org>2026-01-23 15:38:19 +0000
commit05b85fc1abdefd81a5561ac7d7aed433b7a01400 (patch)
treed6b1201041728fc4bbe25ad3cf6c58f9dcd3e1f4
parentf02fffbe0462f5e6b115f86bc5c7e5dc7d47f610 (diff)
[ruby/openssl] Add `sync_close` kwarg to `SSLSocket.new` (fixes
https://github.com/ruby/openssl/pull/955) https://github.com/ruby/openssl/commit/8d9a676dfa
-rw-r--r--ext/openssl/ossl_ssl.c23
-rw-r--r--test/openssl/test_ssl.rb16
2 files changed, 37 insertions, 2 deletions
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 630d46e43f..d622f17585 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -47,7 +47,7 @@ static ID id_i_cert_store, id_i_ca_file, id_i_ca_path, id_i_verify_mode,
id_i_session_remove_cb, id_i_npn_select_cb, id_i_npn_protocols,
id_i_alpn_select_cb, id_i_alpn_protocols, id_i_servername_cb,
id_i_verify_hostname, id_i_keylog_cb, id_i_tmp_dh_callback;
-static ID id_i_io, id_i_context, id_i_hostname;
+static ID id_i_io, id_i_context, id_i_hostname, id_i_sync_close;
static int ossl_ssl_ex_ptr_idx;
static int ossl_sslctx_ex_ptr_idx;
@@ -1616,6 +1616,7 @@ peeraddr_ip_str(VALUE self)
* call-seq:
* SSLSocket.new(io) => aSSLSocket
* SSLSocket.new(io, ctx) => aSSLSocket
+ * SSLSocket.new(io, ctx, sync_close:) => aSSLSocket
*
* Creates a new SSL socket from _io_ which must be a real IO object (not an
* IO-like object that responds to read/write).
@@ -1623,6 +1624,10 @@ peeraddr_ip_str(VALUE self)
* If _ctx_ is provided the SSL Sockets initial params will be taken from
* the context.
*
+ * The optional _sync_close_ keyword parameter sets the _sync_close_ instance
+ * variable. Setting this to +true+ will cause the underlying socket to be
+ * closed when the SSL/TLS connection is shut down.
+ *
* The OpenSSL::Buffering module provides additional IO methods.
*
* This method will freeze the SSLContext if one is provided;
@@ -1631,6 +1636,10 @@ peeraddr_ip_str(VALUE self)
static VALUE
ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
{
+ static ID kw_ids[1];
+ VALUE kw_args[1];
+ VALUE opts;
+
VALUE io, v_ctx;
SSL *ssl;
SSL_CTX *ctx;
@@ -1639,9 +1648,18 @@ ossl_ssl_initialize(int argc, VALUE *argv, VALUE self)
if (ssl)
ossl_raise(eSSLError, "SSL already initialized");
- if (rb_scan_args(argc, argv, "11", &io, &v_ctx) == 1)
+ if (rb_scan_args(argc, argv, "11:", &io, &v_ctx, &opts) == 1)
v_ctx = rb_funcall(cSSLContext, rb_intern("new"), 0);
+ if (!kw_ids[0]) {
+ kw_ids[0] = rb_intern_const("sync_close");
+ }
+
+ rb_get_kwargs(opts, kw_ids, 0, 1, kw_args);
+ if (kw_args[0] != Qundef) {
+ rb_ivar_set(self, id_i_sync_close, kw_args[0]);
+ }
+
GetSSLCTX(v_ctx, ctx);
rb_ivar_set(self, id_i_context, v_ctx);
ossl_sslctx_setup(v_ctx);
@@ -3300,5 +3318,6 @@ Init_ossl_ssl(void)
DefIVarID(io);
DefIVarID(context);
DefIVarID(hostname);
+ DefIVarID(sync_close);
#endif /* !defined(OPENSSL_NO_SOCK) */
}
diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb
index 5d20ccd1f4..6272806585 100644
--- a/test/openssl/test_ssl.rb
+++ b/test/openssl/test_ssl.rb
@@ -355,6 +355,22 @@ class OpenSSL::TestSSL < OpenSSL::SSLTestCase
end
end
+ def test_sync_close_initialize_opt
+ start_server do |port|
+ begin
+ sock = TCPSocket.new("127.0.0.1", port)
+ ssl = OpenSSL::SSL::SSLSocket.new(sock, sync_close: true)
+ assert_equal true, ssl.sync_close
+ ssl.connect
+ ssl.puts "abc"; assert_equal "abc\n", ssl.gets
+ ssl.close
+ assert_predicate sock, :closed?
+ ensure
+ sock&.close
+ end
+ end
+ end
+
def test_copy_stream
start_server do |port|
server_connect(port) do |ssl|