From b4667832448f0a709d2494316497c6dfe505e2c6 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 a017caa..53ef708 100644 --- a/src/hpack/hpack.py +++ b/src/hpack/hpack.py @@ -320,7 +320,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 038618fd72d260bf16db0aeb51f1c4c0b6379b4a 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 ddb58c6..df2fb4b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -17,6 +17,7 @@ dev **Bugfixes** - Headers marked as `sensitive` will no longer log their value at DEBUG level. Instead a placeholder value of `SENSITIVE_REDACTED` is logged. +- Fixed perfect match missed for headers with empty values. 4.1.0 (2025-01-22) ------------------ 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