• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2const common = require('../common');
3const assert = require('assert');
4const async_hooks = require('async_hooks');
5const http = require('http');
6
7// Regression test for https://github.com/nodejs/node/issues/19859.
8// Checks that matching destroys are emitted when creating new/reusing old http
9// parser instances.
10
11const N = 50;
12const KEEP_ALIVE = 100;
13
14const createdIdsIncomingMessage = [];
15const createdIdsClientRequest = [];
16const destroyedIdsIncomingMessage = [];
17const destroyedIdsClientRequest = [];
18
19async_hooks.createHook({
20  init: (asyncId, type) => {
21    if (type === 'HTTPINCOMINGMESSAGE') {
22      createdIdsIncomingMessage.push(asyncId);
23    }
24    if (type === 'HTTPCLIENTREQUEST') {
25      createdIdsClientRequest.push(asyncId);
26    }
27  },
28  destroy: (asyncId) => {
29    if (createdIdsIncomingMessage.includes(asyncId)) {
30      destroyedIdsIncomingMessage.push(asyncId);
31    }
32    if (createdIdsClientRequest.includes(asyncId)) {
33      destroyedIdsClientRequest.push(asyncId);
34    }
35
36    if (destroyedIdsClientRequest.length === N && keepAliveAgent) {
37      keepAliveAgent.destroy();
38      keepAliveAgent = undefined;
39    }
40
41    if (destroyedIdsIncomingMessage.length === N && server.listening) {
42      server.close();
43    }
44  }
45}).enable();
46
47const server = http.createServer((req, res) => {
48  req.on('close', common.mustCall(() => {
49    req.on('readable', common.mustNotCall());
50  }));
51  res.end('Hello');
52});
53
54let keepAliveAgent = new http.Agent({
55  keepAlive: true,
56  keepAliveMsecs: KEEP_ALIVE,
57});
58
59server.listen(0, () => {
60  for (let i = 0; i < N; ++i) {
61    (function makeRequest() {
62      http.get({
63        port: server.address().port,
64        agent: keepAliveAgent
65      }, (res) => {
66        res.resume();
67      });
68    })();
69  }
70});
71
72function checkOnExit() {
73  assert.strictEqual(createdIdsIncomingMessage.length, N);
74  assert.strictEqual(createdIdsClientRequest.length, N);
75  assert.strictEqual(destroyedIdsIncomingMessage.length, N);
76  assert.strictEqual(destroyedIdsClientRequest.length, N);
77
78  assert.deepStrictEqual(destroyedIdsIncomingMessage.sort(),
79                         createdIdsIncomingMessage.sort());
80  assert.deepStrictEqual(destroyedIdsClientRequest.sort(),
81                         createdIdsClientRequest.sort());
82}
83
84process.on('SIGTERM', () => {
85  // Catching SIGTERM and calling `process.exit(1)`  so that the `exit` event
86  // is triggered and the assertions are checked. This can be useful for
87  // troubleshooting this test if it times out.
88  process.exit(1);
89});
90
91// Ordinary exit.
92process.on('exit', checkOnExit);
93