Skip to content

Commit 28ecf93

Browse files
mafintoshmcollina
authored andcommitted
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: #19852 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Trivikram Kamat <[email protected]> Co-authored-by: Matteo Collina <[email protected]>
1 parent 9422909 commit 28ecf93

7 files changed

+79
-8
lines changed

lib/internal/http2/core.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1175,7 +1175,7 @@ class Http2Session extends EventEmitter {
11751175
// Otherwise, destroy immediately.
11761176
if (!socket.destroyed) {
11771177
if (!error) {
1178-
setImmediate(socket.end.bind(socket));
1178+
setImmediate(socket.destroy.bind(socket));
11791179
} else {
11801180
socket.destroy(error);
11811181
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
if (!common.hasCrypto)
5+
common.skip('missing crypto');
6+
const http2 = require('http2');
7+
8+
{
9+
const server = http2.createServer((req, res) => {
10+
req.pipe(res);
11+
});
12+
13+
server.listen(0, () => {
14+
const url = `http://localhost:${server.address().port}`;
15+
const client = http2.connect(url);
16+
const req = client.request({ ':method': 'POST' });
17+
18+
for (let i = 0; i < 4000; i++) {
19+
req.write(Buffer.alloc(6));
20+
}
21+
22+
req.on('close', common.mustCall(() => {
23+
console.log('(req onclose)');
24+
server.close();
25+
client.close();
26+
}));
27+
28+
req.once('data', common.mustCall(() => req.destroy()));
29+
});
30+
}

test/parallel/test-http2-pipe.js

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ server.listen(0, common.mustCall(() => {
3333
const client = http2.connect(`http://localhost:${server.address().port}`);
3434

3535
const req = client.request({ ':method': 'POST' });
36+
3637
req.on('response', common.mustCall());
3738
req.resume();
3839

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
if (!common.hasCrypto)
5+
common.skip('missing crypto');
6+
7+
const http2 = require('http2');
8+
9+
const server = http2.createServer();
10+
11+
server.listen(0, common.mustCall(() => {
12+
const client = http2.connect(`http://localhost:${server.address().port}`);
13+
client.on('error', (err) => {
14+
if (err.code !== 'ECONNRESET')
15+
throw err;
16+
});
17+
}));
18+
19+
server.on('session', common.mustCall((s) => {
20+
setImmediate(() => {
21+
server.close(common.mustCall());
22+
s.destroy();
23+
});
24+
}));

test/parallel/test-http2-server-stream-session-destroy.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,16 @@ server.on('stream', common.mustCall((stream) => {
4444

4545
server.listen(0, common.mustCall(() => {
4646
const client = h2.connect(`http://localhost:${server.address().port}`);
47-
client.on('error', () => {});
47+
client.on('error', (err) => {
48+
if (err.code !== 'ECONNRESET')
49+
throw err;
50+
});
4851
const req = client.request();
4952
req.resume();
5053
req.on('end', common.mustCall());
51-
req.on('close', common.mustCall(() => server.close()));
52-
req.on('error', () => {});
54+
req.on('close', common.mustCall(() => server.close(common.mustCall())));
55+
req.on('error', (err) => {
56+
if (err.code !== 'ECONNRESET')
57+
throw err;
58+
});
5359
}));

test/parallel/test-http2-session-unref.js

+10-4
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,23 @@ server.listen(0, common.mustCall(() => {
3434
// unref destroyed client
3535
{
3636
const client = http2.connect(`http://localhost:${port}`);
37-
client.destroy();
38-
client.unref();
37+
38+
client.on('connect', common.mustCall(() => {
39+
client.destroy();
40+
client.unref();
41+
}));
3942
}
4043

4144
// unref destroyed client
4245
{
4346
const client = http2.connect(`http://localhost:${port}`, {
4447
createConnection: common.mustCall(() => clientSide)
4548
});
46-
client.destroy();
47-
client.unref();
49+
50+
client.on('connect', common.mustCall(() => {
51+
client.destroy();
52+
client.unref();
53+
}));
4854
}
4955
}));
5056
server.emit('connection', serverSide);

test/sequential/test-http2-max-session-memory.js

+4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ const largeBuffer = Buffer.alloc(1e6);
1313
const server = http2.createServer({ maxSessionMemory: 1 });
1414

1515
server.on('stream', common.mustCall((stream) => {
16+
stream.on('error', (err) => {
17+
if (err.code !== 'ECONNRESET')
18+
throw err;
19+
});
1620
stream.respond();
1721
stream.end(largeBuffer);
1822
}));

0 commit comments

Comments
 (0)