Implement LZMA query param inflating as middleware

The req2params method is doing too many things,
this is an initial step to do fewer things in that method.
This commit is contained in:
Raul Ochoa 2017-08-04 17:30:46 +02:00
parent 7eae2a0618
commit 399561d076
5 changed files with 95 additions and 60 deletions

View File

@ -4,9 +4,6 @@ var _ = require('underscore');
var step = require('step'); var step = require('step');
var debug = require('debug')('windshaft:cartodb'); var debug = require('debug')('windshaft:cartodb');
var LZMA = require('lzma').LZMA;
var lzmaWorker = new LZMA();
// Whitelist query parameters and attach format // Whitelist query parameters and attach format
var REQUEST_QUERY_PARAMS_WHITELIST = [ var REQUEST_QUERY_PARAMS_WHITELIST = [
'config', 'config',
@ -28,7 +25,7 @@ function BaseController(authApi, pgConnection) {
module.exports = BaseController; module.exports = BaseController;
// jshint maxcomplexity:10 // jshint maxcomplexity:8
/** /**
* Whitelist input and get database name & default geometry type from * Whitelist input and get database name & default geometry type from
* subdomain/user metadata held in CartoDB Redis * subdomain/user metadata held in CartoDB Redis
@ -38,35 +35,6 @@ module.exports = BaseController;
BaseController.prototype.req2params = function(req, callback){ BaseController.prototype.req2params = function(req, callback){
var self = this; 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) {
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;
}
var allowedQueryParams = REQUEST_QUERY_PARAMS_WHITELIST; var allowedQueryParams = REQUEST_QUERY_PARAMS_WHITELIST;
if (Array.isArray(req.context.allowedQueryParams)) { if (Array.isArray(req.context.allowedQueryParams)) {
allowedQueryParams = allowedQueryParams.concat(req.context.allowedQueryParams); allowedQueryParams = allowedQueryParams.concat(req.context.allowedQueryParams);

View File

@ -0,0 +1,30 @@
'use strict';
var LZMA = require('lzma').LZMA;
var 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));
}
});
};

View File

@ -4,6 +4,8 @@ var RedisPool = require('redis-mpool');
var cartodbRedis = require('cartodb-redis'); var cartodbRedis = require('cartodb-redis');
var _ = require('underscore'); var _ = require('underscore');
var lzmaMiddleware = require('./middleware/lzma');
var controller = require('./controllers'); var controller = require('./controllers');
var SurrogateKeysCache = require('./cache/surrogate_keys_cache'); var SurrogateKeysCache = require('./cache/surrogate_keys_cache');
@ -345,6 +347,8 @@ function bootstrap(opts) {
next(); next();
}); });
app.use(lzmaMiddleware);
// temporary measure until we upgrade to newer version expressjs so we can check err.status // temporary measure until we upgrade to newer version expressjs so we can check err.status
app.use(function(err, req, res, next) { app.use(function(err, req, res, next) {
if (err) { if (err) {

View File

@ -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();
});
});
});
});

View File

@ -1,6 +1,6 @@
var assert = require('assert'); var assert = require('assert');
var _ = require('underscore'); var _ = require('underscore');
var test_helper = require('../../support/test_helper'); require('../../support/test_helper');
var RedisPool = require('redis-mpool'); var RedisPool = require('redis-mpool');
var cartodbRedis = require('cartodb-redis'); var cartodbRedis = require('cartodb-redis');
@ -98,13 +98,10 @@ describe('req2params', function() {
}); });
}); });
it('it should extend params with decoded lzma', function(done) { it('it should remove invalid params', function(done) {
var qo = { var config = {
config: {
version: '1.3.0' version: '1.3.0'
}
}; };
test_helper.lzma_compress_to_base64(JSON.stringify(qo), 1, function(err, data) {
var req = { var req = {
headers: { headers: {
host:'localhost' host:'localhost'
@ -113,7 +110,7 @@ describe('req2params', function() {
non_included: 'toberemoved', non_included: 'toberemoved',
api_key: 'test', api_key: 'test',
style: 'override', style: 'override',
lzma: data config: config
} }
}; };
baseController.req2params(prepareRequest(req), function(err, req) { baseController.req2params(prepareRequest(req), function(err, req) {
@ -121,12 +118,12 @@ describe('req2params', function() {
return done(err); return done(err);
} }
var query = req.params; var query = req.params;
assert.deepEqual(qo.config, query.config); assert.deepEqual(config, query.config);
assert.equal('test', query.api_key); assert.equal('test', query.api_key);
assert.equal(undefined, query.non_included); assert.equal(undefined, query.non_included);
assert.equal(undefined, query.style);
done(); done();
}); });
}); });
});
}); });