Add support for LZMA compressed GET parameters
You can now replace the whole query string with a single `lzma` parameter having as value an hex encoded LZMA compressed version of the whole query string as a JSON object.
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
* Add last_modified field to POST layergroup response (#72)
|
||||
* Deprecate signal handler for USR1, add handler for USR2 (#71)
|
||||
* Fix support for ampersend characters in CartoCSS
|
||||
* Add support for LZMA compressed GET parameters
|
||||
|
||||
1.1.8
|
||||
-----
|
||||
|
||||
@@ -5,6 +5,7 @@ var _ = require('underscore')
|
||||
, mapnik = require('mapnik')
|
||||
, crypto = require('crypto')
|
||||
, request = require('request')
|
||||
, LZMA = require('lzma/lzma_worker.js').LZMA
|
||||
;
|
||||
|
||||
module.exports = function(){
|
||||
@@ -255,6 +256,42 @@ module.exports = function(){
|
||||
*/
|
||||
me.req2params = function(req, callback){
|
||||
|
||||
if ( req.query.lzma ) {
|
||||
|
||||
// TODO: check ?
|
||||
//console.log("type of req.query.lzma is " + typeof(req.query.lzma));
|
||||
//console.log("req.query.lzma is " + req.query.lzma);
|
||||
|
||||
// Decode
|
||||
var lzma = [];
|
||||
for (var i=0; i<req.query.lzma.length/2; ++i) {
|
||||
var hex = req.query.lzma.substring(i*2, i*2+2);
|
||||
var num = parseInt(hex, "16");
|
||||
if ( num > 127 ) num = 127-num;
|
||||
//console.log(i + " hex: " + hex + " decodes as " + num);
|
||||
lzma.push( num );
|
||||
}
|
||||
|
||||
// Decompress
|
||||
//console.log("LZMA decompression starts with " + lzma);
|
||||
LZMA.decompress(
|
||||
lzma,
|
||||
function(result) {
|
||||
//console.log("LZMA decompression completed, payload: "); console.dir(result);
|
||||
try {
|
||||
req.query = JSON.parse(result);
|
||||
me.req2params(req, callback);
|
||||
} catch (err) {
|
||||
callback(new Error('Error parsing lzma as JSON: ' + err));
|
||||
}
|
||||
},
|
||||
function(percent) { // progress
|
||||
//console.log("LZMA decompression " + percent + "%");
|
||||
}
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Whitelist query parameters and attach format
|
||||
var good_query = ['sql', 'geom_type', 'cache_buster', 'cache_policy', 'callback', 'interactivity', 'map_key', 'api_key', 'style', 'style_version', 'style_convert' ];
|
||||
var bad_query = _.difference(_.keys(req.query), good_query);
|
||||
|
||||
Generated
+3
@@ -332,6 +332,9 @@
|
||||
"mapnik": {
|
||||
"version": "0.7.22"
|
||||
},
|
||||
"lzma": {
|
||||
"version": "1.2.2"
|
||||
},
|
||||
"semver": {
|
||||
"version": "1.1.3"
|
||||
},
|
||||
|
||||
+2
-1
@@ -28,7 +28,8 @@
|
||||
"redis": "0.7.2",
|
||||
"hiredis": "~0.1.14",
|
||||
"request": "2.9.202",
|
||||
"mapnik": "~0.7.14"
|
||||
"mapnik": "~0.7.14",
|
||||
"lzma": "~1.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "1.2.1",
|
||||
|
||||
@@ -7,6 +7,7 @@ var semver = require('semver');
|
||||
var mapnik = require('mapnik');
|
||||
var Step = require('step');
|
||||
var http = require('http');
|
||||
var LZMA = require('lzma/lzma_worker.js').LZMA;
|
||||
var SQLAPIEmu = require(__dirname + '/../support/SQLAPIEmu.js');
|
||||
|
||||
require(__dirname + '/../support/test_helper');
|
||||
@@ -16,6 +17,27 @@ var serverOptions = require(__dirname + '/../../lib/cartodb/server_options');
|
||||
var server = new CartodbWindshaft(serverOptions);
|
||||
server.setMaxListeners(0);
|
||||
|
||||
// Utility function to compress & encode LZMA
|
||||
function lzma_compress_to_hex(payload, mode, callback) {
|
||||
var HEX = [ '0','1','2','3','4','5','6','7',
|
||||
'8','9','a','b','c','d','e','f' ];
|
||||
LZMA.compress(payload, mode,
|
||||
function(ints) {
|
||||
for (var i=0; i<ints.length; ++i) {
|
||||
if ( ints[i] < 0 ) ints[i] = 127-ints[i];
|
||||
var hi = ints[i] >> 4;
|
||||
var lo = ints[i] & 0x0f;
|
||||
ints[i] = HEX[hi] + HEX[lo];
|
||||
};
|
||||
var hex = ints.join('');
|
||||
callback(null, hex);
|
||||
},
|
||||
function(percent) {
|
||||
//console.log("Compressing: " + percent + "%");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
suite('server', function() {
|
||||
|
||||
var redis_client = redis.createClient(global.environment.redis.port);
|
||||
@@ -782,6 +804,41 @@ suite('server', function() {
|
||||
});
|
||||
});
|
||||
|
||||
test("get'ing a tile with url specified 2.1.0 style (lzma version)", function(done){
|
||||
var qo = {
|
||||
style: test_style_black_210,
|
||||
style_version: '2.1.0',
|
||||
cache_buster: 5
|
||||
};
|
||||
Step (
|
||||
function compressQuery () {
|
||||
//console.log("Compressing starts");
|
||||
var next = this;
|
||||
lzma_compress_to_hex(JSON.stringify(qo), 1, this);
|
||||
//cosole.log("compress returned " + x );
|
||||
},
|
||||
function sendRequest(err, lzma) {
|
||||
//console.log("Compressing ends: " + typeof(lzma) + " - " + lzma);
|
||||
assert.response(server, {
|
||||
headers: {host: 'localhost'},
|
||||
url: '/tiles/test_table/15/16046/12354.png?lzma=' + lzma,
|
||||
method: 'GET',
|
||||
encoding: 'binary'
|
||||
},{}, this);
|
||||
},
|
||||
function checkResponse(res) {
|
||||
assert.equal(res.statusCode, 200, res.statusCode + ': ' + res.body);
|
||||
var ct = res.headers['content-type'];
|
||||
assert.equal(ct, 'image/png');
|
||||
assert.imageEqualsFile(res.body, './test/fixtures/test_table_15_16046_12354_styled_black.png', 2,
|
||||
function(err, similarity) {
|
||||
if (err) throw err;
|
||||
done();
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// See http://github.com/Vizzuality/Windshaft-cartodb/issues/57
|
||||
test("GET'ing a tile as anonymous with style set by POST", function(done){
|
||||
var style = querystring.stringify({style: test_style_black_210, style_version: '2.1.0'});
|
||||
|
||||
Reference in New Issue
Block a user