diff --git a/lib/cartodb/controllers/analyses.js b/lib/cartodb/controllers/analyses.js index a9eee758..f632b394 100644 --- a/lib/cartodb/controllers/analyses.js +++ b/lib/cartodb/controllers/analyses.js @@ -9,6 +9,7 @@ const authorize = require('../middleware/authorize'); const dbConnSetup = require('../middleware/db-conn-setup'); const rateLimit = require('../middleware/rate-limit'); const { RATE_LIMIT_ENDPOINTS_GROUPS } = rateLimit; +const cacheControlHeader = require('../middleware/cache-control-header'); const sendResponse = require('../middleware/send-response'); function AnalysesController(pgConnection, authApi, userLimitsApi) { @@ -37,7 +38,7 @@ AnalysesController.prototype.register = function (app) { getDataFromQuery({ queryTemplate: catalogQueryTpl, key: 'catalog' }), getDataFromQuery({ queryTemplate: tablesQueryTpl, key: 'tables' }), prepareResponse(), - setCacheControlHeader(), + cacheControlHeader({ ttl: 10, revalidate: true }), sendResponse(), 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 () { return function unathorizedErrorMiddleware(err, req, res, next) { if (err.message.match(/permission\sdenied/)) { diff --git a/lib/cartodb/controllers/layergroup.js b/lib/cartodb/controllers/layergroup.js index 9da86ff4..a77a7168 100644 --- a/lib/cartodb/controllers/layergroup.js +++ b/lib/cartodb/controllers/layergroup.js @@ -9,6 +9,7 @@ const dbConnSetup = require('../middleware/db-conn-setup'); const authorize = require('../middleware/authorize'); const rateLimit = require('../middleware/rate-limit'); const { RATE_LIMIT_ENDPOINTS_GROUPS } = rateLimit; +const cacheControlHeader = require('../middleware/cache-control-header'); const cacheChannelHeader = require('../middleware/cache-channel-header'); const surrogateKeyHeader = require('../middleware/surrogate-key-header'); const lastModifiedHeader = require('../middleware/last-modified-header'); @@ -87,7 +88,7 @@ LayergroupController.prototype.register = function(app) { this.layergroupAffectedTablesCache ), getTile(this.tileBackend, 'map_tile'), - setCacheControlHeader(), + cacheControlHeader(), cacheChannelHeader(), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), lastModifiedHeader(), @@ -116,7 +117,7 @@ LayergroupController.prototype.register = function(app) { this.layergroupAffectedTablesCache ), getTile(this.tileBackend, 'map_tile'), - setCacheControlHeader(), + cacheControlHeader(), cacheChannelHeader(), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), lastModifiedHeader(), @@ -146,7 +147,7 @@ LayergroupController.prototype.register = function(app) { this.layergroupAffectedTablesCache ), getTile(this.tileBackend, 'maplayer_tile'), - setCacheControlHeader(), + cacheControlHeader(), cacheChannelHeader(), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), lastModifiedHeader(), @@ -175,7 +176,7 @@ LayergroupController.prototype.register = function(app) { this.layergroupAffectedTablesCache ), getFeatureAttributes(this.attributesBackend), - setCacheControlHeader(), + cacheControlHeader(), cacheChannelHeader(), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), lastModifiedHeader(), @@ -203,7 +204,7 @@ LayergroupController.prototype.register = function(app) { forcedFormat ), getPreviewImageByCenter(this.previewBackend), - setCacheControlHeader(), + cacheControlHeader(), cacheChannelHeader(), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), lastModifiedHeader(), @@ -229,7 +230,7 @@ LayergroupController.prototype.register = function(app) { forcedFormat ), getPreviewImageByBoundingBox(this.previewBackend), - setCacheControlHeader(), + cacheControlHeader(), cacheChannelHeader(), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), lastModifiedHeader(), @@ -272,7 +273,7 @@ LayergroupController.prototype.register = function(app) { this.layergroupAffectedTablesCache ), getDataview(this.dataviewBackend), - setCacheControlHeader(), + cacheControlHeader(), cacheChannelHeader(), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), lastModifiedHeader(), @@ -297,7 +298,7 @@ LayergroupController.prototype.register = function(app) { this.layergroupAffectedTablesCache ), getDataview(this.dataviewBackend), - setCacheControlHeader(), + cacheControlHeader(), cacheChannelHeader(), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), lastModifiedHeader(), @@ -322,7 +323,7 @@ LayergroupController.prototype.register = function(app) { this.layergroupAffectedTablesCache ), dataviewSearch(this.dataviewBackend), - setCacheControlHeader(), + cacheControlHeader(), cacheChannelHeader(), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), lastModifiedHeader(), @@ -347,7 +348,7 @@ LayergroupController.prototype.register = function(app) { this.layergroupAffectedTablesCache ), dataviewSearch(this.dataviewBackend), - setCacheControlHeader(), + cacheControlHeader(), cacheChannelHeader(), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), 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) { return function incrementSuccessMetricsMiddleware (req, res, next) { const formatStat = parseFormat(req.params.format); diff --git a/lib/cartodb/controllers/map.js b/lib/cartodb/controllers/map.js index 670ed9d7..0caa61ce 100644 --- a/lib/cartodb/controllers/map.js +++ b/lib/cartodb/controllers/map.js @@ -11,6 +11,7 @@ const layergroupToken = require('../middleware/layergroup-token'); const credentials = require('../middleware/credentials'); const dbConnSetup = require('../middleware/db-conn-setup'); const authorize = require('../middleware/authorize'); +const cacheControlHeader = require('../middleware/cache-control-header'); const cacheChannelHeader = require('../middleware/cache-channel-header'); const surrogateKeyHeader = require('../middleware/surrogate-key-header'); const lastModifiedHeader = require('../middleware/last-modified-header'); @@ -114,11 +115,11 @@ MapController.prototype.composeCreateMapMiddleware = function (endpointGroup, us this.getCreateMapMiddlewares(useTemplate), incrementMapViewCount(this.metadataBackend), augmentLayergroupData(), + cacheControlHeader({ ttl: global.environment.varnish.layergroupTtl || 86400, revalidate: true }), cacheChannelHeader(), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), lastModifiedHeader({ now: true }), setLastUpdatedTimeToLayergroup(), - setCacheControl(), setLayerStats(this.pgConnection, this.statsBackend), setLayergroupIdHeader(this.templateMaps ,useTemplateHash), setDataviewsAndWidgetsUrlsToLayergroupMetadata(this.layergroupMetadata), diff --git a/lib/cartodb/controllers/named_maps.js b/lib/cartodb/controllers/named_maps.js index c9d67c95..05dba8f8 100644 --- a/lib/cartodb/controllers/named_maps.js +++ b/lib/cartodb/controllers/named_maps.js @@ -6,6 +6,7 @@ const layergroupToken = require('../middleware/layergroup-token'); const credentials = require('../middleware/credentials'); const dbConnSetup = require('../middleware/db-conn-setup'); const authorize = require('../middleware/authorize'); +const cacheControlHeader = require('../middleware/cache-control-header'); const cacheChannelHeader = require('../middleware/cache-channel-header'); const surrogateKeyHeader = require('../middleware/surrogate-key-header'); const lastModifiedHeader = require('../middleware/last-modified-header'); @@ -83,10 +84,10 @@ NamedMapsController.prototype.register = function(app) { tileBackend: this.tileBackend, label: 'NAMED_MAP_TILE' }), + cacheControlHeader(), cacheChannelHeader(), surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), lastModifiedHeader(), - setCacheControlHeader(), setContentTypeHeader(), sendResponse(), vectorError() @@ -115,10 +116,10 @@ NamedMapsController.prototype.register = function(app) { getStaticImageOptions({ tablesExtentApi: this.tablesExtentApi }), getImage({ previewBackend: this.previewBackend, label: 'STATIC_VIZ_MAP' }), incrementMapViews({ metadataBackend: this.metadataBackend }), - surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), + cacheControlHeader(), cacheChannelHeader(), + surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), lastModifiedHeader(), - setCacheControlHeader(), setContentTypeHeader(), sendResponse() ); @@ -444,24 +445,8 @@ function templateBounds(view) { 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 () { return function setContentTypeHeaderMiddleware(req, res, next) { - res.set('Content-Type', res.get('content-type') || res.get('Content-Type') || 'image/png'); next(); diff --git a/lib/cartodb/middleware/cache-control-header.js b/lib/cartodb/middleware/cache-control-header.js new file mode 100644 index 00000000..25e2b04f --- /dev/null +++ b/lib/cartodb/middleware/cache-control-header.js @@ -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(); + }; +} diff --git a/test/acceptance/multilayer.js b/test/acceptance/multilayer.js index a1a93e40..148ec6db 100644 --- a/test/acceptance/multilayer.js +++ b/test/acceptance/multilayer.js @@ -1272,6 +1272,8 @@ describe(suiteName, function() { it("cache control for layergroup default value", function(done) { global.environment.varnish.layergroupTtl = null; + var server = new CartodbWindshaft(serverOptions); + assert.response(server, layergroupTtlRequest, layergroupTtlResponseExpectation, function(res) { assert.equal(res.headers['cache-control'], 'public,max-age=86400,must-revalidate'); @@ -1287,6 +1289,8 @@ describe(suiteName, function() { var layergroupTtl = 300; global.environment.varnish.layergroupTtl = layergroupTtl; + var server = new CartodbWindshaft(serverOptions); + assert.response(server, layergroupTtlRequest, layergroupTtlResponseExpectation, function(res) { assert.equal(res.headers['cache-control'], 'public,max-age=' + layergroupTtl + ',must-revalidate');