Merge branch 'standalone-server' into standalone-server-mvt

Conflicts:
	npm-shrinkwrap.json
	package.json
This commit is contained in:
Raul Ochoa 2015-09-18 01:34:14 +02:00
commit c97f78bb39
40 changed files with 987 additions and 982 deletions

View File

@ -18,35 +18,26 @@ config.status--test:
config/environments/test.js: config.status--test
./config.status--test
TEST_SUITE := $(shell find test/{acceptance,integration,unit} -name "*.js")
TEST_SUITE_UNIT := $(shell find test/unit -name "*.js")
TEST_SUITE_INTEGRATION := $(shell find test/integration -name "*.js")
TEST_SUITE_ACCEPTANCE := $(shell find test/acceptance -name "*.js")
test: config/environments/test.js
@echo "***tests***"
@$(SHELL) ./run_tests.sh ${RUNTESTFLAGS} \
test/unit/cartodb/*.js \
test/unit/cartodb/ported/*.js \
test/unit/cartodb/cache/model/*.js \
test/integration/*.js \
test/acceptance/*.js \
test/acceptance/cache/*.js \
test/acceptance/ported/*.js \
test/unit/cartodb/ported/*.js
@$(SHELL) ./run_tests.sh ${RUNTESTFLAGS} $(TEST_SUITE)
test-unit: config/environments/test.js
@echo "***tests***"
@$(SHELL) ./run_tests.sh ${RUNTESTFLAGS} \
test/unit/cartodb/*.js \
test/unit/cartodb/ported/*.js \
test/unit/cartodb/cache/model/*.js
@$(SHELL) ./run_tests.sh ${RUNTESTFLAGS} $(TEST_SUITE_UNIT)
test-integration: config/environments/test.js
@echo "***tests***"
@$(SHELL) ./run_tests.sh ${RUNTESTFLAGS} \
test/integration/*.js
@$(SHELL) ./run_tests.sh ${RUNTESTFLAGS} $(TEST_SUITE_INTEGRATION)
test-acceptance: config/environments/test.js
@echo "***tests***"
@$(SHELL) ./run_tests.sh ${RUNTESTFLAGS} \
test/acceptance/*.js \
test/acceptance/cache/*.js
@$(SHELL) ./run_tests.sh ${RUNTESTFLAGS} $(TEST_SUITE_ACCEPTANCE)
jshint:
@echo "***jshint***"

View File

@ -0,0 +1,241 @@
var assert = require('assert');
var _ = require('underscore');
var step = require('step');
var debug = require('debug')('windshaft:cartodb');
var LZMA = require('lzma').LZMA;
var lzmaWorker = new LZMA();
// Whitelist query parameters and attach format
var REQUEST_QUERY_PARAMS_WHITELIST = [
'config',
'map_key',
'api_key',
'auth_token',
'callback'
];
function BaseController(authApi, pgConnection) {
this.authApi = authApi;
this.pgConnection = pgConnection;
}
module.exports = BaseController;
// jshint maxcomplexity:9
/**
* Whitelist input and get database name & default geometry type from
* subdomain/user metadata held in CartoDB Redis
* @param req - standard express request obj. Should have host & table
* @param callback
*/
BaseController.prototype.req2params = function(req, callback){
var self = this;
if ( req.query.lzma ) {
// Decode (from base64)
var lzma = new Buffer(req.query.lzma, 'base64')
.toString('binary')
.split('')
.map(function(c) {
return c.charCodeAt(0) - 128;
});
// Decompress
lzmaWorker.decompress(
lzma,
function(result) {
if (req.profiler) {
req.profiler.done('lzma');
}
try {
delete req.query.lzma;
_.extend(req.query, JSON.parse(result));
self.req2params(req, callback);
} catch (err) {
req.profiler.done('req2params');
callback(new Error('Error parsing lzma as JSON: ' + err));
}
}
);
return;
}
req.query = _.pick(req.query, REQUEST_QUERY_PARAMS_WHITELIST);
req.params = _.extend({}, req.params); // shuffle things as request is a strange array/object
var user = req.context.user;
if ( req.params.token ) {
// Token might match the following patterns:
// - {user}@{tpl_id}@{token}:{cache_buster}
//console.log("Request parameters include token " + req.params.token);
var tksplit = req.params.token.split(':');
req.params.token = tksplit[0];
if ( tksplit.length > 1 ) {
req.params.cache_buster= tksplit[1];
}
tksplit = req.params.token.split('@');
if ( tksplit.length > 1 ) {
req.params.signer = tksplit.shift();
if ( ! req.params.signer ) {
req.params.signer = user;
}
else if ( req.params.signer !== user ) {
var err = new Error(
'Cannot use map signature of user "' + req.params.signer + '" on db of user "' + user + '"'
);
err.http_status = 403;
req.profiler.done('req2params');
callback(err);
return;
}
if ( tksplit.length > 1 ) {
/*var template_hash = */tksplit.shift(); // unused
}
req.params.token = tksplit.shift();
//console.log("Request for token " + req.params.token + " with signature from " + req.params.signer);
}
}
// bring all query values onto req.params object
_.extend(req.params, req.query);
if (req.profiler) {
req.profiler.done('req2params.setup');
}
step(
function getPrivacy(){
self.authApi.authorize(req, this);
},
function validateAuthorization(err, authorized) {
if (req.profiler) {
req.profiler.done('authorize');
}
assert.ifError(err);
if(!authorized) {
err = new Error("Sorry, you are unauthorized (permission denied)");
err.http_status = 403;
throw err;
}
return null;
},
function getDatabase(err){
assert.ifError(err);
self.pgConnection.setDBConn(user, req.params, this);
},
function finishSetup(err) {
if ( err ) {
req.profiler.done('req2params');
return callback(err, req);
}
// Add default database connection parameters
// if none given
_.defaults(req.params, {
dbuser: global.environment.postgres.user,
dbpassword: global.environment.postgres.password,
dbhost: global.environment.postgres.host,
dbport: global.environment.postgres.port
});
req.profiler.done('req2params');
callback(null, req);
}
);
};
// jshint maxcomplexity:6
BaseController.prototype.send = function(req, res, args) {
if (global.environment && global.environment.api_hostname) {
res.header('X-Served-By-Host', global.environment.api_hostname);
}
if (req.params && req.params.dbhost) {
res.header('X-Served-By-DB-Host', req.params.dbhost);
}
if (req.profiler) {
res.header('X-Tiler-Profiler', req.profiler.toJSONString());
}
res.send.apply(res, args);
if (req.profiler ) {
try {
// May throw due to dns, see
// See http://github.com/CartoDB/Windshaft/issues/166
req.profiler.sendStats();
} catch (err) {
debug("error sending profiling stats: " + err);
}
}
};
BaseController.prototype.sendError = function(req, res, err, label) {
label = label || 'UNKNOWN';
var statusCode = findStatusCode(err);
debug('[%s ERROR] -- %d: %s', label, statusCode, err);
// If a callback was requested, force status to 200
if (req.query && req.query.callback) {
statusCode = 200;
}
var errorResponseBody = { errors: [errorMessage(err)] };
this.send(req, res, [errorResponseBody, statusCode]);
};
function errorMessage(err) {
// See https://github.com/Vizzuality/Windshaft-cartodb/issues/68
var message = (_.isString(err) ? err : err.message) || 'Unknown error';
// Strip connection info, if any
return message
// See https://github.com/CartoDB/Windshaft/issues/173
.replace(/Connection string: '[^']*'\n\s/im, '')
// See https://travis-ci.org/CartoDB/Windshaft/jobs/20703062#L1644
.replace(/is the server.*encountered/im, 'encountered');
}
module.exports.errorMessage = errorMessage;
function findStatusCode(err) {
var statusCode;
if ( err.http_status ) {
statusCode = err.http_status;
} else {
statusCode = statusFromErrorMessage('' + err);
}
return statusCode;
}
module.exports.findStatusCode = findStatusCode;
function statusFromErrorMessage(errMsg) {
// Find an appropriate statusCode based on message
var statusCode = 400;
if ( -1 !== errMsg.indexOf('permission denied') ) {
statusCode = 403;
}
else if ( -1 !== errMsg.indexOf('authentication failed') ) {
statusCode = 403;
}
else if (errMsg.match(/Postgis Plugin.*[\s|\n].*column.*does not exist/)) {
statusCode = 400;
}
else if ( -1 !== errMsg.indexOf('does not exist') ) {
if ( -1 !== errMsg.indexOf(' role ') ) {
statusCode = 403; // role 'xxx' does not exist
} else {
statusCode = 404;
}
}
return statusCode;
}

View File

