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

Commit 25f10db

Browse files
committed
Allow endpoint to update max frame size
If the setting frame contains a new valid max frame size then update hyper's settings. Add tests to confirm that this setting is updated only with values between the accepted range.
1 parent 4f051a4 commit 25f10db

File tree

2 files changed

+66
-2
lines changed

2 files changed

+66
-2
lines changed

hyper/http20/connection.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from ..packages.hyperframe.frame import (
1313
FRAMES, DataFrame, HeadersFrame, PushPromiseFrame, RstStreamFrame,
1414
SettingsFrame, Frame, WindowUpdateFrame, GoAwayFrame, PingFrame,
15-
BlockedFrame, FRAME_MAX_LEN
15+
BlockedFrame, FRAME_MAX_LEN, FRAME_MAX_ALLOWED_LEN
1616
)
1717
from ..packages.hpack.hpack_compat import Encoder, Decoder
1818
from .stream import Stream
@@ -450,6 +450,11 @@ def _update_settings(self, frame):
450450

451451
self._settings[SettingsFrame.INITIAL_WINDOW_SIZE] = newsize
452452

453+
if SettingsFrame.SETTINGS_MAX_FRAME_SIZE in frame.settings:
454+
new_size = frame.settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE]
455+
if new_size > FRAME_MAX_LEN and new_size < FRAME_MAX_ALLOWED_LEN:
456+
self._settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE] = new_size
457+
453458
def _new_stream(self, stream_id=None, local_closed=False):
454459
"""
455460
Returns a new stream object for this connection.

test/test_hyper.py

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from hyper.packages.hyperframe.frame import (
33
Frame, DataFrame, RstStreamFrame, SettingsFrame,
44
PushPromiseFrame, PingFrame, WindowUpdateFrame, HeadersFrame,
5-
ContinuationFrame, BlockedFrame, GoAwayFrame, FRAME_MAX_LEN
5+
ContinuationFrame, BlockedFrame, GoAwayFrame, FRAME_MAX_LEN, FRAME_MAX_ALLOWED_LEN
66
)
77
from hyper.packages.hpack.hpack_compat import Encoder, Decoder
88
from hyper.http20.connection import HTTP20Connection
@@ -246,6 +246,65 @@ def test_connections_increment_send_window_properly(self):
246246

247247
assert c._out_flow_control_window == 65535 + 1000
248248

249+
def test_connections_handle_resizing_max_frame_size_properly(self):
250+
sock = DummySocket()
251+
f = SettingsFrame(0)
252+
f.settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE] = 65536 # 2^16
253+
c = HTTP20Connection('www.google.com')
254+
c._sock = sock
255+
256+
# 'Receive' the SETTINGS frame.
257+
c.receive_frame(f)
258+
259+
# Confirm that the setting is stored and the max frame size increased.
260+
assert c._settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE] == 65536
261+
262+
# Confirm we got a SETTINGS ACK.
263+
f2 = decode_frame(sock.queue[0])
264+
assert isinstance(f2, SettingsFrame)
265+
assert f2.stream_id == 0
266+
assert f2.flags == set(['ACK'])
267+
268+
def test_connections_handle_too_small_max_frame_size_properly(self):
269+
sock = DummySocket()
270+
f = SettingsFrame(0)
271+
f.settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE] = 1024
272+
c = HTTP20Connection('www.google.com')
273+
c._sock = sock
274+
275+
# 'Receive' the SETTINGS frame.
276+
c.receive_frame(f)
277+
278+
# The value advertised by an endpoint MUST be between 2^14 and
279+
# 2^24-1 octets. Confirm that the max frame size did not increase.
280+
assert c._settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE] == FRAME_MAX_LEN
281+
282+
# Confirm we got a SETTINGS ACK.
283+
f2 = decode_frame(sock.queue[0])
284+
assert isinstance(f2, SettingsFrame)
285+
assert f2.stream_id == 0
286+
assert f2.flags == set(['ACK'])
287+
288+
def test_connections_handle_too_big_max_frame_size_properly(self):
289+
sock = DummySocket()
290+
f = SettingsFrame(0)
291+
f.settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE] = 67108864 # 2^26
292+
c = HTTP20Connection('www.google.com')
293+
c._sock = sock
294+
295+
# 'Receive' the SETTINGS frame.
296+
c.receive_frame(f)
297+
298+
# The value advertised by an endpoint MUST be between 2^14 and
299+
# 2^24-1 octets. Confirm that the max frame size did not increase.
300+
assert c._settings[SettingsFrame.SETTINGS_MAX_FRAME_SIZE] == FRAME_MAX_LEN
301+
302+
# Confirm we got a SETTINGS ACK.
303+
f2 = decode_frame(sock.queue[0])
304+
assert isinstance(f2, SettingsFrame)
305+
assert f2.stream_id == 0
306+
assert f2.flags == set(['ACK'])
307+
249308
def test_connections_handle_resizing_header_tables_properly(self):
250309
sock = DummySocket()
251310
f = SettingsFrame(0)

0 commit comments

Comments
 (0)