UNPKG

3.17 kBJavaScriptView Raw
1'use strict';
2
3function createMultipartBuffers(boundary, sizes) {
4 const bufs = [];
5 for (let i = 0; i < sizes.length; ++i) {
6 const mb = sizes[i] * 1024 * 1024;
7 bufs.push(Buffer.from([
8 `--${boundary}`,
9 `content-disposition: form-data; name="field${i + 1}"`,
10 '',
11 '0'.repeat(mb),
12 '',
13 ].join('\r\n')));
14 }
15 bufs.push(Buffer.from([
16 `--${boundary}--`,
17 '',
18 ].join('\r\n')));
19 return bufs;
20}
21
22const boundary = '-----------------------------168072824752491622650073';
23const buffers = createMultipartBuffers(boundary, (new Array(100)).fill(1));
24const calls = {
25 partBegin: 0,
26 headerField: 0,
27 headerValue: 0,
28 headerEnd: 0,
29 headersEnd: 0,
30 partData: 0,
31 partEnd: 0,
32 end: 0,
33};
34
35const moduleName = process.argv[2];
36switch (moduleName) {
37 case 'busboy': {
38 const busboy = require('busboy');
39
40 const parser = busboy({
41 limits: {
42 fieldSizeLimit: Infinity,
43 },
44 headers: {
45 'content-type': `multipart/form-data; boundary=${boundary}`,
46 },
47 });
48 parser.on('field', (name, val, info) => {
49 ++calls.partBegin;
50 ++calls.partData;
51 ++calls.partEnd;
52 }).on('close', () => {
53 ++calls.end;
54 console.timeEnd(moduleName);
55 });
56
57 console.time(moduleName);
58 for (const buf of buffers)
59 parser.write(buf);
60 break;
61 }
62
63 case 'formidable': {
64 const { MultipartParser } = require('formidable');
65
66 const parser = new MultipartParser();
67 parser.initWithBoundary(boundary);
68 parser.on('data', ({ name }) => {
69 ++calls[name];
70 if (name === 'end')
71 console.timeEnd(moduleName);
72 });
73
74 console.time(moduleName);
75 for (const buf of buffers)
76 parser.write(buf);
77
78 break;
79 }
80
81 case 'multiparty': {
82 const { Readable } = require('stream');
83
84 const { Form } = require('multiparty');
85
86 const form = new Form({
87 maxFieldsSize: Infinity,
88 maxFields: Infinity,
89 maxFilesSize: Infinity,
90 autoFields: false,
91 autoFiles: false,
92 });
93
94 const req = new Readable({ read: () => {} });
95 req.headers = {
96 'content-type': `multipart/form-data; boundary=${boundary}`,
97 };
98
99 function hijack(name, fn) {
100 const oldFn = form[name];
101 form[name] = function() {
102 fn();
103 return oldFn.apply(this, arguments);
104 };
105 }
106
107 hijack('onParseHeaderField', () => {
108 ++calls.headerField;
109 });
110 hijack('onParseHeaderValue', () => {
111 ++calls.headerValue;
112 });
113 hijack('onParsePartBegin', () => {
114 ++calls.partBegin;
115 });
116 hijack('onParsePartData', () => {
117 ++calls.partData;
118 });
119 hijack('onParsePartEnd', () => {
120 ++calls.partEnd;
121 });
122
123 form.on('close', () => {
124 ++calls.end;
125 console.timeEnd(moduleName);
126 }).on('part', (p) => p.resume());
127
128 console.time(moduleName);
129 form.parse(req);
130 for (const buf of buffers)
131 req.push(buf);
132 req.push(null);
133
134 break;
135 }
136
137 default:
138 if (moduleName === undefined)
139 console.error('Missing parser module name');
140 else
141 console.error(`Invalid parser module name: ${moduleName}`);
142 process.exit(1);
143}