@ -1,6 +1,9 @@
var assert = require('assert');
var step = require('step');
var util = require('util');
var BaseController = require('./base');
var cors = require('../middleware/cors');
var MapStoreMapConfigProvider = require('../models/mapconfig/map_store_provider');
@ -8,6 +11,8 @@ var TablesCacheEntry = require('../cache/model/database_tables_entry');
/**
* @param app
* @param {AuthApi} authApi
* @param {PgConnection} pgConnection
* @param {MapStore} mapStore
* @param {TileBackend} tileBackend
* @param {PreviewBackend} previewBackend
@ -18,8 +23,10 @@ var TablesCacheEntry = require('../cache/model/database_tables_entry');
* @param {LayergroupAffectedTables} layergroupAffectedTables
* @constructor
*/
function LayergroupController(app, mapStore, tileBackend, previewBackend, attributesBackend, surrogateKeysCache,
userLimitsApi, queryTablesApi, layergroupAffectedTables) {
function LayergroupController(app, authApi, pgConnection, mapStore, tileBackend, previewBackend, attributesBackend,
surrogateKeysCache, userLimitsApi, queryTablesApi, layergroupAffectedTables) {
BaseController.call(this, authApi, pgConnection);
this.app = app;
this.mapStore = mapStore;
this.tileBackend = tileBackend;
@ -31,6 +38,8 @@ function LayergroupController(app, mapStore, tileBackend, previewBackend, attrib
this.layergroupAffectedTables = layergroupAffectedTables;
}
util.inherits(LayergroupController, BaseController);
module.exports = LayergroupController;
@ -52,7 +61,7 @@ LayergroupController.prototype.attributes = function(req, res) {
step(
function setupParams() {
self.app.req2params(req, this);
self.req2params(req, this);
},
function retrieveFeatureAttributes(err) {
assert.ifError(err);
@ -66,7 +75,7 @@ LayergroupController.prototype.attributes = function(req, res) {
req.profiler.add(stats || {});
if (err) {
res.sendError(err, 'GET ATTRIBUTES');
self.sendError(req, res, err, 'GET ATTRIBUTES');
} else {
self.sendResponse(req, res, [tile, 200]);
}
@ -95,7 +104,7 @@ LayergroupController.prototype.tileOrLayer = function (req, res) {
step(
function mapController$prepareParams() {
self.app.req2params(req, this);
self.req2params(req, this);
},
function mapController$getTileOrGrid(err) {
assert.ifError(err);
@ -146,7 +155,7 @@ LayergroupController.prototype.finalizeGetTileOrGrid = function(err, req, res, t
}
err.message = errMsg;
res.sendError(err, 'TILE RENDER');
this.sendError(req, res, err, 'TILE RENDER');
global.statsClient.increment('windshaft.tiles.error');
global.statsClient.increment('windshaft.tiles.' + formatStat + '.error');
} else {
@ -181,7 +190,7 @@ LayergroupController.prototype.staticMap = function(req, res, width, height, zoo
step(
function() {
self.app.req2params(req, this);
self.req2params(req, this);
},
function(err) {
assert.ifError(err);
@ -200,7 +209,7 @@ LayergroupController.prototype.staticMap = function(req, res, width, height, zoo
req.profiler.add(stats || {});
if (err) {
res.sendError(err, 'STATIC_MAP');
self.sendError(req, res, err, 'STATIC_MAP');
} else {
res.setHeader('Content-Type', headers['Content-Type'] || 'image/' + format);
self.sendResponse(req, res, [image, 200]);
@ -239,7 +248,7 @@ LayergroupController.prototype.sendResponse = function(req, res, args) {
res.header('X-Cache-Channel', tablesCacheEntry.getCacheChannel());
self.surrogateKeysCache.tag(res, tablesCacheEntry);
}
res.sendResponse(args);
self.send(req, res, args);
}
);

View File

@ -3,6 +3,9 @@ var assert = require('assert');
var step = require('step');
var windshaft = require('windshaft');
var util = require('util');
var BaseController = require('./base');
var cors = require('../middleware/cors');
var MapConfig = windshaft.model.MapConfig;
@ -17,6 +20,7 @@ var CreateLayergroupMapConfigProvider = require('../models/mapconfig/create_laye
/**
* @param app
* @param {AuthApi} authApi
* @param {PgConnection} pgConnection
* @param {TemplateMaps} templateMaps
* @param {MapBackend} mapBackend
@ -27,8 +31,11 @@ var CreateLayergroupMapConfigProvider = require('../models/mapconfig/create_laye
* @param {LayergroupAffectedTables} layergroupAffectedTables
* @constructor
*/
function MapController(app, pgConnection, templateMaps, mapBackend, metadataBackend, queryTablesApi,
function MapController(app, authApi, pgConnection, templateMaps, mapBackend, metadataBackend, queryTablesApi,
surrogateKeysCache, userLimitsApi, layergroupAffectedTables) {
BaseController.call(this, authApi, pgConnection);
this.app = app;
this.pgConnection = pgConnection;
this.templateMaps = templateMaps;
@ -42,6 +49,8 @@ function MapController(app, pgConnection, templateMaps, mapBackend, metadataBack
this.namedLayersAdapter = new MapConfigNamedLayersAdapter(templateMaps);
}
util.inherits(MapController, BaseController);
module.exports = MapController;
@ -121,7 +130,7 @@ MapController.prototype.create = function(req, res, prepareConfigFn) {
step(
function setupParams(){
self.app.req2params(req, this);
self.req2params(req, this);
},
prepareConfigFn,
function beforeLayergroupCreate(err, requestMapConfig) {
@ -155,10 +164,10 @@ MapController.prototype.create = function(req, res, prepareConfigFn) {
},
function finish(err, layergroup) {
if (err) {
res.sendError(err, 'ANONYMOUS LAYERGROUP');
self.sendError(req, res, err, 'ANONYMOUS LAYERGROUP');
} else {
res.header('X-Layergroup-Id', layergroup.layergroupid);
res.sendResponse([layergroup, 200]);
self.send(req, res, [layergroup, 200]);
}
}
);
@ -174,7 +183,7 @@ MapController.prototype.instantiateTemplate = function(req, res, prepareParamsFn
step(
function setupParams(){
self.app.req2params(req, this);
self.req2params(req, this);
},
function getTemplateParams() {
prepareParamsFn(this);
@ -209,7 +218,7 @@ MapController.prototype.instantiateTemplate = function(req, res, prepareParamsFn
},
function finishTemplateInstantiation(err, layergroup) {
if (err) {
res.sendError(err, 'NAMED MAP LAYERGROUP');
self.sendError(req, res, err, 'NAMED MAP LAYERGROUP');
} else {
var templateHash = self.templateMaps.fingerPrint(mapConfigProvider.template).substring(0, 8);
layergroup.layergroupid = cdbuser + '@' + templateHash + '@' + layergroup.layergroupid;
@ -217,7 +226,7 @@ MapController.prototype.instantiateTemplate = function(req, res, prepareParamsFn
res.header('X-Layergroup-Id', layergroup.layergroupid);
self.surrogateKeysCache.tag(res, new NamedMapsCacheEntry(cdbuser, mapConfigProvider.getTemplateName()));
res.sendResponse([layergroup, 200]);
self.send(req, res, [layergroup, 200]);
}
}
);

View File

@ -2,12 +2,18 @@ var step = require('step');
var assert = require('assert');
var _ = require('underscore');
var NamedMapsCacheEntry = require('../cache/model/named_maps_entry');
var util = require('util');
var BaseController = require('./base');
var cors = require('../middleware/cors');
var TablesCacheEntry = require('../cache/model/database_tables_entry');
function NamedMapsController(app, namedMapProviderCache, tileBackend, previewBackend, surrogateKeysCache,
tablesExtentApi) {
function NamedMapsController(app, authApi, pgConnection, namedMapProviderCache, tileBackend, previewBackend,
surrogateKeysCache, tablesExtentApi) {
BaseController.call(this, authApi, pgConnection);
this.app = app;
this.namedMapProviderCache = namedMapProviderCache;
this.tileBackend = tileBackend;
@ -16,6 +22,8 @@ function NamedMapsController(app, namedMapProviderCache, tileBackend, previewBac
this.tablesExtentApi = tablesExtentApi;
}
util.inherits(NamedMapsController, BaseController);
module.exports = NamedMapsController;
NamedMapsController.prototype.register = function(app) {
@ -60,7 +68,7 @@ NamedMapsController.prototype.sendResponse = function(req, res, resource, header
self.surrogateKeysCache.tag(res, tablesCacheEntry);
}
}
res.sendResponse([resource, 200]);
self.send(req, res, [resource, 200]);
}
);
};
@ -73,7 +81,7 @@ NamedMapsController.prototype.tile = function(req, res) {
var namedMapProvider;
step(
function reqParams() {
self.app.req2params(req, this);
self.req2params(req, this);
},
function getTile() {
namedMapProvider = self.namedMapProviderCache.get(
@ -90,7 +98,7 @@ NamedMapsController.prototype.tile = function(req, res) {
req.profiler.add(stats);
}
if (err) {
res.sendError(err, 'NAMED_MAP_TILE');
self.sendError(req, res, err, 'NAMED_MAP_TILE');
} else {
self.sendResponse(req, res, tile, headers, namedMapProvider);
}
@ -110,7 +118,7 @@ NamedMapsController.prototype.staticMap = function(req, res) {
var namedMapProvider;
step(
function reqParams() {
self.app.req2params(req, this);
self.req2params(req, this);
},
function getTemplate(err) {
assert.ifError(err);
@ -179,7 +187,7 @@ NamedMapsController.prototype.staticMap = function(req, res) {
}
if (err) {
res.sendError(err, 'STATIC_VIZ_MAP');
self.sendError(req, res, err, 'STATIC_VIZ_MAP');
} else {
self.sendResponse(req, res, image, headers, namedMapProvider);
}

View File

@ -1,19 +1,28 @@
var step = require('step');
var assert = require('assert');
var templateName = require('../backends/template_maps').templateName;
var util = require('util');
var BaseController = require('./base');
var cors = require('../middleware/cors');
/**
* @param {TemplateMaps} templateMaps
* @param {AuthApi} authApi
* @param {PgConnection} pgConnection
* @constructor
*/
function NamedMapsAdminController(templateMaps, authApi) {
function NamedMapsAdminController(templateMaps, authApi, pgConnection) {
BaseController.call(this, authApi, pgConnection);
this.templateMaps = templateMaps;
this.authApi = authApi;
}
util.inherits(NamedMapsAdminController, BaseController);
module.exports = NamedMapsAdminController;
NamedMapsAdminController.prototype.register = function(app) {
@ -45,7 +54,7 @@ NamedMapsAdminController.prototype.create = function(req, res) {
assert.ifError(err);
return { template_id: tpl_id };
},
finishFn(res, 'POST TEMPLATE')
finishFn(self, req, res, 'POST TEMPLATE')
);
};
@ -73,7 +82,7 @@ NamedMapsAdminController.prototype.update = function(req, res) {
return { template_id: tpl_id };
},
finishFn(res, 'PUT TEMPLATE')
finishFn(self, req, res, 'PUT TEMPLATE')
);
};
@ -109,7 +118,7 @@ NamedMapsAdminController.prototype.retrieve = function(req, res) {
delete tpl_val.auth_id;
return { template: tpl_val };
},
finishFn(res, 'GET TEMPLATE')
finishFn(self, req, res, 'GET TEMPLATE')
);
};
@ -137,7 +146,7 @@ NamedMapsAdminController.prototype.destroy = function(req, res) {
assert.ifError(err);
return { status: 'ok' };
},
finishFn(res, 'DELETE TEMPLATE', ['', 204])
finishFn(self, req, res, 'DELETE TEMPLATE', ['', 204])
);
};
@ -163,16 +172,16 @@ NamedMapsAdminController.prototype.list = function(req, res) {
assert.ifError(err);
return { template_ids: tpl_ids };
},
finishFn(res, 'GET TEMPLATE LIST')
finishFn(self, req, res, 'GET TEMPLATE LIST')
);
};
function finishFn(res, description, okResponse) {
function finishFn(controller, req, res, description, okResponse) {
return function finish(err, response){
if (err) {
res.sendError(err, description);
controller.sendError(req, res, err, description);
} else {
res.sendResponse(okResponse || [response, 200]);
controller.send(req, res, okResponse || [response, 200]);
}
};
}

View File

@ -1,10 +1,7 @@
var assert = require('assert');
var express = require('express');
var RedisPool = require('redis-mpool');
var cartodbRedis = require('cartodb-redis');
var _ = require('underscore');
var step = require('step');
var controller = require('./controllers');
@ -32,18 +29,6 @@ var PgConnection = require('./backends/pg_connection');
var CdbRequest = require('./models/cdb_request');
var cdbRequest = new CdbRequest();
var LZMA = require('lzma').LZMA;
// Whitelist query parameters and attach format
var REQUEST_QUERY_PARAMS_WHITELIST = [
'config',
'map_key',
'api_key',
'auth_token',
'callback'
];
var lzmaWorker = new LZMA();
var timeoutErrorTilePath = __dirname + '/../../assets/render-timeout-fallback.png';
var timeoutErrorTile = require('fs').readFileSync(timeoutErrorTilePath, {encoding: null});
@ -178,6 +163,8 @@ module.exports = function(serverOptions) {
new controller.Layergroup(
app,
authApi,
pgConnection,
mapStore,
tileBackend,
previewBackend,
@ -190,6 +177,7 @@ module.exports = function(serverOptions) {
new controller.Map(
app,
authApi,
pgConnection,
templateMaps,
mapBackend,
@ -202,6 +190,8 @@ module.exports = function(serverOptions) {
new controller.NamedMaps(
app,
authApi,
pgConnection,
namedMapProviderCache,
tileBackend,
previewBackend,
@ -209,7 +199,7 @@ module.exports = function(serverOptions) {
tablesExtentApi
).register(app);
new controller.NamedMapsAdmin(templateMaps, authApi).register(app);
new controller.NamedMapsAdmin(templateMaps, authApi, pgConnection).register(app);
new controller.ServerInfo().register(app);
@ -217,131 +207,6 @@ module.exports = function(serverOptions) {
* END Routing
******************************************************************************************************************/
// jshint maxcomplexity:10
/**
* Whitelist input and get database name & default geometry type from
* subdomain/user metadata held in CartoDB Redis
* @param req - standard express request obj. Should have host & table
* @param callback
*/
app.req2params = function(req, callback){
if ( req.query.lzma ) {
// Decode (from base64)
var lzma = new Buffer(req.query.lzma, 'base64')
.toString('binary')
.split('')
.map(function(c) {
return c.charCodeAt(0) - 128;
});
// Decompress
lzmaWorker.decompress(
lzma,
function(result) {
if (req.profiler) {
req.profiler.done('lzma');
}
try {
delete req.query.lzma;
_.extend(req.query, JSON.parse(result));
app.req2params(req, callback);
} catch (err) {
req.profiler.done('req2params');
callback(new Error('Error parsing lzma as JSON: ' + err));
}
}
);
return;
}
req.query = _.pick(req.query, REQUEST_QUERY_PARAMS_WHITELIST);
req.params = _.extend({}, req.params); // shuffle things as request is a strange array/object
var user = req.context.user;
if ( req.params.token ) {
// Token might match the following patterns:
// - {user}@{tpl_id}@{token}:{cache_buster}
//console.log("Request parameters include token " + req.params.token);
var tksplit = req.params.token.split(':');
req.params.token = tksplit[0];
if ( tksplit.length > 1 ) {
req.params.cache_buster= tksplit[1];
}
tksplit = req.params.token.split('@');
if ( tksplit.length > 1 ) {
req.params.signer = tksplit.shift();
if ( ! req.params.signer ) {
req.params.signer = user;
}
else if ( req.params.signer !== user ) {
var err = new Error(
'Cannot use map signature of user "' + req.params.signer + '" on db of user "' + user + '"'
);
err.http_status = 403;
req.profiler.done('req2params');
callback(err);
return;
}
if ( tksplit.length > 1 ) {
/*var template_hash = */tksplit.shift(); // unused
}
req.params.token = tksplit.shift();
//console.log("Request for token " + req.params.token + " with signature from " + req.params.signer);
}
}
// bring all query values onto req.params object
_.extend(req.params, req.query);
if (req.profiler) {
req.profiler.done('req2params.setup');
}
step(
function getPrivacy(){
authApi.authorize(req, this);
},
function validateAuthorization(err, authorized) {
if (req.profiler) {
req.profiler.done('authorize');
}
assert.ifError(err);
if(!authorized) {
err = new Error("Sorry, you are unauthorized (permission denied)");
err.http_status = 403;
throw err;
}
return null;
},
function getDatabase(err){
assert.ifError(err);
pgConnection.setDBConn(user, req.params, this);
},
function finishSetup(err) {
if ( err ) {
req.profiler.done('req2params');
return callback(err, req);
}
// Add default database connection parameters
// if none given
_.defaults(req.params, {
dbuser: global.environment.postgres.user,
dbpassword: global.environment.postgres.password,
dbhost: global.environment.postgres.host,
dbport: global.environment.postgres.port
});
req.profiler.done('req2params');
callback(null, req);
}
);
};
// jshint maxcomplexity:6
return app;
};
@ -390,62 +255,6 @@ function bootstrap(opts) {
res.removeHeader('x-powered-by');
res.sendResponse = function(args) {
if (global.environment && global.environment.api_hostname) {
res.header('X-Served-By-Host', global.environment.api_hostname);
}
if (req.params && req.params.dbhost) {
res.header('X-Served-By-DB-Host', req.params.dbhost);
}
if (req.profiler) {
res.header('X-Tiler-Profiler', req.profiler.toJSONString());
}
res.send.apply(res, args);
if (req.profiler ) {
try {
// May throw due to dns, see
// See http://github.com/CartoDB/Windshaft/issues/166
req.profiler.sendStats();
} catch (err) {
console.error("error sending profiling stats: " + err);
}
}
};
res.sendError = function(err, label) {
label = label || 'UNKNOWN';
var statusCode = findStatusCode(err);
// use console.log for statusCode != 500 ?
if (statusCode >= 500) {
console.error('[%s ERROR] -- %d: %s', label, statusCode, err);
} else {
console.warn('[%s WARN] -- %d: %s', label, statusCode, err);
}
// If a callback was requested, force status to 200
if (req.query.callback) {
statusCode = 200;
}
// See https://github.com/Vizzuality/Windshaft-cartodb/issues/68
var message = (_.isString(err) ? err : err.message) || 'Unknown error';
// Strip connection info, if any
message = message
// See https://github.com/CartoDB/Windshaft/issues/173
.replace(/Connection string: '[^']*'\\n/, '')
// See https://travis-ci.org/CartoDB/Windshaft/jobs/20703062#L1644
.replace(/is the server.*encountered/im, 'encountered');
var errorResponseBody = { errors: [message] };
res.sendResponse([errorResponseBody, statusCode]);
};
next();
});
@ -506,39 +315,6 @@ function surrogateKeysCacheBackends(serverOptions) {
return cacheBackends;
}
function findStatusCode(err) {
var statusCode;
if ( err.http_status ) {
statusCode = err.http_status;
} else {
statusCode = statusFromErrorMessage('' + err);
}
return statusCode;
}
module.exports.findStatusCode = findStatusCode;
function statusFromErrorMessage(errMsg) {
// Find an appropriate statusCode based on message
var statusCode = 400;
if ( -1 !== errMsg.indexOf('permission denied') ) {
statusCode = 403;
}
else if ( -1 !== errMsg.indexOf('authentication failed') ) {
statusCode = 403;
}
else if (errMsg.match(/Postgis Plugin.*[\s|\n].*column.*does not exist/)) {
statusCode = 400;
}
else if ( -1 !== errMsg.indexOf('does not exist') ) {
if ( -1 !== errMsg.indexOf(' role ') ) {
statusCode = 403; // role 'xxx' does not exist
} else {
statusCode = 404;
}
}
return statusCode;
}
function mapnikVersion(opts) {
return opts.grainstore.mapnik_version || mapnik.versions.mapnik;
}

909
npm-shrinkwrap.json generated
View File

@ -119,309 +119,7 @@
},
"fastly-purge": {
"version": "1.0.0",
"from": "fastly-purge@~1.0.0",
"dependencies": {
"request": {
"version": "2.62.0",
"from": "request@^2.55.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.62.0.tgz",
"dependencies": {
"bl": {
"version": "1.0.0",
"from": "bl@~1.0.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-1.0.0.tgz",
"dependencies": {
"readable-stream": {
"version": "2.0.2",
"from": "readable-stream@~2.0.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz",
"dependencies": {
"core-util-is": {
"version": "1.0.1",
"from": "core-util-is@~1.0.0",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz"
},
"inherits": {
"version": "2.0.1",
"from": "inherits@~2.0.1",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
},
"isarray": {
"version": "0.0.1",
"from": "isarray@0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
},
"process-nextick-args": {
"version": "1.0.3",
"from": "process-nextick-args@~1.0.0",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz"
},
"string_decoder": {
"version": "0.10.31",
"from": "string_decoder@~0.10.x",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
},
"util-deprecate": {
"version": "1.0.1",
"from": "util-deprecate@~1.0.1",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz"
}
}
}
}
},
"caseless": {
"version": "0.11.0",
"from": "caseless@~0.11.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz"
},
"extend": {
"version": "3.0.0",
"from": "extend@~3.0.0",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz"
},
"forever-agent": {
"version": "0.6.1",
"from": "forever-agent@~0.6.0",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz"
},
"form-data": {
"version": "1.0.0-rc3",
"from": "form-data@~1.0.0-rc1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.0-rc3.tgz",
"dependencies": {
"async": {
"version": "1.4.2",
"from": "async@^1.4.0",
"resolved": "https://registry.npmjs.org/async/-/async-1.4.2.tgz"
}
}
},
"json-stringify-safe": {
"version": "5.0.1",
"from": "json-stringify-safe@~5.0.0",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz"
},
"mime-types": {
"version": "2.1.6",
"from": "mime-types@~2.1.2",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.6.tgz",
"dependencies": {
"mime-db": {
"version": "1.18.0",
"from": "mime-db@~1.18.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.18.0.tgz"
}
}
},
"node-uuid": {
"version": "1.4.3",
"from": "node-uuid@~1.4.0",
"resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.3.tgz"
},
"qs": {
"version": "5.1.0",
"from": "qs@~5.1.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-5.1.0.tgz"
},
"tunnel-agent": {
"version": "0.4.1",
"from": "tunnel-agent@~0.4.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.1.tgz"
},
"tough-cookie": {
"version": "2.0.0",
"from": "tough-cookie@>=0.12.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.0.0.tgz"
},
"http-signature": {
"version": "0.11.0",
"from": "http-signature@~0.11.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.11.0.tgz",
"dependencies": {
"assert-plus": {
"version": "0.1.5",
"from": "assert-plus@^0.1.5",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz"
},
"asn1": {
"version": "0.1.11",
"from": "asn1@0.1.11",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz"
},
"ctype": {
"version": "0.5.3",
"from": "ctype@0.5.3",
"resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz"
}
}
},
"oauth-sign": {
"version": "0.8.0",
"from": "oauth-sign@~0.8.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.0.tgz"
},
"hawk": {
"version": "3.1.0",
"from": "hawk@~3.1.0",
"resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.0.tgz",
"dependencies": {
"hoek": {
"version": "2.16.0",
"from": "hoek@2.x.x",
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.0.tgz"
},
"boom": {
"version": "2.8.0",
"from": "boom@^2.8.x",
"resolved": "https://registry.npmjs.org/boom/-/boom-2.8.0.tgz"
},
"cryptiles": {
"version": "2.0.5",
"from": "cryptiles@2.x.x",
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz"
},
"sntp": {
"version": "1.0.9",
"from": "sntp@1.x.x",
"resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz"
}
}
},
"aws-sign2": {
"version": "0.5.0",
"from": "aws-sign2@~0.5.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz"
},
"stringstream": {
"version": "0.0.4",
"from": "stringstream@~0.0.4",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.4.tgz"
},
"combined-stream": {
"version": "1.0.5",
"from": "combined-stream@~1.0.1",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
"dependencies": {
"delayed-stream": {
"version": "1.0.0",
"from": "delayed-stream@~1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
}
}
},
"isstream": {
"version": "0.1.2",
"from": "isstream@~0.1.1",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz"
},
"har-validator": {
"version": "1.8.0",
"from": "har-validator@^1.6.1",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-1.8.0.tgz",
"dependencies": {
"bluebird": {
"version": "2.10.0",
"from": "bluebird@^2.9.30",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.10.0.tgz"
},
"chalk": {
"version": "1.1.1",
"from": "chalk@^1.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.1.tgz",
"dependencies": {
"ansi-styles": {
"version": "2.1.0",
"from": "ansi-styles@^2.1.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.1.0.tgz"
},
"escape-string-regexp": {
"version": "1.0.3",
"from": "escape-string-regexp@^1.0.2",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.3.tgz"
},
"has-ansi": {
"version": "2.0.0",
"from": "has-ansi@^2.0.0",
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
"dependencies": {
"ansi-regex": {
"version": "2.0.0",
"from": "ansi-regex@^2.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz"
}
}
},
"strip-ansi": {
"version": "3.0.0",
"from": "strip-ansi@^3.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz",
"dependencies": {
"ansi-regex": {
"version": "2.0.0",
"from": "ansi-regex@^2.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz"
}
}
},
"supports-color": {
"version": "2.0.0",
"from": "supports-color@^2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz"
}
}
},
"commander": {
"version": "2.8.1",
"from": "commander@^2.8.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
"dependencies": {
"graceful-readlink": {
"version": "1.0.1",
"from": "graceful-readlink@>= 1.0.0",
"resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz"
}
}
},
"is-my-json-valid": {
"version": "2.12.2",
"from": "is-my-json-valid@^2.12.0",
"resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.12.2.tgz",
"dependencies": {
"generate-function": {
"version": "2.0.0",
"from": "generate-function@^2.0.0",
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz"
},
"generate-object-property": {
"version": "1.2.0",
"from": "generate-object-property@^1.1.0",
"resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
"dependencies": {
"is-property": {
"version": "1.0.2",
"from": "is-property@^1.0.0",
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz"
}
}
},
"jsonpointer": {
"version": "2.0.0",
"from": "jsonpointer@2.0.0",
"resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-2.0.0.tgz"
},
"xtend": {
"version": "4.0.0",
"from": "xtend@^4.0.0",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.0.tgz"
}
}
}
}
}
}
}
}
"from": "fastly-purge@~1.0.0"
},
"log4js": {
"version": "0.6.25",
@ -526,13 +224,308 @@
}
},
"request": {
"version": "2.9.203",
"from": "request@~2.9.203",
"resolved": "https://registry.npmjs.org/request/-/request-2.9.203.tgz"
"version": "2.62.0",
"from": "request@~2.62.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.62.0.tgz",
"dependencies": {
"bl": {
"version": "1.0.0",
"from": "bl@~1.0.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-1.0.0.tgz",
"dependencies": {
"readable-stream": {
"version": "2.0.2",
"from": "readable-stream@~2.0.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz",
"dependencies": {
"core-util-is": {
"version": "1.0.1",
"from": "core-util-is@~1.0.0",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz"
},
"inherits": {
"version": "2.0.1",
"from": "inherits@~2.0.1",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
},
"isarray": {
"version": "0.0.1",
"from": "isarray@0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
},
"process-nextick-args": {
"version": "1.0.3",
"from": "process-nextick-args@~1.0.0",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz"
},
"string_decoder": {
"version": "0.10.31",
"from": "string_decoder@~0.10.x",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
},
"util-deprecate": {
"version": "1.0.1",
"from": "util-deprecate@~1.0.1",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz"
}
}
}
}
},
"caseless": {
"version": "0.11.0",
"from": "caseless@~0.11.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz"
},
"extend": {
"version": "3.0.0",
"from": "extend@~3.0.0",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz"
},
"forever-agent": {
"version": "0.6.1",
"from": "forever-agent@~0.6.0",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz"
},
"form-data": {
"version": "1.0.0-rc3",
"from": "form-data@~1.0.0-rc1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.0-rc3.tgz",
"dependencies": {
"async": {
"version": "1.4.2",
"from": "async@^1.4.0",
"resolved": "https://registry.npmjs.org/async/-/async-1.4.2.tgz"
}
}
},
"json-stringify-safe": {
"version": "5.0.1",
"from": "json-stringify-safe@~5.0.0",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz"
},
"mime-types": {
"version": "2.1.6",
"from": "mime-types@~2.1.2",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.6.tgz",
"dependencies": {
"mime-db": {
"version": "1.18.0",
"from": "mime-db@~1.18.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.18.0.tgz"
}
}
},
"node-uuid": {
"version": "1.4.3",
"from": "node-uuid@~1.4.0",
"resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.3.tgz"
},
"qs": {
"version": "5.1.0",
"from": "qs@~5.1.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-5.1.0.tgz"
},
"tunnel-agent": {
"version": "0.4.1",
"from": "tunnel-agent@~0.4.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.1.tgz"
},
"tough-cookie": {
"version": "2.0.0",
"from": "tough-cookie@>=0.12.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.0.0.tgz"
},
"http-signature": {
"version": "0.11.0",
"from": "http-signature@~0.11.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.11.0.tgz",
"dependencies": {
"assert-plus": {
"version": "0.1.5",
"from": "assert-plus@^0.1.5",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz"
},
"asn1": {
"version": "0.1.11",
"from": "asn1@0.1.11",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz"
},
"ctype": {
"version": "0.5.3",
"from": "ctype@0.5.3",
"resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz"
}
}
},
"oauth-sign": {
"version": "0.8.0",
"from": "oauth-sign@~0.8.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.0.tgz"
},
"hawk": {
"version": "3.1.0",
"from": "hawk@~3.1.0",
"resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.0.tgz",
"dependencies": {
"hoek": {
"version": "2.16.2",
"from": "hoek@2.x.x",
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.2.tgz"
},
"boom": {
"version": "2.8.0",
"from": "boom@^2.8.x",
"resolved": "https://registry.npmjs.org/boom/-/boom-2.8.0.tgz"
},
"cryptiles": {
"version": "2.0.5",
"from": "cryptiles@2.x.x",
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz"
},
"sntp": {
"version": "1.0.9",
"from": "sntp@1.x.x",
"resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz"
}
}
},
"aws-sign2": {
"version": "0.5.0",
"from": "aws-sign2@~0.5.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz"
},
"stringstream": {
"version": "0.0.4",
"from": "stringstream@~0.0.4",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.4.tgz"
},
"combined-stream": {
"version": "1.0.5",
"from": "combined-stream@~1.0.1",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
"dependencies": {
"delayed-stream": {
"version": "1.0.0",
"from": "delayed-stream@~1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
}
}
},
"isstream": {
"version": "0.1.2",
"from": "isstream@~0.1.1",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz"
},
"har-validator": {
"version": "1.8.0",
"from": "har-validator@^1.6.1",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-1.8.0.tgz",
"dependencies": {
"bluebird": {
"version": "2.10.0",
"from": "bluebird@^2.9.30",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.10.0.tgz"
},
"chalk": {
"version": "1.1.1",
"from": "chalk@^1.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.1.tgz",
"dependencies": {
"ansi-styles": {
"version": "2.1.0",
"from": "ansi-styles@^2.1.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.1.0.tgz"
},
"escape-string-regexp": {
"version": "1.0.3",
"from": "escape-string-regexp@^1.0.2",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.3.tgz"
},
"has-ansi": {
"version": "2.0.0",
"from": "has-ansi@^2.0.0",
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
"dependencies": {
"ansi-regex": {
"version": "2.0.0",
"from": "ansi-regex@^2.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz"
}
}
},
"strip-ansi": {
"version": "3.0.0",
"from": "strip-ansi@^3.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz",
"dependencies": {
"ansi-regex": {
"version": "2.0.0",
"from": "ansi-regex@^2.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz"
}
}
},
"supports-color": {
"version": "2.0.0",
"from": "supports-color@^2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz"
}
}
},
"commander": {
"version": "2.8.1",
"from": "commander@^2.8.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
"dependencies": {
"graceful-readlink": {
"version": "1.0.1",
"from": "graceful-readlink@>= 1.0.0",
"resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz"
}
}
},
"is-my-json-valid": {
"version": "2.12.2",
"from": "is-my-json-valid@^2.12.0",
"resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.12.2.tgz",
"dependencies": {
"generate-function": {
"version": "2.0.0",
"from": "generate-function@^2.0.0",
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz"
},
"generate-object-property": {
"version": "1.2.0",
"from": "generate-object-property@^1.1.0",
"resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
"dependencies": {
"is-property": {
"version": "1.0.2",
"from": "is-property@^1.0.0",
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz"
}
}
},
"jsonpointer": {
"version": "2.0.0",
"from": "jsonpointer@2.0.0",
"resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-2.0.0.tgz"
},
"xtend": {
"version": "4.0.0",
"from": "xtend@^4.0.0",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.0.tgz"
}
}
}
}
}
}
},
"step": {
"version": "0.0.6",
"from": "step@~0.0.5",
"from": "step@~0.0.6",
"resolved": "https://registry.npmjs.org/step/-/step-0.0.6.tgz"
},
"step-profiler": {
@ -2340,7 +2333,7 @@
},
"mime": {
"version": "1.2.11",
"from": "mime@~1.2.11",
"from": "mime@~1.2.9",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz"
}
}
@ -2823,306 +2816,6 @@
"from": "torque.js@~2.11.0",
"resolved": "https://registry.npmjs.org/torque.js/-/torque.js-2.11.0.tgz"
},
"request": {
"version": "2.62.0",
"from": "request@2.62.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.62.0.tgz",
"dependencies": {
"bl": {
"version": "1.0.0",
"from": "bl@~1.0.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-1.0.0.tgz",
"dependencies": {
"readable-stream": {
"version": "2.0.2",
"from": "readable-stream@~2.0.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz",
"dependencies": {
"core-util-is": {
"version": "1.0.1",
"from": "core-util-is@~1.0.0",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz"
},
"inherits": {
"version": "2.0.1",
"from": "inherits@~2.0.1",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz"
},
"isarray": {
"version": "0.0.1",
"from": "isarray@0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
},
"process-nextick-args": {
"version": "1.0.3",
"from": "process-nextick-args@~1.0.0",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.3.tgz"
},
"string_decoder": {
"version": "0.10.31",
"from": "string_decoder@~0.10.x",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
},
"util-deprecate": {
"version": "1.0.1",
"from": "util-deprecate@~1.0.1",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz"
}
}
}
}
},
"caseless": {
"version": "0.11.0",
"from": "caseless@~0.11.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz"
},
"extend": {
"version": "3.0.0",
"from": "extend@~3.0.0",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz"
},
"forever-agent": {
"version": "0.6.1",
"from": "forever-agent@~0.6.0",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz"
},
"form-data": {
"version": "1.0.0-rc3",
"from": "form-data@~1.0.0-rc1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.0-rc3.tgz",
"dependencies": {
"async": {
"version": "1.4.2",
"from": "async@^1.4.0",
"resolved": "https://registry.npmjs.org/async/-/async-1.4.2.tgz"
}
}
},
"json-stringify-safe": {
"version": "5.0.1",
"from": "json-stringify-safe@~5.0.0",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz"
},
"mime-types": {
"version": "2.1.6",
"from": "mime-types@~2.1.2",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.6.tgz",
"dependencies": {
"mime-db": {
"version": "1.18.0",
"from": "mime-db@~1.18.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.18.0.tgz"
}
}
},
"node-uuid": {
"version": "1.4.3",
"from": "node-uuid@~1.4.0",
"resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.3.tgz"
},
"qs": {
"version": "5.1.0",
"from": "qs@~5.1.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-5.1.0.tgz"
},
"tunnel-agent": {
"version": "0.4.1",
"from": "tunnel-agent@~0.4.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.1.tgz"
},
"tough-cookie": {
"version": "2.0.0",
"from": "tough-cookie@>=0.12.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.0.0.tgz"
},
"http-signature": {
"version": "0.11.0",
"from": "http-signature@~0.11.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.11.0.tgz",
"dependencies": {
"assert-plus": {
"version": "0.1.5",
"from": "assert-plus@^0.1.5",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz"
},
"asn1": {
"version": "0.1.11",
"from": "asn1@0.1.11",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz"
},
"ctype": {
"version": "0.5.3",
"from": "ctype@0.5.3",
"resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz"
}
}
},
"oauth-sign": {
"version": "0.8.0",
"from": "oauth-sign@~0.8.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.0.tgz"
},
"hawk": {
"version": "3.1.0",
"from": "hawk@~3.1.0",
"resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.0.tgz",
"dependencies": {
"hoek": {
"version": "2.16.0",
"from": "hoek@2.x.x",
"resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.0.tgz"
},
"boom": {
"version": "2.8.0",
"from": "boom@^2.8.x",
"resolved": "https://registry.npmjs.org/boom/-/boom-2.8.0.tgz"
},
"cryptiles": {
"version": "2.0.5",
"from": "cryptiles@2.x.x",
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz"
},
"sntp": {
"version": "1.0.9",
"from": "sntp@1.x.x",
"resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz"
}
}
},
"aws-sign2": {
"version": "0.5.0",
"from": "aws-sign2@~0.5.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz"
},
"stringstream": {
"version": "0.0.4",
"from": "stringstream@~0.0.4",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.4.tgz"
},
"combined-stream": {
"version": "1.0.5",
"from": "combined-stream@~1.0.1",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
"dependencies": {
"delayed-stream": {
"version": "1.0.0",
"from": "delayed-stream@~1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
}
}
},
"isstream": {
"version": "0.1.2",
"from": "isstream@~0.1.1",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz"
},
"har-validator": {
"version": "1.8.0",
"from": "har-validator@^1.6.1",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-1.8.0.tgz",
"dependencies": {
"bluebird": {
"version": "2.10.0",
"from": "bluebird@^2.9.30",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.10.0.tgz"
},
"chalk": {
"version": "1.1.1",
"from": "chalk@^1.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.1.tgz",
"dependencies": {
"ansi-styles": {
"version": "2.1.0",
"from": "ansi-styles@^2.1.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.1.0.tgz"
},
"escape-string-regexp": {
"version": "1.0.3",
"from": "escape-string-regexp@^1.0.2",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.3.tgz"
},
"has-ansi": {
"version": "2.0.0",
"from": "has-ansi@^2.0.0",
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
"dependencies": {
"ansi-regex": {
"version": "2.0.0",
"from": "ansi-regex@^2.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz"
}
}
},
"strip-ansi": {
"version": "3.0.0",
"from": "strip-ansi@^3.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz",
"dependencies": {
"ansi-regex": {
"version": "2.0.0",
"from": "ansi-regex@^2.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz"
}
}
},
"supports-color": {
"version": "2.0.0",
"from": "supports-color@^2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz"
}
}
},
"commander": {
"version": "2.8.1",
"from": "commander@^2.8.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
"dependencies": {
"graceful-readlink": {
"version": "1.0.1",
"from": "graceful-readlink@>= 1.0.0",
"resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz"
}
}
},
"is-my-json-valid": {
"version": "2.12.2",
"from": "is-my-json-valid@^2.12.0",
"resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.12.2.tgz",
"dependencies": {
"generate-function": {
"version": "2.0.0",
"from": "generate-function@^2.0.0",
"resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz"
},
"generate-object-property": {
"version": "1.2.0",
"from": "generate-object-property@^1.1.0",
"resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
"dependencies": {
"is-property": {
"version": "1.0.2",
"from": "is-property@^1.0.0",
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz"
}
}
},
"jsonpointer": {
"version": "2.0.0",
"from": "jsonpointer@2.0.0",
"resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-2.0.0.tgz"
},
"xtend": {
"version": "4.0.0",
"from": "xtend@^4.0.0",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.0.tgz"
}
}
}
}
}
}
},
"abaculus": {
"version": "1.1.0",
"from": "https://github.com/CartoDB/abaculus/tarball/cdb",

View File

@ -29,9 +29,9 @@
"underscore" : "~1.6.0",
"dot": "~1.0.2",
"windshaft": "https://github.com/CartoDB/Windshaft/tarball/backend-foundations-mvt",
"step": "~0.0.5",
"step": "~0.0.6",
"queue-async": "~1.0.7",
"request": "~2.9.203",
"request": "~2.62.0",
"cartodb-redis": "~0.13.0",
"cartodb-psql": "~0.4.0",
"fastly-purge": "~1.0.0",
@ -43,7 +43,7 @@
"devDependencies": {
"istanbul": "~0.3.6",
"mocha": "~1.21.4",
"nock": "~1.3.0",
"nock": "~2.11.0",
"jshint": "~2.6.0",
"redis": "~0.8.6",
"strftime": "~0.8.2",

View File

@ -158,7 +158,9 @@ describe('templates surrogate keys', function() {
status: 200
},
function(res) {
next(null, res);
setTimeout(function() {
next(null, res);
}, 50);
}
);
},
@ -229,7 +231,9 @@ describe('templates surrogate keys', function() {
status: 204
},
function(res) {
next(null, res);
setTimeout(function() {
next(null, res);
}, 50);
}
);
},
@ -256,6 +260,15 @@ describe('templates surrogate keys', function() {
.matchHeader('Invalidation-Match', invalidationMatchHeader)
.reply(503, '');
var fastlyScope = nock(FastlyPurge.FASTLY_API_ENDPOINT)
.post(fastlyPurgePath)
.matchHeader('Fastly-Key', FAKE_FASTLY_API_KEY)
.matchHeader('Fastly-Soft-Purge', 1)
.matchHeader('Accept', 'application/json')
.reply(200, {
status:'ok'
});
step(
function createTemplateToUpdate() {
createTemplate(this);
@ -280,7 +293,9 @@ describe('templates surrogate keys', function() {
status: 200
},
function(res) {
next(null, res);
setTimeout(function() {
next(null, res);
}, 50);
}
);
},
@ -292,6 +307,7 @@ describe('templates surrogate keys', function() {
assert.deepEqual(parsedBody, expectedBody);
assert.equal(scope.pendingMocks().length, 0);
assert.equal(fastlyScope.pendingMocks().length, 0);
return null;
},

View File

@ -5,11 +5,12 @@ var redis = require('redis');
var step = require('step');
var cartodbServer = require('../../../lib/cartodb/server');
var PortedServerOptions = require('./support/ported_server_options');
var BaseController = require('../../../lib/cartodb/controllers/base');
describe('attributes', function() {
var server = cartodbServer(PortedServerOptions);
server.req2params = PortedServerOptions.req2params;
server.setMaxListeners(0);
var redis_client = redis.createClient(PortedServerOptions.redis.port);
@ -38,6 +39,16 @@ describe('attributes', function() {
assert.equal(res.headers['access-control-allow-origin'], '*');
}
var req2paramsFn;
before(function() {
req2paramsFn = BaseController.prototype.req2params;
BaseController.prototype.req2params = PortedServerOptions.req2params;
});
after(function() {
BaseController.prototype.req2params = req2paramsFn;
});
it("can only be fetched from layer having an attributes spec", function(done) {
var expected_token;

View File

@ -3,8 +3,21 @@ require('../../support/test_helper');
var assert = require('../../support/assert');
var testClient = require('./support/test_client');
var PortedServerOptions = require('./support/ported_server_options');
var BaseController = require('../../../lib/cartodb/controllers/base');
describe('blend png renderer', function() {
var req2paramsFn;
before(function() {
req2paramsFn = BaseController.prototype.req2params;
BaseController.prototype.req2params = PortedServerOptions.req2params;
});
after(function() {
BaseController.prototype.req2params = req2paramsFn;
});
var IMAGE_TOLERANCE_PER_MIL = 20;
function plainTorqueMapConfig(plainColor) {

View File

@ -5,13 +5,20 @@ var testClient = require('./support/test_client');
var fs = require('fs');
var http = require('http');
var PortedServerOptions = require('./support/ported_server_options');
var BaseController = require('../../../lib/cartodb/controllers/base');
describe('blend layer filtering', function() {
var IMG_TOLERANCE_PER_MIL = 20;
var httpRendererResourcesServer;
var req2paramsFn;
before(function(done) {
req2paramsFn = BaseController.prototype.req2params;
BaseController.prototype.req2params = PortedServerOptions.req2params;
// Start a server to test external resources
httpRendererResourcesServer = http.createServer( function(request, response) {
var filename = __dirname + '/../../fixtures/http/light_nolabels-1-0-0.png';
@ -25,6 +32,7 @@ describe('blend layer filtering', function() {
});
after(function(done) {
BaseController.prototype.req2params = req2paramsFn;
httpRendererResourcesServer.close(done);
});

View File

@ -5,13 +5,19 @@ var testClient = require('./support/test_client');
var fs = require('fs');
var http = require('http');
var PortedServerOptions = require('./support/ported_server_options');
var BaseController = require('../../../lib/cartodb/controllers/base');
describe('blend http fallback', function() {
var IMG_TOLERANCE_PER_MIL = 20;
var httpRendererResourcesServer;
var req2paramsFn;
before(function(done) {
req2paramsFn = BaseController.prototype.req2params;
BaseController.prototype.req2params = PortedServerOptions.req2params;
// Start a server to test external resources
httpRendererResourcesServer = http.createServer( function(request, response) {
if (request.url.match(/^\/error404\//)) {
@ -33,6 +39,7 @@ describe('blend http fallback', function() {
});
after(function(done) {
BaseController.prototype.req2params = req2paramsFn;
httpRendererResourcesServer.close(done);
});

View File

@ -6,8 +6,21 @@ var serverOptions = require('./support/ported_server_options');
var fs = require('fs');
var http = require('http');
var PortedServerOptions = require('./support/ported_server_options');
var BaseController = require('../../../lib/cartodb/controllers/base');
describe.skip('blend http client timeout', function() {
var req2paramsFn;
before(function() {
req2paramsFn = BaseController.prototype.req2params;
BaseController.prototype.req2params = PortedServerOptions.req2params;
});
after(function() {
BaseController.prototype.req2params = req2paramsFn;
});
var mapConfig = {
version: '1.3.0',
layers: [

View File

@ -7,6 +7,8 @@ var PortedServerOptions = require('./support/ported_server_options');
var http = require('http');
var testClient = require('./support/test_client');
var BaseController = require('../../../lib/cartodb/controllers/base');
function rmdir_recursive_sync(dirname) {
var files = fs.readdirSync(dirname);
for (var i=0; i<files.length; ++i) {
@ -29,7 +31,10 @@ describe('external resources', function() {
var IMAGE_EQUALS_TOLERANCE_PER_MIL = 25;
var req2paramsFn;
before(function(done) {
req2paramsFn = BaseController.prototype.req2params;
BaseController.prototype.req2params = PortedServerOptions.req2params;
// Start a server to test external resources
res_serv = http.createServer( function(request, response) {
++res_serv_status.numrequests;
@ -48,6 +53,15 @@ describe('external resources', function() {
res_serv.listen(res_serv_port, done);
});
after(function(done) {
BaseController.prototype.req2params = req2paramsFn;
rmdir_recursive_sync(global.environment.millstone.cache_basedir);
// Close the resources server
res_serv.close(done);
});
function imageCompareFn(fixture, done) {
return function(err, res) {
if (err) {
@ -121,12 +135,5 @@ describe('external resources', function() {
});
});
after(function(done) {
rmdir_recursive_sync(global.environment.millstone.cache_basedir);
// Close the resources server
res_serv.close(done);
});
});

View File

@ -6,13 +6,19 @@ var assert = require('../../support/assert');
var testClient = require('./support/test_client');
var serverOptions = require('./support/ported_server_options');
var PortedServerOptions = require('./support/ported_server_options');
var BaseController = require('../../../lib/cartodb/controllers/base');
describe.skip('render limits', function() {
var IMAGE_EQUALS_TOLERANCE_PER_MIL = 25;
var limitsConfig;
var onTileErrorStrategy;
var req2paramsFn;
before(function() {
req2paramsFn = BaseController.prototype.req2params;
BaseController.prototype.req2params = PortedServerOptions.req2params;
limitsConfig = serverOptions.renderer.mapnik.limits;
serverOptions.renderer.mapnik.limits = {
render: 50,
@ -25,6 +31,7 @@ describe.skip('render limits', function() {
});
after(function() {
BaseController.prototype.req2params = req2paramsFn;
serverOptions.renderer.mapnik.limits = limitsConfig;
serverOptions.renderer.onTileErrorStrategy = onTileErrorStrategy;
});

View File

@ -11,11 +11,11 @@ var cartodbServer = require('../../../lib/cartodb/server');
var ServerOptions = require('./support/ported_server_options');
var http = require('http');
var LayergroupToken = require('../../../lib/cartodb/models/layergroup_token');
var BaseController = require('../../../lib/cartodb/controllers/base');
describe('multilayer', function() {
var server = cartodbServer(ServerOptions);
server.req2params = ServerOptions.req2params;
server.setMaxListeners(0);
var redis_client = redis.createClient(ServerOptions.redis.port);
var res_serv; // resources server
@ -30,7 +30,11 @@ describe('multilayer', function() {
assert.equal(res.headers['access-control-allow-origin'], '*');
}
var req2paramsFn;
before(function(done) {
req2paramsFn = BaseController.prototype.req2params;
BaseController.prototype.req2params = ServerOptions.req2params;
// Start a server to test external resources
res_serv = http.createServer( function(request, response) {
var filename = __dirname + '/../fixtures/markers' + request.url;
@ -50,6 +54,8 @@ describe('multilayer', function() {
});
after(function(done) {
BaseController.prototype.req2params = req2paramsFn;
// Close the resources server
res_serv.close(done);
});
@ -1283,7 +1289,7 @@ describe('multilayer', function() {
step(
function do_post()
{
server.req2params_calls = 0;
global.req2params_calls = 0;
var next = this;
assert.response(server, {
url: '/database/windshaft_test/layergroup',
@ -1297,7 +1303,7 @@ describe('multilayer', function() {
assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body);
var parsedBody = JSON.parse(res.body);
expected_token = LayergroupToken.parse(parsedBody.layergroupid).token;
assert.equal(server.req2params_calls, 1);
assert.equal(global.req2params_calls, 1);
return null;
},
function finish(err) {

View File

@ -6,12 +6,23 @@ var cartodbServer = require('../../../lib/cartodb/server');
var ServerOptions = require('./support/ported_server_options');
var testClient = require('./support/test_client');
var BaseController = require('../../../lib/cartodb/controllers/base');
describe('multilayer error cases', function() {
var server = cartodbServer(ServerOptions);
server.req2params = ServerOptions.req2params;
server.setMaxListeners(0);
var req2paramsFn;
before(function() {
req2paramsFn = BaseController.prototype.req2params;
BaseController.prototype.req2params = ServerOptions.req2params;
});
after(function() {
BaseController.prototype.req2params = req2paramsFn;
});
it("post layergroup with wrong Content-Type", function(done) {
assert.response(server, {
url: '/database/windshaft_test/layergroup',

View File

@ -8,13 +8,24 @@ var getLayerTypeFn = require('windshaft').model.MapConfig.prototype.getType;
var PortedServerOptions = require('./support/ported_server_options');
var LayergroupToken = require('../../../lib/cartodb/models/layergroup_token');
var BaseController = require('../../../lib/cartodb/controllers/base');
describe('multilayer interactivity and layers order', function() {
var server = cartodbServer(PortedServerOptions);
server.req2params = PortedServerOptions.req2params;
server.setMaxListeners(0);
var redisClient = redis.createClient(PortedServerOptions.redis.port);
var req2paramsFn;
before(function() {
req2paramsFn = BaseController.prototype.req2params;
BaseController.prototype.req2params = PortedServerOptions.req2params;
});
after(function() {
BaseController.prototype.req2params = req2paramsFn;
});
function layerType(layer) {
return layer.type || 'undefined';
}

View File

@ -6,10 +6,11 @@ var step = require('step');
var cartodbServer = require('../../../lib/cartodb/server');
var ServerOptions = require('./support/ported_server_options');
var BaseController = require('../../../lib/cartodb/controllers/base');
describe('raster', function() {
var server = cartodbServer(ServerOptions);
server.req2params = ServerOptions.req2params;
server.setMaxListeners(0);
var redis_client = redis.createClient(ServerOptions.redis.port);
@ -20,6 +21,16 @@ describe('raster', function() {
var IMAGE_EQUALS_TOLERANCE_PER_MIL = 2;
var req2paramsFn;
before(function() {
req2paramsFn = BaseController.prototype.req2params;
BaseController.prototype.req2params = ServerOptions.req2params;
});
after(function() {
BaseController.prototype.req2params = req2paramsFn;
});
it("can render raster for valid mapconfig", function(done) {
var mapconfig = {

View File

@ -8,6 +8,8 @@ var cartodbServer = require('../../../lib/cartodb/server');
var ServerOptions = require('./support/ported_server_options');
var testClient = require('./support/test_client');
var BaseController = require('../../../lib/cartodb/controllers/base');
function rmdir_recursive_sync(dirname) {
var files = fs.readdirSync(dirname);
for (var i=0; i<files.length; ++i) {
@ -28,7 +30,10 @@ describe('regressions', function() {
var res_serv_status = { numrequests:0 }; // status of resources server
var res_serv_port = 8033; // FIXME: make configurable ?
var req2paramsFn;
before(function(done) {
req2paramsFn = BaseController.prototype.req2params;
BaseController.prototype.req2params = ServerOptions.req2params;
// Start a server to test external resources
res_serv = http.createServer( function(request, response) {
++res_serv_status.numrequests;
@ -49,6 +54,7 @@ describe('regressions', function() {
after(function(done) {
BaseController.prototype.req2params = req2paramsFn;
rmdir_recursive_sync(global.environment.millstone.cache_basedir);
// Close the resources server
@ -129,31 +135,4 @@ describe('regressions', function() {
testClient.createLayergroup(mapConfig, { server: server }, completed);
}
});
// See https://github.com/CartoDB/Windshaft/issues/173
it.skip("#173 does not send db details in connection error response", function(done) {
var mapConfig = testClient.defaultTableMapConfig('test_table');
var CustomOptions = _.clone(ServerOptions);
CustomOptions.grainstore = _.clone(CustomOptions.grainstore);
CustomOptions.grainstore.datasource = _.clone(CustomOptions.grainstore.datasource);
CustomOptions.grainstore.datasource.port = '666';
var options = {
statusCode: 400,
serverOptions: CustomOptions
};
testClient.createLayergroup(mapConfig, options, function(err, res, parsedBody) {
assert.ok(parsedBody.errors);
var msg = parsedBody.errors[0];
assert.ok(msg.match(/connect/), msg);
assert.ok(!msg.match(/666/), msg);
done();
});
});
});

View File

@ -6,15 +6,26 @@ var mapnik = require('windshaft').mapnik;
var cartodbServer = require('../../../lib/cartodb/server');
var ServerOptions = require('./support/ported_server_options');
var BaseController = require('../../../lib/cartodb/controllers/base');
describe('retina support', function() {
var layergroupId = null;
var server = cartodbServer(ServerOptions);
server.req2params = ServerOptions.req2params;
server.setMaxListeners(0);
var redis_client = redis.createClient(ServerOptions.redis.port);
var req2paramsFn;
before(function() {
req2paramsFn = BaseController.prototype.req2params;
BaseController.prototype.req2params = ServerOptions.req2params;
});
after(function() {
BaseController.prototype.req2params = req2paramsFn;
});
beforeEach(function(done) {
var retinaSampleMapConfig = {
version: '1.2.0',

View File

@ -7,6 +7,8 @@ var cartodbServer = require('../../../lib/cartodb/server');
var ServerOptions = require('./support/ported_server_options');
var testClient = require('./support/test_client');
var BaseController = require('../../../lib/cartodb/controllers/base');
function rmdir_recursive_sync(dirname) {
var files = fs.readdirSync(dirname);
for (var i=0; i<files.length; ++i) {
@ -23,13 +25,15 @@ function rmdir_recursive_sync(dirname) {
describe('server', function() {
var server = cartodbServer(ServerOptions);
server.req2params = ServerOptions.req2params;
server.setMaxListeners(0);
var res_serv; // resources server
var res_serv_status = { numrequests:0 }; // status of resources server
var res_serv_port = 8033; // FIXME: make configurable ?
var req2paramsFn;
before(function(done) {
req2paramsFn = BaseController.prototype.req2params;
BaseController.prototype.req2params = ServerOptions.req2params;
// Start a server to test external resources
res_serv = http.createServer( function(request, response) {
@ -51,6 +55,8 @@ describe('server', function() {
});
after(function(done) {
BaseController.prototype.req2params = req2paramsFn;
rmdir_recursive_sync(global.environment.millstone.cache_basedir);
// Close the resources server

View File

@ -9,6 +9,8 @@ var cartodbServer = require('../../../lib/cartodb/server');
var ServerOptions = require('./support/ported_server_options');
var testClient = require('./support/test_client');
var BaseController = require('../../../lib/cartodb/controllers/base');
function rmdir_recursive_sync(dirname) {
var files = fs.readdirSync(dirname);
for (var i=0; i<files.length; ++i) {
@ -26,7 +28,6 @@ function rmdir_recursive_sync(dirname) {
describe('server_gettile', function() {
var server = cartodbServer(ServerOptions);
server.req2params = ServerOptions.req2params;
server.setMaxListeners(0);
var res_serv; // resources server
var res_serv_status = { numrequests:0 }; // status of resources server
@ -34,7 +35,11 @@ describe('server_gettile', function() {
var IMAGE_EQUALS_TOLERANCE_PER_MIL = 25;
var req2paramsFn;
before(function(done) {
req2paramsFn = BaseController.prototype.req2params;
BaseController.prototype.req2params = ServerOptions.req2params;
// Start a server to test external resources
res_serv = http.createServer( function(request, response) {
++res_serv_status.numrequests;
@ -55,6 +60,8 @@ describe('server_gettile', function() {
after(function(done) {
BaseController.prototype.req2params = req2paramsFn;
rmdir_recursive_sync(global.environment.millstone.cache_basedir);
// Close the resources server

View File

@ -7,6 +7,8 @@ var redis = require('redis');
var cartodbServer = require('../../../lib/cartodb/server');
var ServerOptions = require('./support/ported_server_options');
var BaseController = require('../../../lib/cartodb/controllers/base');
var IMAGE_EQUALS_TOLERANCE_PER_MIL = 85;
describe('server_png8_format', function() {
@ -15,14 +17,12 @@ describe('server_png8_format', function() {
serverOptionsPng32.grainstore = _.clone(ServerOptions.grainstore);
serverOptionsPng32.grainstore.mapnik_tile_format = 'png32';
var serverPng32 = new cartodbServer(serverOptionsPng32);
serverPng32.req2params = ServerOptions.req2params;
serverPng32.setMaxListeners(0);
var serverOptionsPng8 = ServerOptions;
serverOptionsPng8.grainstore = _.clone(ServerOptions.grainstore);
serverOptionsPng8.grainstore.mapnik_tile_format = 'png8:m=h';
var serverPng8 = new cartodbServer(serverOptionsPng8);
serverPng8.req2params = ServerOptions.req2params;
serverPng8.setMaxListeners(0);
@ -30,7 +30,10 @@ describe('server_png8_format', function() {
var layergroupId;
var req2paramsFn;
before(function(done) {
req2paramsFn = BaseController.prototype.req2params;
BaseController.prototype.req2params = ServerOptions.req2params;
var testPngFilesDir = __dirname + '/../../results/png';
fs.readdirSync(testPngFilesDir)
.filter(function(fileName) {
@ -44,6 +47,10 @@ describe('server_png8_format', function() {
done();
});
after(function() {
BaseController.prototype.req2params = req2paramsFn;
});
function testOutputForPng32AndPng8(desc, tile, callback) {
var bufferPng32,

View File

@ -5,6 +5,9 @@ var testClient = require('./support/test_client');
var http = require('http');
var fs = require('fs');
var PortedServerOptions = require('./support/ported_server_options');
var BaseController = require('../../../lib/cartodb/controllers/base');
describe('static_maps', function() {
var validUrlTemplate = 'http://127.0.0.1:8033/{s}/{z}/{x}/{y}.png';
@ -12,7 +15,11 @@ describe('static_maps', function() {
var httpRendererResourcesServer;
var req2paramsFn;
before(function(done) {
req2paramsFn = BaseController.prototype.req2params;
BaseController.prototype.req2params = PortedServerOptions.req2params;
// Start a server to test external resources
httpRendererResourcesServer = http.createServer( function(request, response) {
var filename = __dirname + '/../../fixtures/http/basemap.png';
@ -26,6 +33,7 @@ describe('static_maps', function() {
});
after(function(done) {
BaseController.prototype.req2params = req2paramsFn;
httpRendererResourcesServer.close(done);
});

View File

@ -70,8 +70,7 @@ module.exports = _.extend({}, serverOptions, {
// increment number of calls counter
// NOTE: "this" would likely point to the server instance
this.req2params_calls = this.req2params_calls ? this.req2params_calls + 1 : 1;
global.req2params_calls = global.req2params_calls ? global.req2params_calls + 1 : 1;
// send the finished req object on
callback(null,req);

View File

@ -40,7 +40,6 @@ module.exports = {
var server = new CartodbServer(PortedServerOptions);
server.req2params = PortedServerOptions.req2params;
server.setMaxListeners(0);
var redisClient = redis.createClient(global.environment.redis.port);

View File

@ -7,13 +7,24 @@ var step = require('step');
var cartodbServer = require('../../../lib/cartodb/server');
var ServerOptions = require('./support/ported_server_options');
var BaseController = require('../../../lib/cartodb/controllers/base');
describe('torque', function() {
var server = cartodbServer(ServerOptions);
server.req2params = ServerOptions.req2params;
server.setMaxListeners(0);
var redis_client = redis.createClient(ServerOptions.redis.port);
var req2paramsFn;
before(function() {
req2paramsFn = BaseController.prototype.req2params;
BaseController.prototype.req2params = ServerOptions.req2params;
});
after(function() {
BaseController.prototype.req2params = req2paramsFn;
});
function checkCORSHeaders(res) {
assert.equal(res.headers['access-control-allow-headers'], 'X-Requested-With, X-Prototype-Version, X-CSRF-Token');
assert.equal(res.headers['access-control-allow-origin'], '*');

View File

@ -5,16 +5,34 @@ var redis = require('redis');
var cartodbServer = require('../../../lib/cartodb/server');
var ServerOptions = require('./support/ported_server_options');
var BaseController = require('../../../lib/cartodb/controllers/base');
describe('torque boundary points', function() {
var req2paramsFn;
before(function() {
req2paramsFn = BaseController.prototype.req2params;
BaseController.prototype.req2params = ServerOptions.req2params;
});
after(function() {
BaseController.prototype.req2params = req2paramsFn;
});
var layergroupIdToDelete = null;
beforeEach(function() {
layergroupIdToDelete = null;
});
afterEach(function(done) {
var redisKey = 'map_cfg|' + layergroupIdToDelete;
redis_client.del(redisKey, function () {
done();
});
});
var server = cartodbServer(ServerOptions);
server.req2params = ServerOptions.req2params;
server.setMaxListeners(0);
var redis_client = redis.createClient(ServerOptions.redis.port);
@ -437,10 +455,4 @@ describe('torque boundary points', function() {
});
});
afterEach(function(done) {
var redisKey = 'map_cfg|' + layergroupIdToDelete;
redis_client.del(redisKey, function () {
done();
});
});
});

View File

@ -3,8 +3,21 @@ require('../../support/test_helper');
var assert = require('../../support/assert');
var testClient = require('./support/test_client');
var PortedServerOptions = require('./support/ported_server_options');
var BaseController = require('../../../lib/cartodb/controllers/base');
describe('torque png renderer', function() {
var req2paramsFn;
before(function() {
req2paramsFn = BaseController.prototype.req2params;
BaseController.prototype.req2params = PortedServerOptions.req2params;
});
after(function() {
BaseController.prototype.req2params = req2paramsFn;
});
var IMAGE_TOLERANCE_PER_MIL = 20;
var torquePngPointsMapConfig = {

View File

@ -3,8 +3,21 @@ require('../../support/test_helper');
var assert = require('../../support/assert');
var testClient = require('./support/test_client');
var PortedServerOptions = require('./support/ported_server_options');
var BaseController = require('../../../lib/cartodb/controllers/base');
describe('torque tiles at 0,0 point', function() {
var req2paramsFn;
before(function() {
req2paramsFn = BaseController.prototype.req2params;
BaseController.prototype.req2params = PortedServerOptions.req2params;
});
after(function() {
BaseController.prototype.req2params = req2paramsFn;
});
/*
Tiles are represented as in:

View File

@ -3,8 +3,21 @@ require('../../support/test_helper');
var assert = require('../../support/assert');
var testClient = require('./support/test_client');
var PortedServerOptions = require('./support/ported_server_options');
var BaseController = require('../../../lib/cartodb/controllers/base');
describe('wrap x coordinate', function() {
var req2paramsFn;
before(function() {
req2paramsFn = BaseController.prototype.req2params;
BaseController.prototype.req2params = PortedServerOptions.req2params;
});
after(function() {
BaseController.prototype.req2params = req2paramsFn;
});
describe('renders correct tile', function() {
var IMG_TOLERANCE_PER_MIL = 20;

View File

@ -13,6 +13,9 @@ var redis_stats_db = 5;
process.env.PGPORT = '666';
process.env.PGHOST = 'fake';
var fs = require('fs');
var http = require('http');
var helper = require(__dirname + '/../support/test_helper');
var CartodbWindshaft = require(__dirname + '/../../lib/cartodb/server');
@ -23,6 +26,24 @@ server.setMaxListeners(0);
describe('template_api', function() {
server.layergroupAffectedTablesCache.cache.reset();
var httpRendererResourcesServer;
before(function(done) {
// Start a server to test external resources
httpRendererResourcesServer = http.createServer( function(request, response) {
var filename = __dirname + '/../fixtures/http/light_nolabels-1-0-0.png';
fs.readFile(filename, {encoding: 'binary'}, function(err, file) {
response.writeHead(200);
response.write(file, "binary");
response.end();
});
});
httpRendererResourcesServer.listen(8033, done);
});
after(function(done) {
httpRendererResourcesServer.close(done);
});
var redis_client = redis.createClient(global.environment.redis.port);
var template_acceptance1 = {
@ -2006,7 +2027,7 @@ describe('template_api', function() {
{
type: "http",
options: {
urlTemplate: "http://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png",
urlTemplate: "http://127.0.0.1:8033/{s}/{z}/{x}/{y}.png",
subdomains: [
"a",
"b",

View File

@ -0,0 +1,23 @@
require('../../support/test_helper.js');
var assert = require('assert');
var BaseController = require('../../../lib/cartodb/controllers/base');
describe('BaseController', function() {
it('different formats for postgis plugin error returns 400 as status code', function() {
var expectedStatusCode = 400;
assert.equal(
BaseController.findStatusCode("Postgis Plugin: ERROR: column \"missing\" does not exist\n"),
expectedStatusCode,
"Error status code for single line does not match"
);
assert.equal(
BaseController.findStatusCode("Postgis Plugin: PSQL error:\nERROR: column \"missing\" does not exist\n"),
expectedStatusCode,
"Error status code for multiline/PSQL does not match"
);
});
});

View File

@ -0,0 +1,24 @@
require('../../support/test_helper');
var assert = require('assert');
var BaseController = require('../../../lib/cartodb/controllers/base');
describe('error messages clean up', function() {
// See https://github.com/CartoDB/Windshaft/issues/173
it("#173 does not send db details in connection error response", function() {
var inMessage = [
"Postgis Plugin: Bad connection",
"Connection string: 'host=127.0.0.1 port=5432 dbname=test_windshaft_cartodb_user_1_db " +
"user=test_windshaft_cartodb_user_1 connect_timeout=4'",
" encountered during parsing of layer 'layer0' in Layer"
].join('\n');
var outMessage = BaseController.errorMessage(inMessage);
assert.ok(outMessage.match('connect'), outMessage);
assert.ok(!outMessage.match(/666/), outMessage);
});
});

View File

@ -36,7 +36,7 @@ describe('tile stats', function() {
}
};
var resMock = {
sendError: function() {}
send: function() {}
};
layergroupController.finalizeGetTileOrGrid('Unsupported format png2', reqMock, resMock, null, null);
@ -61,7 +61,7 @@ describe('tile stats', function() {
}
};
var resMock = {
sendError: function() {}
send: function() {}
};
var layergroupController = new LayergroupController(cartodbServer(serverOptions));

View File

@ -36,24 +36,9 @@ describe('windshaft', function() {
it('options are set on main windshaft object', function(){
var ws = cartodbServer(serverOptions);
assert.ok(_.isFunction(ws.req2params));
assert.ok(_.isObject(ws.bind));
assert.ok(_.isObject(ws.grainstore));
assert.equal(ws.base_url, '/tiles/:table');
});
it('different formats for postgis plugin error returns 400 as status code', function() {
var expectedStatusCode = 400;
assert.equal(
cartodbServer.findStatusCode("Postgis Plugin: ERROR: column \"missing\" does not exist\n"),
expectedStatusCode,
"Error status code for single line does not match"
);
assert.equal(
cartodbServer.findStatusCode("Postgis Plugin: PSQL error:\nERROR: column \"missing\" does not exist\n"),
expectedStatusCode,
"Error status code for multiline/PSQL does not match"
);
});
});

View File

@ -2,20 +2,37 @@ var assert = require('assert');
var _ = require('underscore');
var test_helper = require('../../support/test_helper');
suite('req2params', function() {
var RedisPool = require('redis-mpool');
var cartodbRedis = require('cartodb-redis');
var PgConnection = require('../../../lib/cartodb/backends/pg_connection');
var AuthApi = require('../../../lib/cartodb/api/auth_api');
var TemplateMaps = require('../../../lib/cartodb/backends/template_maps');
// configure redis pool instance to use in tests
var CartodbWindshaft = require('../../../lib/cartodb/server');
var serverOptions = require('../../../lib/cartodb/server_options');
var server = new CartodbWindshaft(serverOptions);
var BaseController = require('../../../lib/cartodb/controllers/base');
var windshaft = require('windshaft');
suite('req2params', function() {
var test_user = _.template(global.environment.postgres_auth_user, {user_id:1});
var test_pubuser = global.environment.postgres.user;
var test_database = test_user + '_db';
var baseController;
before(function() {
var redisPool = new RedisPool(global.environment.redis);
var mapStore = new windshaft.storage.MapStore();
var metadataBackend = cartodbRedis({pool: redisPool});
var pgConnection = new PgConnection(metadataBackend);
var templateMaps = new TemplateMaps(redisPool);
var authApi = new AuthApi(pgConnection, metadataBackend, mapStore, templateMaps);
baseController = new BaseController(authApi, pgConnection);
});
test('can be found in server_options', function(){
assert.ok(_.isFunction(server.req2params));
assert.ok(_.isFunction(baseController.req2params));
});
function prepareRequest(req) {
@ -28,7 +45,7 @@ suite('req2params', function() {
test('cleans up request', function(done){
var req = {headers: { host:'localhost' }, query: {dbuser:'hacker',dbname:'secret'}};
server.req2params(prepareRequest(req), function(err, req) {
baseController.req2params(prepareRequest(req), function(err, req) {
if ( err ) { done(err); return; }
assert.ok(_.isObject(req.query), 'request has query');
assert.ok(!req.query.hasOwnProperty('dbuser'), 'dbuser was removed from query');
@ -42,7 +59,7 @@ suite('req2params', function() {
test('sets dbname from redis metadata', function(done){
var req = {headers: { host:'localhost' }, query: {} };
server.req2params(prepareRequest(req), function(err, req) {
baseController.req2params(prepareRequest(req), function(err, req) {
if ( err ) { done(err); return; }
//console.dir(req);
assert.ok(_.isObject(req.query), 'request has query');
@ -57,7 +74,7 @@ suite('req2params', function() {
test('sets also dbuser for authenticated requests', function(done){
var req = {headers: { host:'localhost' }, query: {map_key: '1234'} };
server.req2params(prepareRequest(req), function(err, req) {
baseController.req2params(prepareRequest(req), function(err, req) {
if ( err ) { done(err); return; }
//console.dir(req);
assert.ok(_.isObject(req.query), 'request has query');
@ -75,7 +92,7 @@ suite('req2params', function() {
map_key: '1235'
}
};
server.req2params(prepareRequest(req), function(err, req) {
baseController.req2params(prepareRequest(req), function(err, req) {
// wrong key resets params to no user
assert.ok(req.params.dbuser === test_pubuser, 'could inject dbuser ('+req.params.dbuser+')');
done();
@ -101,7 +118,7 @@ suite('req2params', function() {
lzma: data
}
};
server.req2params(prepareRequest(req), function(err, req) {
baseController.req2params(prepareRequest(req), function(err, req) {
if ( err ) {
return done(err);
}