mirror of
https://github.com/nodejs/node.git
synced 2025-05-03 11:41:22 +00:00

This fixes a potential segfault, among various other likely-related issues, which all occur because TLSSockets were not informed if their underlying stream was closed in many cases. This also significantly modifies an existing TLS test. With this change in place, that test no longer works, as it tries to mess with internals to trigger a race, and those internals are now cleaned up earlier. This test has been simplified to a more general TLS shutdown test. PR-URL: https://github.com/nodejs/node/pull/49327 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Debadree Chatterjee <debadree333@gmail.com>
68 lines
1.8 KiB
JavaScript
68 lines
1.8 KiB
JavaScript
'use strict';
|
|
|
|
const common = require('../common');
|
|
const fixtures = require('../common/fixtures');
|
|
if (!common.hasCrypto)
|
|
common.skip('missing crypto');
|
|
const assert = require('assert');
|
|
const net = require('net');
|
|
const h2 = require('http2');
|
|
|
|
const tlsOptions = {
|
|
key: fixtures.readKey('agent1-key.pem'),
|
|
cert: fixtures.readKey('agent1-cert.pem'),
|
|
ALPNProtocols: ['h2']
|
|
};
|
|
|
|
// Create a net server that upgrades sockets to HTTP/2 manually, handles the
|
|
// request, and then shuts down via a short socket timeout and a longer H2 session
|
|
// timeout. This is an unconventional way to shut down a session (the underlying
|
|
// socket closing first) but it should work - critically, it shouldn't segfault
|
|
// (as it did until Node v20.5.1).
|
|
|
|
let serverRawSocket;
|
|
let serverH2Session;
|
|
|
|
const netServer = net.createServer((socket) => {
|
|
serverRawSocket = socket;
|
|
h2Server.emit('connection', socket);
|
|
});
|
|
|
|
const h2Server = h2.createSecureServer(tlsOptions, (req, res) => {
|
|
res.writeHead(200);
|
|
res.end();
|
|
});
|
|
|
|
h2Server.on('session', (session) => {
|
|
serverH2Session = session;
|
|
});
|
|
|
|
netServer.listen(0, common.mustCall(() => {
|
|
const proxyClient = h2.connect(`https://localhost:${netServer.address().port}`, {
|
|
rejectUnauthorized: false
|
|
});
|
|
|
|
proxyClient.on('close', common.mustCall(() => {
|
|
netServer.close();
|
|
}));
|
|
|
|
const req = proxyClient.request({
|
|
':method': 'GET',
|
|
':path': '/'
|
|
});
|
|
|
|
req.on('response', common.mustCall((response) => {
|
|
assert.strictEqual(response[':status'], 200);
|
|
|
|
// Asynchronously shut down the server's connections after the response,
|
|
// but not in the order it typically expects:
|
|
setTimeout(() => {
|
|
serverRawSocket.destroy();
|
|
|
|
setTimeout(() => {
|
|
serverH2Session.close();
|
|
}, 10);
|
|
}, 10);
|
|
}));
|
|
}));
|