Skip to content

Commit 0234a8e

Browse files
RaisinTentargos
authored andcommitted
http2: add diagnostics channel 'http2.server.stream.finish'
Signed-off-by: Darshan Sen <raisinten@gmail.com> PR-URL: #58560 Reviewed-By: Stephen Belanger <admin@stephenbelanger.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
1 parent 29f34a7 commit 0234a8e

3 files changed

Lines changed: 80 additions & 1 deletion

File tree

‎doc/api/diagnostics_channel.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,6 +1260,14 @@ Emitted when a stream is started on the server.
12601260

12611261
Emitted when an error occurs during the processing of a stream on the server.
12621262

1263+
`http2.server.stream.finish`
1264+
1265+
*`stream` {ServerHttp2Stream}
1266+
*`headers` {HTTP/2 Headers Object}
1267+
*`flags` {number}
1268+
1269+
Emitted when a stream is sent on the server.
1270+
12631271
#### Modules
12641272

12651273
> Stability: 1 - Experimental

‎lib/internal/http2/core.js‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ const onClientStreamCloseChannel = dc.channel('http2.client.stream.close');
193193
constonServerStreamCreatedChannel=dc.channel('http2.server.stream.created');
194194
constonServerStreamStartChannel=dc.channel('http2.server.stream.start');
195195
constonServerStreamErrorChannel=dc.channel('http2.server.stream.error');
196+
constonServerStreamFinishChannel=dc.channel('http2.server.stream.finish');
196197

197198
letdebug=require('internal/util/debuglog').debuglog('http2',(fn)=>{
198199
debug=fn;
@@ -2917,8 +2918,17 @@ class ServerHttp2Stream extends Http2Stream {
29172918
}
29182919

29192920
constret=this[kHandle].respond(headersList,streamOptions);
2920-
if(ret<0)
2921+
if(ret<0){
29212922
this.destroy(newNghttpError(ret));
2923+
}elseif(onServerStreamFinishChannel.hasSubscribers){
2924+
// No point in running this if the respond() call above fails because
2925+
// that would mean that it is an invalid call.
2926+
onServerStreamFinishChannel.publish({
2927+
stream: this,
2928+
headers,
2929+
flags: state.flags,
2930+
});
2931+
}
29222932
}
29232933

29242934
// Initiate a response using an open FD. Note that there are fewer
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
'use strict';
2+
3+
constcommon=require('../common');
4+
if(!common.hasCrypto)
5+
common.skip('missing crypto');
6+
7+
// This test ensures that the built-in HTTP/2 diagnostics channels are reporting
8+
// the diagnostics messages for the 'http2.server.stream.finish' channel when
9+
// ServerHttp2Streams#respond() sends a regular stream as well as a push stream.
10+
11+
constCountdown=require('../common/countdown');
12+
constassert=require('assert');
13+
constdc=require('diagnostics_channel');
14+
consthttp2=require('http2');
15+
const{ Duplex }=require('stream');
16+
17+
constserverHttp2StreamFinishCount=2;
18+
19+
dc.subscribe('http2.server.stream.finish',common.mustCall(({ stream, headers, flags })=>{
20+
// Since ServerHttp2Stream is not exported from any module, this just checks
21+
// if the stream is an instance of Duplex and the constructor name is
22+
// 'ServerHttp2Stream'.
23+
assert.ok(streaminstanceofDuplex);
24+
assert.strictEqual(stream.constructor.name,'ServerHttp2Stream');
25+
26+
assert.ok(headers&&!Array.isArray(headers)&&typeofheaders==='object');
27+
28+
assert.strictEqual(typeofflags,'number');
29+
},serverHttp2StreamFinishCount));
30+
31+
constserver=http2.createServer();
32+
server.on('stream',common.mustCall((stream)=>{
33+
stream.respond();
34+
stream.end();
35+
36+
stream.pushStream({},common.mustSucceed((pushStream)=>{
37+
pushStream.respond();
38+
pushStream.end();
39+
}));
40+
}));
41+
42+
server.listen(0,common.mustCall(()=>{
43+
constport=server.address().port;
44+
constclient=http2.connect(`http://localhost:${port}`);
45+
46+
constcountdown=newCountdown(serverHttp2StreamFinishCount,()=>{
47+
client.close();
48+
server.close();
49+
});
50+
51+
conststream=client.request({});
52+
stream.on('response',common.mustCall(()=>{
53+
countdown.dec();
54+
}));
55+
56+
client.on('stream',common.mustCall((pushStream)=>{
57+
pushStream.on('push',common.mustCall(()=>{
58+
countdown.dec();
59+
}));
60+
}));
61+
}));

0 commit comments

Comments
 (0)