2014-04-21 19:16:23 +01:00
|
|
|
var Busboy = require('busboy');
|
2020-06-08 20:56:17 +01:00
|
|
|
var Winston = require('winston');
|
2011-11-18 20:51:38 +00:00
|
|
|
|
2020-06-08 20:56:17 +01:00
|
|
|
// For handling serving stored documents.
|
2011-11-18 20:51:38 +00:00
|
|
|
|
2020-06-08 20:56:17 +01:00
|
|
|
var DocumentHandler = function(options = {}) {
|
2011-11-28 21:46:59 +00:00
|
|
|
this.store = options.store;
|
2012-01-07 16:35:11 +00:00
|
|
|
this.keyGenerator = options.keyGenerator;
|
2011-11-18 20:51:38 +00:00
|
|
|
};
|
|
|
|
|
2011-11-28 21:46:59 +00:00
|
|
|
|
2020-06-08 20:56:17 +01:00
|
|
|
// Handle retrieving a document.
|
|
|
|
DocumentHandler.prototype.handleGet = function(key, response) {
|
2011-11-18 22:54:57 +00:00
|
|
|
this.store.get(key, function(ret) {
|
2011-11-18 22:12:28 +00:00
|
|
|
if (ret) {
|
2020-06-08 20:56:17 +01:00
|
|
|
Winston.verbose("Retrieved document.", { key: key });
|
|
|
|
response.writeHead(200, { "content-type": "application/json" });
|
2011-11-18 22:12:28 +00:00
|
|
|
response.end(JSON.stringify({ data: ret, key: key }));
|
|
|
|
}
|
|
|
|
else {
|
2020-06-08 20:56:17 +01:00
|
|
|
Winston.warn("Document not found.", { key: key });
|
|
|
|
response.writeHead(404, { "content-type": "application/json" });
|
|
|
|
response.end(JSON.stringify({ message: "Document not found." }));
|
2011-11-18 22:12:28 +00:00
|
|
|
}
|
2020-06-08 20:56:17 +01:00
|
|
|
});
|
2011-11-18 20:51:38 +00:00
|
|
|
};
|
|
|
|
|
2020-06-08 20:56:17 +01:00
|
|
|
// Handle retrieving the raw version of a document.
|
|
|
|
DocumentHandler.prototype.handleRawGet = function(key, response) {
|
2011-12-16 12:57:09 +00:00
|
|
|
this.store.get(key, function(ret) {
|
|
|
|
if (ret) {
|
2020-06-08 20:56:17 +01:00
|
|
|
Winston.verbose("Retrieved raw document.", { key: key });
|
|
|
|
response.writeHead(200, { "content-type": "text/plain; charset=UTF-8" });
|
2011-12-16 12:57:09 +00:00
|
|
|
response.end(ret);
|
|
|
|
}
|
|
|
|
else {
|
2020-06-08 20:56:17 +01:00
|
|
|
Winston.warn("Raw document not found.", { key: key });
|
|
|
|
response.writeHead(404, { "content-type": "application/json" });
|
|
|
|
response.end(JSON.stringify({ message: "Document not found." }));
|
2011-12-16 12:57:09 +00:00
|
|
|
}
|
2020-06-08 20:56:17 +01:00
|
|
|
});
|
2011-12-16 12:57:09 +00:00
|
|
|
};
|
|
|
|
|
2020-06-08 20:56:17 +01:00
|
|
|
// Handle adding a new document.
|
2014-04-21 19:16:23 +01:00
|
|
|
DocumentHandler.prototype.handlePost = function (request, response) {
|
2011-11-18 22:54:57 +00:00
|
|
|
var _this = this;
|
2020-06-08 20:56:17 +01:00
|
|
|
var buffer = "";
|
2011-12-19 20:20:22 +00:00
|
|
|
var cancelled = false;
|
2014-04-21 19:16:23 +01:00
|
|
|
|
2020-06-08 20:56:17 +01:00
|
|
|
// If success...
|
2014-04-21 19:16:23 +01:00
|
|
|
var onSuccess = function () {
|
|
|
|
_this.chooseKey(function (key) {
|
|
|
|
_this.store.set(key, buffer, function (res) {
|
2011-11-22 02:48:09 +00:00
|
|
|
if (res) {
|
2020-06-08 20:56:17 +01:00
|
|
|
Winston.verbose("Added document.", { key: key });
|
|
|
|
response.writeHead(200, { "content-type": "application/json" });
|
2011-11-22 02:48:09 +00:00
|
|
|
response.end(JSON.stringify({ key: key }));
|
|
|
|
}
|
|
|
|
else {
|
2020-06-08 20:56:17 +01:00
|
|
|
Winston.verbose("Error adding document");
|
|
|
|
response.writeHead(500, { "content-type": "application/json" });
|
|
|
|
response.end(JSON.stringify({ message: "Error adding document." }));
|
2011-11-22 02:48:09 +00:00
|
|
|
}
|
|
|
|
});
|
2011-11-18 22:12:28 +00:00
|
|
|
});
|
2014-04-21 19:16:23 +01:00
|
|
|
};
|
|
|
|
|
2020-06-08 20:56:17 +01:00
|
|
|
// Parse form to grab the data.
|
|
|
|
var ct = request.headers["content-type"];
|
|
|
|
if (ct && ct.split(";")[0] === "multipart/form-data") {
|
2014-04-21 19:16:23 +01:00
|
|
|
var busboy = new Busboy({ headers: request.headers });
|
2020-06-08 20:56:17 +01:00
|
|
|
busboy.on("field", function (fieldname, val) {
|
|
|
|
if (fieldname === "data") {
|
2014-04-21 19:16:23 +01:00
|
|
|
buffer = val;
|
|
|
|
}
|
|
|
|
});
|
2020-06-08 20:56:17 +01:00
|
|
|
busboy.on("finish", function () {
|
2014-04-21 19:16:23 +01:00
|
|
|
onSuccess();
|
|
|
|
});
|
|
|
|
request.pipe(busboy);
|
2020-06-08 20:56:17 +01:00
|
|
|
// Otherwise, use our own and just grab flat data from POST body.
|
2014-04-21 19:16:23 +01:00
|
|
|
} else {
|
2020-06-08 20:56:17 +01:00
|
|
|
request.on("data", function (data) {
|
2014-04-21 19:16:23 +01:00
|
|
|
buffer += data.toString();
|
|
|
|
});
|
2020-06-08 20:56:17 +01:00
|
|
|
request.on("end", function () {
|
2014-04-21 19:16:23 +01:00
|
|
|
if (cancelled) { return; }
|
|
|
|
onSuccess();
|
|
|
|
});
|
2020-06-08 20:56:17 +01:00
|
|
|
request.on("error", function (error) {
|
|
|
|
Winston.error("Connection error: " + error.message);
|
|
|
|
response.writeHead(500, { "content-type": "application/json" });
|
|
|
|
response.end(JSON.stringify({ message: "Connection error." }));
|
2014-04-21 19:16:23 +01:00
|
|
|
cancelled = true;
|
|
|
|
});
|
|
|
|
}
|
2011-11-18 20:51:38 +00:00
|
|
|
};
|
|
|
|
|
2020-06-08 20:56:17 +01:00
|
|
|
// Keep choosing keys until we find one that isn't taken.
|
2011-11-22 02:48:09 +00:00
|
|
|
DocumentHandler.prototype.chooseKey = function(callback) {
|
2012-01-13 16:16:42 +00:00
|
|
|
var key = this.acceptableKey();
|
2011-11-22 02:48:09 +00:00
|
|
|
var _this = this;
|
|
|
|
this.store.get(key, function(ret) {
|
|
|
|
if (ret) {
|
|
|
|
_this.chooseKey(callback);
|
|
|
|
} else {
|
|
|
|
callback(key);
|
|
|
|
}
|
2020-06-08 20:56:17 +01:00
|
|
|
}, true); // Don't bump expirations when key searching.
|
2011-11-22 02:48:09 +00:00
|
|
|
};
|
|
|
|
|
2012-01-13 16:16:42 +00:00
|
|
|
DocumentHandler.prototype.acceptableKey = function() {
|
2020-06-08 20:56:17 +01:00
|
|
|
return this.keyGenerator.createKey();
|
2012-01-13 16:16:42 +00:00
|
|
|
};
|
|
|
|
|
2011-11-18 20:51:38 +00:00
|
|
|
module.exports = DocumentHandler;
|