If anyone cares, here's how we do keys and vary in our cache: On store:
Generate key: using url and r->args (we can ignore r->args per server, if needed) (http://www.domain.com/index.html?you=me) If(vary) { store the following info in meta file: cache_version_t - ala disk_cache (ours includes expire time) length of key (apr_size_t) including \0 key with \0 length of "array" (apr_size_t) a \0 delimited array of Vary headers regenerate key (basically the original key + vary info: http://www.domain.com/index.html?you=meuser-agentmozillaaccept-encodinggzip ) } Store key in meta file. a normal meta file has this format: cache_version_t (ours includes expire time) length of key (apr_size_t) including \0 key with \0 length of "table" (apr_size_t) a \0 delimited table (key\0value\0key\0value\0....) of response headers Note: the reason we use \0 delimited arrays/tables is we read the entire metafile info into memory on serving and then just apr_table_setn on the values. In theory we could mmap the meta files, but we actually found that to be slower. On serving: Generate key: using url and r->args (we can ignore r->args per server, if needed) (http://www.domain.com/index.html?you=me) Open metafile If(vary) { thaw vary array generate new key (vary values may be overridden by env) open new metafile } Thaw headers, etc. So, we only store the headers that we use in vary key calculation. On my TODO list is to make key generation a hook bcs we have apps that would benefit from that. Of course, we have only one provider (disk) and ignore a lot of RFC stuff (although we have made most of that configurable), but our key/vary handling is pretty fast (I spent a lot of time with profilers when writing it). I'm still working on my side to allow us to actually release the code. -- Brian Akins Chief Operations Engineer Turner Digital Media Technologies