From 51fade6bd314ba856c8813f069772abbec9878d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa=20Aubert?= Date: Wed, 28 Mar 2018 19:11:19 +0200 Subject: [PATCH] Ensure each controller only receives one router --- lib/cartodb/controllers/index.js | 2 - .../admin.js} | 20 +-- .../middlewares/named-map-provider.js | 32 +++++ .../{named_maps.js => template/preview.js} | 116 +++--------------- lib/cartodb/controllers/template/tile.js | 91 ++++++++++++++ lib/cartodb/server.js | 25 +++- 6 files changed, 168 insertions(+), 118 deletions(-) rename lib/cartodb/controllers/{named_maps_admin.js => template/admin.js} (92%) create mode 100644 lib/cartodb/controllers/template/middlewares/named-map-provider.js rename lib/cartodb/controllers/{named_maps.js => template/preview.js} (72%) create mode 100644 lib/cartodb/controllers/template/tile.js diff --git a/lib/cartodb/controllers/index.js b/lib/cartodb/controllers/index.js index 429a4b87..bb73af0f 100644 --- a/lib/cartodb/controllers/index.js +++ b/lib/cartodb/controllers/index.js @@ -2,7 +2,5 @@ module.exports = { Analyses: require('./analyses'), Layergroup: require('./layergroup'), Map: require('./map'), - NamedMaps: require('./named_maps'), - NamedMapsAdmin: require('./named_maps_admin'), ServerInfo: require('./server_info') }; diff --git a/lib/cartodb/controllers/named_maps_admin.js b/lib/cartodb/controllers/template/admin.js similarity index 92% rename from lib/cartodb/controllers/named_maps_admin.js rename to lib/cartodb/controllers/template/admin.js index 95ac0d51..f5f2fec7 100644 --- a/lib/cartodb/controllers/named_maps_admin.js +++ b/lib/cartodb/controllers/template/admin.js @@ -1,9 +1,9 @@ -const { templateName } = require('../backends/template_maps'); -const cors = require('../middleware/cors'); -const credentials = require('../middleware/credentials'); -const rateLimit = require('../middleware/rate-limit'); +const { templateName } = require('../../backends/template_maps'); +const cors = require('../../middleware/cors'); +const credentials = require('../../middleware/credentials'); +const rateLimit = require('../../middleware/rate-limit'); const { RATE_LIMIT_ENDPOINTS_GROUPS } = rateLimit; -const sendResponse = require('../middleware/send-response'); +const sendResponse = require('../../middleware/send-response'); /** * @param {AuthApi} authApi @@ -11,21 +11,21 @@ const sendResponse = require('../middleware/send-response'); * @param {TemplateMaps} templateMaps * @constructor */ -function NamedMapsAdminController(authApi, templateMaps, userLimitsApi) { +function AdminTemplateController(authApi, templateMaps, userLimitsApi) { this.authApi = authApi; this.templateMaps = templateMaps; this.userLimitsApi = userLimitsApi; } -module.exports = NamedMapsAdminController; +module.exports = AdminTemplateController; -NamedMapsAdminController.prototype.register = function (templateRouter) { +AdminTemplateController.prototype.register = function (templateRouter) { templateRouter.post( `/`, credentials(), - checkContentType({ action: 'POST', label: 'POST TEMPLATE' }), authorizedByAPIKey({ authApi: this.authApi, action: 'create', label: 'POST TEMPLATE' }), rateLimit(this.userLimitsApi, RATE_LIMIT_ENDPOINTS_GROUPS.NAMED_CREATE), + checkContentType({ action: 'POST', label: 'POST TEMPLATE' }), createTemplate({ templateMaps: this.templateMaps }), sendResponse() ); @@ -33,9 +33,9 @@ NamedMapsAdminController.prototype.register = function (templateRouter) { templateRouter.put( `/:template_id`, credentials(), - checkContentType({ action: 'PUT', label: 'PUT TEMPLATE' }), authorizedByAPIKey({ authApi: this.authApi, action: 'update', label: 'PUT TEMPLATE' }), rateLimit(this.userLimitsApi, RATE_LIMIT_ENDPOINTS_GROUPS.NAMED_UPDATE), + checkContentType({ action: 'PUT', label: 'PUT TEMPLATE' }), updateTemplate({ templateMaps: this.templateMaps }), sendResponse() ); diff --git a/lib/cartodb/controllers/template/middlewares/named-map-provider.js b/lib/cartodb/controllers/template/middlewares/named-map-provider.js new file mode 100644 index 00000000..08f0cad5 --- /dev/null +++ b/lib/cartodb/controllers/template/middlewares/named-map-provider.js @@ -0,0 +1,32 @@ +module.exports = function getNamedMapProvider ({ namedMapProviderCache, label, forcedFormat = null }) { + return function getNamedMapProviderMiddleware (req, res, next) { + const { user, token, cache_buster, api_key } = res.locals; + const { dbuser, dbname, dbpassword, dbhost, dbport } = res.locals; + const { template_id, layer: layerFromParams, z, x, y, format } = req.params; + const { layer: layerFromQuery } = req.query; + + const params = { + user, token, cache_buster, api_key, + dbuser, dbname, dbpassword, dbhost, dbport, + template_id, layer: (layerFromQuery || layerFromParams), z, x, y, format + }; + + if (forcedFormat) { + params.format = forcedFormat; + params.layer = params.layer || 'all'; + } + + const { config, auth_token } = req.query; + + namedMapProviderCache.get(user, template_id, config, auth_token, params, (err, namedMapProvider) => { + if (err) { + err.label = label; + return next(err); + } + + res.locals.mapConfigProvider = namedMapProvider; + + next(); + }); + }; +}; diff --git a/lib/cartodb/controllers/named_maps.js b/lib/cartodb/controllers/template/preview.js similarity index 72% rename from lib/cartodb/controllers/named_maps.js rename to lib/cartodb/controllers/template/preview.js index c5347190..d1abc587 100644 --- a/lib/cartodb/controllers/named_maps.js +++ b/lib/cartodb/controllers/template/preview.js @@ -1,14 +1,14 @@ -const cleanUpQueryParams = require('../middleware/clean-up-query-params'); -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'); -const sendResponse = require('../middleware/send-response'); -const vectorError = require('../middleware/vector-error'); -const rateLimit = require('../middleware/rate-limit'); +const cleanUpQueryParams = require('../../middleware/clean-up-query-params'); +const credentials = require('../../middleware/credentials'); +const dbConnSetup = require('../../middleware/db-conn-setup'); +const authorize = require('../../middleware/authorize'); +const namedMapProvider = require('./middlewares/named-map-provider'); +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'); +const sendResponse = require('../../middleware/send-response'); +const rateLimit = require('../../middleware/rate-limit'); const { RATE_LIMIT_ENDPOINTS_GROUPS } = rateLimit; const DEFAULT_ZOOM_CENTER = { @@ -23,9 +23,8 @@ function numMapper(n) { return +n; } -function NamedMapsController ( +function PreviewTemplateController ( namedMapProviderCache, - tileBackend, previewBackend, surrogateKeysCache, tablesExtentApi, @@ -35,7 +34,6 @@ function NamedMapsController ( userLimitsApi ) { this.namedMapProviderCache = namedMapProviderCache; - this.tileBackend = tileBackend; this.previewBackend = previewBackend; this.surrogateKeysCache = surrogateKeysCache; this.tablesExtentApi = tablesExtentApi; @@ -45,34 +43,9 @@ function NamedMapsController ( this.userLimitsApi = userLimitsApi; } -module.exports = NamedMapsController; - -NamedMapsController.prototype.register = function(mapRouter, templateRouter) { - - templateRouter.get( - `/:template_id/:layer/:z/:x/:y.(:format)`, - credentials(), - authorize(this.authApi), - dbConnSetup(this.pgConnection), - rateLimit(this.userLimitsApi, RATE_LIMIT_ENDPOINTS_GROUPS.NAMED_TILES), - cleanUpQueryParams(), - getNamedMapProvider({ - namedMapProviderCache: this.namedMapProviderCache, - label: 'NAMED_MAP_TILE' - }), - getTile({ - tileBackend: this.tileBackend, - label: 'NAMED_MAP_TILE' - }), - setContentTypeHeader(), - cacheControlHeader(), - cacheChannelHeader(), - surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), - lastModifiedHeader(), - sendResponse(), - vectorError() - ); +module.exports = PreviewTemplateController; +PreviewTemplateController.prototype.register = function (mapRouter) { mapRouter.get( `/static/named/:template_id/:width/:height.:format`, credentials(), @@ -80,7 +53,7 @@ NamedMapsController.prototype.register = function(mapRouter, templateRouter) { dbConnSetup(this.pgConnection), rateLimit(this.userLimitsApi, RATE_LIMIT_ENDPOINTS_GROUPS.STATIC_NAMED), cleanUpQueryParams(['layer', 'zoom', 'lon', 'lat', 'bbox']), - getNamedMapProvider({ + namedMapProvider({ namedMapProviderCache: this.namedMapProviderCache, label: 'STATIC_VIZ_MAP', forcedFormat: 'png' }), @@ -101,39 +74,6 @@ NamedMapsController.prototype.register = function(mapRouter, templateRouter) { ); }; -function getNamedMapProvider ({ namedMapProviderCache, label, forcedFormat = null }) { - return function getNamedMapProviderMiddleware (req, res, next) { - const { user, token, cache_buster, api_key } = res.locals; - const { dbuser, dbname, dbpassword, dbhost, dbport } = res.locals; - const { template_id, layer: layerFromParams, z, x, y, format } = req.params; - const { layer: layerFromQuery } = req.query; - - const params = { - user, token, cache_buster, api_key, - dbuser, dbname, dbpassword, dbhost, dbport, - template_id, layer: (layerFromQuery || layerFromParams), z, x, y, format - }; - - if (forcedFormat) { - params.format = forcedFormat; - params.layer = params.layer || 'all'; - } - - const { config, auth_token } = req.query; - - namedMapProviderCache.get(user, template_id, config, auth_token, params, (err, namedMapProvider) => { - if (err) { - err.label = label; - return next(err); - } - - res.locals.mapConfigProvider = namedMapProvider; - - next(); - }); - }; -} - function getTemplate ({ label }) { return function getTemplateMiddleware (req, res, next) { const { mapConfigProvider } = res.locals; @@ -200,32 +140,6 @@ function prepareLayerFilterFromPreviewLayers ({ namedMapProviderCache, label }) }; } -function getTile ({ tileBackend, label }) { - return function getTileMiddleware (req, res, next) { - const { mapConfigProvider } = res.locals; - const { layer, z, x, y, format } = req.params; - const params = { layer, z, x, y, format }; - - tileBackend.getTile(mapConfigProvider, params, (err, tile, headers, stats) => { - req.profiler.add(stats); - req.profiler.done('render-' + format); - - if (err) { - err.label = label; - return next(err); - } - - if (headers) { - res.set(headers); - } - - res.body = tile; - - next(); - }); - }; -} - function getStaticImageOptions ({ tablesExtentApi }) { return function getStaticImageOptionsMiddleware(req, res, next) { const { user, mapConfigProvider, template } = res.locals; diff --git a/lib/cartodb/controllers/template/tile.js b/lib/cartodb/controllers/template/tile.js new file mode 100644 index 00000000..29b7f852 --- /dev/null +++ b/lib/cartodb/controllers/template/tile.js @@ -0,0 +1,91 @@ +const cleanUpQueryParams = require('../../middleware/clean-up-query-params'); +const credentials = require('../../middleware/credentials'); +const dbConnSetup = require('../../middleware/db-conn-setup'); +const authorize = require('../../middleware/authorize'); +const namedMapProvider = require('./middlewares/named-map-provider'); +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'); +const sendResponse = require('../../middleware/send-response'); +const vectorError = require('../../middleware/vector-error'); +const rateLimit = require('../../middleware/rate-limit'); +const { RATE_LIMIT_ENDPOINTS_GROUPS } = rateLimit; + +function TileTemplateController ( + namedMapProviderCache, + tileBackend, + surrogateKeysCache, + pgConnection, + authApi, + userLimitsApi +) { + this.namedMapProviderCache = namedMapProviderCache; + this.tileBackend = tileBackend; + this.surrogateKeysCache = surrogateKeysCache; + this.pgConnection = pgConnection; + this.authApi = authApi; + this.userLimitsApi = userLimitsApi; +} + +module.exports = TileTemplateController; + +TileTemplateController.prototype.register = function (templateRouter) { + templateRouter.get( + `/:template_id/:layer/:z/:x/:y.(:format)`, + credentials(), + authorize(this.authApi), + dbConnSetup(this.pgConnection), + rateLimit(this.userLimitsApi, RATE_LIMIT_ENDPOINTS_GROUPS.NAMED_TILES), + cleanUpQueryParams(), + namedMapProvider({ + namedMapProviderCache: this.namedMapProviderCache, + label: 'NAMED_MAP_TILE' + }), + getTile({ + tileBackend: this.tileBackend, + label: 'NAMED_MAP_TILE' + }), + setContentTypeHeader(), + cacheControlHeader(), + cacheChannelHeader(), + surrogateKeyHeader({ surrogateKeysCache: this.surrogateKeysCache }), + lastModifiedHeader(), + sendResponse(), + vectorError() + ); +}; + +function getTile ({ tileBackend, label }) { + return function getTileMiddleware (req, res, next) { + const { mapConfigProvider } = res.locals; + const { layer, z, x, y, format } = req.params; + const params = { layer, z, x, y, format }; + + tileBackend.getTile(mapConfigProvider, params, (err, tile, headers, stats) => { + req.profiler.add(stats); + req.profiler.done('render-' + format); + + if (err) { + err.label = label; + return next(err); + } + + if (headers) { + res.set(headers); + } + + res.body = tile; + + 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/server.js b/lib/cartodb/server.js index f9161b21..0641629c 100644 --- a/lib/cartodb/server.js +++ b/lib/cartodb/server.js @@ -7,6 +7,9 @@ var cartodbRedis = require('cartodb-redis'); var _ = require('underscore'); var controller = require('./controllers'); +const AdminTemplateController = require('./controllers/template/admin'); +const PreviewTemplateController = require('./controllers/template/preview'); +const TileTemplateController = require('./controllers/template/tile'); var SurrogateKeysCache = require('./cache/surrogate_keys_cache'); var NamedMapsCacheEntry = require('./cache/model/named_maps_entry'); @@ -224,8 +227,6 @@ module.exports = function(serverOptions) { const templateRouter = express.Router(); const monitorRouter = express.Router(); - const { base_url_mapconfig: mapConfigBasePath, base_url_templated: templateBasePath } = serverOptions; - new controller.Layergroup( pgConnection, mapStore, @@ -252,9 +253,17 @@ module.exports = function(serverOptions) { authApi ).register(mapRouter, templateRouter); - new controller.NamedMaps( + new TileTemplateController( namedMapProviderCache, tileBackend, + surrogateKeysCache, + pgConnection, + authApi, + userLimitsApi + ).register(templateRouter); + + new PreviewTemplateController( + namedMapProviderCache, previewBackend, surrogateKeysCache, tablesExtentApi, @@ -262,14 +271,20 @@ module.exports = function(serverOptions) { pgConnection, authApi, userLimitsApi - ).register(mapRouter, templateRouter); + ).register(mapRouter); - new controller.NamedMapsAdmin(authApi, templateMaps, userLimitsApi).register(templateRouter); + new AdminTemplateController( + authApi, + templateMaps, + userLimitsApi + ).register(templateRouter); new controller.Analyses(pgConnection, authApi, userLimitsApi).register(mapRouter); new controller.ServerInfo(versions).register(monitorRouter); + const { base_url_mapconfig: mapConfigBasePath, base_url_templated: templateBasePath } = serverOptions; + app.use(mapConfigBasePath, mapRouter); app.use(templateBasePath, templateRouter); app.use('/', monitorRouter);