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.formLimit = 'formLimit' in opts ? opts.formLimit : '56kb';
|
44 | opts.queryString = 'queryString' in opts ? opts.queryString : null;
|
45 | opts.formidable = 'formidable' in opts ? opts.formidable : {};
|
46 | opts.textLimit = 'textLimit' in opts ? opts.textLimit : '56kb';
|
47 | opts.strict = 'strict' in opts ? opts.strict : true;
|
48 |
|
49 | return function (ctx, next) {
|
50 | var bodyPromise;
|
51 |
|
52 | if (!opts.strict || ["GET", "HEAD", "DELETE"].indexOf(ctx.method.toUpperCase()) === -1) {
|
53 | try {
|
54 | if (opts.json && ctx.is('json')) {
|
55 | bodyPromise = buddy.json(ctx, {
|
56 | encoding: opts.encoding,
|
57 | limit: opts.jsonLimit
|
58 | });
|
59 | } else if (opts.urlencoded && ctx.is('urlencoded')) {
|
60 | bodyPromise = buddy.form(ctx, {
|
61 | encoding: opts.encoding,
|
62 | limit: opts.formLimit,
|
63 | queryString: opts.queryString
|
64 | });
|
65 | } else if (opts.text && ctx.is('text')) {
|
66 | bodyPromise = buddy.text(ctx, {
|
67 | encoding: opts.encoding,
|
68 | limit: opts.textLimit
|
69 | });
|
70 | } else if (opts.multipart && ctx.is('multipart')) {
|
71 | bodyPromise = formy(ctx, opts.formidable);
|
72 | }
|
73 | } catch (parsingError) {
|
74 | if (typeof opts.onError === 'function') {
|
75 | opts.onError(parsingError, ctx);
|
76 | } else {
|
77 | throw parsingError;
|
78 | }
|
79 | }
|
80 | }
|
81 |
|
82 | bodyPromise = bodyPromise || Promise.resolve({});
|
83 | return bodyPromise.catch(function(parsingError) {
|
84 | if (typeof opts.onError === 'function') {
|
85 | opts.onError(parsingError, ctx);
|
86 | } else {
|
87 | throw parsingError;
|
88 | }
|
89 | return next();
|
90 | })
|
91 | .then(function(body) {
|
92 | if (opts.patchNode) {
|
93 | ctx.req.body = body;
|
94 | }
|
95 | if (opts.patchKoa) {
|
96 | ctx.request.body = body;
|
97 | }
|
98 | return next();
|
99 | })
|
100 | };
|
101 | }
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 |
|
111 | function formy(ctx, opts) {
|
112 | return new Promise(function (resolve, reject) {
|
113 | var fields = {};
|
114 | var files = {};
|
115 | var form = new forms.IncomingForm(opts);
|
116 | form.on('end', function () {
|
117 | return resolve({
|
118 | fields: fields,
|
119 | files: files
|
120 | });
|
121 | }).on('error', function (err) {
|
122 | return reject(err);
|
123 | }).on('field', function (field, value) {
|
124 | if (fields[field]) {
|
125 | if (Array.isArray(fields[field])) {
|
126 | fields[field].push(value);
|
127 | } else {
|
128 | fields[field] = [fields[field], value];
|
129 | }
|
130 | } else {
|
131 | fields[field] = value;
|
132 | }
|
133 | }).on('file', function (field, file) {
|
134 | if (files[field]) {
|
135 | if (Array.isArray(files[field])) {
|
136 | files[field].push(file);
|
137 | } else {
|
138 | files[field] = [files[field], file];
|
139 | }
|
140 | } else {
|
141 | files[field] = file;
|
142 | }
|
143 | });
|
144 | if (opts.onFileBegin) {
|
145 | form.on('fileBegin', opts.onFileBegin);
|
146 | }
|
147 | form.parse(ctx.req);
|
148 | });
|
149 | }
|