Skip to content

Commit 336ce1c

Browse files
authored
Merge pull request #193 from redis-rb/workaround-ssl-socket-buffer-clear
Workaround SSLSocket always clearing the buffer
2 parents c550381 + 49b0d16 commit 336ce1c

File tree

3 files changed

+21
-5
lines changed

3 files changed

+21
-5
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

test/redis_client/middlewares_test.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,11 @@ def test_multi_instrumentation
7070
end
7171

7272
module DummyMiddleware
73-
def call(command, _config)
73+
def call(command, _config, &_)
7474
command
7575
end
7676

77-
def call_pipelined(commands, _config)
77+
def call_pipelined(commands, _config, &_)
7878
commands
7979
end
8080
end

test/redis_client_test.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def test_dns_resolution_failure
5252

5353
def test_older_server
5454
fake_redis5_driver = Class.new(RedisClient::RubyConnection) do
55-
def call_pipelined(commands, *)
55+
def call_pipelined(commands, *, &_)
5656
if commands.any? { |c| c == ["HELLO", "3"] }
5757
raise RedisClient::CommandError, "ERR unknown command `HELLO`, with args beginning with: `3`"
5858
else
@@ -71,7 +71,7 @@ def call_pipelined(commands, *)
7171

7272
def test_redis_6_server_with_missing_hello_command
7373
fake_redis6_driver = Class.new(RedisClient::RubyConnection) do
74-
def call_pipelined(commands, *)
74+
def call_pipelined(commands, *, &_)
7575
if commands.any? { |c| c == ["HELLO", "3"] }
7676
raise RedisClient::CommandError, "ERR unknown command 'HELLO'"
7777
else

0 commit comments

Comments
 (0)