UNPKG

1.5 kBJavaScriptView Raw
1
2/**
3 * Module dependencies.
4 */
5
6var raw = require('raw-body');
7var inflate = require('inflation');
8
9// Allowed whitespace is defined in RFC 7159
10// http://www.rfc-editor.org/rfc/rfc7159.txt
11var strictJSONReg = /^[\x20\x09\x0a\x0d]*(\[|\{)/;
12
13/**
14 * Return a Promise which parses json requests.
15 *
16 * Pass a node request or an object with `.req`,
17 * such as a koa Context.
18 *
19 * @param {Request} req
20 * @param {Options} [opts]
21 * @return {Function}
22 * @api public
23 */
24
25module.exports = function(req, opts){
26 req = req.req || req;
27 opts = opts || {};
28
29 // defaults
30 var len = req.headers['content-length'];
31 var encoding = req.headers['content-encoding'] || 'identity';
32 if (len && encoding === 'identity') opts.length = len = ~~len;
33 opts.encoding = opts.encoding || 'utf8';
34 opts.limit = opts.limit || '1mb';
35 var strict = opts.strict !== false;
36
37 // raw-body returns a promise when no callback is specified
38 return Promise.resolve()
39 .then(function() {
40 return raw(inflate(req), opts);
41 })
42 .then(function(str) {
43 try {
44 return parse(str);
45 } catch (err) {
46 err.status = 400;
47 err.body = str;
48 throw err;
49 }
50 });
51
52 function parse(str){
53 if (!strict) return str ? JSON.parse(str) : str;
54 // strict mode always return object
55 if (!str) return {};
56 // strict JSON test
57 if (!strictJSONReg.test(str)) {
58 throw new Error('invalid JSON, only supports object and array');
59 }
60 return JSON.parse(str);
61 }
62};