From 4ededf0d4cb6f7a9c129c0ce9ffce660c1633811 Mon Sep 17 00:00:00 2001 From: Julien Portalier Date: Fri, 6 Feb 2026 17:27:03 +0100 Subject: [PATCH 1/2] Fix: OpenSSL sockets shouldn't flush on read --- src/openssl/bio.cr | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/openssl/bio.cr b/src/openssl/bio.cr index 43f7e2d5f435..3f9c20da0982 100644 --- a/src/openssl/bio.cr +++ b/src/openssl/bio.cr @@ -41,10 +41,6 @@ struct OpenSSL::BIO def self.read_ex(bio, buffer, len, readp) count = len > Int32::MAX ? Int32::MAX : len.to_i io = Box(IO).unbox(LibCrypto.BIO_get_data(bio)) - - # FIXME: why flush (write) before reading?! - io.flush - ret = io.read Slice.new(buffer, count) readp.value = LibC::SizeT.new(ret) 1 @@ -52,10 +48,6 @@ struct OpenSSL::BIO def self.read(bio, buffer, len) io = Box(IO).unbox(LibCrypto.BIO_get_data(bio)) - - # FIXME: why flush (write) before reading?! - io.flush - io.read(Slice.new(buffer, len)).to_i end From 9c289338d412802e75d51644408649f24814ae17 Mon Sep 17 00:00:00 2001 From: Julien Portalier Date: Tue, 10 Feb 2026 12:45:46 +0100 Subject: [PATCH 2/2] Fix: Crystal::BIO shall disable buffers of underlying IO --- src/openssl/bio.cr | 8 ++++++++ src/openssl/ssl/socket.cr | 7 ------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/openssl/bio.cr b/src/openssl/bio.cr index 3f9c20da0982..3bbe541d565e 100644 --- a/src/openssl/bio.cr +++ b/src/openssl/bio.cr @@ -84,6 +84,14 @@ struct OpenSSL::BIO @boxed_io : Void* def initialize(@io : IO) + if io.is_a?(IO::Buffered) + # Disable buffers of the underlying IO (e.g. TCP socket) so OpenSSL + # becomes responsible of what needs to be read/written on the wire; + # instead, buffers shall be on OpenSSL::SSL::Socket (for example). + io.sync = true + io.read_buffering = false + end + @bio = LibCrypto.BIO_new(CRYSTAL_BIO) # We need to store a reference to the box because it's diff --git a/src/openssl/ssl/socket.cr b/src/openssl/ssl/socket.cr index a8ad2ed222bc..9b7a4b1ce0e3 100644 --- a/src/openssl/ssl/socket.cr +++ b/src/openssl/ssl/socket.cr @@ -101,13 +101,6 @@ abstract class OpenSSL::SSL::Socket < IO raise OpenSSL::Error.new("SSL_new") end - # Since OpenSSL::SSL::Socket is buffered it makes no - # sense to wrap a IO::Buffered with buffering activated. - if io.is_a?(IO::Buffered) - io.sync = true - io.read_buffering = false - end - @bio = BIO.new(io) LibSSL.ssl_set_bio(@ssl, @bio, @bio) end