150 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			150 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| function createMultipartBuffers(boundary, sizes) {
 | |
|   const bufs = [];
 | |
|   for (let i = 0; i < sizes.length; ++i) {
 | |
|     const mb = sizes[i] * 1024 * 1024;
 | |
|     bufs.push(Buffer.from([
 | |
|       `--${boundary}`,
 | |
|       `content-disposition: form-data; name="field${i + 1}"`,
 | |
|       '',
 | |
|       '0'.repeat(mb),
 | |
|       '',
 | |
|     ].join('\r\n')));
 | |
|   }
 | |
|   bufs.push(Buffer.from([
 | |
|     `--${boundary}--`,
 | |
|     '',
 | |
|   ].join('\r\n')));
 | |
|   return bufs;
 | |
| }
 | |
| 
 | |
| const boundary = '-----------------------------168072824752491622650073';
 | |
| const buffers = createMultipartBuffers(boundary, [
 | |
|   10,
 | |
|   10,
 | |
|   10,
 | |
|   20,
 | |
|   50,
 | |
| ]);
 | |
| const calls = {
 | |
|   partBegin: 0,
 | |
|   headerField: 0,
 | |
|   headerValue: 0,
 | |
|   headerEnd: 0,
 | |
|   headersEnd: 0,
 | |
|   partData: 0,
 | |
|   partEnd: 0,
 | |
|   end: 0,
 | |
| };
 | |
| 
 | |
| const moduleName = process.argv[2];
 | |
| switch (moduleName) {
 | |
|   case 'busboy': {
 | |
|     const busboy = require('busboy');
 | |
| 
 | |
|     const parser = busboy({
 | |
|       limits: {
 | |
|         fieldSizeLimit: Infinity,
 | |
|       },
 | |
|       headers: {
 | |
|         'content-type': `multipart/form-data; boundary=${boundary}`,
 | |
|       },
 | |
|     });
 | |
|     parser.on('field', (name, val, info) => {
 | |
|       ++calls.partBegin;
 | |
|       ++calls.partData;
 | |
|       ++calls.partEnd;
 | |
|     }).on('close', () => {
 | |
|       ++calls.end;
 | |
|       console.timeEnd(moduleName);
 | |
|     });
 | |
| 
 | |
|     console.time(moduleName);
 | |
|     for (const buf of buffers)
 | |
|       parser.write(buf);
 | |
|     break;
 | |
|   }
 | |
| 
 | |
|   case 'formidable': {
 | |
|     const { MultipartParser } = require('formidable');
 | |
| 
 | |
|     const parser = new MultipartParser();
 | |
|     parser.initWithBoundary(boundary);
 | |
|     parser.on('data', ({ name }) => {
 | |
|       ++calls[name];
 | |
|       if (name === 'end')
 | |
|         console.timeEnd(moduleName);
 | |
|     });
 | |
| 
 | |
|     console.time(moduleName);
 | |
|     for (const buf of buffers)
 | |
|       parser.write(buf);
 | |
| 
 | |
|     break;
 | |
|   }
 | |
| 
 | |
|   case 'multiparty': {
 | |
|     const { Readable } = require('stream');
 | |
| 
 | |
|     const { Form } = require('multiparty');
 | |
| 
 | |
|     const form = new Form({
 | |
|       maxFieldsSize: Infinity,
 | |
|       maxFields: Infinity,
 | |
|       maxFilesSize: Infinity,
 | |
|       autoFields: false,
 | |
|       autoFiles: false,
 | |
|     });
 | |
| 
 | |
|     const req = new Readable({ read: () => {} });
 | |
|     req.headers = {
 | |
|       'content-type': `multipart/form-data; boundary=${boundary}`,
 | |
|     };
 | |
| 
 | |
|     function hijack(name, fn) {
 | |
|       const oldFn = form[name];
 | |
|       form[name] = function() {
 | |
|         fn();
 | |
|         return oldFn.apply(this, arguments);
 | |
|       };
 | |
|     }
 | |
| 
 | |
|     hijack('onParseHeaderField', () => {
 | |
|       ++calls.headerField;
 | |
|     });
 | |
|     hijack('onParseHeaderValue', () => {
 | |
|       ++calls.headerValue;
 | |
|     });
 | |
|     hijack('onParsePartBegin', () => {
 | |
|       ++calls.partBegin;
 | |
|     });
 | |
|     hijack('onParsePartData', () => {
 | |
|       ++calls.partData;
 | |
|     });
 | |
|     hijack('onParsePartEnd', () => {
 | |
|       ++calls.partEnd;
 | |
|     });
 | |
| 
 | |
|     form.on('close', () => {
 | |
|       ++calls.end;
 | |
|       console.timeEnd(moduleName);
 | |
|     }).on('part', (p) => p.resume());
 | |
| 
 | |
|     console.time(moduleName);
 | |
|     form.parse(req);
 | |
|     for (const buf of buffers)
 | |
|       req.push(buf);
 | |
|     req.push(null);
 | |
| 
 | |
|     break;
 | |
|   }
 | |
| 
 | |
|   default:
 | |
|     if (moduleName === undefined)
 | |
|       console.error('Missing parser module name');
 | |
|     else
 | |
|       console.error(`Invalid parser module name: ${moduleName}`);
 | |
|     process.exit(1);
 | |
| }
 |