Skip to content

Commit e40f0c9

Browse files
daeyeontargos
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 4a3297a commit e40f0c9

File tree

8 files changed

+97
-8
lines changed

8 files changed

+97
-8
lines changed

doc/api/http2.md

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,6 +1445,9 @@ the client should send the request body.
14451445
added: v8.4.0
14461446
-->
14471447

1448+
* `headers` {HTTP/2 Headers Object}
1449+
* `flags` {number}
1450+
14481451
The `'headers'` event is emitted when an additional block of headers is received
14491452
for a stream, such as when a block of `1xx` informational headers is received.
14501453
The listener callback is passed the [HTTP/2 Headers Object][] and flags
@@ -1462,6 +1465,9 @@ stream.on('headers', (headers, flags) => {
14621465
added: v8.4.0
14631466
-->
14641467

1468+
* `headers` {HTTP/2 Headers Object}
1469+
* `flags` {number}
1470+
14651471
The `'push'` event is emitted when response headers for a Server Push stream
14661472
are received. The listener callback is passed the [HTTP/2 Headers Object][] and
14671473
flags associated with the headers.
@@ -1478,6 +1484,9 @@ stream.on('push', (headers, flags) => {
14781484
added: v8.4.0
14791485
-->
14801486

1487+
* `headers` {HTTP/2 Headers Object}
1488+
* `flags` {number}
1489+
14811490
The `'response'` event is emitted when a response `HEADERS` frame has been
14821491
received for this stream from the connected HTTP/2 server. The listener is
14831492
invoked with two arguments: an `Object` containing the received
@@ -1612,10 +1621,10 @@ server.on('stream', (stream) => {
16121621
});
16131622
```
16141623

1615-
When the `options.waitForTrailers` option is set, the `'wantTrailers'` event
1616-
will be emitted immediately after queuing the last chunk of payload data to be
1617-
sent. The `http2stream.sendTrailers()` method can then be used to sent trailing
1618-
header fields to the peer.
1624+
Initiates a response. When the `options.waitForTrailers` option is set, the
1625+
`'wantTrailers'` event will be emitted immediately after queuing the last chunk
1626+
of payload data to be sent. The `http2stream.sendTrailers()` method can then be
1627+
used to sent trailing header fields to the peer.
16191628

16201629
When `options.waitForTrailers` is set, the `Http2Stream` will not automatically
16211630
close when the final `DATA` frame is transmitted. User code must call either
@@ -1933,6 +1942,8 @@ per session. See the [Compatibility API][].
19331942
added: v8.4.0
19341943
-->
19351944

1945+
* `session` {ServerHttp2Session}
1946+
19361947
The `'session'` event is emitted when a new `Http2Session` is created by the
19371948
`Http2Server`.
19381949

@@ -1942,6 +1953,9 @@ The `'session'` event is emitted when a new `Http2Session` is created by the
19421953
added: v8.4.0
19431954
-->
19441955

1956+
* `error` {Error}
1957+
* `session` {ServerHttp2Session}
1958+
19451959
The `'sessionError'` event is emitted when an `'error'` event is emitted by
19461960
an `Http2Session` object associated with the `Http2Server`.
19471961

@@ -2141,6 +2155,8 @@ per session. See the [Compatibility API][].
21412155
added: v8.4.0
21422156
-->
21432157

2158+
* `session` {ServerHttp2Session}
2159+
21442160
The `'session'` event is emitted when a new `Http2Session` is created by the
21452161
`Http2SecureServer`.
21462162

@@ -2150,6 +2166,9 @@ The `'session'` event is emitted when a new `Http2Session` is created by the
21502166
added: v8.4.0
21512167
-->
21522168

2169+
* `error` {Error}
2170+
* `session` {ServerHttp2Session}
2171+
21532172
The `'sessionError'` event is emitted when an `'error'` event is emitted by
21542173
an `Http2Session` object associated with the `Http2SecureServer`.
21552174

@@ -2211,6 +2230,8 @@ a given number of milliseconds set using `http2secureServer.setTimeout()`.
22112230
added: v8.4.0
22122231
-->
22132232

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

lib/internal/http2/core.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3393,6 +3393,7 @@ module.exports = {
33933393
sensitiveHeaders: kSensitiveHeaders,
33943394
Http2Session,
33953395
Http2Stream,
3396+
ServerHttp2Session,
33963397
Http2ServerRequest,
33973398
Http2ServerResponse
33983399
};

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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 55 additions & 2 deletions
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

Lines changed: 2 additions & 1 deletion
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

Lines changed: 2 additions & 1 deletion
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

Lines changed: 9 additions & 0 deletions
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

Lines changed: 1 addition & 0 deletions
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)