Skip to content

Commit db6f0c0

Browse files
committed
Limit amount of _closed_streams
1 parent 1df6a15 commit db6f0c0

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

h2/connection.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
from .frame_buffer import FrameBuffer
3434
from .settings import Settings, SettingCodes
3535
from .stream import H2Stream, StreamClosedBy
36-
from .utilities import guard_increment_window
36+
from .utilities import SizeLimitDict, guard_increment_window
3737
from .windows import WindowManager
3838

3939

@@ -281,6 +281,9 @@ class H2Connection(object):
281281
# The initial default value of SETTINGS_MAX_HEADER_LIST_SIZE.
282282
DEFAULT_MAX_HEADER_LIST_SIZE = 2**16
283283

284+
# Keep in memory limited amount of results for streams closes
285+
MAX_CLOSED_STREAMS = 2**31
286+
284287
def __init__(self, config=None):
285288
self.state_machine = H2ConnectionStateMachine()
286289
self.streams = {}
@@ -355,7 +358,9 @@ def __init__(self, config=None):
355358
# Also used to determine whether we should consider a frame received
356359
# while a stream is closed as either a stream error or a connection
357360
# error.
358-
self._closed_streams = {}
361+
self._closed_streams = SizeLimitDict(
362+
size_limit=self.MAX_CLOSED_STREAMS
363+
)
359364

360365
# The flow control window manager for the connection.
361366
self._inbound_flow_control_window_manager = WindowManager(

h2/utilities.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,3 +617,22 @@ def validate_outbound_headers(headers, hdr_validation_flags):
617617
headers = _check_path_header(headers, hdr_validation_flags)
618618

619619
return headers
620+
621+
622+
class SizeLimitDict(collections.OrderedDict):
623+
624+
def __init__(self, *args, **kwargs):
625+
self._size_limit = kwargs.pop("size_limit", None)
626+
super(SizeLimitDict, self).__init__(*args, **kwargs)
627+
628+
self._check_size_limit()
629+
630+
def __setitem__(self, key, value):
631+
super(SizeLimitDict, self).__setitem__(key, value)
632+
633+
self._check_size_limit()
634+
635+
def _check_size_limit(self):
636+
if self._size_limit is not None:
637+
while len(self) > self._size_limit:
638+
self.popitem(last=False)

0 commit comments

Comments
 (0)