You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							144 lines
						
					
					
						
							3.1 KiB
						
					
					
				
			
		
		
	
	
							144 lines
						
					
					
						
							3.1 KiB
						
					
					
				'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, (new Array(100)).fill(1));
 | 
						|
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);
 | 
						|
}
 |