1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 | 'use strict';
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | var buddy = require('co-body');
|
18 | var forms = require('formidable');
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 | module.exports = requestbody;
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 | function requestbody(opts) {
|
33 | opts = opts || {};
|
34 | opts.onError = 'onError' in opts ? opts.onError : false;
|
35 | opts.patchNode = 'patchNode' in opts ? opts.patchNode : false;
|
36 | opts.patchKoa = 'patchKoa' in opts ? opts.patchKoa : true;
|
37 | opts.multipart = 'multipart' in opts ? opts.multipart : false;
|
38 | opts.urlencoded = 'urlencoded' in opts ? opts.urlencoded : true;
|
39 | opts.json = 'json' in opts ? opts.json : true;
|
40 | opts.text = 'text' in opts ? opts.text : true;
|
41 | opts.encoding = 'encoding' in opts ? opts.encoding : 'utf-8';
|
42 | opts.jsonLimit = 'jsonLimit' in opts ? opts.jsonLimit : '1mb';
|
43 | opts.jsonStrict = 'jsonStrict' in opts ? opts.jsonStrict : true;
|
44 | opts.formLimit = 'formLimit' in opts ? opts.formLimit : '56kb';
|
45 | opts.queryString = 'queryString' in opts ? opts.queryString : null;
|
46 | opts.formidable = 'formidable' in opts ? opts.formidable : {};
|
47 | opts.textLimit = 'textLimit' in opts ? opts.textLimit : '56kb';
|
48 | opts.strict = 'strict' in opts ? opts.strict : true;
|
49 |
|
50 | return function (ctx, next) {
|
51 | var bodyPromise;
|
52 |
|
53 | if (!opts.strict || ["GET", "HEAD", "DELETE"].indexOf(ctx.method.toUpperCase()) === -1) {
|
54 | try {
|
55 | if (opts.json && ctx.is('json')) {
|
56 | bodyPromise = buddy.json(ctx, {
|
57 | encoding: opts.encoding,
|
58 | limit: opts.jsonLimit,
|
59 | strict: opts.jsonStrict
|
60 | });
|
61 | } else if (opts.urlencoded && ctx.is('urlencoded')) {
|
62 | bodyPromise = buddy.form(ctx, {
|
63 | encoding: opts.encoding,
|
64 | limit: opts.formLimit,
|
65 | queryString: opts.queryString
|
66 | });
|
67 | } else if (opts.text && ctx.is('text')) {
|
68 | bodyPromise = buddy.text(ctx, {
|
69 | encoding: opts.encoding,
|
70 | limit: opts.textLimit
|
71 | });
|
72 | } else if (opts.multipart && ctx.is('multipart')) {
|
73 | bodyPromise = formy(ctx, opts.formidable);
|
74 | }
|
75 | } catch (parsingError) {
|
76 | if (typeof opts.onError === 'function') {
|
77 | opts.onError(parsingError, ctx);
|
78 | } else {
|
79 | throw parsingError;
|
80 | }
|
81 | }
|
82 | }
|
83 |
|
84 | bodyPromise = bodyPromise || Promise.resolve({});
|
85 | return bodyPromise.catch(function(parsingError) {
|
86 | if (typeof opts.onError === 'function') {
|
87 | opts.onError(parsingError, ctx);
|
88 | } else {
|
89 | throw parsingError;
|
90 | }
|
91 | return next();
|
92 | })
|
93 | .then(function(body) {
|
94 | if (opts.patchNode) {
|
95 | if (isMultiPart(ctx, opts)) {
|
96 | ctx.req.body = body.fields;
|
97 | ctx.req.files = body.files;
|
98 | } else {
|
99 | ctx.req.body = body;
|
100 | }
|
101 | }
|
102 | if (opts.patchKoa) {
|
103 | if (isMultiPart(ctx, opts)) {
|
104 | ctx.request.body = body.fields;
|
105 | ctx.request.files = body.files;
|
106 | } else {
|
107 | ctx.request.body = body;
|
108 | }
|
109 | }
|
110 | return next();
|
111 | })
|
112 | };
|
113 | }
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 | function isMultiPart(ctx, opts) {
|
124 | return opts.multipart && ctx.is('multipart');
|
125 | }
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 |
|
132 |
|
133 |
|
134 |
|
135 | function formy(ctx, opts) {
|
136 | return new Promise(function (resolve, reject) {
|
137 | var fields = {};
|
138 | var files = {};
|
139 | var form = new forms.IncomingForm(opts);
|
140 | form.on('end', function () {
|
141 | return resolve({
|
142 | fields: fields,
|
143 | files: files
|
144 | });
|
145 | }).on('error', function (err) {
|
146 | return reject(err);
|
147 | }).on('field', function (field, value) {
|
148 | if (fields[field]) {
|
149 | if (Array.isArray(fields[field])) {
|
150 | fields[field].push(value);
|
151 | } else {
|
152 | fields[field] = [fields[field], value];
|
153 | }
|
154 | } else {
|
155 | fields[field] = value;
|
156 | }
|
157 | }).on('file', function (field, file) {
|
158 | if (files[field]) {
|
159 | if (Array.isArray(files[field])) {
|
160 | files[field].push(file);
|
161 | } else {
|
162 | files[field] = [files[field], file];
|
163 | }
|
164 | } else {
|
165 | files[field] = file;
|
166 | }
|
167 | });
|
168 | if (opts.onFileBegin) {
|
169 | form.on('fileBegin', opts.onFileBegin);
|
170 | }
|
171 | form.parse(ctx.req);
|
172 | });
|
173 | }
|