Add ability to pass stale-while-revalidate option to cache control

closes TryGhost/Team#2094
This value can be used for non-crucial data with a `public` option. For example: `public, max-age=1, stale-while-revalidate=9`.
The idea behind this option is that the browser would cache the value for the number of seconds in `max-age` and would use it for the number of seconds in `stale-while-revalidate` until it gets a "validated response" from the server. The behaviour should be almost unnoticeable for the end user but would make a big difference in the amount of requests to server.
This commit is contained in:
e.baidakova 2022-11-02 09:57:23 +04:00 committed by Elena Baidakova
parent 81e6a7c5bd
commit 93c6abcad5
2 changed files with 18 additions and 1 deletions

View File

@ -12,10 +12,18 @@ const isString = require('lodash/isString');
* @param {'public'|'private'} profile Use "private" if you do not want caching * @param {'public'|'private'} profile Use "private" if you do not want caching
* @param {object} [options] * @param {object} [options]
* @param {number} [options.maxAge] The max-age in seconds to use when profile is "public" * @param {number} [options.maxAge] The max-age in seconds to use when profile is "public"
* @param {number} [options.staleWhileRevalidate] The stale-while-revalidate in seconds to use when profile is "public"
*/ */
const cacheControl = (profile, options = {maxAge: 0}) => { const cacheControl = (profile, options = {maxAge: 0}) => {
const isOptionHasProperty = property => Object.prototype.hasOwnProperty.call(options, property);
const publicOptions = [
'public',
`max-age=${options.maxAge}`,
isOptionHasProperty('staleWhileRevalidate') ? `stale-while-revalidate=${options.staleWhileRevalidate}` : ''
];
const profiles = { const profiles = {
public: `public, max-age=${options.maxAge}`, public: publicOptions.filter(option => option).join(', '),
private: 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0' private: 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'
}; };

View File

@ -34,6 +34,15 @@ describe('Cache-Control middleware', function () {
}); });
}); });
it('correctly sets the public profile headers with staleWhileRevalidate', function (done) {
cacheControl('public', {maxAge: 1, staleWhileRevalidate: 9})(null, res, function (a) {
should.not.exist(a);
res.set.calledOnce.should.be.true();
res.set.calledWith({'Cache-Control': 'public, max-age=1, stale-while-revalidate=9'}).should.be.true();
done();
});
});
it('correctly sets the private profile headers', function (done) { it('correctly sets the private profile headers', function (done) {
cacheControl('private')(null, res, function (a) { cacheControl('private')(null, res, function (a) {
should.not.exist(a); should.not.exist(a);