Browse Source

Assume headers using pre-check are meaningless

master
Kornel Lesiński 8 years ago
parent
commit
97c4c4bcea
  1. 2
      README.md
  2. 10
      index.js
  3. 14
      test/responsetest.js

2
README.md

@ -52,6 +52,8 @@ If `options.shared` is true (default), then response is evaluated from perspecti
`options.cacheHeuristic` is a fraction of response's age that is used as a fallback cache duration. The default is 0.1 (10%), e.g. if a file hasn't been modified for 100 days, it'll be cached for 100*0.1 = 10 days.
If `options.ignoreCargoCult` is true, common anti-cache directives will be completely ignored if the `pre-check` and `post-check` directives are present. These two useless directives are most commonly found in bad StackOverflow answers and PHP's "session limiter" defaults.
### `storable()`
Returns `true` if the response can be stored in a cache. If it's `false` then you MUST NOT store either the request or the response.

10
index.js

@ -23,7 +23,7 @@ function parseCacheControl(header) {
}
module.exports = class CachePolicy {
constructor(req, res, {shared, cacheHeuristic, _fromObject} = {}) {
constructor(req, res, {shared, cacheHeuristic, ignoreCargoCult, _fromObject} = {}) {
if (_fromObject) {
this._fromObject(_fromObject);
return;
@ -50,6 +50,14 @@ module.exports = class CachePolicy {
this._reqHeaders = res.headers.vary ? req.headers : null; // Don't keep all request headers if they won't be used
this._reqcc = parseCacheControl(req.headers['cache-control']);
// Assume that if someone uses legacy, non-standard uncecessary options they don't understand caching,
// so there's no point stricly adhering to the blindly copy&pasted directives.
if (ignoreCargoCult && "pre-check" in this._rescc && "post-check" in this._rescc) {
delete this._rescc['no-cache'];
delete this._rescc['no-store'];
delete this._rescc['must-revalidate'];
}
// When the Cache-Control header field is not present in a request, caches MUST consider the no-cache request pragma-directive
// as having the same effect as if "Cache-Control: no-cache" were present (see Section 5.2.1).
if (!res.headers['cache-control'] && /no-cache/.test(res.headers.pragma)) {

14
test/responsetest.js

@ -34,6 +34,20 @@ describe('Response headers', function() {
assert.equal(cache.maxAge(), 678);
});
it('pre-check tolerated', function() {
const cache = new CachePolicy(req, {headers:{'cache-control': 'pre-check=0, post-check=0, no-store, no-cache, max-age=100'}});
assert(cache.stale());
assert(!cache.storable());
assert.equal(cache.maxAge(), 0);
});
it('pre-check poison', function() {
const cache = new CachePolicy(req, {headers:{'cache-control': 'pre-check=0, post-check=0, no-cache, no-store, max-age=100'}}, {ignoreCargoCult:true});
assert(!cache.stale());
assert(cache.storable());
assert.equal(cache.maxAge(), 100);
});
it('cache with expires', function() {
const cache = new CachePolicy(req, {headers:{
'date': new Date().toGMTString(),

Loading…
Cancel
Save