From 05fe534e14bbac2a65c8e8c1299aeaa6004ccb22 Mon Sep 17 00:00:00 2001 From: Danny Coates Date: Thu, 29 Jun 2017 10:27:36 -0700 Subject: [PATCH] use header for file metadata --- frontend/src/fileReceiver.js | 9 ++++---- frontend/src/fileSender.js | 3 +-- server/portal_server.js | 30 ++++++++++++------------- server/storage.js | 43 +++++++++++++++++++++--------------- 4 files changed, 44 insertions(+), 41 deletions(-) diff --git a/frontend/src/fileReceiver.js b/frontend/src/fileReceiver.js index 8bf44ab3..29d07784 100644 --- a/frontend/src/fileReceiver.js +++ b/frontend/src/fileReceiver.js @@ -34,12 +34,11 @@ class FileReceiver extends EventEmitter { const blob = new Blob([this.response]); const fileReader = new FileReader(); fileReader.onload = function() { + const meta = JSON.parse(xhr.getResponseHeader('X-File-Metadata')) resolve({ data: this.result, - aad: xhr.getResponseHeader('Additional-Data'), - fname: xhr - .getResponseHeader('Content-Disposition') - .match(/=(.+)/)[1] + aad: meta.aad, + filename: meta.filename }); }; @@ -78,7 +77,7 @@ class FileReceiver extends EventEmitter { fdata.data ), new Promise((resolve, reject) => { - resolve(fdata.fname); + resolve(fdata.filename); }) ]); }); diff --git a/frontend/src/fileSender.js b/frontend/src/fileSender.js index a4709d28..837dfbd0 100644 --- a/frontend/src/fileSender.js +++ b/frontend/src/fileSender.js @@ -75,9 +75,7 @@ class FileSender extends EventEmitter { const dataView = new DataView(encrypted); const blob = new Blob([dataView], { type: file.type }); const fd = new FormData(); - fd.append('fname', file.name); fd.append('data', blob, file.name); - fd.append('aad', arrayToHex(this.aad)); const xhr = new XMLHttpRequest(); @@ -102,6 +100,7 @@ class FileSender extends EventEmitter { }; xhr.open('post', '/upload/' + fileId, true); + xhr.setRequestHeader('X-File-Metadata', JSON.stringify({ aad: arrayToHex(this.aad), iv: fileId, filename: file.name })) xhr.send(fd); }); }) diff --git a/server/portal_server.js b/server/portal_server.js index c966e882..9685ac14 100644 --- a/server/portal_server.js +++ b/server/portal_server.js @@ -78,17 +78,15 @@ app.get('/assets/download/:id', (req, res) => { return; } - Promise.all([ - storage.filename(id), - storage.aad(id)]) - .then(([reply, aad]) => { + storage.metadata(id) + .then(meta => { storage.length(id).then(contentLength => { - + res.writeHead(200, { - 'Content-Disposition': 'attachment; filename=' + reply, + 'Content-Disposition': 'attachment; filename=' + meta.filename, 'Content-Type': 'application/octet-stream', 'Content-Length': contentLength, - 'Additional-Data': aad + 'X-File-Metadata': JSON.stringify(meta) }); const file_stream = storage.get(id); @@ -143,20 +141,20 @@ app.post('/upload/:id', (req, res, next) => { res.sendStatus(404); return; } - + const meta = JSON.parse(req.header('X-File-Metadata')); + log.info('meta', meta) req.pipe(req.busboy); - - req.busboy.on('field', (fieldname, value) => { - storage.setField(req.params.id, fieldname, value); - }) req.busboy.on('file', (fieldname, file, filename) => { log.info('Uploading:', req.params.id); - const protocol = conf.env === 'production' ? 'https' : req.protocol; - const url = `${protocol}://${req.get('host')}/download/${req.params.id}/`; - storage.set(req.params.id, file, filename, url).then(linkAndID => { - res.json(linkAndID); + storage.set(req.params.id, file, filename, meta).then(delete_token => { + const protocol = conf.env === 'production' ? 'https' : req.protocol; + const url = `${protocol}://${req.get('host')}/download/${req.params.id}/`; + res.json({ + url, + delete: delete_token + }); }); }); diff --git a/server/storage.js b/server/storage.js index f90d4f07..ce912186 100644 --- a/server/storage.js +++ b/server/storage.js @@ -31,7 +31,8 @@ if (conf.s3_bucket) { setField: setField, delete: awsDelete, forceDelete: awsForceDelete, - ping: awsPing + ping: awsPing, + metadata }; } else { module.exports = { @@ -44,10 +45,23 @@ if (conf.s3_bucket) { setField: setField, delete: localDelete, forceDelete: localForceDelete, - ping: localPing + ping: localPing, + metadata }; } +function metadata(id) { + return new Promise((resolve, reject) => { + redis_client.hgetall(id, (err, reply) => { + if (!err) { + resolve(reply); + } else { + reject(err); + } + }) + }) +} + function filename(id) { return new Promise((resolve, reject) => { redis_client.hget(id, 'filename', (err, reply) => { @@ -102,20 +116,16 @@ function localGet(id) { return fs.createReadStream(path.join(__dirname, '../static', id)); } -function localSet(id, file, filename, url) { +function localSet(id, file, filename, meta) { return new Promise((resolve, reject) => { const fstream = fs.createWriteStream(path.join(__dirname, '../static', id)); file.pipe(fstream); - fstream.on('close', () => { - const uuid = crypto.randomBytes(10).toString('hex'); - - redis_client.hmset([id, 'filename', filename, 'delete', uuid]); + fstream.on('close', () => { + meta.delete = crypto.randomBytes(10).toString('hex'); + redis_client.hmset(id, meta); redis_client.expire(id, 86400000); log.info('localSet:', 'Upload Finished of ' + id); - resolve({ - uuid: uuid, - url: url - }); + resolve(meta.delete); }); fstream.on('error', () => { @@ -183,7 +193,7 @@ function awsGet(id) { } } -function awsSet(id, file, filename, url) { +function awsSet(id, file, filename, meta) { const params = { Bucket: conf.s3_bucket, Key: id, @@ -196,16 +206,13 @@ function awsSet(id, file, filename, url) { log.info('awsUploadError:', err.stack); // an error occurred reject(); } else { - const uuid = crypto.randomBytes(10).toString('hex'); + meta.delete = crypto.randomBytes(10).toString('hex'); - redis_client.hmset([id, 'filename', filename, 'delete', uuid]); + redis_client.hmset(id, meta); redis_client.expire(id, 86400000); log.info('awsUploadFinish', 'Upload Finished of ' + filename); - resolve({ - uuid: uuid, - url: url - }); + resolve(meta.delete); } }); });