Skip to content

Commit 98b8944

Browse files
committed
Workaround SSLSocket always clearing the buffer
Fix: #190 ```ruby buff = "blah".b p io.read_nonblock(10, buffer, exception: false) # :wait_readable p buff ``` The above code when using a regular Ruby IO socket leaves the buffer intact, because it only replaces the content if it actually read something. However when using a `SSLSocket`, the buffer is always cleared regardless of whether something was read or not. This difference could cause the offset to be corrupted by pointing forward.
1 parent c550381 commit 98b8944

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

lib/redis_client/ruby_connection/buffered_io.rb

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,8 @@ def ensure_remaining(bytes)
190190

191191
def fill_buffer(strict, size = @chunk_size)
192192
remaining = size
193-
start = @offset - @buffer.bytesize
193+
buffer_size = @buffer.bytesize
194+
start = @offset - buffer_size
194195
empty_buffer = start >= 0
195196

196197
loop do
@@ -199,12 +200,27 @@ def fill_buffer(strict, size = @chunk_size)
199200
else
200201
@io.read_nonblock([remaining, @chunk_size].max, exception: false)
201202
end
203+
202204
case bytes
203205
when :wait_readable
206+
# Ref: https://github.com/redis-rb/redis-client/issues/190
207+
# SSLSocket always clear the provided buffer, even when it didn't
208+
# read anything. So we need to reset the offset accordingly.
209+
if empty_buffer && @buffer.empty?
210+
@offset -= buffer_size
211+
end
212+
204213
unless @io.to_io.wait_readable(@read_timeout)
205214
raise ReadTimeoutError, "Waited #{@read_timeout} seconds" unless @blocking_reads
206215
end
207216
when :wait_writable
217+
# Ref: https://github.com/redis-rb/redis-client/issues/190
218+
# SSLSocket always clear the provided buffer, even when it didn't
219+
# read anything. So we need to reset the offset accordingly.
220+
if empty_buffer && @buffer.empty?
221+
@offset -= buffer_size
222+
end
223+
208224
@io.to_io.wait_writable(@write_timeout) or raise(WriteTimeoutError, "Waited #{@write_timeout} seconds")
209225
when nil
210226
raise EOFError

0 commit comments

Comments
 (0)