index.js
2.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/**!
* koa-body-parser - index.js
* Copyright(c) 2014
* MIT Licensed
*
* Authors:
* dead_horse <dead_horse@qq.com> (http://deadhorse.me)
* fengmk2 <m@fengmk2.com> (http://fengmk2.com)
*/
'use strict';
/**
* Module dependencies.
*/
var parse = require('co-body');
var copy = require('copy-to');
/**
* @param [Object] opts
* - {String} jsonLimit default '1mb'
* - {String} formLimit default '56kb'
* - {string} encoding default 'utf-8'
* - {Object} extendTypes
*/
module.exports = function (opts) {
opts = opts || {};
var detectJSON = opts.detectJSON;
var onerror = opts.onerror;
var enableTypes = opts.enableTypes || ['json', 'form'];
var enableForm = checkEnable(enableTypes, 'form');
var enableJson = checkEnable(enableTypes, 'json');
var enableText = checkEnable(enableTypes, 'text');
opts.detectJSON = undefined;
opts.onerror = undefined;
// force co-body return raw body
opts.returnRawBody = true;
// default json types
var jsonTypes = [
'application/json',
'application/json-patch+json',
'application/vnd.api+json',
'application/csp-report',
];
// default form types
var formTypes = [
'application/x-www-form-urlencoded',
];
// default text types
var textTypes = [
'text/plain',
];
var jsonOpts = formatOptions(opts, 'json');
var formOpts = formatOptions(opts, 'form');
var textOpts = formatOptions(opts, 'text');
var extendTypes = opts.extendTypes || {};
extendType(jsonTypes, extendTypes.json);
extendType(formTypes, extendTypes.form);
extendType(textTypes, extendTypes.text);
return async function bodyParser(ctx, next) {
if (ctx.request.body !== undefined) return await next();
if (ctx.disableBodyParser) return await next();
try {
const res = await parseBody(ctx);
ctx.request.body = 'parsed' in res ? res.parsed : {};
if (ctx.request.rawBody === undefined) ctx.request.rawBody = res.raw;
} catch (err) {
if (onerror) {
onerror(err, ctx);
} else {
throw err;
}
}
await next();
};
async function parseBody(ctx) {
if (enableJson && ((detectJSON && detectJSON(ctx)) || ctx.request.is(jsonTypes))) {
return await parse.json(ctx, jsonOpts);
}
if (enableForm && ctx.request.is(formTypes)) {
return await parse.form(ctx, formOpts);
}
if (enableText && ctx.request.is(textTypes)) {
return await parse.text(ctx, textOpts) || '';
}
return {};
}
};
function formatOptions(opts, type) {
var res = {};
copy(opts).to(res);
res.limit = opts[type + 'Limit'];
return res;
}
function extendType(original, extend) {
if (extend) {
if (!Array.isArray(extend)) {
extend = [extend];
}
extend.forEach(function (extend) {
original.push(extend);
});
}
}
function checkEnable(types, type) {
return types.indexOf(type) >= 0;
}