Skip to content

[Bug]: Off-by-one in HPACK dynamic table index calculation breaks HTTP/2 connection reuse #830

@ycastorium

Description

@ycastorium

The HPACK encoder in hackney_hpack.erl has an off-by-one error when converting absolute dynamic table indices to HPACK relative indices. This causes HTTP/2 requests to fail on any connection that reuses an existing HTTP/2 connection with a populated HPACK dynamic table.

The first request on a new connection works fine. The second request fails because the encoder emits incorrect indexed references that point to static table entries instead of dynamic table entries, causing pseudo-headers (:method, :path, etc.) to appear after regular headers in the encoded block.

How to reproduce:

%% Connect to any HTTP/2 server
{ok, Ref} = hackney:connect(hackney_ssl, "httpbin.org", 443, [{pool, false}, {protocols, [http2]}]),

%% First request succeeds (headers encoded as literals)
{ok, 200, _, _} = hackney_conn:request(Ref, <<"GET">>, <<"/">>, [{<<"host">>, <<"httpbin.org">>}], <<>>),

%% Second request fails -- server rejects pseudo-header ordering
{error, _} = hackney_conn:request(Ref, <<"GET">>, <<"/">>, [{<<"host">>, <<"httpbin.org">>}], <<>>).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions