summaryrefslogtreecommitdiff
path: root/test/sequential/test-http-regr-gh-2928.js
blob: 3794eddaa093695ef2e72b3270c08b74613bf802 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// This test is designed to fail with a segmentation fault in Node.js 4.1.0 and
// execute without issues in Node.js 4.1.1 and up.

// Flags: --expose-internals
'use strict';
const common = require('../common');
const assert = require('assert');
const httpCommon = require('_http_common');
const { internalBinding } = require('internal/test/binding');
const is_reused_symbol = require('internal/freelist').symbols.is_reused_symbol;
const { HTTPParser } = internalBinding('http_parser');
const net = require('net');

const COUNT = httpCommon.parsers.max + 1;

const parsers = new Array(COUNT);
for (let i = 0; i < parsers.length; i++)
  parsers[i] = httpCommon.parsers.alloc();

let gotRequests = 0;
let gotResponses = 0;

function execAndClose() {
  if (parsers.length === 0)
    return;
  process.stdout.write('.');

  const parser = parsers.pop();
  parser.reinitialize(HTTPParser.RESPONSE, parser[is_reused_symbol]);

  const socket = net.connect(common.PORT);
  socket.on('error', (e) => {
    // If SmartOS and ECONNREFUSED, then retry. See
    // https://github.com/nodejs/node/issues/2663.
    if (common.isSunOS && e.code === 'ECONNREFUSED') {
      parsers.push(parser);
      socket.destroy();
      setImmediate(execAndClose);
      return;
    }
    throw e;
  });

  parser.consume(socket._handle._externalStream);

  parser.onIncoming = function onIncoming() {
    process.stdout.write('+');
    gotResponses++;
    parser.unconsume(socket._handle._externalStream);
    httpCommon.freeParser(parser);
    socket.destroy();
    setImmediate(execAndClose);
  };
}

const server = net.createServer(function(c) {
  if (++gotRequests === COUNT)
    server.close();
  c.end('HTTP/1.1 200 OK\r\n\r\n', function() {
    c.destroySoon();
  });
}).listen(common.PORT, execAndClose);

process.on('exit', function() {
  assert.strictEqual(gotResponses, COUNT);
});