• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2const common = require('../common');
3if (!common.hasCrypto)
4  common.skip('missing crypto');
5const fixtures = require('../common/fixtures');
6const http2 = require('http2');
7
8// Regression test for https://github.com/nodejs/node/issues/29223.
9// There was a "leak" in the accounting of session memory leading
10// to streams eventually failing with NGHTTP2_ENHANCE_YOUR_CALM.
11
12const server = http2.createSecureServer({
13  key: fixtures.readKey('agent2-key.pem'),
14  cert: fixtures.readKey('agent2-cert.pem'),
15});
16
17// Simple server that sends 200k and closes the stream.
18const data200k = 'a'.repeat(200 * 1024);
19server.on('stream', (stream) => {
20  stream.write(data200k);
21  stream.end();
22});
23
24server.listen(0, common.mustCall(() => {
25  const client = http2.connect(`https://localhost:${server.address().port}`, {
26    ca: fixtures.readKey('agent2-cert.pem'),
27    servername: 'agent2',
28
29    // Set maxSessionMemory to 1MB so the leak causes errors faster.
30    maxSessionMemory: 1
31  });
32
33  // Repeatedly create a new stream and read the incoming data. Even though we
34  // only have one stream active at a time, prior to the fix for #29223,
35  // session memory would steadily increase and we'd eventually hit the 1MB
36  // maxSessionMemory limit and get NGHTTP2_ENHANCE_YOUR_CALM errors trying to
37  // create new streams.
38  let streamsLeft = 50;
39  function newStream() {
40    const stream = client.request({ ':path': '/' });
41
42    stream.on('data', () => { });
43
44    stream.on('close', () => {
45      if (streamsLeft-- > 0) {
46        newStream();
47      } else {
48        client.destroy();
49        server.close();
50      }
51    });
52  }
53
54  newStream();
55}));
56