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

Commit 6149a40

Browse files
committed
Merge pull request #247 from Lukasa/issue/244
Tolerate errors in resetting streams.
2 parents c45ff79 + e1fd712 commit 6149a40

File tree

4 files changed

+41
-3
lines changed

4 files changed

+41
-3
lines changed

HISTORY.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ Release History
44
dev
55
---
66

7+
*Bugfixes*
8+
9+
- Tolerate errors when attempting to send a RST_STREAM frame.
10+
711
0.6.0 (2016-05-06)
812
------------------
913

hyper/http20/connection.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,7 @@ def _recv_cb(self, stream_id=0):
727727
# Ignore this read if some other thread has recently read data from
728728
# from the requested stream.
729729
#
730-
# The lock here looks broad, but is need to ensure correct behavior
730+
# The lock here looks broad, but is needed to ensure correct behavior
731731
# when there are multiple readers of the same stream. It is
732732
# re-acquired in the calls to self._single_read.
733733
#

hyper/http20/stream.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
Each stream is identified by a monotonically increasing integer, assigned to
1414
the stream by the endpoint that initiated the stream.
1515
"""
16+
import h2.exceptions
17+
1618
from ..common.headers import HTTPHeaderMap
1719
from .util import h2_safe_headers
1820
import logging
@@ -275,8 +277,16 @@ def close(self, error_code=None):
275277
"""
276278
# FIXME: I think this is overbroad, but for now it's probably ok.
277279
if not (self.remote_closed and self.local_closed):
278-
self._conn.reset_stream(self.stream_id, error_code or 0)
279-
self._send_cb(self._conn.data_to_send())
280+
try:
281+
self._conn.reset_stream(self.stream_id, error_code or 0)
282+
except h2.exceptions.ProtocolError:
283+
# If for any reason we can't reset the stream, just tolerate
284+
# it.
285+
pass
286+
else:
287+
self._send_cb(
288+
self._conn.data_to_send(), tolerate_peer_gone=True
289+
)
280290
self.remote_closed = True
281291
self.local_closed = True
282292

test/test_hyper.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,29 @@ def test_goaway_frame_invalid_error_code(self):
10671067

10681068
assert str(f.error_code) in err_msg
10691069

1070+
def test_resetting_streams_after_close(self):
1071+
"""
1072+
Attempts to reset streams when the connection is torn down are
1073+
tolerated.
1074+
"""
1075+
f = SettingsFrame(0)
1076+
1077+
c = HTTP20Connection('www.google.com')
1078+
c._sock = DummySocket()
1079+
c._sock.buffer = BytesIO(f.serialize())
1080+
1081+
# Open stream 1.
1082+
c.request('GET', '/')
1083+
1084+
# Swap out the buffer to get a GoAway frame.
1085+
f = GoAwayFrame(0)
1086+
f.error_code = 1
1087+
c._sock.buffer = BytesIO(f.serialize())
1088+
1089+
# "Read" the GoAway
1090+
with pytest.raises(ConnectionError):
1091+
c._single_read()
1092+
10701093

10711094
# Some utility classes for the tests.
10721095
class NullEncoder(object):
@@ -1107,6 +1130,7 @@ def buffer(self):
11071130
@buffer.setter
11081131
def buffer(self, value):
11091132
self._buffer = value
1133+
self._read_counter = 0
11101134

11111135
def advance_buffer(self, amt):
11121136
self._read_counter += amt

0 commit comments

Comments
 (0)