|
|
/*!
|
|
* Connect - json
|
|
* Copyright(c) 2010 Sencha Inc.
|
|
* Copyright(c) 2011 TJ Holowaychuk
|
|
* MIT Licensed
|
|
*/
|
|
|
|
/**
|
|
* Module dependencies.
|
|
*/
|
|
|
|
var utils = require('../utils')
|
|
, _limit = require('./limit');
|
|
|
|
/**
|
|
* noop middleware.
|
|
*/
|
|
|
|
function noop(req, res, next) {
|
|
next();
|
|
}
|
|
|
|
/**
|
|
* JSON:
|
|
*
|
|
* Parse JSON request bodies, providing the
|
|
* parsed object as `req.body`.
|
|
*
|
|
* Options:
|
|
*
|
|
* - `strict` when `false` anything `JSON.parse()` accepts will be parsed
|
|
* - `reviver` used as the second "reviver" argument for JSON.parse
|
|
* - `limit` byte limit disabled by default
|
|
*
|
|
* @param {Object} options
|
|
* @return {Function}
|
|
* @api public
|
|
*/
|
|
|
|
exports = module.exports = function(options){
|
|
var options = options || {}
|
|
, strict = options.strict !== false;
|
|
|
|
var limit = options.limit
|
|
? _limit(options.limit)
|
|
: noop;
|
|
|
|
return function json(req, res, next) {
|
|
if (req._body) return next();
|
|
req.body = req.body || {};
|
|
|
|
if (!utils.hasBody(req)) return next();
|
|
|
|
// check Content-Type
|
|
if ('application/json' != utils.mime(req)) return next();
|
|
|
|
// flag as parsed
|
|
req._body = true;
|
|
|
|
// parse
|
|
limit(req, res, function(err){
|
|
if (err) return next(err);
|
|
var buf = '';
|
|
req.setEncoding('utf8');
|
|
req.on('data', function(chunk){ buf += chunk });
|
|
req.on('end', function(){
|
|
var first = buf.trim()[0];
|
|
|
|
if (0 == buf.length) {
|
|
return next(utils.error(400, 'invalid json, empty body'));
|
|
}
|
|
|
|
if (strict && '{' != first && '[' != first) return next(utils.error(400, 'invalid json'));
|
|
try {
|
|
req.body = JSON.parse(buf, options.reviver);
|
|
} catch (err){
|
|
err.body = buf;
|
|
err.status = 400;
|
|
return next(err);
|
|
}
|
|
next();
|
|
});
|
|
});
|
|
};
|
|
};
|