• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Flags: --expose-gc
2'use strict';
3const common = require('../common');
4if (!common.hasCrypto)
5  common.skip('missing crypto');
6const assert = require('assert');
7const http2 = require('http2');
8const makeDuplexPair = require('../common/duplexpair');
9
10// Make sure the Http2Stream destructor works, since we don't clean the
11// stream up like we would otherwise do.
12process.on('exit', global.gc);
13
14{
15  const { clientSide, serverSide } = makeDuplexPair();
16
17  let serverSideHttp2Stream;
18  let serverSideHttp2StreamDestroyed = false;
19  const server = http2.createServer();
20  server.on('stream', common.mustCall((stream, headers) => {
21    serverSideHttp2Stream = stream;
22    stream.respond({
23      'content-type': 'text/html',
24      ':status': 200
25    });
26
27    const originalWrite = serverSide._write;
28    serverSide._write = (buf, enc, cb) => {
29      if (serverSideHttp2StreamDestroyed) {
30        serverSide.destroy();
31        serverSide.write = () => {};
32      } else {
33        setImmediate(() => {
34          originalWrite.call(serverSide, buf, enc, () => setImmediate(cb));
35        });
36      }
37    };
38
39    // Enough data to fit into a single *session* window,
40    // not enough data to fit into a single *stream* window.
41    stream.write(Buffer.alloc(40000));
42  }));
43
44  server.emit('connection', serverSide);
45
46  const client = http2.connect('http://localhost:80', {
47    createConnection: common.mustCall(() => clientSide)
48  });
49
50  const req = client.request({ ':path': '/' });
51
52  req.on('response', common.mustCall((headers) => {
53    assert.strictEqual(headers[':status'], 200);
54  }));
55
56  req.on('data', common.mustCallAtLeast(() => {
57    if (!serverSideHttp2StreamDestroyed) {
58      serverSideHttp2Stream.destroy();
59      serverSideHttp2StreamDestroyed = true;
60    }
61  }));
62}
63