From: k@... Date: 2017-10-06T12:35:58+00:00 Subject: [ruby-core:83161] [Ruby trunk Bug#13921][Closed] buffered read_nonblock doesn't work as expected using SSLSocket Issue #13921 has been updated by rhenium (Kazuki Yamaguchi). Status changed from Open to Closed chucke (Tiago Cardoso) wrote: > rhenium, thank you for the link to the openssl issue, I just tested, and I can confirm that it solves the issue! Indeed I had problems with data left in the destination buffer passed as argument, as my example above shows. > > But I still have to keep my workaround for openssl < 2.0.6, as those versions won't go away anytime soon. > > But there should be a warning in the documentation for #read_nonblock saying that passing a buffer as argument is unsafe for ssl sockets. Thanks for the confirmation. Backport request for Ruby 2.3 and 2.4 is [Bug #13935]. I suggest you check the return value from *#read_nonblock. It happens only in error cases where read_nonblock could not read anything. ---------------------------------------- Bug #13921: buffered read_nonblock doesn't work as expected using SSLSocket https://bugs.ruby-lang.org/issues/13921#change-67097 * Author: chucke (Tiago Cardoso) * Status: Closed * Priority: Normal * Assignee: * Target version: * ruby -v: 2.4.2 * Backport: 2.2: UNKNOWN, 2.3: UNKNOWN, 2.4: UNKNOWN ---------------------------------------- I have something similar to the following code that handles both tcp as well as ssl sockets. The idea is to use the #read_nonblock API which uses a buffer when passed in the argument (instead of creating a string every time). ``` class A def initialize @buffer = String.new("", encoding: Encoding::BINARY) end def read(io) io.read_nonblock(16_384, @buffer, exception: false) # do stuff... @buffer.clear end ``` For plain tcp sockets, it works as expected (buffers payload). However, when passed an ssl socket, it buffers the whole SSL payload, which SSLSocket's usually handle transparently. Of course, my logic fails after that. My current workaround is to resort to the unbuffered API: ``` buffer = io.read_nonblock(16_384, exception: false) ``` however, the call mentioned above should have worked transparently. -- https://bugs.ruby-lang.org/ Unsubscribe: