diff --git a/lib/cartodb/controllers/base.js b/lib/cartodb/controllers/base.js index 07758977..2986f97e 100644 --- a/lib/cartodb/controllers/base.js +++ b/lib/cartodb/controllers/base.js @@ -7,8 +7,6 @@ function BaseController(authApi, pgConnection) { module.exports = BaseController; -// jshint maxcomplexity:6 - // jshint maxcomplexity:9 BaseController.prototype.send = function(req, res, body, status, headers) { if (req.params.dbhost) { diff --git a/lib/cartodb/middleware/lzma.js b/lib/cartodb/middleware/lzma.js new file mode 100644 index 00000000..6655cdeb --- /dev/null +++ b/lib/cartodb/middleware/lzma.js @@ -0,0 +1,30 @@ +'use strict'; + +const LZMA = require('lzma').LZMA; + +const lzmaWorker = new LZMA(); + +module.exports = function lzmaMiddleware(req, res, next) { + if (!req.query.hasOwnProperty('lzma')) { + return next(); + } + + // 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) { + try { + delete req.query.lzma; + Object.assign(req.query, JSON.parse(result)); + next(); + } catch (err) { + next(new Error('Error parsing lzma as JSON: ' + err)); + } + }); +}; diff --git a/lib/cartodb/middleware/req2params-middleware.js b/lib/cartodb/middleware/req2params-middleware.js index dc67c117..d6e0a5d1 100644 --- a/lib/cartodb/middleware/req2params-middleware.js +++ b/lib/cartodb/middleware/req2params-middleware.js @@ -2,9 +2,6 @@ var assert = require('assert'); var _ = require('underscore'); var step = require('step'); -var LZMA = require('lzma').LZMA; -var lzmaWorker = new LZMA(); - // Whitelist query parameters and attach format var REQUEST_QUERY_PARAMS_WHITELIST = [ @@ -20,7 +17,7 @@ var REQUEST_QUERY_PARAMS_WHITELIST = [ 'filters' // json ]; -// jshint maxcomplexity:10 +// jshint maxcomplexity:8 /** * Whitelist input and get database name & default geometry type from * subdomain/user metadata held in CartoDB Redis @@ -29,35 +26,6 @@ var REQUEST_QUERY_PARAMS_WHITELIST = [ */ module.exports = function req2paramsMiddleware (authApi, pgConnection) { return function req2params (req, res, next) { - 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) { - req.profiler.done('lzma'); - try { - delete req.query.lzma; - _.extend(req.query, JSON.parse(result)); - req2params(req, res, next); - } catch (err) { - req.profiler.done('req2params'); - next(new Error('Error parsing lzma as JSON: ' + err)); - } - } - ); - return; - } - var allowedQueryParams = REQUEST_QUERY_PARAMS_WHITELIST; if (Array.isArray(req.context.allowedQueryParams)) { allowedQueryParams = allowedQueryParams.concat(req.context.allowedQueryParams); diff --git a/lib/cartodb/server.js b/lib/cartodb/server.js index 75b26145..8e5a2b7a 100644 --- a/lib/cartodb/server.js +++ b/lib/cartodb/server.js @@ -44,6 +44,7 @@ var MapConfigAdapter = require('./models/mapconfig/adapter'); var StatsBackend = require('./backends/stats'); +const lzmaMiddleware = require('./middleware/lzma'); const errorMiddleware = require('./middleware/error-middleware'); module.exports = function(serverOptions) { @@ -376,6 +377,8 @@ function bootstrap(opts) { next(); }); + app.use(lzmaMiddleware); + // temporary measure until we upgrade to newer version expressjs so we can check err.status app.use(function(err, req, res, next) { if (err) { diff --git a/test/unit/cartodb/lzmaMiddleware.test.js b/test/unit/cartodb/lzmaMiddleware.test.js new file mode 100644 index 00000000..9a41030a --- /dev/null +++ b/test/unit/cartodb/lzmaMiddleware.test.js @@ -0,0 +1,36 @@ +var assert = require('assert'); +var testHelper = require('../../support/test_helper'); + +var lzmaMiddleware = require('../../../lib/cartodb/middleware/lzma'); + +describe('lzma-middleware', function() { + + it('it should extend params with decoded lzma', function(done) { + var qo = { + config: { + version: '1.3.0' + } + }; + testHelper.lzma_compress_to_base64(JSON.stringify(qo), 1, function(err, data) { + var req = { + headers: { + host:'localhost' + }, + query: { + api_key: 'test', + lzma: data + } + }; + lzmaMiddleware(req, {}, function(err) { + if ( err ) { + return done(err); + } + var query = req.query; + assert.deepEqual(qo.config, query.config); + assert.equal('test', query.api_key); + done(); + }); + }); + }); + +}); diff --git a/test/unit/cartodb/req2params.test.js b/test/unit/cartodb/req2params.test.js index cd067254..5edf36c4 100644 --- a/test/unit/cartodb/req2params.test.js +++ b/test/unit/cartodb/req2params.test.js @@ -1,6 +1,5 @@ var assert = require('assert'); var _ = require('underscore'); -var test_helper = require('../../support/test_helper'); var RedisPool = require('redis-mpool'); var cartodbRedis = require('cartodb-redis'); @@ -101,35 +100,32 @@ describe('req2params', function() { }); }); - it('it should extend params with decoded lzma', function(done) { - var qo = { - config: { - version: '1.3.0' + it('it should remove invalid params', function(done) { + var config = { + version: '1.3.0' + }; + var req = { + headers: { + host:'localhost' + }, + query: { + non_included: 'toberemoved', + api_key: 'test', + style: 'override', + config: config } }; - test_helper.lzma_compress_to_base64(JSON.stringify(qo), 1, function(err, data) { - var req = { - headers: { - host:'localhost' - }, - query: { - non_included: 'toberemoved', - api_key: 'test', - style: 'override', - lzma: data - } - }; - var res = {}; - req2params(prepareRequest(req), res, function(err, req) { - if ( err ) { - return done(err); - } - var query = req.params; - assert.deepEqual(qo.config, query.config); - assert.equal('test', query.api_key); - assert.equal(undefined, query.non_included); - done(); - }); + var res = {}; + + req2params(prepareRequest(req), res, function(err, req) { + if ( err ) { + return done(err); + } + var query = req.params; + assert.deepEqual(config, query.config); + assert.equal('test', query.api_key); + assert.equal(undefined, query.non_included); + done(); }); });