Skip to content

Commit a07f5f2

Browse files
daeyeonbengl
authored andcommitted
http2: improve tests and docs
This commit documents the event parameters and `http2stream.respond`, and adds some tests to ensure the actual behaviors are aligned with the docs. Testing the 'Http2Server.sessionError' event is added by updating `test/parallel/test-http2-options-max-headers-exceeds-nghttp2.js`. The event seemingly has not been tested so far. `ServerHttp2Session` is exported to validate the `session` event and the `sessionError` event. Signed-off-by: Daeyeon Jeong daeyeon.dev@gmail.com PR-URL: #42858 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Paolo Insogna <paolo@cowtech.it> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
1 parent 3082c75 commit a07f5f2

8 files changed

+97
-8
lines changed

doc/api/http2.md

+25-4
Original file line numberDiff line numberDiff line change
@@ -1479,6 +1479,9 @@ the client should send the request body.
14791479
added: v8.4.0
14801480
-->
14811481

1482+
* `headers` {HTTP/2 Headers Object}
1483+
* `flags` {number}
1484+
14821485
The `'headers'` event is emitted when an additional block of headers is received
14831486
for a stream, such as when a block of `1xx` informational headers is received.
14841487
The listener callback is passed the [HTTP/2 Headers Object][] and flags
@@ -1496,6 +1499,9 @@ stream.on('headers', (headers, flags) => {
14961499
added: v8.4.0
14971500
-->
14981501

1502+
* `headers` {HTTP/2 Headers Object}
1503+
* `flags` {number}
1504+
14991505
The `'push'` event is emitted when response headers for a Server Push stream
15001506
are received. The listener callback is passed the [HTTP/2 Headers Object][] and
15011507
flags associated with the headers.
@@ -1512,6 +1518,9 @@ stream.on('push', (headers, flags) => {
15121518
added: v8.4.0
15131519
-->
15141520

1521+
* `headers` {HTTP/2 Headers Object}
1522+
* `flags` {number}
1523+
15151524
The `'response'` event is emitted when a response `HEADERS` frame has been
15161525
received for this stream from the connected HTTP/2 server. The listener is
15171526
invoked with two arguments: an `Object` containing the received
@@ -1652,10 +1661,10 @@ server.on('stream', (stream) => {
16521661
});
16531662
```
16541663

1655-
When the `options.waitForTrailers` option is set, the `'wantTrailers'` event
1656-
will be emitted immediately after queuing the last chunk of payload data to be
1657-
sent. The `http2stream.sendTrailers()` method can then be used to sent trailing
1658-
header fields to the peer.
1664+
Initiates a response. When the `options.waitForTrailers` option is set, the
1665+
`'wantTrailers'` event will be emitted immediately after queuing the last chunk
1666+
of payload data to be sent. The `http2stream.sendTrailers()` method can then be
1667+
used to sent trailing header fields to the peer.
16591668

16601669
When `options.waitForTrailers` is set, the `Http2Stream` will not automatically
16611670
close when the final `DATA` frame is transmitted. User code must call either
@@ -1973,6 +1982,8 @@ per session. See the [Compatibility API][].
19731982
added: v8.4.0
19741983
-->
19751984

1985+
* `session` {ServerHttp2Session}
1986+
19761987
The `'session'` event is emitted when a new `Http2Session` is created by the
19771988
`Http2Server`.
19781989

@@ -1982,6 +1993,9 @@ The `'session'` event is emitted when a new `Http2Session` is created by the
19821993
added: v8.4.0
19831994
-->
19841995

1996+
* `error` {Error}
1997+
* `session` {ServerHttp2Session}
1998+
19851999
The `'sessionError'` event is emitted when an `'error'` event is emitted by
19862000
an `Http2Session` object associated with the `Http2Server`.
19872001

@@ -2188,6 +2202,8 @@ per session. See the [Compatibility API][].
21882202
added: v8.4.0
21892203
-->
21902204

2205+
* `session` {ServerHttp2Session}
2206+
21912207
The `'session'` event is emitted when a new `Http2Session` is created by the
21922208
`Http2SecureServer`.
21932209

@@ -2197,6 +2213,9 @@ The `'session'` event is emitted when a new `Http2Session` is created by the
21972213
added: v8.4.0
21982214
-->
21992215

2216+
* `error` {Error}
2217+
* `session` {ServerHttp2Session}
2218+
22002219
The `'sessionError'` event is emitted when an `'error'` event is emitted by
22012220
an `Http2Session` object associated with the `Http2SecureServer`.
22022221

@@ -2258,6 +2277,8 @@ a given number of milliseconds set using `http2secureServer.setTimeout()`.
22582277
added: v8.4.0
22592278
-->
22602279

2280+
* `socket` {stream.Duplex}
2281+
22612282
The `'unknownProtocol'` event is emitted when a connecting client fails to
22622283
negotiate an allowed protocol (i.e. HTTP/2 or HTTP/1.1). The event handler
22632284
receives the socket for handling. If no listener is registered for this event,

lib/internal/http2/core.js

+1
Original file line numberDiff line numberDiff line change
@@ -3401,6 +3401,7 @@ module.exports = {
34013401
sensitiveHeaders: kSensitiveHeaders,
34023402
Http2Session,
34033403
Http2Stream,
3404+
ServerHttp2Session,
34043405
Http2ServerRequest,
34053406
Http2ServerResponse
34063407
};

test/parallel/test-http2-https-fallback.js

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const { createSecureServer, connect } = require('http2');
1212
const { get } = require('https');
1313
const { parse } = require('url');
1414
const { connect: tls } = require('tls');
15+
const { Duplex } = require('stream');
1516

1617
const countdown = (count, done) => () => --count === 0 && done();
1718

@@ -115,6 +116,7 @@ function onSession(session, next) {
115116
);
116117

117118
server.once('unknownProtocol', common.mustCall((socket) => {
119+
strictEqual(socket instanceof Duplex, true);
118120
socket.destroy();
119121
}));
120122

test/parallel/test-http2-options-max-headers-exceeds-nghttp2.js

+55-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
// Flags: --expose-internals
12
'use strict';
23

34
const common = require('../common');
4-
if (!common.hasCrypto)
5-
common.skip('missing crypto');
5+
if (!common.hasCrypto) common.skip('missing crypto');
66
const h2 = require('http2');
7+
const assert = require('assert');
8+
const { ServerHttp2Session } = require('internal/http2/core');
79

810
const server = h2.createServer();
911

@@ -44,3 +46,54 @@ server.listen(0, common.mustCall(() => {
4446
}));
4547
req.end();
4648
}));
49+
50+
{
51+
const options = {
52+
maxSendHeaderBlockLength: 100000,
53+
};
54+
55+
const server = h2.createServer(options);
56+
57+
server.on('error', common.mustNotCall());
58+
server.on(
59+
'session',
60+
common.mustCall((session) => {
61+
assert.strictEqual(session instanceof ServerHttp2Session, true);
62+
}),
63+
);
64+
server.on(
65+
'stream',
66+
common.mustCall((stream) => {
67+
stream.additionalHeaders({
68+
// Greater than 65536 bytes
69+
'test-header': 'A'.repeat(90000),
70+
});
71+
stream.respond();
72+
stream.end();
73+
}),
74+
);
75+
76+
server.on(
77+
'sessionError',
78+
common.mustCall((err, session) => {
79+
assert.strictEqual(err.code, 'ERR_HTTP2_SESSION_ERROR');
80+
assert.strictEqual(err.name, 'Error');
81+
assert.strictEqual(err.message, 'Session closed with error code 9');
82+
assert.strictEqual(session instanceof ServerHttp2Session, true);
83+
server.close();
84+
}),
85+
);
86+
87+
server.listen(
88+
0,
89+
common.mustCall(() => {
90+
const client = h2.connect(`http://localhost:${server.address().port}`);
91+
client.on('error', common.mustNotCall());
92+
93+
const req = client.request();
94+
req.on('response', common.mustNotCall());
95+
req.on('error', common.mustNotCall());
96+
req.end();
97+
}),
98+
);
99+
}

