HPACK Implementation for Erlang
This implementation was designed for use by Chatterbox, but could be used by any HTTP/2 implementation (or, if something other than HTTP/2 has need for HPACK, this would work as well)
- Use by other projects
- A separate RFC seemed like a really clear abstraction
- Indexed Header Field Representation
- Literal Header Field Representation
- Dynamic Table Size Update
An HTTP/2 implementation should be responsible for anything you need to do in order to read a compressed header block from various PUSH_PROMISE, HEADERS, and/or CONTINUATION frames. Once you have a complete block, you can use this library to turn it into something you can use for fulfilling HTTP requests
Encoding Contexts and Decoding Contexts are now the same type. You can
create new one with hpack:new_context()
or pass an argument which is
an integer of byte size provided by HTTP/2's HEADER_TABLE_SIZE
setting.
If HTTP/2 settings get renegotiated, you can pass that information
along by calling hpack:new_max_table_size/2
, like this:
NewContext = hpack:new_max_table_size(NewSize, OldContext),
Decode a headers binary with hpack:decode/2
. It's your job to
assemble the binary if it's coming from multiple HTTP/2 frames.
{Headers, NewContext} = hpack:decode(Binary, OldContext),
Headers is of type [{binary(), binary()}]
Encoding headers works the same way, only a [{binary(), binary()}]
goes in, and a binary()
comes out.
{Bin, NewContext} = hpack:encode(Headers, OldContext),
Here's how to do the whole thing!
DecodeContext1 = hpack:new_context(), %% Server context
EncodeContext1 = hpack:new_context(), %% client context
ClientRequestHeaders = [
{<<":method">>, <<"GET">>},
{<<":path">>, <<"/">>},
{<<"X-Whatev">>, <<"commands">>}
],
%% Client operation
{RequestHeadersBin, EncodeContext2} = hpack:encode(
ClientRequestHeaders,
EncodeContext1),
%% Server operation, after receiving RequestHeadersBin
{ServerRequestHeaders, DecodeContext2} = hpack:decode(
RequestHeadersBin,
DecodeContext1),
%% Note the following truths:
ClientRequestHeaders = ServerRequestHeaders,
EncodeContext1 = DecodeContext1,
EncodeContext2 = DecodeContext2.
The whole reason hpack works is that the client and server both keep their contexts in sync with each other.
** Note: I used the terms client
and server
here, but it could as
easily be sender
and receiver
if you're a proxy