playframework / playframework/cachecontrol
CacheControl does not deal with Vary / secondary keys
Nobody has claimed this yet.
- Dominant language
- Scala
- Stars
- 16
- Forks
- 15
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 24
Description
CacheControl does not have the concept of secondary keys as described in overview of cache operation
If a request target is subject to content negotiation, its cache entry might consist of multiple stored responses, each differentiated by a secondary key for the values of the original request's selecting header fields (Section 4.1).
Secondary keys are calculated from the Vary header as described in Calculating Secondary Keys with Vary.
This is mostly an issue when dealing with resources which use explicit content negotiation, which has failed miserably, but... it is part of the spec.
More details in https://www.smashingmagazine.com/2017/11/understanding-vary-header/
Also see how current browsers handle the fine points of Vary: https://wpt.fyi/results/fetch/http-cache/vary.html?label=stable&aligned
Other hints: https://www.mnot.net/blog/2017/03/16/browser-caching#vary
Discussion of "secondary keys" (a term completely undefined in the RFC itself) https://github.com/tempesta-tech/tempesta/issues/508 -- part of the issue I have with the spec is that it assumes that you are working with a cache which even provides primary and secondary keys. As The Insanity of the Vary Header says:
This isn't really a major problem for developers writing clients and servers, but it's a pain for people trying to write caches. In fact, I haven't found a private cache implementation that actually does this yet.
and
If you think the specification is bad, you should see the implementations.
So even when CacheControl tells you to do the right thing, you're still going to be hosed unless your cache implementation can deal with the ambiguity: the cache entry can be either a single response, or a map of multiple stored responses.
val entry: Entry = cache(primaryCacheKey)
val response: Response = if (entry.containsMultiple) {
entry.response(secondaryKey)
} else {
entry.response
}
Do you understand the Vary HTTP header?
Also see https://github.com/httpwg/http-core/issues/110 and https://github.com/httpwg/http-core/issues/28
https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#Varying_responses
https://dzone.com/articles/getting-the-most-out-of-vary-with-fastly
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the RFC 7234 sections on cache operation and calculating secondary keys, then trace the cache lookup and storage model represented by Entry, primaryCacheKey, and secondaryKey in the issue example. The work is complete when Vary responses can be represented and selected correctly without ambiguity; the issue does not name implementation files or tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- scala
- Domain
- networking
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100