http-cache-semantics
Advanced tools
Comparing version 3.6.1 to 3.7.0
16
index.js
@@ -43,3 +43,3 @@ 'use strict'; | ||
module.exports = class CachePolicy { | ||
constructor(req, res, {shared, cacheHeuristic, ignoreCargoCult, _fromObject} = {}) { | ||
constructor(req, res, {shared, cacheHeuristic, immutableMinTimeToLive, ignoreCargoCult, _fromObject} = {}) { | ||
if (_fromObject) { | ||
@@ -58,2 +58,3 @@ this._fromObject(_fromObject); | ||
this._cacheHeuristic = undefined !== cacheHeuristic ? cacheHeuristic : 0.1; // 10% matches IE | ||
this._immutableMinTtl = undefined !== immutableMinTimeToLive ? immutableMinTimeToLive : 24*3600*1000; | ||
@@ -271,3 +272,3 @@ this._status = 'status' in res ? res.status : 200; | ||
// so this implementation requires explicit opt-in via public header | ||
if (this._isShared && (this._resHeaders['set-cookie'] && !this._rescc.public)) { | ||
if (this._isShared && (this._resHeaders['set-cookie'] && !this._rescc.public && !this._rescc.immutable)) { | ||
return 0; | ||
@@ -295,2 +296,4 @@ } | ||
const defaultMinTtl = this._rescc.immutable ? this._immutableMinTtl : 0; | ||
const dateValue = this.date(); | ||
@@ -303,3 +306,3 @@ if (this._resHeaders.expires) { | ||
} | ||
return (expires - dateValue)/1000; | ||
return Math.max(defaultMinTtl, (expires - dateValue)/1000); | ||
} | ||
@@ -310,6 +313,7 @@ | ||
if (isFinite(lastModified) && dateValue > lastModified) { | ||
return (dateValue - lastModified)/1000 * this._cacheHeuristic; | ||
return Math.max(defaultMinTtl, (dateValue - lastModified)/1000 * this._cacheHeuristic); | ||
} | ||
} | ||
return 0; | ||
return defaultMinTtl; | ||
} | ||
@@ -336,2 +340,3 @@ | ||
this._cacheHeuristic = obj.ch; | ||
this._immutableMinTtl = obj.imm !== undefined ? obj.imm : 24*3600*1000; | ||
this._status = obj.st; | ||
@@ -354,2 +359,3 @@ this._resHeaders = obj.resh; | ||
ch: this._cacheHeuristic, | ||
imm: this._immutableMinTtl, | ||
st: this._status, | ||
@@ -356,0 +362,0 @@ resh: this._resHeaders, |
{ | ||
"name": "http-cache-semantics", | ||
"version": "3.6.1", | ||
"version": "3.7.0", | ||
"description": "Parses Cache-Control and other headers. Helps building correct HTTP caches and proxies", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -62,2 +62,3 @@ # Can I cache this? | ||
cacheHeuristic: 0.1, | ||
immutableMinTimeToLive: 24*3600*1000, // 24h | ||
ignoreCargoCult: false, | ||
@@ -71,2 +72,4 @@ }; | ||
`options.immutableMinTimeToLive` is a number of milliseconds to assume as the default time to cache responses with `Cache-Control: immutable`. Note that [per RFC](http://httpwg.org/http-extensions/immutable.html) these can become stale, so `max-age` still overrides the default. | ||
If `options.ignoreCargoCult` is true, common anti-cache directives will be completely ignored if the non-standard `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. | ||
@@ -73,0 +76,0 @@ |
@@ -161,2 +161,34 @@ 'use strict'; | ||
it('immutable simple hit', function() { | ||
const cache = new CachePolicy(req, {headers:{'cache-control': 'immutable, max-age=999999'}}); | ||
assert(!cache.stale()); | ||
assert.equal(cache.maxAge(), 999999); | ||
}); | ||
it('immutable can expire', function() { | ||
const cache = new CachePolicy(req, {headers:{'cache-control': 'immutable, max-age=0'}}); | ||
assert(cache.stale()); | ||
assert.equal(cache.maxAge(), 0); | ||
}); | ||
it('cache immutable files', function() { | ||
const cache = new CachePolicy(req, {headers:{ | ||
'date': new Date().toGMTString(), | ||
'cache-control':'immutable', | ||
'last-modified': new Date().toGMTString(), | ||
}}); | ||
assert(!cache.stale()); | ||
assert(cache.maxAge() > 100); | ||
}); | ||
it('immutable can be off', function() { | ||
const cache = new CachePolicy(req, {headers:{ | ||
'date': new Date().toGMTString(), | ||
'cache-control':'immutable', | ||
'last-modified': new Date().toGMTString(), | ||
}}, {immutableMinTimeToLive: 0}); | ||
assert(cache.stale()); | ||
assert.equal(cache.maxAge(), 0); | ||
}); | ||
it('pragma: no-cache', function() { | ||
@@ -205,2 +237,12 @@ const cache = new CachePolicy(req, {headers:{ | ||
it('do share cookies if immutable', function() { | ||
const cookieHeader = { | ||
'set-cookie': 'foo=bar', | ||
'cache-control': 'immutable, max-age=99', | ||
}; | ||
const proxyCache = new CachePolicy(req, {headers:cookieHeader}, {shared:true}); | ||
assert(!proxyCache.stale()); | ||
assert.equal(99, proxyCache.maxAge()); | ||
}); | ||
it('cache explicitly public cookie', function() { | ||
@@ -207,0 +249,0 @@ const cookieHeader = { |
70213
1342
174