Skip to content

Commit

Permalink
Fix broken HTTP::Connection#readpartial
Browse files Browse the repository at this point in the history
800c581 broke `readpartial` method: it returns same chunk twice :(

Ref httprb#454
  • Loading branch information
marshall-lee committed Mar 15, 2018
1 parent 085a47f commit 071e157
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 2 deletions.
2 changes: 1 addition & 1 deletion lib/http/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def readpartial(size = BUFFER_SIZE)
return chunk if chunk

finished = (read_more(size) == :eof) || @parser.finished?
chunk = @parser.chunk
chunk = @parser.read(size)
finish_response if finished

chunk.to_s
Expand Down
2 changes: 1 addition & 1 deletion lib/http/response/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module HTTP
class Response
class Parser
attr_reader :headers, :chunk
attr_reader :headers

def initialize
@parser = HTTP::Parser.new(self)
Expand Down
63 changes: 63 additions & 0 deletions spec/lib/http/connection_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# frozen_string_literal: true

RSpec.describe HTTP::Connection do
let(:req) do
HTTP::Request.new(
:verb => :get,
:uri => "http://example.com/",
:headers => {}
)
end
let(:socket) { double(:connect => nil) }
let(:timeout_class) { double(:new => socket) }
let(:opts) { HTTP::Options.new(:timeout_class => timeout_class) }
let(:connection) { HTTP::Connection.new(req, opts) }

describe "#read_headers!" do
before do
connection.instance_variable_set(:@pending_response, true)
expect(socket).to receive(:readpartial) do
<<-RESPONSE.gsub(/^\s*\| */, "").gsub(/\n/, "\r\n")
| HTTP/1.1 200 OK
| Content-Type: text
|
RESPONSE
end
end

it "reads data in parts" do
connection.read_headers!
expect(connection.headers).to eq("Content-Type" => "text")
end
end

describe "#readpartial" do
before do
connection.instance_variable_set(:@pending_response, true)
expect(socket).to receive(:readpartial) do
<<-RESPONSE.gsub(/^\s*\| */, "").gsub(/\n/, "\r\n")
| HTTP/1.1 200 OK
| Content-Type: text
|
RESPONSE
end
expect(socket).to receive(:readpartial) { "1" }
expect(socket).to receive(:readpartial) { "23" }
expect(socket).to receive(:readpartial) { "456" }
expect(socket).to receive(:readpartial) { "78" }
expect(socket).to receive(:readpartial) { "9" }
expect(socket).to receive(:readpartial) { "0" }
expect(socket).to receive(:readpartial) { :eof }
expect(socket).to receive(:closed?) { true }
end

it "reads data in parts" do
connection.read_headers!
buffer = String.new
while (s = connection.readpartial(3))
buffer << s
end
expect(buffer).to eq "1234567890"
end
end
end

0 comments on commit 071e157

Please sign in to comment.