105 lines
2.9 KiB
JavaScript
105 lines
2.9 KiB
JavaScript
// Copyright 2012 Mark Cavage, Inc. All rights reserved.
|
|
|
|
'use strict';
|
|
|
|
var assert = require('assert-plus');
|
|
var errors = require('restify-errors');
|
|
|
|
var bodyReader = require('./bodyReader');
|
|
var regex = require('./utils/regex');
|
|
|
|
///--- API
|
|
|
|
/**
|
|
* Parses json body from the request.
|
|
*
|
|
* @public
|
|
* @function jsonBodyParser
|
|
* @param {Object} options - an options object
|
|
* @throws {InvalidContentError} on bad input
|
|
* @returns {Function} Handler
|
|
*/
|
|
function jsonBodyParser(options) {
|
|
assert.optionalObject(options, 'options');
|
|
var opts = options || {};
|
|
|
|
var override = opts.overrideParams;
|
|
|
|
function parseJson(req, res, next) {
|
|
// save original body on req.rawBody and req._body
|
|
req.rawBody = req._body = req.body;
|
|
|
|
var contentType = req.getContentType();
|
|
|
|
// check for empty body first, don't pay regex tax unless necessary.
|
|
// for content type, check for exact match and any of the *+json types
|
|
if (
|
|
!req.body ||
|
|
(contentType !== 'application/json' &&
|
|
!regex.jsonContentType.test(contentType))
|
|
) {
|
|
return next();
|
|
}
|
|
|
|
var params;
|
|
|
|
try {
|
|
params = JSON.parse(req.body, opts.reviver);
|
|
} catch (e) {
|
|
return next(
|
|
new errors.InvalidContentError(
|
|
'%s',
|
|
'Invalid JSON: ' + e.message
|
|
)
|
|
);
|
|
}
|
|
|
|
if (opts.mapParams === true) {
|
|
if (Array.isArray(params)) {
|
|
// if req.params exists, we have url params. we can't map an
|
|
// array safely onto req.params, throw an error.
|
|
if (
|
|
req.params &&
|
|
Object.keys(req.params).length > 0 &&
|
|
!(req.params instanceof Array)
|
|
) {
|
|
return next(
|
|
new errors.InternalServerError(
|
|
'Cannot map POST body of [Array array] onto ' +
|
|
'req.params'
|
|
)
|
|
);
|
|
}
|
|
req.params = params;
|
|
} else if (typeof params === 'object' && params !== null) {
|
|
// else, try to merge the objects
|
|
Object.keys(params).forEach(function forEach(k) {
|
|
var p = req.params[k];
|
|
|
|
if (p && !override) {
|
|
return;
|
|
}
|
|
req.params[k] = params[k];
|
|
});
|
|
} else {
|
|
// otherwise, do a wholesale stomp, no need to merge one by one.
|
|
req.params = params || req.params;
|
|
}
|
|
}
|
|
|
|
req.body = params;
|
|
|
|
return next();
|
|
}
|
|
|
|
var chain = [];
|
|
|
|
if (!opts.bodyReader) {
|
|
chain.push(bodyReader(opts));
|
|
}
|
|
chain.push(parseJson);
|
|
return chain;
|
|
}
|
|
|
|
module.exports = jsonBodyParser;
|