mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-06 22:40:14 -05:00
Cache control middleware refactor
refs #5286 - split cache control middleware into its own file - split out cache control tests - add new mochacli command for running just middleware tests
This commit is contained in:
parent
3b30e34b77
commit
050b03d2bd
5 changed files with 122 additions and 92 deletions
|
@ -201,6 +201,10 @@ var _ = require('lodash'),
|
||||||
src: ['core/test/unit/server_helpers/*_spec.js']
|
src: ['core/test/unit/server_helpers/*_spec.js']
|
||||||
},
|
},
|
||||||
|
|
||||||
|
middleware: {
|
||||||
|
src: ['core/test/unit/middleware/*_spec.js']
|
||||||
|
},
|
||||||
|
|
||||||
showdown: {
|
showdown: {
|
||||||
src: ['core/test/unit/**/showdown*_spec.js']
|
src: ['core/test/unit/**/showdown*_spec.js']
|
||||||
},
|
},
|
||||||
|
|
32
core/server/middleware/cache-control.js
Normal file
32
core/server/middleware/cache-control.js
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
// # CacheControl Middleware
|
||||||
|
// Usage: cacheControl(profile), where profile is one of 'public' or 'private'
|
||||||
|
// After: checkIsPrivate
|
||||||
|
// Before: routes
|
||||||
|
// App: Admin|Blog|API
|
||||||
|
//
|
||||||
|
// Allows each app to declare its own default caching rules
|
||||||
|
|
||||||
|
var _ = require('lodash'),
|
||||||
|
cacheControl;
|
||||||
|
|
||||||
|
cacheControl = function (options) {
|
||||||
|
/*jslint unparam:true*/
|
||||||
|
var profiles = {
|
||||||
|
public: 'public, max-age=0',
|
||||||
|
private: 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'
|
||||||
|
},
|
||||||
|
output;
|
||||||
|
|
||||||
|
if (_.isString(options) && profiles.hasOwnProperty(options)) {
|
||||||
|
output = profiles[options];
|
||||||
|
}
|
||||||
|
|
||||||
|
return function cacheControlHeaders(req, res, next) {
|
||||||
|
if (output) {
|
||||||
|
res.set({'Cache-Control': output});
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = cacheControl;
|
|
@ -5,7 +5,6 @@
|
||||||
var _ = require('lodash'),
|
var _ = require('lodash'),
|
||||||
fs = require('fs'),
|
fs = require('fs'),
|
||||||
express = require('express'),
|
express = require('express'),
|
||||||
busboy = require('./ghost-busboy'),
|
|
||||||
config = require('../config'),
|
config = require('../config'),
|
||||||
crypto = require('crypto'),
|
crypto = require('crypto'),
|
||||||
path = require('path'),
|
path = require('path'),
|
||||||
|
@ -17,6 +16,9 @@ var _ = require('lodash'),
|
||||||
url = require('url'),
|
url = require('url'),
|
||||||
utils = require('../utils'),
|
utils = require('../utils'),
|
||||||
|
|
||||||
|
busboy = require('./ghost-busboy'),
|
||||||
|
cacheControl = require('./cache-control'),
|
||||||
|
|
||||||
middleware,
|
middleware,
|
||||||
blogApp,
|
blogApp,
|
||||||
oauthServer,
|
oauthServer,
|
||||||
|
@ -140,28 +142,6 @@ middleware = {
|
||||||
next();
|
next();
|
||||||
},
|
},
|
||||||
|
|
||||||
// ### CacheControl Middleware
|
|
||||||
// provide sensible cache control headers
|
|
||||||
cacheControl: function (options) {
|
|
||||||
/*jslint unparam:true*/
|
|
||||||
var profiles = {
|
|
||||||
public: 'public, max-age=0',
|
|
||||||
private: 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'
|
|
||||||
},
|
|
||||||
output;
|
|
||||||
|
|
||||||
if (_.isString(options) && profiles.hasOwnProperty(options)) {
|
|
||||||
output = profiles[options];
|
|
||||||
}
|
|
||||||
|
|
||||||
return function cacheControlHeaders(req, res, next) {
|
|
||||||
if (output) {
|
|
||||||
res.set({'Cache-Control': output});
|
|
||||||
}
|
|
||||||
next();
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
// ### whenEnabled Middleware
|
// ### whenEnabled Middleware
|
||||||
// Selectively use middleware
|
// Selectively use middleware
|
||||||
// From https://github.com/senchalabs/connect/issues/676#issuecomment-9569658
|
// From https://github.com/senchalabs/connect/issues/676#issuecomment-9569658
|
||||||
|
@ -491,7 +471,8 @@ middleware = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
busboy: busboy
|
busboy: busboy,
|
||||||
|
cacheControl: cacheControl
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = middleware;
|
module.exports = middleware;
|
||||||
|
|
81
core/test/unit/middleware/cache-control_spec.js
Normal file
81
core/test/unit/middleware/cache-control_spec.js
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/*globals describe, beforeEach, afterEach, it*/
|
||||||
|
/*jshint expr:true*/
|
||||||
|
var should = require('should'),
|
||||||
|
sinon = require('sinon'),
|
||||||
|
middleware = require('../../../server/middleware').middleware;
|
||||||
|
|
||||||
|
describe('Middleware: cacheControl', function () {
|
||||||
|
var sandbox,
|
||||||
|
res;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
sandbox = sinon.sandbox.create();
|
||||||
|
|
||||||
|
res = {
|
||||||
|
set: sinon.spy()
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
sandbox.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('correctly sets the public profile headers', function (done) {
|
||||||
|
middleware.cacheControl('public')(null, res, function (a) {
|
||||||
|
should.not.exist(a);
|
||||||
|
res.set.calledOnce.should.be.true;
|
||||||
|
res.set.calledWith({'Cache-Control': 'public, max-age=0'});
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('correctly sets the private profile headers', function (done) {
|
||||||
|
middleware.cacheControl('private')(null, res, function (a) {
|
||||||
|
should.not.exist(a);
|
||||||
|
res.set.calledOnce.should.be.true;
|
||||||
|
res.set.calledWith({
|
||||||
|
'Cache-Control':
|
||||||
|
'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'
|
||||||
|
});
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('will not set headers without a profile', function (done) {
|
||||||
|
middleware.cacheControl()(null, res, function (a) {
|
||||||
|
should.not.exist(a);
|
||||||
|
res.set.called.should.be.false;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('will not get confused between serving public and private', function (done) {
|
||||||
|
var public = middleware.cacheControl('public'),
|
||||||
|
private = middleware.cacheControl('private');
|
||||||
|
|
||||||
|
public(null, res, function () {
|
||||||
|
res.set.calledOnce.should.be.true;
|
||||||
|
res.set.calledWith({'Cache-Control': 'public, max-age=0'});
|
||||||
|
|
||||||
|
private(null, res, function () {
|
||||||
|
res.set.calledTwice.should.be.true;
|
||||||
|
res.set.calledWith({
|
||||||
|
'Cache-Control':
|
||||||
|
'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'
|
||||||
|
});
|
||||||
|
|
||||||
|
public(null, res, function () {
|
||||||
|
res.set.calledThrice.should.be.true;
|
||||||
|
res.set.calledWith({'Cache-Control': 'public, max-age=0'});
|
||||||
|
|
||||||
|
private(null, res, function () {
|
||||||
|
res.set.calledWith({
|
||||||
|
'Cache-Control': 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'
|
||||||
|
});
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -29,74 +29,6 @@ describe('Middleware', function () {
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
sandbox.restore();
|
sandbox.restore();
|
||||||
});
|
});
|
||||||
// TODO: needs new test for ember admin
|
|
||||||
// describe('redirectToDashboard', function () {
|
|
||||||
// var req, res;
|
|
||||||
|
|
||||||
// beforeEach(function () {
|
|
||||||
// req = {
|
|
||||||
// session: {}
|
|
||||||
// };
|
|
||||||
|
|
||||||
// res = {
|
|
||||||
// redirect: sinon.spy()
|
|
||||||
// };
|
|
||||||
// });
|
|
||||||
|
|
||||||
// it('should redirect to dashboard', function () {
|
|
||||||
// req.session.user = {};
|
|
||||||
|
|
||||||
// middleware.redirectToDashboard(req, res, null);
|
|
||||||
// assert(res.redirect.calledWithMatch('/ghost/'));
|
|
||||||
// });
|
|
||||||
|
|
||||||
// it('should call next if no user in session', function (done) {
|
|
||||||
// middleware.redirectToDashboard(req, res, function (a) {
|
|
||||||
// should.not.exist(a);
|
|
||||||
// assert(res.redirect.calledOnce.should.be.false);
|
|
||||||
// done();
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
|
|
||||||
describe('cacheControl', function () {
|
|
||||||
var res;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
res = {
|
|
||||||
set: sinon.spy()
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
it('correctly sets the public profile headers', function (done) {
|
|
||||||
middleware.cacheControl('public')(null, res, function (a) {
|
|
||||||
should.not.exist(a);
|
|
||||||
res.set.calledOnce.should.be.true;
|
|
||||||
res.set.calledWith({'Cache-Control': 'public, max-age=0'});
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('correctly sets the private profile headers', function (done) {
|
|
||||||
middleware.cacheControl('private')(null, res, function (a) {
|
|
||||||
should.not.exist(a);
|
|
||||||
res.set.calledOnce.should.be.true;
|
|
||||||
res.set.calledWith({
|
|
||||||
'Cache-Control':
|
|
||||||
'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'
|
|
||||||
});
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('will not set headers without a profile', function (done) {
|
|
||||||
middleware.cacheControl()(null, res, function (a) {
|
|
||||||
should.not.exist(a);
|
|
||||||
res.set.called.should.be.false;
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('whenEnabled', function () {
|
describe('whenEnabled', function () {
|
||||||
var cbFn, blogApp;
|
var cbFn, blogApp;
|
||||||
|
|
Loading…
Reference in a new issue