drop.chapril.org-firefoxsend/server/storage.js

263 lines
5.6 KiB
JavaScript
Raw Normal View History

const AWS = require('aws-sdk');
const s3 = new AWS.S3();
const conf = require('./config.js');
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
2017-06-08 22:45:28 +02:00
const mozlog = require('./log.js');
2017-06-09 19:44:12 +02:00
const log = mozlog('portal.storage');
2017-06-08 22:45:28 +02:00
const redis = require('redis');
2017-06-08 01:46:48 +02:00
const redis_client = redis.createClient({
2017-06-23 20:14:33 +02:00
host: conf.redis_host,
connect_timeout: 10000
2017-06-08 01:46:48 +02:00
});
redis_client.on('error', err => {
log.info('Redis:', err);
});
2017-06-24 05:01:32 +02:00
if (conf.s3_bucket) {
module.exports = {
filename: filename,
exists: exists,
length: awsLength,
get: awsGet,
set: awsSet,
2017-06-20 23:33:28 +02:00
aad: aad,
setField: setField,
delete: awsDelete,
2017-06-23 20:14:33 +02:00
forceDelete: awsForceDelete,
2017-06-29 19:27:36 +02:00
ping: awsPing,
metadata
};
} else {
module.exports = {
filename: filename,
exists: exists,
length: localLength,
get: localGet,
set: localSet,
2017-06-20 23:33:28 +02:00
aad: aad,
setField: setField,
delete: localDelete,
2017-06-23 20:14:33 +02:00
forceDelete: localForceDelete,
2017-06-29 19:27:36 +02:00
ping: localPing,
metadata
};
}
2017-06-29 19:27:36 +02:00
function metadata(id) {
return new Promise((resolve, reject) => {
redis_client.hgetall(id, (err, reply) => {
if (!err) {
resolve(reply);
} else {
reject(err);
}
2017-06-29 19:30:08 +02:00
});
});
2017-06-29 19:27:36 +02:00
}
function filename(id) {
return new Promise((resolve, reject) => {
redis_client.hget(id, 'filename', (err, reply) => {
if (!err) {
resolve(reply);
} else {
2017-06-23 19:53:11 +02:00
reject(err);
}
});
});
}
function exists(id) {
2017-06-08 22:45:28 +02:00
return new Promise((resolve, reject) => {
redis_client.exists(id, (rediserr, reply) => {
2017-06-23 20:42:51 +02:00
if (reply === 1 && !rediserr) {
resolve();
} else {
reject(rediserr);
}
2017-06-08 22:45:28 +02:00
});
});
}
2017-06-20 23:33:28 +02:00
function setField(id, key, value) {
redis_client.hset(id, key, value);
}
function aad(id) {
return new Promise((resolve, reject) => {
redis_client.hget(id, 'aad', (err, reply) => {
if (!err) {
resolve(reply);
} else {
reject();
}
2017-06-29 19:30:08 +02:00
});
});
2017-06-20 23:33:28 +02:00
}
function localLength(id) {
return new Promise((resolve, reject) => {
try {
2017-06-09 19:44:12 +02:00
resolve(fs.statSync(path.join(__dirname, '../static', id)).size);
} catch (err) {
reject();
}
});
}
function localGet(id) {
2017-06-09 19:44:12 +02:00
return fs.createReadStream(path.join(__dirname, '../static', id));
}
2017-06-29 19:27:36 +02:00
function localSet(id, file, filename, meta) {
return new Promise((resolve, reject) => {
2017-07-07 23:47:56 +02:00
const new_id = crypto.randomBytes(5).toString('hex');
const fstream = fs.createWriteStream(path.join(__dirname, '../static', new_id));
file.pipe(fstream);
2017-06-29 19:27:36 +02:00
fstream.on('close', () => {
meta.delete = crypto.randomBytes(10).toString('hex');
2017-07-07 23:47:56 +02:00
meta.id = id;
redis_client.hmset(new_id, meta);
redis_client.expire(id, 86400000);
2017-07-07 23:47:56 +02:00
log.info('localSet:', 'Upload Finished of ' + new_id);
resolve([meta.delete, new_id]);
});
fstream.on('error', () => {
2017-07-07 23:47:56 +02:00
log.error('localSet:', 'Failed upload of ' + new_id);
reject();
});
});
}
function localDelete(id, delete_token) {
return new Promise((resolve, reject) => {
redis_client.hget(id, 'delete', (err, reply) => {
if (!reply || delete_token !== reply) {
reject();
} else {
redis_client.del(id);
2017-06-09 19:44:12 +02:00
resolve(fs.unlinkSync(path.join(__dirname, '../static', id)));
}
});
});
}
function localForceDelete(id) {
return new Promise((resolve, reject) => {
redis_client.del(id);
2017-06-09 19:44:12 +02:00
resolve(fs.unlinkSync(path.join(__dirname, '../static', id)));
});
}
2017-06-23 20:14:33 +02:00
function localPing() {
return new Promise((resolve, reject) => {
redis_client.ping(err => {
return err ? reject() : resolve();
});
});
}
function awsLength(id) {
2017-06-09 19:44:12 +02:00
const params = {
Bucket: conf.s3_bucket,
Key: id
};
return new Promise((resolve, reject) => {
s3.headObject(params, function(err, data) {
if (!err) {
resolve(data.ContentLength);
} else {
reject();
}
});
});
}
function awsGet(id) {
2017-06-09 19:44:12 +02:00
const params = {
Bucket: conf.s3_bucket,
Key: id
};
2017-06-20 19:21:11 +02:00
try {
return s3.getObject(params).createReadStream();
2017-06-20 21:52:01 +02:00
} catch (err) {
2017-06-20 19:21:11 +02:00
log.info('GetFailed', 'Get Object from s3 failed.');
return null;
}
}
2017-06-29 19:27:36 +02:00
function awsSet(id, file, filename, meta) {
2017-07-07 23:47:56 +02:00
const new_id = crypto.randomBytes(5).toString('hex');
2017-06-09 19:44:12 +02:00
const params = {
Bucket: conf.s3_bucket,
2017-07-07 23:47:56 +02:00
Key: new_id,
Body: file
};
return new Promise((resolve, reject) => {
2017-06-09 19:44:12 +02:00
s3.upload(params, function(err, _data) {
if (err) {
2017-06-08 22:45:28 +02:00
log.info('awsUploadError:', err.stack); // an error occurred
reject();
} else {
2017-06-29 19:27:36 +02:00
meta.delete = crypto.randomBytes(10).toString('hex');
2017-07-07 23:47:56 +02:00
meta.id = id;
redis_client.hmset(new_id, meta);
redis_client.expire(id, 86400000);
log.info('awsUploadFinish', 'Upload Finished of ' + filename);
2017-07-07 23:47:56 +02:00
resolve([meta.delete, new_id]);
}
});
});
}
function awsDelete(id, delete_token) {
return new Promise((resolve, reject) => {
redis_client.hget(id, 'delete', (err, reply) => {
if (!reply || delete_token !== reply) {
reject();
} else {
redis_client.del(id);
2017-06-09 19:44:12 +02:00
const params = {
Bucket: conf.s3_bucket,
Key: id
};
2017-06-09 19:44:12 +02:00
s3.deleteObject(params, function(err, _data) {
2017-06-19 22:37:56 +02:00
err ? reject(err) : resolve(err);
});
}
});
});
}
function awsForceDelete(id) {
return new Promise((resolve, reject) => {
redis_client.del(id);
2017-06-09 19:44:12 +02:00
const params = {
Bucket: conf.s3_bucket,
Key: id
};
2017-06-09 19:44:12 +02:00
s3.deleteObject(params, function(err, _data) {
2017-06-19 22:37:56 +02:00
err ? reject(err) : resolve(err);
});
});
}
2017-06-23 20:14:33 +02:00
function awsPing() {
return localPing().then(() =>
s3.headBucket({ Bucket: conf.s3_bucket }).promise()
);
}