Skip to content

Commit

Permalink
Workaround SSLSocket always clearing the buffer
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
byroot committed Apr 16, 2024
1 parent e79e9e5 commit 1121770
Showing 1 changed file with 17 additions and 1 deletion.
18 changes: 17 additions & 1 deletion lib/redis_client/ruby_connection/buffered_io.rb
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ def ensure_remaining(bytes)

def fill_buffer(strict, size = @chunk_size)
remaining = size
start = @offset - @buffer.bytesize
buffer_size = @buffer.bytesize
start = @offset - buffer_size
empty_buffer = start >= 0

loop do
Expand All @@ -199,12 +200,27 @@ def fill_buffer(strict, size = @chunk_size)
else
@io.read_nonblock([remaining, @chunk_size].max, exception: false)
end

case bytes
when :wait_readable
# Ref: https://github.com/redis-rb/redis-client/issues/190
# SSLSocket always clear the provided buffer, even when it didn't
# read anything. So we need to reset the offset accordingly.
if empty_buffer && @buffer.empty?
@offset -= buffer_size
end

unless @io.to_io.wait_readable(@read_timeout)
raise ReadTimeoutError, "Waited #{@read_timeout} seconds" unless @blocking_reads
end
when :wait_writable
# Ref: https://github.com/redis-rb/redis-client/issues/190
# SSLSocket always clear the provided buffer, even when it didn't
# read anything. So we need to reset the offset accordingly.
if empty_buffer && @buffer.empty?
@offset -= buffer_size
end

@io.to_io.wait_writable(@write_timeout) or raise(WriteTimeoutError, "Waited #{@write_timeout} seconds")
when nil
raise EOFError
Expand Down

0 comments on commit 1121770

Please sign in to comment.