Support a form-data POST API

Closes #54
This commit is contained in:
John Crepezzi 2014-04-21 14:16:23 -04:00
parent 7a08960414
commit 0471b059a0
2 changed files with 45 additions and 18 deletions

View file

@ -1,4 +1,5 @@
var winston = require('winston'); var winston = require('winston');
var Busboy = require('busboy');
// For handling serving stored documents // For handling serving stored documents
@ -51,11 +52,11 @@ DocumentHandler.prototype.handlePost = function(request, response) {
var _this = this; var _this = this;
var buffer = ''; var buffer = '';
var cancelled = false; var cancelled = false;
request.on('data', function(data) {
if (!buffer) { // What to do when done
response.writeHead(200, { 'content-type': 'application/json' }); var onSuccess = function () {
} // Check length
buffer += data.toString(); console.log(buffer);
if (_this.maxLength && buffer.length > _this.maxLength) { if (_this.maxLength && buffer.length > _this.maxLength) {
cancelled = true; cancelled = true;
winston.warn('document >maxLength', { maxLength: _this.maxLength }); winston.warn('document >maxLength', { maxLength: _this.maxLength });
@ -63,14 +64,14 @@ DocumentHandler.prototype.handlePost = function(request, response) {
response.end( response.end(
JSON.stringify({ message: 'Document exceeds maximum length.' }) JSON.stringify({ message: 'Document exceeds maximum length.' })
); );
return;
} }
}); // And then save if we should
request.on('end', function(end) {
if (cancelled) return;
_this.chooseKey(function (key) { _this.chooseKey(function (key) {
_this.store.set(key, buffer, function (res) { _this.store.set(key, buffer, function (res) {
if (res) { if (res) {
winston.verbose('added document', { key: key }); winston.verbose('added document', { key: key });
response.writeHead(200, { 'content-type': 'application/json' });
response.end(JSON.stringify({ key: key })); response.end(JSON.stringify({ key: key }));
} }
else { else {
@ -80,12 +81,37 @@ DocumentHandler.prototype.handlePost = function(request, response) {
} }
}); });
}); });
};
// If we should, parse a 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 });
busboy.on('field', function (fieldname, val) {
if (fieldname === 'data') {
buffer = val;
}
});
busboy.on('finish', function () {
onSuccess();
});
request.pipe(busboy);
// Otherwise, use our own and just grab flat data from POST body
} else {
request.on('data', function (data) {
buffer += data.toString();
});
request.on('end', function () {
if (cancelled) { return; }
onSuccess();
}); });
request.on('error', function (error) { request.on('error', function (error) {
winston.error('connection error: ' + error.message); winston.error('connection error: ' + error.message);
response.writeHead(500, { 'content-type': 'application/json' }); response.writeHead(500, { 'content-type': 'application/json' });
response.end(JSON.stringify({ message: 'Connection error.' })); response.end(JSON.stringify({ message: 'Connection error.' }));
cancelled = true;
}); });
}
}; };
// Keep choosing keys until one isn't taken // Keep choosing keys until one isn't taken

View file

@ -18,7 +18,8 @@
"connect": "1.9.2", "connect": "1.9.2",
"redis-url": "0.1.0", "redis-url": "0.1.0",
"redis": "0.8.1", "redis": "0.8.1",
"uglify-js": "1.3.3" "uglify-js": "1.3.3",
"busboy": "0.2.4"
}, },
"devDependencies": { "devDependencies": {
"mocha": "*", "mocha": "*",