Add download bucket as zip archive

This commit is contained in:
Christoph Wiechert
2017-04-25 18:22:24 +02:00
parent 85a88a80c6
commit c7b354386d
4 changed files with 86 additions and 9 deletions

View File

@@ -11,7 +11,9 @@ const fs = require("fs");
const tusMeta = require('tus-metadata');
const assert = require('assert');
const AES = require("crypto-js/aes");
const MD5 = require("crypto-js/md5");
const debug = require('debug')('psitransfer:main');
const archiver = require('archiver');
const errorPage = fs.readFileSync(path.join(__dirname, '../public/html/error.html')).toString();
const store = new Store(config.uploadDir);
@@ -73,6 +75,50 @@ app.get('/files/:fid', async(req, res, next) => {
// let tusboy handle HEAD with Tus Header
if(req.method === 'HEAD' && req.get('Tus-Resumable')) return next();
// Download all files
if(req.params.fid.endsWith('.zip')) {
const sid = req.params.fid.split('++')[0];
const bucket = db.get(sid);
if(req.params.fid !== sid + '++' + MD5(bucket.map(f => f.key).join()).toString() + '.zip') {
res.status(404).send(errorPage.replace('%%ERROR%%', 'Invalid link'));
return;
}
debug(`Download Bucket ${sid}`);
res.header('ContentType', 'application/zip');
res.header('Content-Disposition', 'attachment; filename="' + sid + '.zip"');
const archive = archiver('zip');
archive.on('error', function(err) {
console.error(err);
});
bucket.forEach(info => {
archive.append(
fs.createReadStream(store.getFilename(info.metadata.sid + '++' + info.key)),
{name: info.metadata.name}
);
});
archive.pipe(res);
archive.finalize();
try {
res.on('finish', async () => {
bucket.forEach(async info => {
if(info.metadata.retention === 'one-time') {
await db.remove(info.metadata.sid, info.metadata.key);
}
});
});
} catch(e) {
console.error(e);
}
return;
}
// Download single file
debug(`Download ${req.params.fid}`);
try {
const info = await store.info(req.params.fid); // throws on 404

View File

@@ -97,7 +97,7 @@ class Store {
if(!end) end = info.size - 1;
contentLength = end - start + 1
}
cb({ contentLength, metadata: info.metadata, info });
if(cb) cb({ contentLength, metadata: info.metadata, info });
});
return fsp.createReadStream(this.getFilename(fid), {start, end});
}