Compression Dictionary Transport
Extracted elements (30)
The 'Available-Dictionary' header carries only a single hash for the best matching dictionary rather than advertising all available dictionaries. This limits request header overhead and simplifies server-side selection logic while preserving the client's ability to choose the most relevant match.
The DCZ header is designed as a Zstandard skippable frame (magic 0x184D2A5E, 32-byte payload length) so that existing Zstandard decoders that do not understand the dictionary extension can parse and skip it without error, ensuring backward compatibility with the deployed Zstandard ecosystem.
The DCZ window size floor of max(8 MB, 1.25× dictionary size) is chosen so that the full dictionary remains available during compression and decompression for resources that have grown by up to 25% between releases, while still giving clients control over their maximum memory allocation for a given response.
The match URL Pattern operates on the percent-encoded version of the URL path as per RFC 3986, meaning non-ASCII characters must be percent-encoded in the pattern (e.g., 'http://www.example.com/düsseldorf' is matched as '/d%C3%BCsseldorf'). Regular expressions are explicitly disallowed in match patterns.
An empty list for 'match-dest' MUST match all destinations. Clients that do not support request destinations MUST treat 'match-dest' as an empty list and match all destinations.
Clients announcing support for 'dcz' MUST be able to decompress resources with a window size of at least 8 MB or 1.25 times the size of the dictionary, whichever is greater, up to a maximum of 128 MB. An implementation MAY treat a window size exceeding the limit as a decoding error.
Clients that announce support for 'dcb' content encoding MUST be able to decompress resources compressed with a window size of up to 16 MB.
Compression dictionary transport MUST only be used in secure contexts (HTTPS) to minimize the risk of network intermediaries (proxies, firewalls, IDS) incorrectly processing dictionary-compressed responses.
For clients such as browsers that protect against payload readability and user tracking, dictionary compression MUST only be used when both the dictionary and the compressed response are fully readable by the client — either same-origin or cross-origin passing a CORS check.
If a client receives a dictionary with a 'type' value it does not understand, it MUST NOT use the dictionary. The 'type' value defaults to 'raw', representing an unformatted blob of bytes.
If any security mitigation check fails, the client MUST drop the response and return an error. The URL Pattern for dictionary matching is guaranteed to be for the same origin as the dictionary, preventing cross-origin dictionary influence.
If the dictionary-compressed response is cacheable, it MUST include a 'Vary' header (e.g., 'Vary: accept-encoding, available-dictionary') to prevent caches from serving dictionary-compressed resources to clients that do not support them or that have different dictionaries.
If the 'id' value is present and has nonzero length, the client MUST echo it in a 'Dictionary-ID' request header when sending 'Available-Dictionary' for the same dictionary. The server identifier MUST NOT be relied upon to guarantee dictionary contents; the dictionary hash MUST be validated before use.
The 'match' value MUST be included in the 'Use-As-Dictionary' response header for the dictionary to be considered valid. The URL Pattern MUST NOT use regular expressions and MUST be for the same origin as the dictionary.
To be considered as a match, the dictionary resource MUST be either fresh (per HTTP caching) or allowed to be served stale.
When a client does not have a stored dictionary matching the request or chooses not to use one, the client MUST NOT send its dictionary-aware content encodings (dcb, dcz) in the 'Accept-Encoding' request header.
When multiple dictionaries match a given request URL, the client MUST select a single dictionary using the following precedence: (1) a dictionary that specifies and matches 'match-dest' beats one that does not; (2) the longest 'match' wins among ties; (3) the most recently fetched dictionary wins among remaining ties.
Because dictionaries are advertised by their SHA-256 hash, a server can use a unique dictionary per user as a tracking cookie. Clients MUST treat dictionaries with the same partitioning and clearing policies as cookies, including clearing dictionaries whenever cookies are cleared.
The 'Available-Dictionary' request header is a Structured Field Byte Sequence containing the SHA-256 hash of a single available dictionary. The client MUST only send a single 'Available-Dictionary' header with a single hash value for the best available match.
The 'compression-dictionary' link relation type indicates that fetching and caching the specified resource is likely to be beneficial for future requests. The linked resource must include a 'Use-As-Dictionary' response header and a caching header to be usable as a compression dictionary.
The 'Dictionary-ID' request header is a Structured Field String of up to 1024 characters that MUST be identical to the server-provided 'id' from 'Use-As-Dictionary'. It is sent alongside 'Available-Dictionary' to allow servers to efficiently identify which dictionary the client is advertising.
The 'Use-As-Dictionary' response header is a Structured Field Dictionary with four values: 'match' (required URL Pattern string), 'match-dest' (optional Inner List of destination strings), 'id' (optional opaque server identifier string up to 1024 characters), and 'type' (optional Token defaulting to 'raw'). It advertises that the response body may be used as a compression dictionary for future matching requests.
IANA has added the 'compression-dictionary' link relation type to the 'Link Relation Types' registry, referring to a compression dictionary used for content encoding (Section 3).
IANA has added three permanent entries to the 'HTTP Field Name Registry': 'Use-As-Dictionary' (Section 2.1), 'Available-Dictionary' (Section 2.2), and 'Dictionary-ID' (Section 2.3).
IANA has added two entries to the 'HTTP Content Coding Registry': 'dcb' (Dictionary-Compressed Brotli, Section 4) and 'dcz' (Dictionary-Compressed Zstandard, Section 5).
A server-side timing attack is possible if an attacker can control parts of the dictionary or content across multiple requests with varying content, using response size or processing time to infer secrets. Servers should mitigate by preventing multiple dictionaries per content, disabling compression when content comes from uncontrolled sources, and checking 'Sec-Fetch-Site'/'Sec-Fetch-Mode' headers to detect cross-origin requests.
Compression attacks (analogous to CRIME/BREACH) apply: compressing data from mixed public and private sources with a shared dictionary leaks information about the private data. Both the dictionary and the compressed data can reveal information about each other when an adversary can control parts of the compressed input and observe compressed size.
The dictionary must be treated with the same security precautions as the response content, because a change to the dictionary can change the decompressed content. Dictionary integrity is validated with SHA-256; the same origin constraint means collision resistance is not strictly necessary but the header can be extended to specify a different algorithm if SHA-256 is weakened.
Dictionary-Compressed Brotli ('dcb') uses a 36-byte fixed header: Magic_Number is 4 bytes (0xff, 0x44, 0x43, 0x42) followed by SHA_256_Hash of 32 bytes. The header precedes a Shared Brotli stream that uses the dictionary as a prefix dictionary with a compression window of at most 16 MB.
Dictionary-Compressed Zstandard ('dcz') uses a 40-byte fixed header: Magic_Number is 8 bytes (0x5e, 0x2a, 0x4d, 0x18, 0x20, 0x00, 0x00, 0x00) followed by SHA_256_Hash of 32 bytes. The header is a Zstandard skippable frame (little-endian 0x184D2A5E, length 0x00000020) compatible with existing Zstandard decoders.