Skip to content

Commit e623d67

Browse files
author
Piotr Boniecki
committed
Fix parser so it properly parses headers
..when they are returned in parts Resolves: #589
1 parent edfa4f1 commit e623d67

File tree

2 files changed

+65
-6
lines changed

2 files changed

+65
-6
lines changed

lib/http/response/parser.rb

+20-6
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,17 @@ def status_code
4949
#
5050

5151
def on_header_field(_response, field)
52-
@field = field
52+
append_header if @reading_header_value
53+
@field << field
5354
end
5455

5556
def on_header_value(_response, value)
56-
@headers.add(@field, value) if @field
57+
@reading_header_value = true
58+
@field_value << value
5759
end
5860

5961
def on_headers_complete(_reposse)
62+
append_header if @reading_header_value
6063
@finished[:headers] = true
6164
end
6265

@@ -89,15 +92,26 @@ def on_message_complete(_response)
8992
def reset
9093
@state.reset!
9194

92-
@finished = Hash.new(false)
93-
@headers = HTTP::Headers.new
94-
@field = nil
95-
@chunk = nil
95+
@finished = Hash.new(false)
96+
@headers = HTTP::Headers.new
97+
@reading_header_value = false
98+
@field = +""
99+
@field_value = +""
100+
@chunk = nil
96101
end
97102

98103
def finished?
99104
@finished[:message]
100105
end
106+
107+
private
108+
109+
def append_header
110+
@headers.add(@field, @field_value)
111+
@reading_header_value = false
112+
@field_value = +""
113+
@field = +""
114+
end
101115
end
102116
end
103117
end

spec/lib/http/response/parser_spec.rb

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe HTTP::Response::Parser do
4+
subject(:parser) { described_class.new }
5+
let(:raw_response) do
6+
"HTTP/1.1 200 OK\r\nContent-Length: 2\r\nContent-Type: application/json\r\nMyHeader: val\r\nEmptyHeader: \r\n\r\n{}"
7+
end
8+
let(:expected_headers) do
9+
{
10+
"Content-Length" => "2",
11+
"Content-Type" => "application/json",
12+
"MyHeader" => "val",
13+
"EmptyHeader" => ""
14+
}
15+
end
16+
let(:expected_body) { "{}" }
17+
18+
before do
19+
parts.each { |part| subject.add(part) }
20+
end
21+
22+
context "whole response in one part" do
23+
let(:parts) { [raw_response] }
24+
25+
it "parses headers" do
26+
expect(subject.headers.to_h).to eq(expected_headers)
27+
end
28+
29+
it "parses body" do
30+
expect(subject.read(expected_body.size)).to eq(expected_body)
31+
end
32+
end
33+
34+
context "response in many parts" do
35+
let(:parts) { raw_response.split(//) }
36+
37+
it "parses headers" do
38+
expect(subject.headers.to_h).to eq(expected_headers)
39+
end
40+
41+
it "parses body" do
42+
expect(subject.read(expected_body.size)).to eq(expected_body)
43+
end
44+
end
45+
end

0 commit comments

Comments
 (0)