From 25f15dfc617f4c9331e363db2a073f0ad36d9828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Mar=C3=ADn?= Date: Mon, 11 May 2020 18:28:27 +0200 Subject: [PATCH] Fix an ogr2ogr export issue when the temporal name is too big If the final name is going to be too big, use the hash over the proposed path to create an unique name that fits the requirements of path length under Linux --- NEWS.md | 1 + lib/models/formats/ogr.js | 9 +++++++-- lib/models/formats/ogr/shp.js | 2 +- test/acceptance/export/geopackage-test.js | 20 ++++++++++++++++++++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index 9273b0d2..ab010f14 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,7 @@ Released 2020-mm-dd - Updated allowed list of custom headers with the ones for metrics +- Fix an ogr2ogr export issue when the temporal name is too big [`653`](https://github.com/CartoDB/CartoDB-SQL-API/issues/653). ## 5.0.1 diff --git a/lib/models/formats/ogr.js b/lib/models/formats/ogr.js index 4aa9ff45..4886fb9a 100644 --- a/lib/models/formats/ogr.js +++ b/lib/models/formats/ogr.js @@ -45,6 +45,11 @@ OgrFormat.prototype = { var hash = crypto.createHash('md5'); hash.update(data); return hash.digest('hex'); + }, + + limitPathname: function (pathname) { + if (pathname.length < 128) { return pathname; } + return crypto.createHash('sha256').update(pathname).digest('hex'); } }; @@ -230,14 +235,14 @@ OgrFormat.prototype.toOGR_SingleFile = function (options, fmt, callback) { var layername = options.filename; var tmpdir = global.settings.tmpDir || '/tmp'; - var reqKey = [ + var reqKey = this.limitPathname([ fmt, dbname, userId, gcol, this.generateMD5(layername), this.generateMD5(sql) - ].concat(skipfields).join(':'); + ].concat(skipfields).join(':')); var outdirpath = tmpdir + '/sqlapi-' + process.pid + '-' + reqKey; var dumpfile = outdirpath + ':cartodb-query.' + ext; diff --git a/lib/models/formats/ogr/shp.js b/lib/models/formats/ogr/shp.js index d886c134..33c72cb4 100644 --- a/lib/models/formats/ogr/shp.js +++ b/lib/models/formats/ogr/shp.js @@ -37,7 +37,7 @@ ShpFormat.prototype.toSHP = function (options, callback) { var zip = global.settings.zipCommand || 'zip'; var zipOptions = '-qrj'; var tmpdir = global.settings.tmpDir || '/tmp'; - var reqKey = ['shp', dbname, userId, gcol, this.generateMD5(sql)].concat(skipfields).join(':'); + var reqKey = this.limitPathname(['shp', dbname, userId, gcol, this.generateMD5(sql)].concat(skipfields).join(':')); var outdirpath = tmpdir + '/sqlapi-' + process.pid + '-' + reqKey; var zipfile = outdirpath + '.zip'; var shapefile = outdirpath + '/' + filename + '.shp'; diff --git a/test/acceptance/export/geopackage-test.js b/test/acceptance/export/geopackage-test.js index 02e7ebf9..9b996fb2 100644 --- a/test/acceptance/export/geopackage-test.js +++ b/test/acceptance/export/geopackage-test.js @@ -31,6 +31,26 @@ describe('geopackage query', function () { }); }); + it('works with a long list of skipfields', function (done) { + const longUrl = baseUrl + `&skipfields=the_geom_webmercator,${'a'.repeat(300)}`; + assert.response(server, { + url: longUrl, + headers: { host: 'vizzuality.cartodb.com' }, + method: 'GET' + }, { }, function (err, res) { + assert.ifError(err); + assert.strictEqual(res.statusCode, 200, res.body); + assert.strictEqual(res.headers['content-type'], 'application/x-sqlite3; charset=utf-8'); + assert.notEqual(res.headers['content-disposition'].indexOf(tableName + '.gpkg'), -1); + var db = new sqlite.Database(':memory:', res.body); + var qr = db.get('PRAGMA database_list', function (err) { + assert.strictEqual(err, null); + done(); + }); + assert.notEqual(qr, undefined); + }); + }); + it('gets database and geopackage schema', function (done) { assert.response(server, { url: baseUrl,