diff options
| author | Sharon Rosner <sharon@noteflakes.com> | 2026-01-19 09:15:41 +0100 |
|---|---|---|
| committer | git <svn-admin@ruby-lang.org> | 2026-01-23 15:38:19 +0000 |
| commit | 05b85fc1abdefd81a5561ac7d7aed433b7a01400 (patch) | |
| tree | d6b1201041728fc4bbe25ad3cf6c58f9dcd3e1f4 | |
| parent | f02fffbe0462f5e6b115f86bc5c7e5dc7d47f610 (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.c | 23 | ||||
| -rw-r--r-- | test/openssl/test_ssl.rb | 16 |
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| |
