2017-05-11 12:53:16 -07:00
|
|
|
// Copyright 2012 Mark Cavage, Inc. All rights reserved.
|
|
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
var assert = require('assert-plus');
|
|
|
|
|
var errors = require('restify-errors');
|
|
|
|
|
|
|
|
|
|
var bodyReader = require('./bodyReader');
|
|
|
|
|
|
|
|
|
|
///--- API
|
|
|
|
|
|
|
|
|
|
/**
|
2017-10-24 22:22:30 +02:00
|
|
|
* Parses json body from the request.
|
|
|
|
|
*
|
2017-05-11 12:53:16 -07:00
|
|
|
* @public
|
|
|
|
|
* @function jsonBodyParser
|
2017-10-24 22:22:30 +02:00
|
|
|
* @param {Object} options - an options object
|
|
|
|
|
* @throws {InvalidContentError} on bad input
|
|
|
|
|
* @returns {Function} Handler
|
2017-05-11 12:53:16 -07:00
|
|
|
*/
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
if (req.getContentType() !== 'application/json' || !req.body) {
|
|
|
|
|
return next();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var params;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
params = JSON.parse(req.body, opts.reviver);
|
|
|
|
|
} catch (e) {
|
2017-10-31 19:29:49 +01:00
|
|
|
return next(
|
2018-02-05 09:48:43 +01:00
|
|
|
new errors.InvalidContentError(
|
|
|
|
|
'%s',
|
|
|
|
|
'Invalid JSON: ' + e.message
|
|
|
|
|
)
|
2017-10-31 19:29:49 +01:00
|
|
|
);
|
2017-05-11 12:53:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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.
|
2017-10-31 19:29:49 +01:00
|
|
|
if (
|
|
|
|
|
req.params &&
|
2017-05-11 12:53:16 -07:00
|
|
|
Object.keys(req.params).length > 0 &&
|
2017-10-31 19:29:49 +01:00
|
|
|
!(req.params instanceof Array)
|
|
|
|
|
) {
|
|
|
|
|
return next(
|
|
|
|
|
new errors.InternalServerError(
|
2018-02-23 11:20:44 -08:00
|
|
|
'Cannot map POST body of [Array array] onto ' +
|
|
|
|
|
'req.params'
|
2017-10-31 19:29:49 +01:00
|
|
|
)
|
|
|
|
|
);
|
2017-05-11 12:53:16 -07:00
|
|
|
}
|
|
|
|
|
req.params = params;
|
2017-10-31 19:29:49 +01:00
|
|
|
} else if (typeof params === 'object' && params !== null) {
|
2017-05-11 12:53:16 -07:00
|
|
|
// else, try to merge the objects
|
2017-10-31 19:29:49 +01:00
|
|
|
Object.keys(params).forEach(function forEach(k) {
|
2017-05-11 12:53:16 -07:00
|
|
|
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;
|