http2: destroy the socket properly and add tests

Fix a bug where the socket wasn't being correctly destroyed and
adjust existing tests, as well as add additional tests.

PR-URL: https://github.com/nodejs/node/pull/19852
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>

Co-authored-by: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
Mathias Buus 2018-04-06 17:50:58 +02:00 committed by Anatoli Papirovski
parent a9b399f581
commit b60b18379d
No known key found for this signature in database
GPG Key ID: 614E2E1ABEB4B2C0
7 changed files with 79 additions and 8 deletions

View File

@ -1175,7 +1175,7 @@ class Http2Session extends EventEmitter {
// Otherwise, destroy immediately.
if (!socket.destroyed) {
if (!error) {
setImmediate(socket.end.bind(socket));
setImmediate(socket.destroy.bind(socket));
} else {
socket.destroy(error);
}

View File

@ -0,0 +1,30 @@
'use strict';
const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
const http2 = require('http2');
{
const server = http2.createServer((req, res) => {
req.pipe(res);
});
server.listen(0, () => {
const url = `http://localhost:${server.address().port}`;
const client = http2.connect(url);
const req = client.request({ ':method': 'POST' });
for (let i = 0; i < 4000; i++) {
req.write(Buffer.alloc(6));
}
req.on('close', common.mustCall(() => {
console.log('(req onclose)');
server.close();
client.close();
}));
req.once('data', common.mustCall(() => req.destroy()));
});
}

View File

@ -33,6 +33,7 @@ server.listen(0, common.mustCall(() => {
const client = http2.connect(`http://localhost:${server.address().port}`);
const req = client.request({ ':method': 'POST' });
req.on('response', common.mustCall());
req.resume();

View File

@ -0,0 +1,24 @@
'use strict';
const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
const http2 = require('http2');
const server = http2.createServer();
server.listen(0, common.mustCall(() => {
const client = http2.connect(`http://localhost:${server.address().port}`);
client.on('error', (err) => {
if (err.code !== 'ECONNRESET')
throw err;
});
}));
server.on('session', common.mustCall((s) => {
setImmediate(() => {
server.close(common.mustCall());
s.destroy();
});
}));

View File

@ -44,10 +44,16 @@ server.on('stream', common.mustCall((stream) => {
server.listen(0, common.mustCall(() => {
const client = h2.connect(`http://localhost:${server.address().port}`);
client.on('error', () => {});
client.on('error', (err) => {
if (err.code !== 'ECONNRESET')
throw err;
});
const req = client.request();
req.resume();
req.on('end', common.mustCall());
req.on('close', common.mustCall(() => server.close()));
req.on('error', () => {});
req.on('close', common.mustCall(() => server.close(common.mustCall())));
req.on('error', (err) => {
if (err.code !== 'ECONNRESET')
throw err;
});
}));

View File

@ -34,8 +34,11 @@ server.listen(0, common.mustCall(() => {
// unref destroyed client
{
const client = http2.connect(`http://localhost:${port}`);
client.destroy();
client.unref();
client.on('connect', common.mustCall(() => {
client.destroy();
client.unref();
}));
}
// unref destroyed client
@ -43,8 +46,11 @@ server.listen(0, common.mustCall(() => {
const client = http2.connect(`http://localhost:${port}`, {
createConnection: common.mustCall(() => clientSide)
});
client.destroy();
client.unref();
client.on('connect', common.mustCall(() => {
client.destroy();
client.unref();
}));
}
}));
server.emit('connection', serverSide);

View File

@ -13,6 +13,10 @@ const largeBuffer = Buffer.alloc(1e6);
const server = http2.createServer({ maxSessionMemory: 1 });
server.on('stream', common.mustCall((stream) => {
stream.on('error', (err) => {
if (err.code !== 'ECONNRESET')
throw err;
});
stream.respond();
stream.end(largeBuffer);
}));