Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions lib/protocol/http/body/stream.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,25 @@ def read(length = nil, buffer = nil)
# Will avoid reading from the underlying stream if there is buffered data available.
#
# @parameter length [Integer] The maximum number of bytes to read.
def read_partial(length = nil)
def read_partial(length = nil, buffer = nil)
if @buffer
buffer = @buffer
if buffer
buffer.replace(@buffer)
else
buffer = @buffer
end
@buffer = nil
else
buffer = read_next
if chunk = read_next
if buffer
buffer.replace(chunk)
else
buffer = chunk
end
else
buffer&.clear
buffer = nil
end
end

if buffer and length
Expand All @@ -111,8 +124,8 @@ def read_partial(length = nil)
end

# Similar to {read_partial} but raises an `EOFError` if the stream is at EOF.
def readpartial(length)
read_partial(length) or raise EOFError, "End of file reached!"
def readpartial(length, buffer = nil)
read_partial(length, buffer) or raise EOFError, "End of file reached!"
end

# Read data from the stream without blocking if possible.
Expand Down
38 changes: 38 additions & 0 deletions test/protocol/http/body/stream.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,24 @@
expect(stream.read_partial(2)).to be == "d"
expect(stream.read_partial(2)).to be == nil
end

it "can read partial input with buffer" do
buffer = String.new
expect(stream.read_partial(2, buffer)).to be == "He"
expect(buffer).to be == "He"
expect(stream.read_partial(2, buffer)).to be == "ll"
expect(buffer).to be == "ll"
expect(stream.read_partial(2, buffer)).to be == "o"
expect(buffer).to be == "o"
expect(stream.read_partial(2, buffer)).to be == "Wo"
expect(buffer).to be == "Wo"
expect(stream.read_partial(2, buffer)).to be == "rl"
expect(buffer).to be == "rl"
expect(stream.read_partial(2, buffer)).to be == "d"
expect(buffer).to be == "d"
expect(stream.read_partial(2, buffer)).to be == nil
expect(buffer).to be == ""
end
end

with '#readpartial' do
Expand All @@ -129,6 +147,16 @@
expect(stream.readpartial(20)).to be == "World"
expect{stream.readpartial(20)}.to raise_exception(EOFError)
end

it "can read partial input with buffer" do
buffer = String.new
expect(stream.readpartial(20, buffer)).to be == "Hello"
expect(buffer).to be == "Hello"
expect(stream.readpartial(20, buffer)).to be == "World"
expect(buffer).to be == "World"
expect{stream.readpartial(20, buffer)}.to raise_exception(EOFError)
expect(buffer).to be == ""
end
end

with '#read_until' do
Expand Down Expand Up @@ -224,4 +252,14 @@
expect(stream).to be(:closed?)
end
end

with 'IO.copy_stream' do
let(:output) {StringIO.new}

it "can copy input to output" do
::IO.copy_stream(stream, output)

expect(output.string).to be == "HelloWorld"
end
end
end