Skip to content

Commit d2ec525

Browse files
committed
Raise an error if singleton headers are set multiple times.
1 parent 69c37f5 commit d2ec525

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

lib/protocol/http/headers.rb

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -238,16 +238,16 @@ def []= key, value
238238
# The policy for various headers, including how they are merged and normalized.
239239
POLICY = {
240240
# Headers which may only be specified once:
241-
"content-type" => false,
242241
"content-disposition" => false,
243242
"content-length" => false,
244-
"user-agent" => false,
245-
"referer" => false,
246-
"host" => false,
243+
"content-type" => false,
247244
"from" => false,
245+
"host" => false,
248246
"location" => false,
249247
"max-forwards" => false,
248+
"referer" => false,
250249
"retry-after" => false,
250+
"user-agent" => false,
251251

252252
# Custom headers:
253253
"connection" => Header::Connection,
@@ -267,6 +267,7 @@ def []= key, value
267267
"etag" => Header::ETag,
268268
"if-match" => Header::ETags,
269269
"if-none-match" => Header::ETags,
270+
"if-range" => false,
270271

271272
# Headers which may be specified multiple times, but which can't be concatenated:
272273
"www-authenticate" => Multiple,
@@ -332,7 +333,10 @@ def delete(key)
332333
hash[key] = policy.new(value)
333334
end
334335
else
335-
# We can't merge these, we only expose the last one set.
336+
if hash.key?(key)
337+
raise ArgumentError, "Duplicate singleton header key: #{key.inspect}"
338+
end
339+
336340
hash[key] = value
337341
end
338342
end

test/protocol/http/headers.rb

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,33 @@
4242
with "#merge" do
4343
it "should merge headers" do
4444
other = subject[[
45-
# This will replace the original one:
46-
["Content-Type", "text/plain"],
47-
4845
# This will be appended:
4946
["Set-Cookie", "goodbye=world"],
5047
]]
5148

5249
merged = headers.merge(other)
5350

5451
expect(merged.to_h).to be == {
55-
"content-type" => "text/plain",
52+
"content-type" => "text/html",
5653
"set-cookie" => ["hello=world", "foo=bar", "goodbye=world"],
5754
"accept" => ["*/*"],
5855
"connection" => ["keep-alive"]
5956
}
6057
end
58+
59+
it "can't merge singleton headers" do
60+
other = subject[[
61+
["content-type", "text/plain"],
62+
]]
63+
64+
# This doesn't fail as we haven't built an internal index yet:
65+
merged = headers.merge(other)
66+
67+
expect do
68+
# Once we build the index, it will fail:
69+
merged.to_h
70+
end.to raise_exception(ArgumentError)
71+
end
6172
end
6273

6374
with "#extract" do

0 commit comments

Comments
 (0)