mirror of
https://github.com/seejohnrun/haste-server.git
synced 2024-11-01 03:21:21 +00:00
Added remove route
Signed-off-by: Defman21 <i@defman.me>
This commit is contained in:
parent
0209375865
commit
eb0f868f75
6 changed files with 141 additions and 10 deletions
|
@ -47,6 +47,20 @@ DocumentHandler.prototype.handleRawGet = function(key, response, skipExpire) {
|
|||
}, skipExpire);
|
||||
};
|
||||
|
||||
DocumentHandler.prototype.handleDelete = function (key, secret, response) {
|
||||
this.store.remove(key, secret, function (ret) {
|
||||
if (ret) {
|
||||
winston.verbose('removed document', { key: key });
|
||||
response.writeHead(200, { 'content-type': 'application/json' });
|
||||
response.end(JSON.stringify({ message: "Removed document " + key }));
|
||||
} else {
|
||||
winston.warn('invalid secret or document not found', { key: key, secret: secret });
|
||||
response.writeHead(404, { 'content-type': 'application/json' });
|
||||
response.end(JSON.stringify({ message: 'Document not found.' }));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Handle adding a new Document
|
||||
DocumentHandler.prototype.handlePost = function (request, response) {
|
||||
var _this = this;
|
||||
|
@ -67,11 +81,11 @@ DocumentHandler.prototype.handlePost = function (request, response) {
|
|||
}
|
||||
// And then save if we should
|
||||
_this.chooseKey(function (key) {
|
||||
_this.store.set(key, buffer, function (res) {
|
||||
_this.store.set(key, buffer, function (res, secret) {
|
||||
if (res) {
|
||||
winston.verbose('added document', { key: key });
|
||||
winston.verbose('added document', { key: key, secret: secret });
|
||||
response.writeHead(200, { 'content-type': 'application/json' });
|
||||
response.end(JSON.stringify({ key: key }));
|
||||
response.end(JSON.stringify({ key: key, secret: secret }));
|
||||
}
|
||||
else {
|
||||
winston.verbose('error adding document');
|
||||
|
|
|
@ -12,6 +12,11 @@ var FileDocumentStore = function(options) {
|
|||
this.expire = options.expire;
|
||||
};
|
||||
|
||||
// Generate secret (10 chars)
|
||||
FileDocumentStore.secret = function() {
|
||||
return Math.random().toString(24).slice(-10);
|
||||
};
|
||||
|
||||
// Generate md5 of a string
|
||||
FileDocumentStore.md5 = function(str) {
|
||||
var md5sum = crypto.createHash('md5');
|
||||
|
@ -25,13 +30,17 @@ FileDocumentStore.prototype.set = function(key, data, callback, skipExpire) {
|
|||
try {
|
||||
var _this = this;
|
||||
fs.mkdir(this.basePath, '700', function() {
|
||||
var sc = FileDocumentStore.secret();
|
||||
var fn = _this.basePath + '/' + FileDocumentStore.md5(key);
|
||||
var sfn = fn + "-" + sc;
|
||||
fs.writeFile(fn, data, 'utf8', function(err) {
|
||||
if (err) {
|
||||
callback(false);
|
||||
}
|
||||
else {
|
||||
callback(true);
|
||||
fs.writeFile(sfn, "A validation file for " + fn, 'utf8', function (err) {
|
||||
if (!err) callback(true, sc);
|
||||
});
|
||||
if (_this.expire && !skipExpire) {
|
||||
winston.warn('file store cannot set expirations on keys');
|
||||
}
|
||||
|
@ -43,6 +52,27 @@ FileDocumentStore.prototype.set = function(key, data, callback, skipExpire) {
|
|||
}
|
||||
};
|
||||
|
||||
FileDocumentStore.prototype.remove = function(str, key, callback) {
|
||||
var file = FileDocumentStore.md5(str);
|
||||
var kfn = key;
|
||||
fs.exists(this.basePath + "/" + file + "-" + kfn, function(exists) {
|
||||
if (exists) {
|
||||
try {
|
||||
fs.unlink(this.basePath + "/" + file, function() {
|
||||
fs.unlink(this.basePath + "/" + file + "-" + kfn, function() {
|
||||
callback(true);
|
||||
});
|
||||
});
|
||||
} catch(err) {
|
||||
callback(false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
callback(false);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Get data from a file from key
|
||||
FileDocumentStore.prototype.get = function(key, callback, skipExpire) {
|
||||
var _this = this;
|
||||
|
|
|
@ -8,7 +8,9 @@ var MemcachedDocumentStore = function(options) {
|
|||
MemcachedDocumentStore.connect(options);
|
||||
}
|
||||
};
|
||||
|
||||
MemcachedDocumentStore.secret = function() {
|
||||
return Math.random().toString(24).slice(-10);
|
||||
};
|
||||
// Create a connection
|
||||
MemcachedDocumentStore.connect = function(options) {
|
||||
var host = options.host || '127.0.0.1';
|
||||
|
@ -27,7 +29,17 @@ MemcachedDocumentStore.connect = function(options) {
|
|||
MemcachedDocumentStore.prototype.set =
|
||||
function(key, data, callback, skipExpire) {
|
||||
MemcachedDocumentStore.client.set(key, data, function(err, reply) {
|
||||
err ? callback(false) : callback(true);
|
||||
if (!err) {
|
||||
var sc = MemcachedDocumentStore.secret();
|
||||
MemcachedDocumentStore.client.set(key + "-" + sc, "", function(err, reply) {
|
||||
if (!err) {
|
||||
callback(true, sc);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
callback(false);
|
||||
}
|
||||
}, skipExpire ? 0 : this.expire);
|
||||
};
|
||||
|
||||
|
@ -42,4 +54,21 @@ MemcachedDocumentStore.prototype.get = function(key, callback, skipExpire) {
|
|||
});
|
||||
};
|
||||
|
||||
MemcachedDocumentStore.prototype.remove = function(key, secret, callback) {
|
||||
MemcachedDocumentStore.client.get(key + "-" + secret, function(err, reply) {
|
||||
if (!err) {
|
||||
MemcachedDocumentStore.client.del(key, function(err, reply) {
|
||||
if (err) return callback(false);
|
||||
MemcachedDocumentStore.client.del(key + "-" + secret, function(err, reply) {
|
||||
if (err) return callback(false);
|
||||
callback(reply);
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
callback(false);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = MemcachedDocumentStore;
|
||||
|
|
|
@ -9,6 +9,7 @@ var winston = require('winston');
|
|||
var PostgresDocumentStore = function (options) {
|
||||
this.expireJS = options.expire;
|
||||
this.connectionUrl = process.env.DATABASE_URL || options.connectionUrl;
|
||||
this.secret = () => Math.random().toString(24).slice(-10);
|
||||
};
|
||||
|
||||
PostgresDocumentStore.prototype = {
|
||||
|
@ -19,16 +20,18 @@ PostgresDocumentStore.prototype = {
|
|||
var that = this;
|
||||
this.safeConnect(function (err, client, done) {
|
||||
if (err) { return callback(false); }
|
||||
client.query('INSERT INTO entries (key, value, expiration) VALUES ($1, $2, $3)', [
|
||||
var sc = that.secret();
|
||||
client.query('INSERT INTO entries (key, value, expiration, secret) VALUES ($1, $2, $3, $4)', [
|
||||
key,
|
||||
data,
|
||||
that.expireJS && !skipExpire ? that.expireJS + now : null
|
||||
that.expireJS && !skipExpire ? that.expireJS + now : null,
|
||||
sc
|
||||
], function (err, result) {
|
||||
if (err) {
|
||||
winston.error('error persisting value to postgres', { error: err });
|
||||
return callback(false);
|
||||
}
|
||||
callback(true);
|
||||
callback(true, sc);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -61,6 +64,32 @@ PostgresDocumentStore.prototype = {
|
|||
});
|
||||
});
|
||||
},
|
||||
|
||||
remove: function (key, secret, callback) {
|
||||
var now = Math.floor(new Date().getTime() / 1000);
|
||||
this.safeConnect(function (err, client, done) {
|
||||
if (err) { return callback(false); }
|
||||
client.query('SELECT id,value,expiration,secret from entries where KEY = $1 and (expiration IS NULL or expiration > $2)', [key, now], function (err, result) {
|
||||
if (err) {
|
||||
winston.error('error retrieving value from postgres', { error: err });
|
||||
return callback(false);
|
||||
}
|
||||
if (result.rows[0].secret == secret) {
|
||||
client.query("DELETE FROM entries where KEY = $1", [key], function (err, result) {
|
||||
if (err) {
|
||||
winston.error('error removing an item from postgres', { error: err });
|
||||
return callback(false);
|
||||
}
|
||||
else {
|
||||
callback(true);
|
||||
done();
|
||||
}
|
||||
});
|
||||
}
|
||||
done();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// A connection wrapper
|
||||
safeConnect: function (callback) {
|
||||
|
|
|
@ -43,6 +43,11 @@ RedisDocumentStore.connect = function(options) {
|
|||
});
|
||||
};
|
||||
|
||||
// Generate secret (10 chars)
|
||||
RedisDocumentStore.secret = function() {
|
||||
return Math.random().toString(24).slice(-10);
|
||||
};
|
||||
|
||||
// Save file in a key
|
||||
RedisDocumentStore.prototype.set = function(key, data, callback, skipExpire) {
|
||||
var _this = this;
|
||||
|
@ -54,7 +59,11 @@ RedisDocumentStore.prototype.set = function(key, data, callback, skipExpire) {
|
|||
if (!skipExpire) {
|
||||
_this.setExpiration(key);
|
||||
}
|
||||
callback(true);
|
||||
var sc = RedisDocumentStore.secret();
|
||||
RedisDocumentStore.client.set(key + '-' + sc, "", function(err, reply) {
|
||||
if (err) return callback(false);
|
||||
callback(true, sc);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -81,4 +90,21 @@ RedisDocumentStore.prototype.get = function(key, callback, skipExpire) {
|
|||
});
|
||||
};
|
||||
|
||||
RedisDocumentStore.prototype.remove = function(key, secret, callback) {
|
||||
RedisDocumentStore.client.get(key + "-" + secret, function(err, reply) {
|
||||
if (!err) {
|
||||
RedisDocumentStore.client.del(key, function(err, reply) {
|
||||
if (err) return callback(false);
|
||||
RedisDocumentStore.client.del(key + "-" + secret, function(err, reply) {
|
||||
if (err) return callback(false);
|
||||
callback(reply);
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
callback(false);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = RedisDocumentStore;
|
||||
|
|
|
@ -131,6 +131,9 @@ app.use(route(function(router) {
|
|||
skipExpire
|
||||
);
|
||||
});
|
||||
router.get('/documents/:id/remove/:secret', function(request, response, next) {
|
||||
return documentHandler.handleDelete(request.params.id, request.params.secret, response);
|
||||
});
|
||||
}));
|
||||
|
||||
// Otherwise, try to match static files
|
||||
|
|
Loading…
Reference in a new issue