• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const common = require('../common');
4if (!common.hasCrypto) common.skip('missing crypto');
5
6const fixtures = require('../common/fixtures');
7const makeDuplexPair = require('../common/duplexpair');
8const net = require('net');
9const assert = require('assert');
10const tls = require('tls');
11
12tls.DEFAULT_MAX_VERSION = 'TLSv1.3';
13
14// This test ensures that an instance of StreamWrap should emit "end" and
15// "close" when the socket on the other side call `destroy()` instead of
16// `end()`.
17// Refs: https://github.com/nodejs/node/issues/14605
18const CONTENT = 'Hello World';
19const tlsServer = tls.createServer(
20  {
21    key: fixtures.readKey('rsa_private.pem'),
22    cert: fixtures.readKey('rsa_cert.crt'),
23    ca: [fixtures.readKey('rsa_ca.crt')],
24  },
25  (socket) => {
26    socket.on('close', common.mustCall());
27    socket.write(CONTENT);
28    socket.destroy();
29
30    socket.on('error', (err) => {
31      // destroy() is sync, write() is async, whether write completes depends
32      // on the protocol, it is not guaranteed by stream API.
33      if (err.code === 'ERR_STREAM_DESTROYED')
34        return;
35      assert.ifError(err);
36    });
37  },
38);
39
40const server = net.createServer((conn) => {
41  conn.on('error', common.mustNotCall());
42  // Assume that we want to use data to determine what to do with connections.
43  conn.once('data', common.mustCall((chunk) => {
44    const { clientSide, serverSide } = makeDuplexPair();
45    serverSide.on('close', common.mustCall(() => {
46      conn.destroy();
47    }));
48    clientSide.pipe(conn);
49    conn.pipe(clientSide);
50
51    conn.on('close', common.mustCall(() => {
52      clientSide.destroy();
53    }));
54    clientSide.on('close', common.mustCall(() => {
55      conn.destroy();
56    }));
57
58    process.nextTick(() => {
59      conn.unshift(chunk);
60    });
61
62    tlsServer.emit('connection', serverSide);
63  }));
64});
65
66server.listen(0, () => {
67  const port = server.address().port;
68  const conn = tls.connect({ port, rejectUnauthorized: false }, () => {
69    // Whether the server's write() completed before its destroy() is
70    // indeterminate, but if data was written, we should receive it correctly.
71    conn.on('data', (data) => {
72      assert.strictEqual(data.toString('utf8'), CONTENT);
73    });
74    conn.on('error', common.mustNotCall());
75    conn.on('close', common.mustCall(() => server.close()));
76  });
77});
78