ButlerBin/lib/document_handler.js

117 lines
3.5 KiB
JavaScript
Raw Permalink Normal View History

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;
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) {
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" });
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." }));
}
2020-06-08 20:56:17 +01:00
});
};
2020-06-08 20:56:17 +01:00
// Handle adding a new document.
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 = "";
var cancelled = false;
2020-06-08 20:56:17 +01:00
// If success...
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
});
};
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") {
var busboy = new Busboy({ headers: request.headers });
2020-06-08 20:56:17 +01:00
busboy.on("field", function (fieldname, val) {
if (fieldname === "data") {
buffer = val;
}
});
2020-06-08 20:56:17 +01:00
busboy.on("finish", function () {
onSuccess();
});
request.pipe(busboy);
2020-06-08 20:56:17 +01:00
// Otherwise, use our own and just grab flat data from POST body.
} else {
2020-06-08 20:56:17 +01:00
request.on("data", function (data) {
buffer += data.toString();
});
2020-06-08 20:56:17 +01:00
request.on("end", function () {
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." }));
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) {
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
};
DocumentHandler.prototype.acceptableKey = function() {
2020-06-08 20:56:17 +01:00
return this.keyGenerator.createKey();
};
2011-11-18 20:51:38 +00:00
module.exports = DocumentHandler;