Extract cache control header middleware

This commit is contained in:
Daniel García Aubert 2018-03-21 16:38:37 +01:00
parent d022a1fa5e
commit 72c4a7abd6
6 changed files with 40 additions and 46 deletions

View File

@ -9,6 +9,7 @@ const authorize = require('../middleware/authorize');
const dbConnSetup = require('../middleware/db-conn-setup'); const dbConnSetup = require('../middleware/db-conn-setup');
const rateLimit = require('../middleware/rate-limit'); const rateLimit = require('../middleware/rate-limit');
const { RATE_LIMIT_ENDPOINTS_GROUPS } = rateLimit; const { RATE_LIMIT_ENDPOINTS_GROUPS } = rateLimit;
const cacheControlHeader = require('../middleware/cache-control-header');
const sendResponse = require('../middleware/send-response'); const sendResponse = require('../middleware/send-response');
function AnalysesController(pgConnection, authApi, userLimitsApi) { function AnalysesController(pgConnection, authApi, userLimitsApi) {
@ -37,7 +38,7 @@ AnalysesController.prototype.register = function (app) {
getDataFromQuery({ queryTemplate: catalogQueryTpl, key: 'catalog' }), getDataFromQuery({ queryTemplate: catalogQueryTpl, key: 'catalog' }),
getDataFromQuery({ queryTemplate: tablesQueryTpl, key: 'tables' }), getDataFromQuery({ queryTemplate: tablesQueryTpl, key: 'tables' }),
prepareResponse(), prepareResponse(),
setCacheControlHeader(), cacheControlHeader({ ttl: 10, revalidate: true }),
sendResponse(), sendResponse(),
unauthorizedError() unauthorizedError()
); );
@ -112,13 +113,6 @@ function prepareResponse () {
}; };
} }
function setCacheControlHeader () {
return function setCacheControlHeaderMiddleware (req, res, next) {
res.set('Cache-Control', 'public,max-age=10,must-revalidate');
next();
};
}
function unauthorizedError () { function unauthorizedError () {
return function unathorizedErrorMiddleware(err, req, res, next) { return function unathorizedErrorMiddleware(err, req, res, next) {
if (err.message.match(/permission\sdenied/)) { if (err.message.match(/permission\sdenied/)) {

View File

@ -9,6 +9,7 @@ const dbConnSetup = require('../middleware/db-conn-setup');
const authorize = require('../middleware/authorize'); const authorize = require('../middleware/authorize');
const rateLimit = require('../middleware/rate-limit'); const rateLimit = require('../middleware/rate-limit');
const { RATE_LIMIT_ENDPOINTS_GROUPS } = rateLimit; const { RATE_LIMIT_ENDPOINTS_GROUPS } = rateLimit;
const cacheControlHeader = require('../middleware/cache-control-header');
const cacheChannelHeader = require('../middleware/cache-channel-header'); const cacheChannelHeader = require('../middleware/cache-channel-header');
const surrogateKeyHeader = require('../middleware/surrogate-key-header'); const surrogateKeyHeader = require('../middleware/surrogate-key-header');
const lastModifiedHeader = require('../middleware/last-modified-header'); const lastModifiedHeader = require('../middleware/last-modified-header');
@ -87,7 +88,7 @@ LayergroupController.prototype.register = function(app) {
this.layergroupAffectedTablesCache this.layergroupAffectedTablesCache
), ),
getTile(this.tileBackend, 'map_tile'), getTile(this.tileBackend, 'map_tile'),
setCacheControlHeader(), cacheControlHeader(),
cacheChannelHeader(), cacheChannelHeader(),
surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }),
lastModifiedHeader(), lastModifiedHeader(),
@ -116,7 +117,7 @@ LayergroupController.prototype.register = function(app) {
this.layergroupAffectedTablesCache this.layergroupAffectedTablesCache
), ),
getTile(this.tileBackend, 'map_tile'), getTile(this.tileBackend, 'map_tile'),
setCacheControlHeader(), cacheControlHeader(),
cacheChannelHeader(), cacheChannelHeader(),
surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }),
lastModifiedHeader(), lastModifiedHeader(),
@ -146,7 +147,7 @@ LayergroupController.prototype.register = function(app) {
this.layergroupAffectedTablesCache this.layergroupAffectedTablesCache
), ),
getTile(this.tileBackend, 'maplayer_tile'), getTile(this.tileBackend, 'maplayer_tile'),
setCacheControlHeader(), cacheControlHeader(),
cacheChannelHeader(), cacheChannelHeader(),
surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }),
lastModifiedHeader(), lastModifiedHeader(),
@ -175,7 +176,7 @@ LayergroupController.prototype.register = function(app) {
this.layergroupAffectedTablesCache this.layergroupAffectedTablesCache
), ),
getFeatureAttributes(this.attributesBackend), getFeatureAttributes(this.attributesBackend),
setCacheControlHeader(), cacheControlHeader(),
cacheChannelHeader(), cacheChannelHeader(),
surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }),
lastModifiedHeader(), lastModifiedHeader(),
@ -203,7 +204,7 @@ LayergroupController.prototype.register = function(app) {
forcedFormat forcedFormat
), ),
getPreviewImageByCenter(this.previewBackend), getPreviewImageByCenter(this.previewBackend),
setCacheControlHeader(), cacheControlHeader(),
cacheChannelHeader(), cacheChannelHeader(),
surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }),
lastModifiedHeader(), lastModifiedHeader(),
@ -229,7 +230,7 @@ LayergroupController.prototype.register = function(app) {
forcedFormat forcedFormat
), ),
getPreviewImageByBoundingBox(this.previewBackend), getPreviewImageByBoundingBox(this.previewBackend),
setCacheControlHeader(), cacheControlHeader(),
cacheChannelHeader(), cacheChannelHeader(),
surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }),
lastModifiedHeader(), lastModifiedHeader(),
@ -272,7 +273,7 @@ LayergroupController.prototype.register = function(app) {
this.layergroupAffectedTablesCache this.layergroupAffectedTablesCache
), ),
getDataview(this.dataviewBackend), getDataview(this.dataviewBackend),
setCacheControlHeader(), cacheControlHeader(),
cacheChannelHeader(), cacheChannelHeader(),
surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }),
lastModifiedHeader(), lastModifiedHeader(),
@ -297,7 +298,7 @@ LayergroupController.prototype.register = function(app) {
this.layergroupAffectedTablesCache this.layergroupAffectedTablesCache
), ),
getDataview(this.dataviewBackend), getDataview(this.dataviewBackend),
setCacheControlHeader(), cacheControlHeader(),
cacheChannelHeader(), cacheChannelHeader(),
surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }),
lastModifiedHeader(), lastModifiedHeader(),
@ -322,7 +323,7 @@ LayergroupController.prototype.register = function(app) {
this.layergroupAffectedTablesCache this.layergroupAffectedTablesCache
), ),
dataviewSearch(this.dataviewBackend), dataviewSearch(this.dataviewBackend),
setCacheControlHeader(), cacheControlHeader(),
cacheChannelHeader(), cacheChannelHeader(),
surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }),
lastModifiedHeader(), lastModifiedHeader(),
@ -347,7 +348,7 @@ LayergroupController.prototype.register = function(app) {
this.layergroupAffectedTablesCache this.layergroupAffectedTablesCache
), ),
dataviewSearch(this.dataviewBackend), dataviewSearch(this.dataviewBackend),
setCacheControlHeader(), cacheControlHeader(),
cacheChannelHeader(), cacheChannelHeader(),
surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }),
lastModifiedHeader(), lastModifiedHeader(),
@ -610,14 +611,6 @@ function getPreviewImageByBoundingBox (previewBackend) {
}; };
} }
function setCacheControlHeader () {
return function setCacheControlHeaderMiddleware (req, res, next) {
res.set('Cache-Control', 'public,max-age=31536000');
next();
};
}
function incrementSuccessMetrics (statsClient) { function incrementSuccessMetrics (statsClient) {
return function incrementSuccessMetricsMiddleware (req, res, next) { return function incrementSuccessMetricsMiddleware (req, res, next) {
const formatStat = parseFormat(req.params.format); const formatStat = parseFormat(req.params.format);

View File

@ -11,6 +11,7 @@ const layergroupToken = require('../middleware/layergroup-token');
const credentials = require('../middleware/credentials'); const credentials = require('../middleware/credentials');
const dbConnSetup = require('../middleware/db-conn-setup'); const dbConnSetup = require('../middleware/db-conn-setup');
const authorize = require('../middleware/authorize'); const authorize = require('../middleware/authorize');
const cacheControlHeader = require('../middleware/cache-control-header');
const cacheChannelHeader = require('../middleware/cache-channel-header'); const cacheChannelHeader = require('../middleware/cache-channel-header');
const surrogateKeyHeader = require('../middleware/surrogate-key-header'); const surrogateKeyHeader = require('../middleware/surrogate-key-header');
const lastModifiedHeader = require('../middleware/last-modified-header'); const lastModifiedHeader = require('../middleware/last-modified-header');
@ -114,11 +115,11 @@ MapController.prototype.composeCreateMapMiddleware = function (endpointGroup, us
this.getCreateMapMiddlewares(useTemplate), this.getCreateMapMiddlewares(useTemplate),
incrementMapViewCount(this.metadataBackend), incrementMapViewCount(this.metadataBackend),
augmentLayergroupData(), augmentLayergroupData(),
cacheControlHeader({ ttl: global.environment.varnish.layergroupTtl || 86400, revalidate: true }),
cacheChannelHeader(), cacheChannelHeader(),
surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }),
lastModifiedHeader({ now: true }), lastModifiedHeader({ now: true }),
setLastUpdatedTimeToLayergroup(), setLastUpdatedTimeToLayergroup(),
setCacheControl(),
setLayerStats(this.pgConnection, this.statsBackend), setLayerStats(this.pgConnection, this.statsBackend),
setLayergroupIdHeader(this.templateMaps ,useTemplateHash), setLayergroupIdHeader(this.templateMaps ,useTemplateHash),
setDataviewsAndWidgetsUrlsToLayergroupMetadata(this.layergroupMetadata), setDataviewsAndWidgetsUrlsToLayergroupMetadata(this.layergroupMetadata),

View File

@ -6,6 +6,7 @@ const layergroupToken = require('../middleware/layergroup-token');
const credentials = require('../middleware/credentials'); const credentials = require('../middleware/credentials');
const dbConnSetup = require('../middleware/db-conn-setup'); const dbConnSetup = require('../middleware/db-conn-setup');
const authorize = require('../middleware/authorize'); const authorize = require('../middleware/authorize');
const cacheControlHeader = require('../middleware/cache-control-header');
const cacheChannelHeader = require('../middleware/cache-channel-header'); const cacheChannelHeader = require('../middleware/cache-channel-header');
const surrogateKeyHeader = require('../middleware/surrogate-key-header'); const surrogateKeyHeader = require('../middleware/surrogate-key-header');
const lastModifiedHeader = require('../middleware/last-modified-header'); const lastModifiedHeader = require('../middleware/last-modified-header');
@ -83,10 +84,10 @@ NamedMapsController.prototype.register = function(app) {
tileBackend: this.tileBackend, tileBackend: this.tileBackend,
label: 'NAMED_MAP_TILE' label: 'NAMED_MAP_TILE'
}), }),
cacheControlHeader(),
cacheChannelHeader(), cacheChannelHeader(),
surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }),
lastModifiedHeader(), lastModifiedHeader(),
setCacheControlHeader(),
setContentTypeHeader(), setContentTypeHeader(),
sendResponse(), sendResponse(),
vectorError() vectorError()
@ -115,10 +116,10 @@ NamedMapsController.prototype.register = function(app) {
getStaticImageOptions({ tablesExtentApi: this.tablesExtentApi }), getStaticImageOptions({ tablesExtentApi: this.tablesExtentApi }),
getImage({ previewBackend: this.previewBackend, label: 'STATIC_VIZ_MAP' }), getImage({ previewBackend: this.previewBackend, label: 'STATIC_VIZ_MAP' }),
incrementMapViews({ metadataBackend: this.metadataBackend }), incrementMapViews({ metadataBackend: this.metadataBackend }),
surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), cacheControlHeader(),
cacheChannelHeader(), cacheChannelHeader(),
surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }),
lastModifiedHeader(), lastModifiedHeader(),
setCacheControlHeader(),
setContentTypeHeader(), setContentTypeHeader(),
sendResponse() sendResponse()
); );
@ -444,24 +445,8 @@ function templateBounds(view) {
return false; return false;
} }
function setCacheControlHeader () {
return function setCacheControlHeaderMiddleware(req, res, next) {
const { affectedTables } = res.locals;
res.set('Cache-Control', 'public,max-age=7200,must-revalidate');
if (!affectedTables || !!affectedTables.tables) {
// we increase cache control as we can invalidate it
res.set('Cache-Control', 'public,max-age=31536000');
}
next();
};
}
function setContentTypeHeader () { function setContentTypeHeader () {
return function setContentTypeHeaderMiddleware(req, res, next) { return function setContentTypeHeaderMiddleware(req, res, next) {
res.set('Content-Type', res.get('content-type') || res.get('Content-Type') || 'image/png'); res.set('Content-Type', res.get('content-type') || res.get('Content-Type') || 'image/png');
next(); next();

View File

@ -0,0 +1,17 @@
module.exports = function setCacheControlHeader ({ ttl = 31536000, revalidate = false } = {}) {
return function setCacheControlHeaderMiddleware (req, res, next) {
if (req.method !== 'GET') {
return next();
}
const directives = [ 'public', `max-age=${ttl}` ];
if (revalidate) {
directives.push('must-revalidate');
}
res.set('Cache-Control', directives.join(','));
next();
};
}

View File

@ -1272,6 +1272,8 @@ describe(suiteName, function() {
it("cache control for layergroup default value", function(done) { it("cache control for layergroup default value", function(done) {
global.environment.varnish.layergroupTtl = null; global.environment.varnish.layergroupTtl = null;
var server = new CartodbWindshaft(serverOptions);
assert.response(server, layergroupTtlRequest, layergroupTtlResponseExpectation, assert.response(server, layergroupTtlRequest, layergroupTtlResponseExpectation,
function(res) { function(res) {
assert.equal(res.headers['cache-control'], 'public,max-age=86400,must-revalidate'); assert.equal(res.headers['cache-control'], 'public,max-age=86400,must-revalidate');
@ -1287,6 +1289,8 @@ describe(suiteName, function() {
var layergroupTtl = 300; var layergroupTtl = 300;
global.environment.varnish.layergroupTtl = layergroupTtl; global.environment.varnish.layergroupTtl = layergroupTtl;
var server = new CartodbWindshaft(serverOptions);
assert.response(server, layergroupTtlRequest, layergroupTtlResponseExpectation, assert.response(server, layergroupTtlRequest, layergroupTtlResponseExpectation,
function(res) { function(res) {
assert.equal(res.headers['cache-control'], 'public,max-age=' + layergroupTtl + ',must-revalidate'); assert.equal(res.headers['cache-control'], 'public,max-age=' + layergroupTtl + ',must-revalidate');