- From: James M Snell <jasnell@gmail.com>
- Date: Fri, 18 Jan 2013 11:58:56 -0800
- To: "ietf-http-wg@w3.org" <ietf-http-wg@w3.org>
- Message-ID: <CABP7Rbep0CjJV5OTc9-toJLbEHwc7g=by-3JUTtuoBWYu=L+eA@mail.gmail.com>
Just one more for the day... Looking at Cache-Control.. Currently the cache-control header consists of a list of named directives that optionally have associated values. The format is extensible which is great, but makes things a bit more difficult to optimize. Let's look at a few random examples... Cache-Control: public (6 bytes) Cache-Control: public, max-age=1600 (21 bytes) Cache-Control: no-store, no-transform, must-revalidate (39 bytes) Let's see if we can do better. First off, let's assume that Cache-Control on requests can have a different encoding than Cache-Control on responses. For requests, let's make it: +----------+----------+---------------------+ | no-cache | no-store | no-transform | +----------+-----+----+---------+-----------+ | only-if-cached |xxxx| max-age | max-stale | +-----------+----+----+---------+-----------+ | min-fresh | num-ext | repeating ext block | +-----------+-----+---+---------+-----------+ no-cache = 1 bit no-store = 1 bit no-transform = 1 bit only-of-cached = 1 bit xxx = 4 reserved bits max-age = uintvar max-stale = uintvar min-fresh = uintvar num-ext = 1 byte repeating ext block = +---------------------------+ |TYP|XXXXXX|len(key)|key|val| +---------------------------+ TYP = 2 bit type code 00 = Boolean, no val 01 = Numeric, val is uintvar 10 = Text, val is encoded text 11 = Reserved XXXXXX = Reserved Bits if TYP is 00, then val is omitted. The idea is that this is a boolean flag, like no-cache, no-store, etc. The key identifies the flag. Key is a text label. if TYP is 01, then val is uintvar. if TYP is 02, then val is 2-byte length followed by encoded text So if we look at examples, then, Cache-Control: no-cache encodes as five-bytes Cache-Control: only-if-cached, max-age=1600, encodes as seven-bytes Looking at the Cache-Control header for Responses we can do: +--------+---------+----------+-------------+ | public | private | no-cache | no-transform| +--------+-+-------+----------+-----------+-+ | no-store | must-revalidate |proxy-reval|X| +----------+----------+-------+-----------+-+ | max-age | s-maxage | num-no-cache-headers| +----------+-------+--+---------------------+ | no-cache-headers | num-private-headers | +------------------+------------------------+ |private-headers|num-ext|repeating ext block| +------------------+------------------------+ Same idea, public = 1 bit private = 1 bit no-cache = 1 bit no-transform = 1 bit no-store = 1 bit must-revalidate = 1 bit proxy-reval = 1 bit X = reserved max-age = uintvar s-maxage = uintvar num-no-cache-headers = 1-byte no-cache-headers = null-byte separated list of header names num-private-headers = 1-byte private-headers = null-byte separated list of header names Examples... Cache-Control: public (encodes as 6 bytes) Cache-Control: public, max-age=1600 (encodes as 6 bytes, saving 17 bytes) Cache-Control: no-store, no-transform, must-revalidate (encodes as 6 bytes, saving 33 bytes) So looking at these examples, it is definitely possible to save a lot of space but at the cost of quite a bit of encoding-complexity. I'm sure we could possibly do better but this provides a good starting point, and, it's bidirectionally compatible with 1.1. Whether or not it's worth the effort is a different question entirely. - James
Received on Friday, 18 January 2013 19:59:44 UTC