ninenines / cowlib

Support library for manipulating Web protocols.
ISC License
281 stars 172 forks source link

Add support of no/never indexing for http/2 hpack header encoding #124

Open xcwan opened 2 years ago

xcwan commented 2 years ago

Hi,

Is there any update of adding support of no/never indexing for http/2 hpack header encoding?

https://github.com/ninenines/cowlib/blob/0f5c2f8922c89c58f51696cce690245cbdc5f327/src/cow_hpack.erl#L544

Reference https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-header-compression 6.2.2. Literal Header Field without Indexing . . . . . . . . 16 6.2.3. Literal Header Field never Indexed . . . . . . . . . 17

Thanks!

essen commented 2 years ago

This comment refers to the ability to not index specific header fields. There is no plan to support this for the time being. I am not sure how it would look like right now (probably some kind of blacklist for "never indexed", not sure there is a use case for exposing "no indexing").

xcwan commented 2 years ago

Hi essen,

Thanks for your answer!

In some cases, the ":path" header is unique in each request, so it is not necessary to be added into dynamic table. And long ":path" header will cost too much space of the table, (for example up to 200+ octets in the 4096-octet table only for one ":path" header), and it will easily be evicted in a short time.

Another case is that the "content-length" or timestamp-like header may be different in each request, it is also not necessary to be added into dynamic table.

Those cases require "Literal Header Field without Indexing" implementation, which may need additional "WithoutIndexing" flag/argument to encode function to control the encoding with 4 bit prefix 0x0, and not add the entry to the table after encoding.

":path" header encoding prefix with index is 0x44 ":path" header encoding prefix without index is 0x04

The "Literal Header Field never Indexed" is for anti CRIME attack, as per spec. The encoding is almost the same as "without indexing".

":path" header encoding prefix never indexed is 0x14

The "blacklist" is also a good idea, but it requires an additional search in each encoding.

Thanks!

essen commented 2 years ago

Perhaps Cowlib can come with a set of headers that it will not index like those you cited. This would be workable without having to do breaking changes. This could be done via options, perhaps with a default function for common headers and the ability to define a custom function that would tells cow_hpack whether the header must be indexed, or not, or never.

On the other hand, for the parsing part, we currently cannot inform the user that some headers should never be indexed. So that part will need a breaking change (or at least an opt-in) to return the list of never indexed headers.