diff --git a/lib/www/server/api/index.js b/lib/www/server/api/index.js index dcba6f9..e11dd28 100644 --- a/lib/www/server/api/index.js +++ b/lib/www/server/api/index.js @@ -69,6 +69,7 @@ const allMeta = (key, value) => { return { all: [ meta(key, value) ] }; }; + // // NOTICE These routes do not require authentication // @@ -168,10 +169,10 @@ app.map({ */ '/project/:project/sequence/': { - get: [ mw.auth.access.read, mw.sequence.list ], + get: [ mw.auth.access.read, mw.compress, mw.sequence.list ], }, '/project/:project/sequence/:sequence': { - get: [ mw.auth.access.read, mw.sequence.get ], + get: [ mw.auth.access.read, mw.compress, mw.sequence.get ], patch: [ mw.auth.access.write, mw.sequence.patch ], '/:point': { get: [ mw.auth.access.read, mw.sequence.point.get ] @@ -212,7 +213,7 @@ app.map({ */ '/project/:project/event/': { - get: [ mw.auth.access.read, mw.event.list ], + get: [ mw.auth.access.read, mw.compress, mw.event.list ], post: [ mw.auth.access.write, mw.event.post ], put: [ mw.auth.access.write, mw.event.put ], delete: [ mw.auth.access.write, mw.event.delete ], @@ -221,7 +222,7 @@ app.map({ }, // TODO Rename -/:sequence → sequence/:sequence '-/:sequence/': { // NOTE: We need to avoid conflict with the next endpoint ☹ - get: [ mw.auth.access.read, mw.event.sequence.get ], + get: [ mw.auth.access.read, mw.compress, mw.event.sequence.get ], }, ':id/': { get: [ mw.auth.access.read, mw.event.get ], @@ -300,15 +301,15 @@ app.map({ // // delete: [ mw.permissions.delete ] // }, '/project/:project/files/:path(*)': { - get: [ mw.files.get ] + get: [ mw.compress, mw.files.get ] }, '/files/?:path(*)': { - get: [ mw.etag.noSave, mw.files.get ] + get: [ mw.etag.noSave, mw.compress, mw.files.get ] }, '/navdata/': { // TODO These endpoints should probably need read access auth - get: [ mw.etag.noSave, mw.navdata.get ], + get: [ mw.etag.noSave, mw.compress, mw.navdata.get ], 'gis/:featuretype(line|point)': { - get: [ mw.etag.noSave, mw.gis.navdata.get ] + get: [ mw.etag.noSave, mw.compress, mw.gis.navdata.get ] } }, '/vessel/track': { @@ -316,6 +317,7 @@ app.map({ '/line': { get: [ // GeoJSON Feature: type = LineString //mw.etag.noSave, + mw.compress, (req, res, next) => { req.query.geojson = 'LineString'; next(); }, mw.vessel.track.get ] @@ -323,6 +325,7 @@ app.map({ '/point': { get: [ // GeoJSON FeatureCollection: feature types = Point //mw.etag.noSave, + mw.compress, (req, res, next) => { req.query.geojson = 'Point'; next(); }, mw.vessel.track.get ] @@ -330,6 +333,7 @@ app.map({ '/points': { get: [ // JSON array of (Feature: type = Point) mw.etag.noSave, + mw.compress, (req, res, next) => { req.query.geojson = true; next(); }, mw.vessel.track.get ], diff --git a/lib/www/server/api/middleware/compress/index.js b/lib/www/server/api/middleware/compress/index.js new file mode 100644 index 0000000..2970055 --- /dev/null +++ b/lib/www/server/api/middleware/compress/index.js @@ -0,0 +1,16 @@ +const compression = require('compression'); + +const compress = compression({ + level: 6, // Balance speed vs. ratio (1-9) + threshold: 512, // Compress only if response >512 bytes to avoid overhead on small bundles + filter: (req, res) => { // Ensure bundles are compressed + if (req.get("Accept") == "application/vnd.aaltronav.dougal+octet-stream") { + return true; + } + + // fallback to standard filter function + return compression.filter(req, res) + } +}); + +module.exports = compress; diff --git a/lib/www/server/api/middleware/index.js b/lib/www/server/api/middleware/index.js index 2c6ad51..993ccad 100644 --- a/lib/www/server/api/middleware/index.js +++ b/lib/www/server/api/middleware/index.js @@ -21,5 +21,6 @@ module.exports = { rss: require('./rss'), etag: require('./etag'), version: require('./version'), - admin: require('./admin') + admin: require('./admin'), + compress: require('./compress'), }; diff --git a/lib/www/server/package.json b/lib/www/server/package.json index ff7a1f9..ea89ab8 100644 --- a/lib/www/server/package.json +++ b/lib/www/server/package.json @@ -30,6 +30,7 @@ "@dougal/organisations": "file:../../modules/@dougal/organisations", "@dougal/user": "file:../../modules/@dougal/user", "body-parser": "gitlab:aaltronav/contrib/expressjs/body-parser", + "compression": "^1.8.1", "cookie-parser": "^1.4.5", "csv": "^6.3.3", "d3": "^6.7.0", diff --git a/package-lock.json b/package-lock.json index 6c1fe39..9dcc2a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3370,14 +3370,6 @@ "dev": true, "license": "MIT" }, - "lib/www/client/source/node_modules/bytes": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "lib/www/client/source/node_modules/call-bind": { "version": "1.0.5", "dev": true, @@ -3711,47 +3703,6 @@ "dev": true, "license": "MIT" }, - "lib/www/client/source/node_modules/compressible": { - "version": "2.0.18", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "lib/www/client/source/node_modules/compression": { - "version": "1.7.4", - "dev": true, - "license": "MIT", - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "lib/www/client/source/node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "lib/www/client/source/node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, "lib/www/client/source/node_modules/connect-history-api-fallback": { "version": "2.0.0", "dev": true, @@ -6497,14 +6448,6 @@ "dev": true, "license": "MIT" }, - "lib/www/client/source/node_modules/on-headers": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "lib/www/client/source/node_modules/onetime": { "version": "5.1.2", "dev": true, @@ -8643,14 +8586,6 @@ "spdx-expression-parse": "^3.0.0" } }, - "lib/www/client/source/node_modules/vary": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "lib/www/client/source/node_modules/vue": { "version": "2.6.14", "license": "MIT" @@ -9433,6 +9368,7 @@ "@dougal/organisations": "file:../../modules/@dougal/organisations", "@dougal/user": "file:../../modules/@dougal/user", "body-parser": "gitlab:aaltronav/contrib/expressjs/body-parser", + "compression": "^1.8.1", "cookie-parser": "^1.4.5", "csv": "^6.3.3", "d3": "^6.7.0", @@ -13367,13 +13303,6 @@ "node": ">= 0.4.0" } }, - "lib/www/server/node_modules/vary": { - "version": "1.1.2", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "lib/www/server/node_modules/xtend": { "version": "4.0.2", "license": "MIT", @@ -14457,6 +14386,34 @@ "node": ">= 10" } }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.1.0", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -15996,6 +15953,14 @@ "resolved": "https://registry.npmjs.org/nan/-/nan-2.23.0.tgz", "integrity": "sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==" }, + "node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -16103,6 +16068,14 @@ "node": ">= 0.8" } }, + "node_modules/on-headers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -16726,6 +16699,14 @@ "uuid": "bin/uuid" } }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",