From 6a76097fadd372a4b4710f378491d59e761a4dbd Mon Sep 17 00:00:00 2001 From: James M Snell Date: Wed, 15 Nov 2017 10:55:31 -0800 Subject: [PATCH] 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: https://github.com/nodejs/node/pull/17105 Reviewed-By: Anna Henningsen Reviewed-By: Sebastiaan Deckers --- doc/api/errors.md | 10 + doc/api/http2.md | 94 +- lib/internal/errors.js | 2 + lib/internal/http2/core.js | 741 ++--- lib/internal/http2/util.js | 104 +- node.gyp | 2 - src/async-wrap.h | 3 +- src/env.h | 2 + src/node_http2.cc | 2503 +++++++++++------ src/node_http2.h | 671 ++++- src/node_http2_core-inl.h | 925 ------ src/node_http2_core.h | 516 ---- src/node_http2_state.h | 1 + test/parallel/test-http2-client-data-end.js | 2 +- test/parallel/test-http2-client-destroy.js | 3 - .../test-http2-client-http1-server.js | 27 + .../test-http2-client-onconnect-errors.js | 28 +- ...st-http2-client-priority-before-connect.js | 2 +- ...t-http2-client-rststream-before-connect.js | 10 +- .../test-http2-client-settings-errors.js | 84 - ...est-http2-compat-serverrequest-trailers.js | 2 +- test/parallel/test-http2-getpackedsettings.js | 3 +- .../test-http2-info-headers-errors.js | 22 +- .../test-http2-invalidargtypes-errors.js | 10 +- test/parallel/test-http2-no-more-streams.js | 53 + test/parallel/test-http2-ping.js | 87 + test/parallel/test-http2-pipe.js | 16 +- test/parallel/test-http2-priority-errors.js | 109 - test/parallel/test-http2-respond-errors.js | 21 +- .../test-http2-respond-with-fd-errors.js | 24 +- test/parallel/test-http2-rststream-errors.js | 22 +- .../test-http2-server-http1-client.js | 22 + .../test-http2-server-push-stream-errors.js | 17 +- ...est-http2-server-stream-session-destroy.js | 6 +- test/parallel/test-http2-shutdown-errors.js | 2 +- .../test-http2-util-update-options-buffer.js | 16 +- test/sequential/test-async-wrap-getasyncid.js | 3 +- 37 files changed, 2929 insertions(+), 3236 deletions(-) delete mode 100644 src/node_http2_core-inl.h delete mode 100644 src/node_http2_core.h create mode 100644 test/parallel/test-http2-client-http1-server.js delete mode 100644 test/parallel/test-http2-client-settings-errors.js create mode 100644 test/parallel/test-http2-no-more-streams.js create mode 100644 test/parallel/test-http2-ping.js delete mode 100644 test/parallel/test-http2-priority-errors.js create mode 100644 test/parallel/test-http2-server-http1-client.js diff --git a/doc/api/errors.md b/doc/api/errors.md index cafab4db5fbb23..0475cfb1e0954a 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -873,6 +873,16 @@ created. Used when a message payload is specified for an HTTP response code for which a payload is forbidden. + +### ERR_HTTP2_PING_CANCEL + +An HTTP/2 ping was cancelled. + + +### ERR_HTTP2_PING_LENGTH + +HTTP/2 ping payloads must be exactly 8 bytes in length. + ### ERR_HTTP2_PSEUDOHEADER_NOT_ALLOWED diff --git a/doc/api/http2.md b/doc/api/http2.md index dad14d5ce365bf..bd8356b7fef0f1 100644 --- a/doc/api/http2.md +++ b/doc/api/http2.md @@ -342,6 +342,44 @@ acknowledgement for a sent SETTINGS frame. Will be `true` after calling the `http2session.settings()` method. Will be `false` once all sent SETTINGS frames have been acknowledged. +#### http2session.ping([payload, ]callback) + + +* `payload` {Buffer|TypedArray|DataView} Optional ping payload. +* `callback` {Function} +* Returns: {boolean} + +Sends a `PING` frame to the connected HTTP/2 peer. A `callback` function must +be provided. The method will return `true` if the `PING` was sent, `false` +otherwise. + +The maximum number of outstanding (unacknowledged) pings is determined by the +`maxOutstandingPings` configuration option. The default maximum is 10. + +If provided, the `payload` must be a `Buffer`, `TypedArray`, or `DataView` +containing 8 bytes of data that will be transmitted with the `PING` and +returned with the ping acknowledgement. + +The callback will be invoked with three arguments: an error argument that will +be `null` if the `PING` was successfully acknowledged, a `duration` argument +that reports the number of milliseconds elapsed since the ping was sent and the +acknowledgement was received, and a `Buffer` containing the 8-byte `PING` +payload. + +```js +session.ping(Buffer.from('abcdefgh'), (err, duration, payload) => { + if (!err) { + console.log(`Ping acknowledged in ${duration} milliseconds`); + console.log(`With payload '${payload.toString()}`); + } +}); +``` + +If the `payload` argument is not specified, the default payload will be the +64-bit timestamp (little endian) marking the start of the `PING` duration. + #### http2session.remoteSettings - -* stream {Http2Stream} -* code {number} Unsigned 32-bit integer identifying the error code. **Default:** - `http2.constant.NGHTTP2_NO_ERROR` (`0x00`) -* Returns: {undefined} - -Sends an `RST_STREAM` frame to the connected HTTP/2 peer, causing the given -`Http2Stream` to be closed on both sides using [error code][] `code`. - #### http2session.setTimeout(msecs, callback) - -* `stream` {Http2Stream} -* `options` {Object} - * `exclusive` {boolean} When `true` and `parent` identifies a parent Stream, - the given stream is made the sole direct dependency of the parent, with - all other existing dependents made a dependent of the given stream. **Default:** - `false` - * `parent` {number} Specifies the numeric identifier of a stream the given - stream is dependent on. - * `weight` {number} Specifies the relative dependency of a stream in relation - to other streams with the same `parent`. The value is a number between `1` - and `256` (inclusive). - * `silent` {boolean} When `true`, changes the priority locally without - sending a `PRIORITY` frame to the connected peer. -* Returns: {undefined} - -Updates the priority for the given `Http2Stream` instance. - #### http2session.settings(settings)