Skip to content

Commit a21dca0

Browse files
committed
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
1 parent 804eb3c commit a21dca0

37 files changed

+2922
-3214
lines changed

doc/api/errors.md

+10
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,16 @@ limit.
908908
A message payload was specified for an HTTP response code for which a payload is
909909
forbidden.
910910

911+
<a id="ERR_HTTP2_PING_CANCEL"></a>
912+
### ERR_HTTP2_PING_CANCEL
913+
914+
An HTTP/2 ping was cancelled.
915+
916+
<a id="ERR_HTTP2_PING_LENGTH"></a>
917+
### ERR_HTTP2_PING_LENGTH
918+
919+
HTTP/2 ping payloads must be exactly 8-bytes in length.
920+
911921
<a id="ERR_HTTP2_PSEUDOHEADER_NOT_ALLOWED"></a>
912922
### ERR_HTTP2_PSEUDOHEADER_NOT_ALLOWED
913923

doc/api/http2.md

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

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

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

516541
An object describing the current status of this `Http2Session`.
517542

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

626629
* An `RST_STREAM` frame for the stream is received by the connected peer.
627-
* The `http2stream.rstStream()` or `http2session.rstStream()` methods are
628-
called.
630+
* The `http2stream.rstStream()` methods is called.
629631
* The `http2stream.destroy()` or `http2session.destroy()` methods are called.
630632

631633
When an `Http2Stream` instance is destroyed, an attempt will be made to send an
@@ -1473,6 +1475,10 @@ not be emitted.
14731475
<!-- YAML
14741476
added: v8.4.0
14751477
changes:
1478+
- version: REPLACEME
1479+
pr-url: https://github.com/nodejs/node/pull/17105
1480+
description: Added the `maxOutstandingPings` option with a default limit of
1481+
10.
14761482
- version: v9.1.0
14771483
pr-url: https://github.com/nodejs/node/pull/16676
14781484
description: Added the `maxHeaderListPairs` option with a default limit of
@@ -1484,6 +1490,8 @@ changes:
14841490
for deflating header fields. **Default:** `4Kib`
14851491
* `maxHeaderListPairs` {number} Sets the maximum number of header entries.
14861492
**Default:** `128`. The minimum value is `4`.
1493+
* `maxOutstandingPings` {number} Sets the maximum number of outstanding,
1494+
unacknowledged pings. The default is `10`.
14871495
* `maxSendHeaderBlockLength` {number} Sets the maximum allowed size for a
14881496
serialized, compressed block of headers. Attempts to send headers that
14891497
exceed this limit will result in a `'frameError'` event being emitted
@@ -1535,6 +1543,10 @@ server.listen(80);
15351543
<!-- YAML
15361544
added: v8.4.0
15371545
changes:
1546+
- version: REPLACEME
1547+
pr-url: https://github.com/nodejs/node/pull/17105
1548+
description: Added the `maxOutstandingPings` option with a default limit of
1549+
10.
15381550
- version: v9.1.0
15391551
pr-url: https://github.com/nodejs/node/pull/16676
15401552
description: Added the `maxHeaderListPairs` option with a default limit of
@@ -1549,6 +1561,8 @@ changes:
15491561
for deflating header fields. **Default:** `4Kib`
15501562
* `maxHeaderListPairs` {number} Sets the maximum number of header entries.
15511563
**Default:** `128`. The minimum value is `4`.
1564+
* `maxOutstandingPings` {number} Sets the maximum number of outstanding,
1565+
unacknowledged pings. The default is `10`.
15521566
* `maxSendHeaderBlockLength` {number} Sets the maximum allowed size for a
15531567
serialized, compressed block of headers. Attempts to send headers that
15541568
exceed this limit will result in a `'frameError'` event being emitted
@@ -1607,6 +1621,10 @@ server.listen(80);
16071621
<!-- YAML
16081622
added: v8.4.0
16091623
changes:
1624+
- version: REPLACEME
1625+
pr-url: https://github.com/nodejs/node/pull/17105
1626+
description: Added the `maxOutstandingPings` option with a default limit of
1627+
10.
16101628
- version: v9.1.0
16111629
pr-url: https://github.com/nodejs/node/pull/16676
16121630
description: Added the `maxHeaderListPairs` option with a default limit of
@@ -1619,6 +1637,8 @@ changes:
16191637
for deflating header fields. **Default:** `4Kib`
16201638
* `maxHeaderListPairs` {number} Sets the maximum number of header entries.
16211639
**Default:** `128`. The minimum value is `1`.
1640+
* `maxOutstandingPings` {number} Sets the maximum number of outstanding,
1641+
unacknowledged pings. The default is `10`.
16221642
* `maxReservedRemoteStreams` {number} Sets the maximum number of reserved push
16231643
streams the client will accept at any given time. Once the current number of
16241644
currently reserved push streams exceeds reaches this limit, new push streams

lib/internal/errors.js

+2
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,8 @@ E('ERR_HTTP2_OUT_OF_STREAMS',
299299
'No stream ID is available because maximum stream ID has been reached');
300300
E('ERR_HTTP2_PAYLOAD_FORBIDDEN',
301301
'Responses with %s status must not have a payload');
302+
E('ERR_HTTP2_PING_CANCEL', 'HTTP2 ping cancelled');
303+
E('ERR_HTTP2_PING_LENGTH', 'HTTP2 ping payload must be 8 bytes');
302304
E('ERR_HTTP2_PSEUDOHEADER_NOT_ALLOWED', 'Cannot set HTTP/2 pseudo-headers');
303305
E('ERR_HTTP2_PUSH_DISABLED', 'HTTP/2 client has disabled push streams');
304306
E('ERR_HTTP2_SEND_FILE', 'Only regular files can be sent');

0 commit comments

Comments
 (0)