UNPKG

4.07 kBJavaScriptView Raw
1/**
2 * koa-body - index.js
3 * Copyright(c) 2014
4 * MIT Licensed
5 *
6 * @author Daryl Lau (@dlau)
7 * @author Charlike Mike Reagent (@tunnckoCore)
8 * @api private
9 */
10
11'use strict';
12
13/**
14 * Module dependencies.
15 */
16
17var buddy = require('co-body');
18var forms = require('formidable');
19
20/**
21 * Expose `requestbody()`.
22 */
23
24module.exports = requestbody;
25
26/**
27 *
28 * @param {Object} options
29 * @see https://github.com/dlau/koa-body
30 * @api public
31 */
32function 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 // so don't parse the body in strict mode
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 * Donable formidable
105 *
106 * @param {Stream} ctx
107 * @param {Object} opts
108 * @return {Object}
109 * @api private
110 */
111function 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}