Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ Release History
dev
---

**API Changes (Backward Compatible)**

- Setting Identifier are now correctly serialized as 16-bit values, instead of 8-bit.

**API Changes (Backward Incompatible)**

-
Expand Down
7 changes: 5 additions & 2 deletions src/hyperframe/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,8 +457,11 @@ def _body_repr(self) -> str:
return f"settings={self.settings}"

def serialize_body(self) -> bytes:
return b"".join([_STRUCT_HL.pack(setting & 0xFF, value)
for setting, value in self.settings.items()])
return b"".join([_STRUCT_HL.pack(
setting_identifier & 0xFFFF, # Settings identifiers are 16 bits, mask them appropriately, RFC 9113, Section 6.5.1
setting_value & 0xFFFFFFFF, # Settings values are 32 bits, mask them appropriately, RFC 9113, Section 6.5.1
)
for setting_identifier, setting_value in self.settings.items()])

def parse_body(self, data: memoryview) -> None:
if "ACK" in self.flags and len(data) > 0:
Expand Down
23 changes: 23 additions & 0 deletions tests/test_frames.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,29 @@ def test_short_settings_frame_errors(self):
with pytest.raises(InvalidDataError):
decode_frame(self.serialized[:-2])

def test_settings_frame_with_large_setting_ids(self):
f = SettingsFrame()
f.settings[0xFFFE] = 12345
f.settings[0xFFFF] = 54321

s = f.serialize()
new_f = decode_frame(s)

assert new_f.settings[0xFFFE] == 12345
assert new_f.settings[0xFFFF] == 54321

def test_settings_frame_serializes_with_large_setting_ids(self):
f = SettingsFrame()
f.settings[0xFFFE] = 12345
f.settings[0xFFFF] = 54321

s = f.serialize()
assert s == (
b'\x00\x00\x0C\x04\x00\x00\x00\x00\x00' + # Frame header
b'\xFF\xFE\x00\x00\x30\x39' + # Setting ID 0xFFFE
b'\xFF\xFF\x00\x00\xd4\x31' # Setting ID 0xFFFF
)


class TestPushPromiseFrame:
def test_repr(self):
Expand Down
Loading