Skip to content
Open
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
19 changes: 10 additions & 9 deletions lib/http/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def initialize(req, options)
@pending_request = false
@pending_response = false
@failed_proxy_connect = false
@buffer = "".b
@buffer = String.new(capacity: BUFFER_SIZE, encoding: Encoding::BINARY)

@parser = Response::Parser.new

Expand Down Expand Up @@ -89,18 +89,19 @@ def send_request(req)
# Read a chunk of the body
#
# @return [String] data chunk
# @return [nil] when no more data left
def readpartial(size = BUFFER_SIZE)
return unless @pending_response
# @raise [EOFError] when there's no more data left
def readpartial(size = BUFFER_SIZE, outbuf = nil)
raise EOFError unless @pending_response

chunk = @parser.read(size)
return chunk if chunk

finished = (read_more(size) == :eof) || @parser.finished?
chunk = @parser.read(size)
finish_response if finished
unless chunk
finished = (read_more(size) == :eof) || @parser.finished?
chunk = @parser.read(size) || String.new(encoding: Encoding::BINARY)
finish_response if finished
end

chunk || "".b
outbuf ? outbuf.replace(chunk) : chunk
end

# Reads data from socket up until headers are loaded
Expand Down
8 changes: 5 additions & 3 deletions lib/http/response/body.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,16 @@ def to_s

raise StateError, "body is being streamed" unless @streaming.nil?

begin
@streaming = false
@contents = String.new("", encoding: @encoding)
@streaming = false
@contents = String.new("", encoding: @encoding)

begin
while (chunk = @stream.readpartial)
@contents << String.new(chunk, encoding: @encoding)
chunk = nil # deallocate string
end
rescue EOFError
# do nothing
rescue
@contents = nil
raise
Expand Down
34 changes: 31 additions & 3 deletions spec/lib/http/connection_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require "stringio"

RSpec.describe HTTP::Connection do
let(:req) do
HTTP::Request.new(
Expand Down Expand Up @@ -77,12 +79,38 @@
it "reads data in parts" do
connection.read_headers!
buffer = String.new
while (s = connection.readpartial(3))
expect(connection.finished_request?).to be false if s != ""
buffer << s

begin
while (s = connection.readpartial(3))
expect(connection.finished_request?).to be false if s != ""
buffer << s
end
rescue EOFError
end

expect(buffer).to eq "1234567890"
expect(connection.finished_request?).to be true
end

it "fill outbuf when present" do
connection.read_headers!
outbuf = String.new
buffer = String.new

begin
buffer << outbuf while connection.readpartial(2, outbuf)
rescue EOFError
end

expect(buffer).to eq "1234567890"
end

it "can be used with IO.copy_stream" do
output = StringIO.new

IO.copy_stream(connection, output)

expect(output.string).to eq "1234567890"
end
end
end