From 55fb979923f9e314074aa4b2ae0de86b8acae087 Mon Sep 17 00:00:00 2001 From: Kadir Can Ozden <101993364+bysiber@users.noreply.github.com> Date: Fri, 20 Feb 2026 18:57:52 +0300 Subject: [PATCH 1/2] Fix perfect match missed for headers with empty values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HeaderTable.search() returns (index, name, value) for perfect matches and (index, name, None) for partial matches. The encoder distinguishes them with `if perfect:`, but this fails when value is b"" because empty bytes are falsy in Python. 46 of 61 static table entries have an empty value (e.g. :authority, accept-charset, accept-language, age, allow, …). When encoding a header that perfectly matches one of these entries, the encoder falls through to the indexed-literal path — using 2+ bytes instead of 1 and unnecessarily adding the entry to the dynamic table. Change the check to `if perfect is not None:` so that b"" is treated as a valid perfect match. --- src/hpack/hpack.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hpack/hpack.py b/src/hpack/hpack.py index 7e33e77..20dce0a 100644 --- a/src/hpack/hpack.py +++ b/src/hpack/hpack.py @@ -313,7 +313,7 @@ def add(self, to_add: tuple[bytes, bytes], sensitive: bool, huffman: bool = Fals # can use the indexed literal. index, name, perfect = match - if perfect: + if perfect is not None: # Indexed representation. encoded = self._encode_indexed(index) else: From 53f60ce372d6914b5f774479f9340942eaf4e83b Mon Sep 17 00:00:00 2001 From: Thomas Kriechbaumer Date: Mon, 6 Apr 2026 11:34:38 +0200 Subject: [PATCH 2/2] Fix perfect match missed for headers with empty values: add test and changelog --- CHANGELOG.rst | 1 + tests/test_hpack.py | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8b4c060..62f593f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -13,6 +13,7 @@ dev - Support for Python 3.14 has been added. - Support for PyPy 3.11 has been added. +- Fixed perfect match missed for headers with empty values **Bugfixes** diff --git a/tests/test_hpack.py b/tests/test_hpack.py index 3864a33..e9c170c 100644 --- a/tests/test_hpack.py +++ b/tests/test_hpack.py @@ -126,6 +126,18 @@ def test_indexed_header_field(self): assert e.encode(header_set, huffman=False) == result assert list(e.header_table.dynamic_entries) == [] + def test_indexed_header_field_empty_value_string(self): + """ + The header field representation uses an indexed header field, from + the static table. + """ + e = Encoder() + header_set = {':authority': ''} + result = b'\x81' + + assert e.encode(header_set, huffman=False) == result + assert list(e.header_table.dynamic_entries) == [] + def test_indexed_header_field_from_static_table(self): e = Encoder() e.header_table_size = 0