1'use strict'; 2 3// test HTTP throughput in fragmented header case 4const common = require('../common.js'); 5const net = require('net'); 6 7const bench = common.createBenchmark(main, { 8 len: [1, 4, 8, 16, 32, 64, 128], 9 n: [5, 50, 500, 2000], 10 type: ['send'], 11}); 12 13 14function main({ len, n }) { 15 let todo = []; 16 const headers = []; 17 // Chose 7 because 9 showed "Connection error" / "Connection closed" 18 // An odd number could result in a better length dispersion. 19 for (let i = 7; i <= 7 * 7 * 7; i *= 7) 20 headers.push('o'.repeat(i)); 21 22 function WriteHTTPHeaders(channel, has_keep_alive, extra_header_count) { 23 todo = []; 24 todo.push('GET / HTTP/1.1'); 25 todo.push('Host: localhost'); 26 todo.push('Connection: keep-alive'); 27 todo.push('Accept: text/html,application/xhtml+xml,' + 28 'application/xml;q=0.9,image/webp,*/*;q=0.8'); 29 todo.push('User-Agent: Mozilla/5.0 (X11; Linux x86_64) ' + 30 'AppleWebKit/537.36 (KHTML, like Gecko) ' + 31 'Chrome/39.0.2171.71 Safari/537.36'); 32 todo.push('Accept-Encoding: gzip, deflate, sdch'); 33 todo.push('Accept-Language: en-US,en;q=0.8'); 34 for (let i = 0; i < extra_header_count; i++) { 35 // Utilize first three powers of a small integer for an odd cycle and 36 // because the fourth power of some integers overloads the server. 37 todo.push(`X-Header-${i}: ${headers[i % 3]}`); 38 } 39 todo.push(''); 40 todo.push(''); 41 todo = todo.join('\r\n'); 42 // Using odd numbers in many places may increase length coverage. 43 const chunksize = 37; 44 for (let i = 0; i < todo.length; i += chunksize) { 45 const cur = todo.slice(i, i + chunksize); 46 channel.write(cur); 47 } 48 } 49 50 const min = 10; 51 let size = 0; 52 const mod = 317; 53 const mult = 17; 54 const add = 11; 55 let count = 0; 56 const PIPE = process.env.PIPE_NAME; 57 const socket = net.connect(PIPE, () => { 58 bench.start(); 59 WriteHTTPHeaders(socket, 1, len); 60 socket.setEncoding('utf8'); 61 socket.on('data', (d) => { 62 let did = false; 63 let pattern = 'HTTP/1.1 200 OK\r\n'; 64 if ((d.length === pattern.length && d === pattern) || 65 (d.length > pattern.length && 66 d.slice(0, pattern.length) === pattern)) { 67 did = true; 68 } else { 69 pattern = 'HTTP/1.1 '; 70 if ((d.length === pattern.length && d === pattern) || 71 (d.length > pattern.length && 72 d.slice(0, pattern.length) === pattern)) { 73 did = true; 74 } 75 } 76 size = (size * mult + add) % mod; 77 if (did) { 78 count += 1; 79 if (count === n) { 80 bench.end(count); 81 process.exit(0); 82 } else { 83 WriteHTTPHeaders(socket, 1, min + size); 84 } 85 } 86 }); 87 socket.on('close', () => { 88 console.log('Connection closed'); 89 }); 90 91 socket.on('error', () => { 92 throw new Error('Connection error'); 93 }); 94 }); 95} 96