From fa84813a37af07107c5973a7c5a795ce5420bf13 Mon Sep 17 00:00:00 2001 From: Raul Ochoa Date: Wed, 8 Jul 2015 13:27:56 +0200 Subject: [PATCH] Manage cors with a middleware --- lib/cartodb/controllers/map.js | 28 +++++++------------- lib/cartodb/controllers/named_maps.js | 17 +++--------- lib/cartodb/controllers/named_maps_admin.js | 26 +++++------------- lib/cartodb/controllers/named_static_maps.js | 6 +++-- lib/cartodb/controllers/static_maps.js | 7 +++-- lib/cartodb/middleware/cors.js | 11 ++++++++ lib/cartodb/server.js | 11 -------- 7 files changed, 38 insertions(+), 68 deletions(-) create mode 100644 lib/cartodb/middleware/cors.js diff --git a/lib/cartodb/controllers/map.js b/lib/cartodb/controllers/map.js index bff2b3b5..3abcd134 100644 --- a/lib/cartodb/controllers/map.js +++ b/lib/cartodb/controllers/map.js @@ -2,6 +2,8 @@ var assert = require('assert'); var step = require('step'); +var cors = require('../middleware/cors'); + /** * @param app * @param {MapBackend} mapBackend @@ -18,29 +20,20 @@ module.exports = MapController; MapController.prototype.register = function(app) { - app.get(app.base_url_mapconfig + '/:token/:z/:x/:y@:scale_factor?x.:format', this.tile.bind(this)); - app.get(app.base_url_mapconfig + '/:token/:z/:x/:y.:format', this.tile.bind(this)); - app.get(app.base_url_mapconfig + '/:token/:layer/:z/:x/:y.(:format)', this.layer.bind(this)); - app.options(app.base_url_mapconfig, this.cors.bind(this)); - app.get(app.base_url_mapconfig, this.createGet.bind(this)); - app.post(app.base_url_mapconfig, this.createPost.bind(this)); - app.get(app.base_url_mapconfig + '/:token/:layer/attributes/:fid', this.attributes.bind(this)); + app.get(app.base_url_mapconfig + '/:token/:z/:x/:y@:scale_factor?x.:format', cors(), this.tile.bind(this)); + app.get(app.base_url_mapconfig + '/:token/:z/:x/:y.:format', cors(), this.tile.bind(this)); + app.get(app.base_url_mapconfig + '/:token/:layer/:z/:x/:y.(:format)', cors(), this.layer.bind(this)); + app.options(app.base_url_mapconfig, cors('Content-Type')); + app.get(app.base_url_mapconfig, cors(), this.createGet.bind(this)); + app.post(app.base_url_mapconfig, cors(), this.createPost.bind(this)); + app.get(app.base_url_mapconfig + '/:token/:layer/attributes/:fid', cors(), this.attributes.bind(this)); }; -// send CORS headers when client send options. -MapController.prototype.cors = function(req, res, next) { - this._app.doCORS(res, "Content-Type"); - return next(); -}; - -// Gets attributes for a given layer feature MapController.prototype.attributes = function(req, res) { var self = this; req.profiler.start('windshaft.maplayer_attribute'); - this._app.doCORS(res); - step( function setupParams() { self._app.req2params(req, this); @@ -71,8 +64,6 @@ MapController.prototype.attributes = function(req, res) { MapController.prototype.create = function(req, res, prepareConfigFn) { var self = this; - this._app.doCORS(res); - var layergroupDecorator = { beforeLayergroupCreate: function(requestMapConfig, callback) { self._layergroupRequestDecorator.beforeLayergroupCreate(req, requestMapConfig, callback); @@ -146,7 +137,6 @@ MapController.prototype.layer = function(req, res, next) { MapController.prototype.tileOrLayer = function (req, res) { var self = this; - this._app.doCORS(res); step( function mapController$prepareParams() { self._app.req2params(req, this); diff --git a/lib/cartodb/controllers/named_maps.js b/lib/cartodb/controllers/named_maps.js index 2806d4dd..551aa208 100644 --- a/lib/cartodb/controllers/named_maps.js +++ b/lib/cartodb/controllers/named_maps.js @@ -4,6 +4,7 @@ var _ = require('underscore'); var templateName = require('../backends/template_maps').templateName; var CdbRequest = require('../models/cdb_request'); var NamedMapsCacheEntry = require('../cache/model/named_maps_entry'); +var cors = require('../middleware/cors'); function NamedMapsController(app, templateMaps, metadataBackend, mapBackend, templateBaseUrl, surrogateKeysCache, layergroupRequestDecorator) { @@ -21,17 +22,14 @@ module.exports = NamedMapsController; var cdbRequest = new CdbRequest(); NamedMapsController.prototype.register = function(app) { - app.get(this.templateBaseUrl + '/:template_id/:layer/:z/:x/:y.:format', this.tile.bind(this)); - app.get(this.templateBaseUrl + '/:template_id/jsonp', this.jsonp.bind(this)); - app.options(this.templateBaseUrl + '/:template_id', this.options.bind(this)); - app.post(this.templateBaseUrl + '/:template_id', this.instantiate.bind(this)); + app.get(this.templateBaseUrl + '/:template_id/:layer/:z/:x/:y.:format', cors(), this.tile.bind(this)); + app.get(this.templateBaseUrl + '/:template_id/jsonp', cors(), this.jsonp.bind(this)); + app.post(this.templateBaseUrl + '/:template_id', cors(), this.instantiate.bind(this)); }; NamedMapsController.prototype.tile = function(req, res) { var self = this; - this.app.doCORS(res); - var cdbUser = cdbRequest.userByReq(req); var template; var layergroupConfig; @@ -172,11 +170,6 @@ NamedMapsController.prototype.instantiate = function(req, res) { ); }; -NamedMapsController.prototype.options = function(req, res, next) { - this.app.doCORS(res, "Content-Type"); - return next(); -}; - /** * jsonp endpoint, allows to instantiate a template with a json call. * callback query argument is mandatory @@ -212,8 +205,6 @@ NamedMapsController.prototype.jsonp = function(req, res) { NamedMapsController.prototype.instantiateTemplate = function(req, res, template_params, callback) { var self = this; - this.app.doCORS(res); - var layergroupDecorator = { beforeLayergroupCreate: function(requestMapConfig, callback) { self.layergroupRequestDecorator.beforeLayergroupCreate(req, requestMapConfig, callback); diff --git a/lib/cartodb/controllers/named_maps_admin.js b/lib/cartodb/controllers/named_maps_admin.js index 4fd639b1..80dc9870 100644 --- a/lib/cartodb/controllers/named_maps_admin.js +++ b/lib/cartodb/controllers/named_maps_admin.js @@ -3,6 +3,7 @@ var assert = require('assert'); var _ = require('underscore'); var templateName = require('../backends/template_maps').templateName; var CdbRequest = require('../models/cdb_request'); +var cors = require('../middleware/cors'); function NamedMapsAdminController(app, templateMaps, templateBaseUrl) { @@ -16,19 +17,17 @@ module.exports = NamedMapsAdminController; var cdbRequest = new CdbRequest(); NamedMapsAdminController.prototype.register = function(app) { - app.post(this.templateBaseUrl, this.create.bind(this)); - app.put(this.templateBaseUrl + '/:template_id', this.update.bind(this)); - app.get(this.templateBaseUrl + '/:template_id', this.retrieve.bind(this)); - app.del(this.templateBaseUrl + '/:template_id', this.destroy.bind(this)); - app.get(this.templateBaseUrl, this.list.bind(this)); - app.options(this.templateBaseUrl + '/:template_id', this.options.bind(this)); + app.post(this.templateBaseUrl, cors(), this.create.bind(this)); + app.put(this.templateBaseUrl + '/:template_id', cors(), this.update.bind(this)); + app.get(this.templateBaseUrl + '/:template_id', cors(), this.retrieve.bind(this)); + app.del(this.templateBaseUrl + '/:template_id', cors(), this.destroy.bind(this)); + app.get(this.templateBaseUrl, cors(), this.list.bind(this)); + app.options(this.templateBaseUrl + '/:template_id', cors('Content-Type')); }; NamedMapsAdminController.prototype.create = function(req, res) { var self = this; - this.app.doCORS(res); - var cdbuser = cdbRequest.userByReq(req); step( @@ -53,8 +52,6 @@ NamedMapsAdminController.prototype.create = function(req, res) { NamedMapsAdminController.prototype.update = function(req, res) { var self = this; - this.app.doCORS(res); - var cdbuser = cdbRequest.userByReq(req); var template; var tpl_id; @@ -87,8 +84,6 @@ NamedMapsAdminController.prototype.retrieve = function(req, res) { req.profiler.start('windshaft-cartodb.get_template'); } - this.app.doCORS(res); - var cdbuser = cdbRequest.userByReq(req); var tpl_id; step( @@ -124,7 +119,6 @@ NamedMapsAdminController.prototype.destroy = function(req, res) { if (req.profiler) { req.profiler.start('windshaft-cartodb.delete_template'); } - this.app.doCORS(res); var cdbuser = cdbRequest.userByReq(req); var tpl_id; @@ -152,7 +146,6 @@ NamedMapsAdminController.prototype.list = function(req, res) { if ( req.profiler ) { req.profiler.start('windshaft-cartodb.get_template_list'); } - this.app.doCORS(res); var cdbuser = cdbRequest.userByReq(req); @@ -174,11 +167,6 @@ NamedMapsAdminController.prototype.list = function(req, res) { ); }; -NamedMapsAdminController.prototype.options = function(req, res, next) { - this.app.doCORS(res, "Content-Type"); - return next(); -}; - function finishFn(app, res, description, okResponse) { return function finish(err, response){ var statusCode = 200; diff --git a/lib/cartodb/controllers/named_static_maps.js b/lib/cartodb/controllers/named_static_maps.js index 89428262..0694ddbd 100644 --- a/lib/cartodb/controllers/named_static_maps.js +++ b/lib/cartodb/controllers/named_static_maps.js @@ -4,6 +4,7 @@ var templateName = require('../backends/template_maps').templateName; var CdbRequest = require('../models/cdb_request'); var NamedMapsCacheEntry = require('../cache/model/named_maps_entry'); var _ = require('underscore'); +var cors = require('../middleware/cors'); function NamedStaticMapsController(app, serverOptions, templateMaps, mapBackend, staticMapBackend, surrogateKeysCache, tablesExtentApi, layergroupRequestDecorator) { @@ -22,13 +23,14 @@ module.exports = NamedStaticMapsController; var cdbRequest = new CdbRequest(); NamedStaticMapsController.prototype.register = function(app) { - app.get(app.base_url_mapconfig + '/static/named/:template_id/:width/:height.:format', this.named.bind(this)); + app.get( + app.base_url_mapconfig + '/static/named/:template_id/:width/:height.:format', cors(), this.named.bind(this) + ); }; NamedStaticMapsController.prototype.named = function(req, res) { var self = this; - this.app.doCORS(res); var cdbUser = cdbRequest.userByReq(req); var format = req.params.format === 'jpg' ? 'jpeg' : 'png'; diff --git a/lib/cartodb/controllers/static_maps.js b/lib/cartodb/controllers/static_maps.js index 6511dc76..c147e842 100644 --- a/lib/cartodb/controllers/static_maps.js +++ b/lib/cartodb/controllers/static_maps.js @@ -1,5 +1,6 @@ var step = require('step'); var assert = require('assert'); +var cors = require('../middleware/cors'); function StaticMapsController(app, staticMapBackend) { this._app = app; @@ -10,10 +11,10 @@ module.exports = StaticMapsController; StaticMapsController.prototype.register = function(app) { - app.get(app.base_url_mapconfig + '/static/center/:token/:z/:lat/:lng/:width/:height.:format', + app.get(app.base_url_mapconfig + '/static/center/:token/:z/:lat/:lng/:width/:height.:format', cors(), this.center.bind(this)); - app.get(app.base_url_mapconfig + '/static/bbox/:token/:west,:south,:east,:north/:width/:height.:format', + app.get(app.base_url_mapconfig + '/static/bbox/:token/:west,:south,:east,:north/:width/:height.:format', cors(), this.bbox.bind(this)); }; @@ -34,8 +35,6 @@ StaticMapsController.prototype.center = function(req, res) { }; StaticMapsController.prototype.staticMap = function(req, res, width, height, zoom /* bounds */, center) { - this._app.doCORS(res); - var format = req.params.format === 'jpg' ? 'jpeg' : 'png'; var self = this; diff --git a/lib/cartodb/middleware/cors.js b/lib/cartodb/middleware/cors.js new file mode 100644 index 00000000..f34e4d42 --- /dev/null +++ b/lib/cartodb/middleware/cors.js @@ -0,0 +1,11 @@ +module.exports = function cors(extraHeaders) { + return function(req, res, next) { + var baseHeaders = "X-Requested-With, X-Prototype-Version, X-CSRF-Token"; + if(extraHeaders) { + baseHeaders += ", " + extraHeaders; + } + res.header("Access-Control-Allow-Origin", "*"); + res.header("Access-Control-Allow-Headers", baseHeaders); + next(); + }; +}; \ No newline at end of file diff --git a/lib/cartodb/server.js b/lib/cartodb/server.js index 00cd3390..2281ff5d 100644 --- a/lib/cartodb/server.js +++ b/lib/cartodb/server.js @@ -927,17 +927,6 @@ module.exports = function(serverOptions) { ); }; - app.doCORS = function(res, extraHeaders) { - if (serverOptions.enable_cors) { - var baseHeaders = "X-Requested-With, X-Prototype-Version, X-CSRF-Token"; - if(extraHeaders) { - baseHeaders += ", " + extraHeaders; - } - res.header("Access-Control-Allow-Origin", "*"); - res.header("Access-Control-Allow-Headers", baseHeaders); - } - }; - return app; };