Skip to content

Commit 071e157

Browse files
committed
Fix broken HTTP::Connection#readpartial
800c581 broke `readpartial` method: it returns same chunk twice :( Ref httprb#454
1 parent 085a47f commit 071e157

File tree

3 files changed

+65
-2
lines changed

3 files changed

+65
-2
lines changed

lib/http/connection.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def readpartial(size = BUFFER_SIZE)
9090
return chunk if chunk
9191

9292
finished = (read_more(size) == :eof) || @parser.finished?
93-
chunk = @parser.chunk
93+
chunk = @parser.read(size)
9494
finish_response if finished
9595

9696
chunk.to_s

lib/http/response/parser.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
module HTTP
44
class Response
55
class Parser
6-
attr_reader :headers, :chunk
6+
attr_reader :headers
77

88
def initialize
99
@parser = HTTP::Parser.new(self)

spec/lib/http/connection_spec.rb

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe HTTP::Connection do
4+
let(:req) do
5+
HTTP::Request.new(
6+
:verb => :get,
7+
:uri => "http://example.com/",
8+
:headers => {}
9+
)
10+
end
11+
let(:socket) { double(:connect => nil) }
12+
let(:timeout_class) { double(:new => socket) }
13+
let(:opts) { HTTP::Options.new(:timeout_class => timeout_class) }
14+
let(:connection) { HTTP::Connection.new(req, opts) }
15+
16+
describe "#read_headers!" do
17+
before do
18+
connection.instance_variable_set(:@pending_response, true)
19+
expect(socket).to receive(:readpartial) do
20+
<<-RESPONSE.gsub(/^\s*\| */, "").gsub(/\n/, "\r\n")
21+
| HTTP/1.1 200 OK
22+
| Content-Type: text
23+
|
24+
RESPONSE
25+
end
26+
end
27+
28+
it "reads data in parts" do
29+
connection.read_headers!
30+
expect(connection.headers).to eq("Content-Type" => "text")
31+
end
32+
end
33+
34+
describe "#readpartial" do
35+
before do
36+
connection.instance_variable_set(:@pending_response, true)
37+
expect(socket).to receive(:readpartial) do
38+
<<-RESPONSE.gsub(/^\s*\| */, "").gsub(/\n/, "\r\n")
39+
| HTTP/1.1 200 OK
40+
| Content-Type: text
41+
|
42+
RESPONSE
43+
end
44+
expect(socket).to receive(:readpartial) { "1" }
45+
expect(socket).to receive(:readpartial) { "23" }
46+
expect(socket).to receive(:readpartial) { "456" }
47+
expect(socket).to receive(:readpartial) { "78" }
48+
expect(socket).to receive(:readpartial) { "9" }
49+
expect(socket).to receive(:readpartial) { "0" }
50+
expect(socket).to receive(:readpartial) { :eof }
51+
expect(socket).to receive(:closed?) { true }
52+
end
53+
54+
it "reads data in parts" do
55+
connection.read_headers!
56+
buffer = String.new
57+
while (s = connection.readpartial(3))
58+
buffer << s
59+
end
60+
expect(buffer).to eq "1234567890"
61+
end
62+
end
63+
end

0 commit comments

Comments
 (0)