From 0b40557fa7b08a2b274bc180c68867c3a58b2e5d Mon Sep 17 00:00:00 2001 From: Raynos Date: Mon, 9 Feb 2015 12:17:48 -0800 Subject: [PATCH] re-use caching logic --- index.js | 65 ++++++++++++++++++++++------------------------------ package.json | 1 + test/unit.js | 4 ++-- 3 files changed, 30 insertions(+), 40 deletions(-) diff --git a/index.js b/index.js index a707158..eda2511 100644 --- a/index.js +++ b/index.js @@ -1,12 +1,27 @@ var rawBody = require("raw-body") +var cache = require("continuable-cache") var parseArguments = require("./parse-arguments.js") var ONE_MB = 1024 * 1024 -var RAW_BODY_EVENT = '__rawBodyRead__'; +var THUNK_KEY = '__npm_body_thunk_cache__'; module.exports = body +function parseBodyThunk(req, res, opts) { + return function thunk(callback) { + var limit = "limit" in opts ? opts.limit : ONE_MB + var contentLength = req.headers ? + Number(req.headers["content-length"]) : null; + + rawBody(req, { + limit: limit, + length: contentLength, + encoding: "encoding" in opts ? opts.encoding : true + }, callback); + }; +} + function body(req, res, opts, callback) { var args = parseArguments(req, res, opts, callback) req = args.req @@ -14,45 +29,19 @@ function body(req, res, opts, callback) { opts = args.opts callback = args.callback - if (!callback) { - return body.bind(null, req, res, opts) - } - - var limit = "limit" in opts ? opts.limit : ONE_MB - var contentLength = req.headers ? - Number(req.headers["content-length"]) : null; + var thunk; if (opts.cache) { - if (req.__rawBody__) { - process.nextTick(function() { - callback(null, req.__rawBody__); - }); - return; - } - - if (req.listeners(RAW_BODY_EVENT).length > 0) { - req.on(RAW_BODY_EVENT, callback); - return; - } + var thunk = req[THUNK_KEY] || + cache(parseBodyThunk(req, res, opts)); + req[THUNK_KEY] = thunk; + } else { + thunk = parseBodyThunk(req, res, opts); + } + + if (!callback) { + return thunk; } - req.on(RAW_BODY_EVENT, callback); - - rawBody(req, { - limit: limit, - length: contentLength, - encoding: "encoding" in opts ? opts.encoding : true - }, function onRawBody(err, string) { - if (!err && opts.cache) { - Object.defineProperty(req, '__rawBody__', { - configurable: true, - enumerable: false, - value: string - }); - } - - // Cleanup regardless of cache option - req.emit(RAW_BODY_EVENT, err, string); - req.removeAllListeners(RAW_BODY_EVENT); - }); + thunk(callback); } diff --git a/package.json b/package.json index 7f01b9c..fd189fe 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "email": "raynos2@gmail.com" }, "dependencies": { + "continuable-cache": "^0.3.1", "error": "~2.0.4", "raw-body": "~1.1.0", "safe-json-parse": "~1.0.1" diff --git a/test/unit.js b/test/unit.js index 4f6ee2e..33c2811 100644 --- a/test/unit.js +++ b/test/unit.js @@ -15,8 +15,8 @@ test('caching works', function t(assert) { var done = after(2, assert.end.bind(assert)); - body(request, response, { cache: true }, function onBody() { - assert.equal(request.__rawBody__, 'thisbody', 'raw body has been set'); + body(request, response, { cache: true }, function onBody(err, body) { + assert.equal(body, 'thisbody', 'raw body has been set'); assert.pass('body is parsed'); done(); });