Skip to content

Commit 6a76097

Browse files
jasnellMylesBorins
authored andcommitted
http2: major update to internals
This update does several significant things: 1. It eliminates the base Nghttp2* classes and folds those in to node::http2::Http2Session and node::http2::Http2Stream 2. It makes node::http2::Http2Stream a StreamBase instance and sends that out to JS-land to act as the [kHandle] for the JavaScript Http2Stream class. 3. It shifts some of the callbacks from C++ off of the JavaScript Http2Session class to the Http2Stream class. 4. It refactors the data provider structure for FD and Stream based sending to help encapsulate those functions easier 5. It streamlines some of the functions at the C++ layer to eliminate now unnecessary redirections 6. It cleans up node_http2.cc for better readability and maintainability 7. It refactors some of the debug output 8. Because Http2Stream instances are now StreamBases, they are now also trackable using async-hooks 9. The Stream::OnRead algorithm has been simplified with a couple bugs fixed. 10. I've eliminated node_http2_core.h and node_http2_core-inl.h 11. Detect invalid handshake a report protocol error to session 12. Refactor out of memory error, improve other errors 13. Add Http2Session.prototype.ping PR-URL: #17105 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Sebastiaan Deckers <[email protected]>
1 parent c0954f4 commit 6a76097

37 files changed

+2929
-3236
lines changed

doc/api/errors.md

+10
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,16 @@ created.
873873
Used when a message payload is specified for an HTTP response code for which
874874
a payload is forbidden.
875875

876+
<a id="ERR_HTTP2_PING_CANCEL"></a>
877+
### ERR_HTTP2_PING_CANCEL
878+
879+
An HTTP/2 ping was cancelled.
880+
881+
<a id="ERR_HTTP2_PING_LENGTH"></a>
882+
### ERR_HTTP2_PING_LENGTH
883+
884+
HTTP/2 ping payloads must be exactly 8 bytes in length.
885+
876886
<a id="ERR_HTTP2_PSEUDOHEADER_NOT_ALLOWED"></a>
877887
### ERR_HTTP2_PSEUDOHEADER_NOT_ALLOWED
878888

doc/api/http2.md

+57-37
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,44 @@ acknowledgement for a sent SETTINGS frame. Will be `true` after calling the
342342
`http2session.settings()` method. Will be `false` once all sent SETTINGS
343343
frames have been acknowledged.
344344

