Skip to content

Commit d5b49f2

Browse files
committed
Normalize Content-Length into a single value
If duplicated exactly when merged into a comma seperated list (the unmerged case is handled already). This is allowed as per RFC 7230 Section 3.3.2.
1 parent 4ca69c3 commit d5b49f2

File tree

2 files changed

+10
-0
lines changed

2 files changed

+10
-0
lines changed

h11/_headers.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ def normalize_and_validate(headers, _parsed=False):
132132
raw_name = name
133133
name = name.lower()
134134
if name == b"content-length":
135+
if b"," in value:
136+
lengths = set(length.strip() for length in value.split(b","))
137+
if len(lengths) != 1:
138+
raise LocalProtocolError("conflicting Content-Length headers")
139+
value = list(lengths)[0]
135140
validate(_content_length_re, value, "bad Content-Length")
136141
if seen_content_length is None:
137142
seen_content_length = value

h11/tests/test_headers.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,15 @@ def test_normalize_and_validate():
5757
assert normalize_and_validate(
5858
[("Content-Length", "0"), ("Content-Length", "0")]
5959
) == [(b"content-length", b"0")]
60+
assert normalize_and_validate([("Content-Length", "0 , 0")]) == [
61+
(b"content-length", b"0")
62+
]
6063
with pytest.raises(LocalProtocolError):
6164
normalize_and_validate(
6265
[("Content-Length", "1"), ("Content-Length", "1"), ("Content-Length", "2")]
6366
)
67+
with pytest.raises(LocalProtocolError):
68+
normalize_and_validate([("Content-Length", "1 , 1,2")])
6469

6570
# transfer-encoding
6671
assert normalize_and_validate([("Transfer-Encoding", "chunked")]) == [

0 commit comments

Comments
 (0)