Skip to content

Commit 9f79341

Browse files
mcollinaBethGriggs
authored andcommitted
http2: check if stream is not destroyed before sending trailers
Fixes: #22855 Backport-PR-URL: #22850 PR-URL: #22896 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 2de17ea commit 9f79341

2 files changed

Lines changed: 50 additions & 0 deletions

File tree

‎lib/internal/http2/core.js‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1475,6 +1475,14 @@ function afterShutdown() {
14751475
}
14761476

14771477
functionfinishSendTrailers(stream,headersList){
1478+
// The stream might be destroyed and in that case
1479+
// there is nothing to do.
1480+
// This can happen because finishSendTrailers is
1481+
// scheduled via setImmediate.
1482+
if(stream.destroyed){
1483+
return;
1484+
}
1485+
14781486
stream[kState].flags&=~STREAM_FLAGS_HAS_TRAILERS;
14791487

14801488
constret=stream[kHandle].trailers(headersList);
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
'use strict';
2+
3+
constcommon=require('../common');
4+
const{ mustCall }=common;
5+
6+
if(!common.hasCrypto)
7+
common.skip('missing crypto');
8+
9+
consthttp2=require('http2');
10+
constassert=require('assert');
11+
12+
const{
13+
HTTP2_HEADER_PATH,
14+
HTTP2_HEADER_METHOD,
15+
}=http2.constants;
16+
17+
// This tests verifies that calling `req.socket.destroy()` via
18+
// setImmediate does not crash.
19+
// Fixes https://github.com/nodejs/node/issues/22855.
20+
21+
constapp=http2.createServer(mustCall((req,res)=>{
22+
res.end('hello');
23+
setImmediate(()=>req.socket.destroy());
24+
}));
25+
26+
app.listen(0,mustCall(()=>{
27+
constsession=http2.connect(`http://localhost:${app.address().port}`);
28+
constrequest=session.request({
29+
[HTTP2_HEADER_PATH]: '/',
30+
[HTTP2_HEADER_METHOD]: 'get'
31+
});
32+
request.once('response',mustCall((headers,flags)=>{
33+
letdata='';
34+
request.on('data',(chunk)=>{data+=chunk;});
35+
request.on('end',mustCall(()=>{
36+
assert.strictEqual(data,'hello');
37+
session.close();
38+
app.close();
39+
}));
40+
}));
41+
request.end();
42+
}));

0 commit comments

Comments
 (0)