345+
#### http2session.ping([payload, ]callback)
346+
<!-- YAML
347+
added: REPLACEME
348+
-->
349+
350+
* `payload` {Buffer|TypedArray|DataView} Optional ping payload.
351+
* `callback` {Function}
352+
* Returns: {boolean}
353+
354+
Sends a `PING` frame to the connected HTTP/2 peer. A `callback` function must
355+
be provided. The method will return `true` if the `PING` was sent, `false`
356+
otherwise.
357+
358+
The maximum number of outstanding (unacknowledged) pings is determined by the
359+
`maxOutstandingPings` configuration option. The default maximum is 10.
360+
361+
If provided, the `payload` must be a `Buffer`, `TypedArray`, or `DataView`
362+
containing 8 bytes of data that will be transmitted with the `PING` and
363+
returned with the ping acknowledgement.
364+
365+
The callback will be invoked with three arguments: an error argument that will
366+
be `null` if the `PING` was successfully acknowledged, a `duration` argument
367+
that reports the number of milliseconds elapsed since the ping was sent and the
368+
acknowledgement was received, and a `Buffer` containing the 8-byte `PING`
369+
payload.
370+
371+
```js
372+
session.ping(Buffer.from('abcdefgh'), (err, duration, payload) => {
373+
if (!err) {
374+
console.log(`Ping acknowledged in ${duration} milliseconds`);
375+
console.log(`With payload '${payload.toString()}`);
376+
}
377+
});
378+
```
379+
380+
If the `payload` argument is not specified, the default payload will be the
381+
64-bit timestamp (little endian) marking the start of the `PING` duration.
382+
345383
#### http2session.remoteSettings
346384
<!-- YAML
347385
added: v8.4.0
@@ -409,19 +447,6 @@ the trailing header fields to send to the peer.
409447
will be emitted if the `getTrailers` callback attempts to set such header
410448
fields.
411449

412-
#### http2session.rstStream(stream, code)
413-
<!-- YAML
414-
added: v8.4.0
415-
-->
416-
417-
* stream {Http2Stream}
418-
* code {number} Unsigned 32-bit integer identifying the error code. **Default:**
419-
`http2.constant.NGHTTP2_NO_ERROR` (`0x00`)
420-
* Returns: {undefined}
421-
422-
Sends an `RST_STREAM` frame to the connected HTTP/2 peer, causing the given
423-
`Http2Stream` to be closed on both sides using [error code][] `code`.
424-
425450
#### http2session.setTimeout(msecs, callback)
426451
<!-- YAML
427452
added: v8.4.0
@@ -513,28 +538,6 @@ added: v8.4.0
513538

514539
An object describing the current status of this `Http2Session`.
515540

516-
#### http2session.priority(stream, options)
517-
<!-- YAML
518-
added: v8.4.0
519-
-->
520-
521-
* `stream` {Http2Stream}
522-
* `options` {Object}
523-
* `exclusive` {boolean} When `true` and `parent` identifies a parent Stream,
524-
the given stream is made the sole direct dependency of the parent, with
525-
all other existing dependents made a dependent of the given stream. **Default:**
526-
`false`
527-
* `parent` {number} Specifies the numeric identifier of a stream the given
528-
stream is dependent on.
529-
* `weight` {number} Specifies the relative dependency of a stream in relation
530-
to other streams with the same `parent`. The value is a number between `1`
531-
and `256` (inclusive).
532-
* `silent` {boolean} When `true`, changes the priority locally without
533-
sending a `PRIORITY` frame to the connected peer.
534-
* Returns: {undefined}
535-
536-
Updates the priority for the given `Http2Stream` instance.
537-
538541
#### http2session.settings(settings)
539542
<!-- YAML
540543
added: v8.4.0
@@ -622,8 +625,7 @@ is not yet ready for use.
622625
All [`Http2Stream`][] instances are destroyed either when:
623626

624627
* An `RST_STREAM` frame for the stream is received by the connected peer.
625-
* The `http2stream.rstStream()` or `http2session.rstStream()` methods are
626-
called.
628+
* The `http2stream.rstStream()` methods is called.
627629
* The `http2stream.destroy()` or `http2session.destroy()` methods are called.
628630

629631
When an `Http2Stream` instance is destroyed, an attempt will be made to send an
@@ -1471,6 +1473,10 @@ not be emitted.
14711473
<!-- YAML
14721474
added: v8.4.0
14731475
changes:
1476+
- version: REPLACEME
1477+
pr-url: https://github.com/nodejs/node/pull/17105
1478+
description: Added the `maxOutstandingPings` option with a default limit of
1479+
10.
14741480
- version: v9.1.0
14751481
pr-url: https://github.com/nodejs/node/pull/16676
14761482
description: Added the `maxHeaderListPairs` option with a default limit of
@@ -1482,6 +1488,8 @@ changes:
14821488
for deflating header fields. **Default:** `4Kib`
14831489
* `maxHeaderListPairs` {number} Sets the maximum number of header entries.
14841490
**Default:** `128`. The minimum value is `4`.
1491+
* `maxOutstandingPings` {number} Sets the maximum number of outstanding,
1492+
unacknowledged pings. The default is `10`.
14851493
* `maxSendHeaderBlockLength` {number} Sets the maximum allowed size for a
14861494
serialized, compressed block of headers. Attempts to send headers that
14871495
exceed this limit will result in a `'frameError'` event being emitted
@@ -1533,6 +1541,10 @@ server.listen(80);
15331541
<!-- YAML
15341542
added: v8.4.0
15351543
changes:
1544+
- version: REPLACEME
1545+
pr-url: https://github.com/nodejs/node/pull/17105
1546+
description: Added the `maxOutstandingPings` option with a default limit of
1547+
10.
15361548
- version: v9.1.0
15371549
pr-url: https://github.com/nodejs/node/pull/16676
15381550
description: Added the `maxHeaderListPairs` option with a default limit of
@@ -1547,6 +1559,8 @@ changes:
15471559
for deflating header fields. **Default:** `4Kib`
15481560
* `maxHeaderListPairs` {number} Sets the maximum number of header entries.
15491561
**Default:** `128`. The minimum value is `4`.
1562+
* `maxOutstandingPings` {number} Sets the maximum number of outstanding,
1563+
unacknowledged pings. The default is `10`.
15501564
* `maxSendHeaderBlockLength` {number} Sets the maximum allowed size for a
15511565
serialized, compressed block of headers. Attempts to send headers that
15521566
exceed this limit will result in a `'frameError'` event being emitted
@@ -1605,6 +1619,10 @@ server.listen(80);
16051619
<!-- YAML
16061620
added: v8.4.0
16071621
changes:
1622+
- version: REPLACEME
1623+
pr-url: https://github.com/nodejs/node/pull/17105
1624+
description: Added the `maxOutstandingPings` option with a default limit of
1625+
10.
16081626
- version: v9.1.0
16091627
pr-url: https://github.com/nodejs/node/pull/16676
16101628
description: Added the `maxHeaderListPairs` option with a default limit of
@@ -1617,6 +1635,8 @@ changes:
16171635
for deflating header fields. **Default:** `4Kib`
16181636
* `maxHeaderListPairs` {number} Sets the maximum number of header entries.
16191637
**Default:** `128`. The minimum value is `1`.
1638+
* `maxOutstandingPings` {number} Sets the maximum number of outstanding,
1639+
unacknowledged pings. The default is `10`.
16201640
* `maxReservedRemoteStreams` {number} Sets the maximum number of reserved push
16211641
streams the client will accept at any given time. Once the current number of
16221642
currently reserved push streams exceeds reaches this limit, new push streams

lib/internal/errors.js

+2
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,8 @@ E('ERR_HTTP2_OUT_OF_STREAMS',
221221
'No stream ID is available because maximum stream ID has been reached');
222222
E('ERR_HTTP2_PAYLOAD_FORBIDDEN',
223223
(code) => `Responses with ${code} status must not have a payload`);
224+
E('ERR_HTTP2_PING_CANCEL', 'HTTP2 ping cancelled');
225+
E('ERR_HTTP2_PING_LENGTH', 'HTTP2 ping payload must be 8 bytes');
224226
E('ERR_HTTP2_PSEUDOHEADER_NOT_ALLOWED', 'Cannot set HTTP/2 pseudo-headers');
225227
E('ERR_HTTP2_PUSH_DISABLED', 'HTTP/2 client has disabled push streams');
226228
E('ERR_HTTP2_SEND_FILE', 'Only regular files can be sent');

0 commit comments

Comments
 (0)