UNPKG

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