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

Commit a031605

Browse files
committed
Validate size when sending out of range frames
When sending a frame to the server, care must be taken to not exceed the maximum frame size setting. If the size is higher than the defined setting then a ValueError is thrown.
1 parent 4bdd0e3 commit a031605

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed

hyper/http20/connection.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -510,8 +510,12 @@ def _send_cb(self, frame, tolerate_peer_gone=False):
510510

511511
data = frame.serialize()
512512

513-
if frame.body_len > FRAME_MAX_LEN: # pragma: no cover
514-
raise ValueError("Frame size %d is too large" % frame.body_len)
513+
if frame.body_len > self._settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE]:
514+
raise ValueError(
515+
"Frame size %d exceeds maximum frame size setting %d" %
516+
(frame.body_len,
517+
self._settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE])
518+
)
515519

516520
log.info(
517521
"Sending frame %s on stream %d",

test/test_hyper.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,9 +1351,12 @@ def data_callback(frame):
13511351
def test_connection_sends_rst_frame_if_frame_size_too_large(self):
13521352
sock = DummySocket()
13531353
d = DataFrame(1)
1354-
# Create big data frame that exceeds the FRAME_MAX_LEN value in order
1355-
# to trigger the reset frame with error code 6 (FRAME_SIZE_ERROR)
1356-
d.data = b''.join([b"hi there sir" for x in range(40)])
1354+
# Receive oversized frame on the client side.
1355+
# Create huge data frame that exceeds the FRAME_MAX_LEN value in order
1356+
# to trigger the reset frame with error code 6 (FRAME_SIZE_ERROR).
1357+
# FRAME_MAX_LEN is a constant value for the hyper client and cannot
1358+
# be updated as of now.
1359+
d.data = b''.join([b"hi there client" for x in range(40)])
13571360
sock.buffer = BytesIO(d.serialize())
13581361

13591362
frames = []
@@ -1375,7 +1378,7 @@ def send_rst_frame(stream_id, error_code):
13751378
assert f.stream_id == 1
13761379
assert f.error_code == 6 #FRAME_SIZE_ERROR
13771380

1378-
def test_connection_stream_is_removed_on_frame_size_error(self):
1381+
def test_connection_stream_is_removed_when_receiving_out_of_range_frame(self):
13791382
sock = DummySocket()
13801383
d = DataFrame(1)
13811384
d.data = b''.join([b"hi there sir" for x in range(40)])
@@ -1391,6 +1394,20 @@ def test_connection_stream_is_removed_on_frame_size_error(self):
13911394
c._recv_cb()
13921395
assert len(c.streams) == 0
13931396

1397+
def test_connection_error_when_send_out_of_range_frame(self):
1398+
# Send oversized frame to the server side.
1399+
# Create huge data frame that exceeds the intitial FRAME_MAX_LEN setting
1400+
# in order to trigger a value error when sending it.
1401+
# Note that the value of the FRAME_MAX_LEN setting can be updated
1402+
# by the server through a settings frame.
1403+
d = DataFrame(1)
1404+
d.data = b''.join([b"hi there server" for x in range(1500)])
1405+
1406+
c = HTTP20Connection('www.google.com')
1407+
c._sock = DummySocket()
1408+
with pytest.raises(ValueError):
1409+
c._send_cb(d)
1410+
13941411
# Some utility classes for the tests.
13951412
class NullEncoder(object):
13961413
@staticmethod

0 commit comments

Comments
 (0)