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

Commit e6c47c5

Browse files
committed
Remove all headers referred to by 'Connection'
1 parent ab37185 commit e6c47c5

File tree

5 files changed

+54
-25
lines changed

5 files changed

+54
-25
lines changed

HISTORY.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
Release History
22
===============
33

4+
Upcoming
5+
--------
6+
7+
*Minor Changes*
8+
9+
- We not only remove the Connection header but all headers it refers to.
10+
411
0.2.0 (2015-02-07)
512
------------------
613

hyper/http20/connection.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -277,14 +277,6 @@ def putheader(self, header, argument, stream_id=None):
277277
:returns: Nothing.
278278
"""
279279
stream = self._get_stream(stream_id)
280-
281-
# Initially, strip the Connection header. Note that we do this after
282-
# the call to `_get_stream` to ensure that we don't accidentally hide
283-
# bugs just because the user sent a connection header.
284-
if header.lower() == 'connection':
285-
log.debug('Ignoring connection header with value %s', argument)
286-
return
287-
288280
stream.add_header(header, argument)
289281

290282
return

hyper/http20/stream.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
FRAME_MAX_LEN, FRAMES, HeadersFrame, DataFrame, PushPromiseFrame,
1919
WindowUpdateFrame, ContinuationFrame, BlockedFrame
2020
)
21-
from .util import get_from_key_value_set
21+
from .util import get_from_key_value_set, h2_safe_headers
2222
import collections
2323
import logging
2424
import zlib
@@ -250,8 +250,10 @@ def open(self, end):
250250
The `end` flag controls whether this will be the end of the stream, or
251251
whether data will follow.
252252
"""
253+
# Strip any headers invalid in H2.
254+
headers = h2_safe_headers(self.headers)
253255
# Encode the headers.
254-
encoded_headers = self._encoder.encode(self.headers)
256+
encoded_headers = self._encoder.encode(headers)
255257

256258
# It's possible that there is a substantial amount of data here. The
257259
# data needs to go into one HEADERS frame, followed by a number of

hyper/http20/util.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,17 @@ def split_repeated_headers(kvset):
7474
headers[key] = value.split(b'\x00')
7575

7676
return dict(headers)
77+
78+
79+
def h2_safe_headers(headers):
80+
"""
81+
This method takes a set of headers that are provided by the user and
82+
transforms them into a form that is safe for emitting over HTTP/2.
83+
84+
Currently, this strips the Connection header and any header it refers to.
85+
"""
86+
stripped = {i.lower().strip() for k, v in headers if k == 'connection'
87+
for i in v.split(',')}
88+
stripped.add('connection')
89+
90+
return [header for header in headers if header[0] not in stripped]

test/test_hyper.py

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
HPACKDecodingError, HPACKEncodingError, ProtocolError
1717
)
1818
from hyper.http20.window import FlowControlManager
19-
from hyper.http20.util import combine_repeated_headers, split_repeated_headers
19+
from hyper.http20.util import (
20+
combine_repeated_headers, split_repeated_headers, h2_safe_headers
21+
)
2022
from hyper.compat import zlib_compressobj
2123
from hyper.contrib import HTTP20Adapter
2224
import errno
@@ -1011,20 +1013,6 @@ def test_putheader_puts_headers(self):
10111013
('name', 'value'),
10121014
]
10131015

1014-
def test_putheader_ignores_connection(self):
1015-
c = HTTP20Connection("www.google.com")
1016-
1017-
c.putrequest('GET', '/')
1018-
c.putheader('Connection', 'keep-alive')
1019-
s = c.recent_stream
1020-
1021-
assert s.headers == [
1022-
(':method', 'GET'),
1023-
(':scheme', 'https'),
1024-
(':authority', 'www.google.com'),
1025-
(':path', '/'),
1026-
]
1027-
10281016
def test_endheaders_sends_data(self):
10291017
frames = []
10301018

@@ -2048,6 +2036,32 @@ def test_nghttp2_installs_correctly(self):
20482036

20492037
assert True
20502038

2039+
def test_stripping_connection_header(self):
2040+
headers = [('one', 'two'), ('connection', 'close')]
2041+
stripped = [('one', 'two')]
2042+
2043+
assert h2_safe_headers(headers) == stripped
2044+
2045+
def test_stripping_related_headers(self):
2046+
headers = [
2047+
('one', 'two'), ('three', 'four'), ('five', 'six'),
2048+
('connection', 'close, three, five')
2049+
]
2050+
stripped = [('one', 'two')]
2051+
2052+
assert h2_safe_headers(headers) == stripped
2053+
2054+
def test_stripping_multiple_connection_headers(self):
2055+
headers = [
2056+
('one', 'two'), ('three', 'four'), ('five', 'six'),
2057+
('connection', 'close'),
2058+
('connection', 'three, five')
2059+
]
2060+
stripped = [('one', 'two')]
2061+
2062+
assert h2_safe_headers(headers) == stripped
2063+
2064+
20512065
# Some utility classes for the tests.
20522066
class NullEncoder(object):
20532067
@staticmethod

0 commit comments

Comments
 (0)