Skip to content

Commit

Permalink
feat: Make connection IO.copy_stream compatible
Browse files Browse the repository at this point in the history
  • Loading branch information
ixti committed Aug 28, 2024
1 parent e0382ac commit 07c1f39
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 12 deletions.
9 changes: 4 additions & 5 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,19 +89,18 @@ def send_request(req)
# Read a chunk of the body
#
# @return [String] data chunk
# @return [nil] when no more data left
# @raise [EOFError] when there's no more data left
def readpartial(size = BUFFER_SIZE, outbuf = nil)
return unless @pending_response
raise EOFError unless @pending_response

chunk = @parser.read(size)

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

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

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
28 changes: 24 additions & 4 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,10 +79,15 @@
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
Expand All @@ -89,8 +96,21 @@
connection.read_headers!
outbuf = String.new
buffer = String.new
buffer << outbuf while connection.readpartial(2, outbuf)

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

0 comments on commit 07c1f39

Please sign in to comment.