Skip to content
This repository was archived by the owner on Jan 13, 2021. It is now read-only.

Commit 3a32468

Browse files
committed
Use HTTPHeaderMap instead of list in stream class
1 parent b658463 commit 3a32468

File tree

2 files changed

+49
-43
lines changed

2 files changed

+49
-43
lines changed

hyper/http20/stream.py

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def __init__(self,
6161
local_closed=False):
6262
self.stream_id = stream_id
6363
self.state = STATE_HALF_CLOSED_LOCAL if local_closed else STATE_IDLE
64-
self.headers = []
64+
self.headers = HTTPHeaderMap()
6565

6666
# Set to a key-value set of the response headers once their
6767
# HEADERS..CONTINUATION frame sequence finishes.
@@ -113,18 +113,11 @@ def add_header(self, name, value, replace=False):
113113
"""
114114
Adds a single HTTP header to the headers to be sent on the request.
115115
"""
116-
name = name.lower()
117-
118-
if replace:
119-
try:
120-
idx = [n for n, _ in self.headers].index(name)
121-
self.headers[idx] = (name, value)
122-
return
116+
if not replace:
117+
self.headers[name] = value
118+
else:
119+
self.headers.replace(name, value)
123120

124-
except ValueError:
125-
pass
126-
127-
self.headers.append((name, value))
128121

129122
def send_data(self, data, final):
130123
"""
@@ -279,8 +272,11 @@ def open(self, end):
279272
The `end` flag controls whether this will be the end of the stream, or
280273
whether data will follow.
281274
"""
275+
headers = list(self.headers.items())
276+
282277
# Strip any headers invalid in H2.
283-
headers = h2_safe_headers(self.headers)
278+
headers = h2_safe_headers(headers)
279+
284280
# Encode the headers.
285281
encoded_headers = self._encoder.encode(headers)
286282

test/test_hyper.py

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
combine_repeated_headers, split_repeated_headers, h2_safe_headers
1919
)
2020
from hyper.common.headers import HTTPHeaderMap
21-
from hyper.compat import zlib_compressobj
21+
from hyper.compat import zlib_compressobj, is_py2
2222
from hyper.contrib import HTTP20Adapter
2323
import hyper.http20.errors as errors
2424
import errno
@@ -87,11 +87,11 @@ def test_putrequest_autosets_headers(self):
8787
c.putrequest('GET', '/')
8888
s = c.recent_stream
8989

90-
assert s.headers == [
91-
(':method', 'GET'),
92-
(':scheme', 'https'),
93-
(':authority', 'www.google.com'),
94-
(':path', '/'),
90+
assert list(s.headers.items()) == [
91+
(b':method', b'GET'),
92+
(b':scheme', b'https'),
93+
(b':authority', b'www.google.com'),
94+
(b':path', b'/'),
9595
]
9696

9797
def test_putheader_puts_headers(self):
@@ -101,12 +101,12 @@ def test_putheader_puts_headers(self):
101101
c.putheader('name', 'value')
102102
s = c.recent_stream
103103

104-
assert s.headers == [
105-
(':method', 'GET'),
106-
(':scheme', 'https'),
107-
(':authority', 'www.google.com'),
108-
(':path', '/'),
109-
('name', 'value'),
104+
assert list(s.headers.items()) == [
105+
(b':method', b'GET'),
106+
(b':scheme', b'https'),
107+
(b':authority', b'www.google.com'),
108+
(b':path', b'/'),
109+
(b'name', b'value'),
110110
]
111111

112112
def test_putheader_replaces_headers(self):
@@ -118,12 +118,12 @@ def test_putheader_replaces_headers(self):
118118
c.putheader('name', 'value2', replace=True)
119119
s = c.recent_stream
120120

121-
assert s.headers == [
122-
(':method', 'GET'),
123-
(':scheme', 'https'),
124-
(':authority', 'www.example.org'),
125-
(':path', '/'),
126-
('name', 'value2'),
121+
assert list(s.headers.items()) == [
122+
(b':method', b'GET'),
123+
(b':scheme', b'https'),
124+
(b':authority', b'www.example.org'),
125+
(b':path', b'/'),
126+
(b'name', b'value2'),
127127
]
128128

129129
def test_endheaders_sends_data(self):
@@ -519,11 +519,11 @@ def test_that_using_proxy_keeps_http_headers_intact(self):
519519
c.request('GET', '/')
520520
s = c.recent_stream
521521

522-
assert s.headers == [
523-
(':method', 'GET'),
524-
(':scheme', 'http'),
525-
(':authority', 'www.google.com'),
526-
(':path', '/'),
522+
assert list(s.headers.items()) == [
523+
(b':method', b'GET'),
524+
(b':scheme', b'http'),
525+
(b':authority', b'www.google.com'),
526+
(b':path', b'/'),
527527
]
528528

529529
class TestServerPush(object):
@@ -694,28 +694,28 @@ def test_streams_have_ids(self):
694694

695695
def test_streams_initially_have_no_headers(self):
696696
s = Stream(1, None, None, None, None, None, None)
697-
assert s.headers == []
697+
assert list(s.headers.items()) == []
698698

699699
def test_streams_can_have_headers(self):
700700
s = Stream(1, None, None, None, None, None, None)
701701
s.add_header("name", "value")
702-
assert s.headers == [("name", "value")]
702+
assert list(s.headers.items()) == [(b"name", b"value")]
703703

704704
def test_streams_can_replace_headers(self):
705705
s = Stream(1, None, None, None, None, None, None)
706706
s.add_header("name", "value")
707707
s.add_header("name", "other_value", replace=True)
708708

709-
assert s.headers == [("name", "other_value")]
709+
assert list(s.headers.items()) == [(b"name", b"other_value")]
710710

711711
def test_streams_can_replace_none_headers(self):
712712
s = Stream(1, None, None, None, None, None, None)
713713
s.add_header("name", "value")
714714
s.add_header("other_name", "other_value", replace=True)
715715

716-
assert s.headers == [
717-
("name", "value"),
718-
("other_name", "other_value")
716+
assert list(s.headers.items()) == [
717+
(b"name", b"value"),
718+
(b"other_name", b"other_value")
719719
]
720720

721721
def test_stream_opening_sends_headers(self):
@@ -1485,7 +1485,17 @@ def test_connection_error_when_send_out_of_range_frame(self):
14851485
class NullEncoder(object):
14861486
@staticmethod
14871487
def encode(headers):
1488-
return '\n'.join("%s%s" % (name, val) for name, val in headers)
1488+
1489+
def to_str(v):
1490+
if is_py2:
1491+
return str(v)
1492+
else:
1493+
if not isinstance(v, str):
1494+
v = str(v, 'utf-8')
1495+
return v
1496+
1497+
return '\n'.join("%s%s" % (to_str(name), to_str(val))
1498+
for name, val in headers)
14891499

14901500
class FixedDecoder(object):
14911501
def __init__(self, result):

0 commit comments

Comments
 (0)