From 0471b059a0d62a97c9d93f7b17f8b73f6e4aa77e Mon Sep 17 00:00:00 2001 From: John Crepezzi Date: Mon, 21 Apr 2014 14:16:23 -0400 Subject: [PATCH] Support a form-data POST API Closes #54 --- lib/document_handler.js | 60 +++++++++++++++++++++++++++++------------ package.json | 3 ++- 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/lib/document_handler.js b/lib/document_handler.js index 0ecc773..c4a0f1b 100644 --- a/lib/document_handler.js +++ b/lib/document_handler.js @@ -1,4 +1,5 @@ var winston = require('winston'); +var Busboy = require('busboy'); // For handling serving stored documents @@ -47,15 +48,15 @@ DocumentHandler.prototype.handleRawGet = function(key, response, skipExpire) { }; // Handle adding a new Document -DocumentHandler.prototype.handlePost = function(request, response) { +DocumentHandler.prototype.handlePost = function (request, response) { var _this = this; var buffer = ''; var cancelled = false; - request.on('data', function(data) { - if (!buffer) { - response.writeHead(200, { 'content-type': 'application/json' }); - } - buffer += data.toString(); + + // What to do when done + var onSuccess = function () { + // Check length + console.log(buffer); if (_this.maxLength && buffer.length > _this.maxLength) { cancelled = true; winston.warn('document >maxLength', { maxLength: _this.maxLength }); @@ -63,14 +64,14 @@ DocumentHandler.prototype.handlePost = function(request, response) { response.end( JSON.stringify({ message: 'Document exceeds maximum length.' }) ); + return; } - }); - request.on('end', function(end) { - if (cancelled) return; - _this.chooseKey(function(key) { - _this.store.set(key, buffer, function(res) { + // And then save if we should + _this.chooseKey(function (key) { + _this.store.set(key, buffer, function (res) { if (res) { winston.verbose('added document', { key: key }); + response.writeHead(200, { 'content-type': 'application/json' }); response.end(JSON.stringify({ key: key })); } else { @@ -80,12 +81,37 @@ DocumentHandler.prototype.handlePost = function(request, response) { } }); }); - }); - 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.' })); - }); + }; + + // 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) { + winston.error('connection error: ' + error.message); + response.writeHead(500, { 'content-type': 'application/json' }); + response.end(JSON.stringify({ message: 'Connection error.' })); + cancelled = true; + }); + } }; // Keep choosing keys until one isn't taken diff --git a/package.json b/package.json index 8ba9dea..6bf128b 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "connect": "1.9.2", "redis-url": "0.1.0", "redis": "0.8.1", - "uglify-js": "1.3.3" + "uglify-js": "1.3.3", + "busboy": "0.2.4" }, "devDependencies": { "mocha": "*",