Skip to content

Commit 660b6a2

Browse files
committed
Always return headers as bytes
Fixes: gh-60
1 parent 429f465 commit 660b6a2

File tree

3 files changed

+31
-6
lines changed

3 files changed

+31
-6
lines changed

docs/source/changes.rst

+9
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@ History of changes
33

44
.. currentmodule:: h11
55

6+
vNEXT (unreleased)
7+
------------------
8+
9+
Bug fixes:
10+
11+
* Always return headers as ``bytes`` objects (`#60
12+
<https://github.com/python-hyper/h11/issues/60>`__)
13+
14+
615
v0.8.0 (2018-03-20)
716
-------------------
817

h11/_readers.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,11 @@ def _obsolete_line_fold(lines):
5151

5252
def _decode_header_lines(lines):
5353
for line in _obsolete_line_fold(lines):
54-
matches = validate(header_field_re, line)
54+
# _obsolete_line_fold yields either bytearray or bytes objects. On
55+
# Python 3, validate() takes either and returns matches as bytes. But
56+
# on Python 2, validate can return matches as bytearrays, so we have
57+
# to explicitly cast back.
58+
matches = validate(header_field_re, bytes(line))
5559
yield (matches["field_name"], matches["field_value"])
5660

5761
request_line_re = re.compile(request_line.encode("ascii"))

h11/tests/test_io.py

+17-5
Original file line numberDiff line numberDiff line change
@@ -58,22 +58,31 @@ def makebuf(data):
5858
return buf
5959

6060
def tr(reader, data, expected):
61+
def check(got):
62+
assert got == expected
63+
# Headers should always be returned as bytes, not e.g. bytearray
64+
# https://github.com/python-hyper/wsproto/pull/54#issuecomment-377709478
65+
for name, value in getattr(got, "headers", []):
66+
print(name, value)
67+
assert type(name) is bytes
68+
assert type(value) is bytes
69+
6170
# Simple: consume whole thing
6271
buf = makebuf(data)
63-
assert reader(buf) == expected
72+
check(reader(buf))
6473
assert not buf
6574

6675
# Incrementally growing buffer
6776
buf = ReceiveBuffer()
6877
for i in range(len(data)):
6978
assert reader(buf) is None
7079
buf += data[i:i + 1]
71-
assert reader(buf) == expected
80+
check(reader(buf))
7281

73-
# Extra
82+
# Trailing data
7483
buf = makebuf(data)
7584
buf += b"trailing"
76-
assert reader(buf) == expected
85+
check(reader(buf))
7786
assert bytes(buf) == b"trailing"
7887

7988
def test_writers_simple():
@@ -157,12 +166,15 @@ def test_readers_unusual():
157166
b" header\r\n"
158167
b"\tnonsense\r\n"
159168
b" \t \t\tI guess\r\n"
160-
b"Connection: close\r\n\r\n",
169+
b"Connection: close\r\n"
170+
b"More-nonsense: in the\r\n"
171+
b" last header \r\n\r\n",
161172
Request(method="HEAD", target="/foo",
162173
headers=[
163174
("Host", "example.com"),
164175
("Some", "multi-line header nonsense I guess"),
165176
("Connection", "close"),
177+
("More-nonsense", "in the last header"),
166178
]))
167179

168180
with pytest.raises(LocalProtocolError):

0 commit comments

Comments
 (0)