test/parallel/test-http2-sent-headers.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ server.listen(0, common.mustCall(() => {
2929
const client = h2.connect(`http://localhost:${server.address().port}`);
3030
const req = client.request();
3131

32-
req.on('headers', common.mustCall((headers) => {
32+
req.on('headers', common.mustCall((headers, flags) => {
3333
assert.strictEqual(headers[':status'], 102);
34+
assert.strictEqual(typeof flags === 'number', true);
3435
}));
3536

3637
assert.strictEqual(req.sentHeaders[':method'], 'GET');

test/parallel/test-http2-server-push-stream.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,11 @@ server.listen(0, common.mustCall(() => {
4848
assert.strictEqual(headers[':scheme'], 'http');
4949
assert.strictEqual(headers[':path'], '/foobar');
5050
assert.strictEqual(headers[':authority'], `localhost:${port}`);
51-
stream.on('push', common.mustCall((headers) => {
51+
stream.on('push', common.mustCall((headers, flags) => {
5252
assert.strictEqual(headers[':status'], 200);
5353
assert.strictEqual(headers['content-type'], 'text/html');
5454
assert.strictEqual(headers['x-push-data'], 'pushed by server');
55+
assert.strictEqual(typeof flags === 'number', true);
5556
}));
5657
stream.on('aborted', common.mustNotCall());
5758
// We have to read the data of the push stream to end gracefully.

test/parallel/test-http2-server-sessionerror.js

+9
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,17 @@ const common = require('../common');
66
if (!common.hasCrypto)
77
common.skip('missing crypto');
88
const http2 = require('http2');
9+
const assert = require('assert');
910
const { kSocket } = require('internal/http2/util');
11+
const { ServerHttp2Session } = require('internal/http2/core');
1012

1113
const server = http2.createServer();
1214
server.on('stream', common.mustNotCall());
1315

1416
let test = 0;
1517

1618
server.on('session', common.mustCall((session) => {
19+
assert.strictEqual(session instanceof ServerHttp2Session, true);
1720
switch (++test) {
1821
case 1:
1922
server.on('error', common.mustNotCall());
@@ -32,6 +35,12 @@ server.on('session', common.mustCall((session) => {
3235
}
3336
}, 2));
3437

38+
server.on('sessionError', common.mustCall((err, session) => {
39+
assert.strictEqual(err.name, 'Error');
40+
assert.strictEqual(err.message, 'test');
41+
assert.strictEqual(session instanceof ServerHttp2Session, true);
42+
}, 2));
43+
3544
server.listen(0, common.mustCall(() => {
3645
const url = `http://localhost:${server.address().port}`;
3746
http2.connect(url)

tools/doc/type-parser.mjs

+1
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ const customTypesMap = {
164164
'Http2Session': 'http2.html#class-http2session',
165165
'Http2Stream': 'http2.html#class-http2stream',
166166
'ServerHttp2Stream': 'http2.html#class-serverhttp2stream',
167+
'ServerHttp2Session': 'http2.html#class-serverhttp2session',
167168

168169
'https.Server': 'https.html#class-httpsserver',
169170

0 commit comments

Comments
 (0)