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

Commit

Permalink
Merge pull request #247 from Lukasa/issue/244
Browse files Browse the repository at this point in the history
Tolerate errors in resetting streams.
  • Loading branch information
Lukasa committed May 29, 2016
2 parents c45ff79 + e1fd712 commit 6149a40
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 3 deletions.
4 changes: 4 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ Release History
dev
---

*Bugfixes*

- Tolerate errors when attempting to send a RST_STREAM frame.

0.6.0 (2016-05-06)
------------------

Expand Down
2 changes: 1 addition & 1 deletion hyper/http20/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ def _recv_cb(self, stream_id=0):
# Ignore this read if some other thread has recently read data from
# from the requested stream.
#
# The lock here looks broad, but is need to ensure correct behavior
# The lock here looks broad, but is needed to ensure correct behavior
# when there are multiple readers of the same stream. It is
# re-acquired in the calls to self._single_read.
#
Expand Down
14 changes: 12 additions & 2 deletions hyper/http20/stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
Each stream is identified by a monotonically increasing integer, assigned to
the stream by the endpoint that initiated the stream.
"""
import h2.exceptions

from ..common.headers import HTTPHeaderMap
from .util import h2_safe_headers
import logging
Expand Down Expand Up @@ -275,8 +277,16 @@ def close(self, error_code=None):
"""
# FIXME: I think this is overbroad, but for now it's probably ok.
if not (self.remote_closed and self.local_closed):
self._conn.reset_stream(self.stream_id, error_code or 0)
self._send_cb(self._conn.data_to_send())
try:
self._conn.reset_stream(self.stream_id, error_code or 0)
except h2.exceptions.ProtocolError:
# If for any reason we can't reset the stream, just tolerate
# it.
pass
else:
self._send_cb(
self._conn.data_to_send(), tolerate_peer_gone=True
)
self.remote_closed = True
self.local_closed = True

Expand Down
24 changes: 24 additions & 0 deletions test/test_hyper.py
Original file line number Diff line number Diff line change
Expand Up @@ -1067,6 +1067,29 @@ def test_goaway_frame_invalid_error_code(self):

assert str(f.error_code) in err_msg

def test_resetting_streams_after_close(self):
"""
Attempts to reset streams when the connection is torn down are
tolerated.
"""
f = SettingsFrame(0)

c = HTTP20Connection('www.google.com')
c._sock = DummySocket()
c._sock.buffer = BytesIO(f.serialize())

# Open stream 1.
c.request('GET', '/')

# Swap out the buffer to get a GoAway frame.
f = GoAwayFrame(0)
f.error_code = 1
c._sock.buffer = BytesIO(f.serialize())

# "Read" the GoAway
with pytest.raises(ConnectionError):
c._single_read()


# Some utility classes for the tests.
class NullEncoder(object):
Expand Down Expand Up @@ -1107,6 +1130,7 @@ def buffer(self):
@buffer.setter
def buffer(self, value):
self._buffer = value
self._read_counter = 0

def advance_buffer(self, amt):
self._read_counter += amt
Expand Down

0 comments on commit 6149a40

Please sign in to comment.