summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorJames M Snell <jasnell@gmail.com>2017-07-17 10:17:16 -0700
committerJames M Snell <jasnell@gmail.com>2017-08-04 12:55:44 -0700
commite71e71b5138c3dfee080f4215dd957dc7a6cbdaf (patch)
treea46b77ae1bd423c0db3cf0f65ea370a721b67c24 /doc
parent71a1876f6c3f2a7131c7019d63fea5c8fa740276 (diff)
downloadnode-new-e71e71b5138c3dfee080f4215dd957dc7a6cbdaf.tar.gz
http2: introducing HTTP/2
At long last: The initial *experimental* implementation of HTTP/2. This is an accumulation of the work that has been done in the nodejs/http2 repository, squashed down to a couple of commits. The original commit history has been preserved in the nodejs/http2 repository. This PR introduces the nghttp2 C library as a new dependency. This library provides the majority of the HTTP/2 protocol implementation, with the rest of the code here providing the mapping of the library into a usable JS API. Within src, a handful of new node_http2_*.c and node_http2_*.h files are introduced. These provide the internal mechanisms that interface with nghttp and define the `process.binding('http2')` interface. The JS API is defined within `internal/http2/*.js`. There are two APIs provided: Core and Compat. The Core API is HTTP/2 specific and is designed to be as minimal and as efficient as possible. The Compat API is intended to be as close to the existing HTTP/1 API as possible, with some exceptions. Tests, documentation and initial benchmarks are included. The `http2` module is gated by a new `--expose-http2` command line flag. When used, `require('http2')` will be exposed to users. Note that there is an existing `http2` module on npm that would be impacted by the introduction of this module, which is the main reason for gating this behind a flag. When using `require('http2')` the first time, a process warning will be emitted indicating that an experimental feature is being used. To run the benchmarks, the `h2load` tool (part of the nghttp project) is required: `./node benchmarks/http2/simple.js benchmarker=h2load`. Only two benchmarks are currently available. Additional configuration options to enable verbose debugging are provided: ``` $ ./configure --debug-http2 --debug-nghttp2 $ NODE_DEBUG=http2 ./node ``` The `--debug-http2` configuration option enables verbose debug statements from the `src/node_http2_*` files. The `--debug-nghttp2` enables the nghttp library's own verbose debug output. The `NODE_DEBUG=http2` enables JS-level debug output. The following illustrates as simple HTTP/2 server and client interaction: (The HTTP/2 client and server support both plain text and TLS connections) ```jt client = http2.connect('http://localhost:80'); const req = client.request({ ':path': '/some/path' }); req.on('data', (chunk) => { /* do something with the data */ }); req.on('end', () => { client.destroy(); }); // Plain text (non-TLS server) const server = http2.createServer(); server.on('stream', (stream, requestHeaders) => { stream.respond({ ':status': 200 }); stream.write('hello '); stream.end('world'); }); server.listen(80); ``` ```js const http2 = require('http2'); const client = http2.connect('http://localhost'); ``` Author: Anna Henningsen <anna@addaleax.net> Author: Colin Ihrig <cjihrig@gmail.com> Author: Daniel Bevenius <daniel.bevenius@gmail.com> Author: James M Snell <jasnell@gmail.com> Author: Jun Mukai Author: Kelvin Jin Author: Matteo Collina <matteo.collina@gmail.com> Author: Robert Kowalski <rok@kowalski.gd> Author: Santiago Gimeno <santiago.gimeno@gmail.com> Author: Sebastiaan Deckers <sebdeckers83@gmail.com> Author: Yosuke Furukawa <yosuke.furukawa@gmail.com> PR-URL: https://github.com/nodejs/node/pull/14239 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Diffstat (limited to 'doc')
-rw-r--r--doc/api/_toc.md1
-rw-r--r--doc/api/cli.md7
-rw-r--r--doc/api/errors.md184
-rwxr-xr-xdoc/api/http2.md1704
-rw-r--r--doc/guides/writing-and-running-benchmarks.md9
-rw-r--r--doc/node.14
6 files changed, 1909 insertions, 0 deletions
diff --git a/doc/api/_toc.md b/doc/api/_toc.md
index 1075bc6be3..6791e63f0c 100644
--- a/doc/api/_toc.md
+++ b/doc/api/_toc.md
@@ -24,6 +24,7 @@
* [File System](fs.html)
* [Globals](globals.html)
* [HTTP](http.html)
+* [HTTP/2](http2.html)
* [HTTPS](https.html)
* [Inspector](inspector.html)
* [Internationalization](intl.html)
diff --git a/doc/api/cli.md b/doc/api/cli.md
index d4703c1cf0..6665941480 100644
--- a/doc/api/cli.md
+++ b/doc/api/cli.md
@@ -170,6 +170,13 @@ added: v6.0.0
Silence all process warnings (including deprecations).
+### `--expose-http2`
+<!-- YAML
+added: REPLACEME
+-->
+
+Enable the experimental `'http2'` module.
+
### `--napi-modules`
<!-- YAML
added: v8.0.0
diff --git a/doc/api/errors.md b/doc/api/errors.md
index 5de3fa4067..cb55ed05fd 100644
--- a/doc/api/errors.md
+++ b/doc/api/errors.md
@@ -624,6 +624,190 @@ Used for status codes outside the regular status code ranges (100-999).
Used when the `Trailer` header is set even though the transfer encoding does not
support that.
+<a id="ERR_HTTP2_CONNECT_AUTHORITY"></a>
+### ERR_HTTP2_CONNECT_AUTHORITY
+
+For HTTP/2 requests using the `CONNECT` method, the `:authority` pseudo-header
+is required.
+
+<a id="ERR_HTTP2_CONNECT_PATH"></a>
+### ERR_HTTP2_CONNECT_PATH
+
+For HTTP/2 requests using the `CONNECT` method, the `:path` pseudo-header is
+forbidden.
+
+<a id="ERR_HTTP2_CONNECT_SCHEME"></a>
+### ERR_HTTP2_CONNECT_SCHEME
+
+The HTTP/2 requests using the `CONNECT` method, the `:scheme` pseudo-header is
+forbidden.
+
+<a id="ERR_HTTP2_ERROR"></a>
+### ERR_HTTP2_ERROR
+
+A non-specific HTTP/2 error has occurred.
+
+<a id="ERR_HTTP2_FRAME_ERROR"></a>
+### ERR_HTTP2_FRAME_ERROR
+
+Used when a failure occurs sending an individual frame on the HTTP/2
+session.
+
+<a id="ERR_HTTP2_HEADERS_OBJECT"></a>
+### ERR_HTTP2_HEADERS_OBJECT
+
+Used when an HTTP/2 Headers Object is expected.
+
+<a id="ERR_HTTP2_HEADERS_SENT"></a>
+### ERR_HTTP2_HEADERS_SENT
+
+Used when an attempt is made to send multiple response headers.
+
+<a id="ERR_HTTP2_HEADER_SINGLE_VALUE"></a>
+### ERR_HTTP2_HEADER_SINGLE_VALUE
+
+Used when multiple values have been provided for an HTTP header field that
+required to have only a single value.
+
+<a id="ERR_HTTP2_INFO_HEADERS_AFTER_RESPOND"></a>
+### ERR_HTTP2_INFO_HEADERS_AFTER_RESPOND
+
+HTTP/2 Informational headers must only be sent *prior* to calling the
+`Http2Stream.prototype.respond()` method.
+
+<a id="ERR_HTTP2_INFO_STATUS_NOT_ALLOWED"></a>
+### ERR_HTTP2_INFO_STATUS_NOT_ALLOWED
+
+Informational HTTP status codes (`1xx`) may not be set as the response status
+code on HTTP/2 responses.
+
+<a id="ERR_HTTP2_INVALID_CONNECTION_HEADERS"></a>
+### ERR_HTTP2_INVALID_CONNECTION_HEADERS
+
+HTTP/1 connection specific headers are forbidden to be used in HTTP/2
+requests and responses.
+
+<a id="ERR_HTTP2_INVALID_HEADER_VALUE"></a>
+### ERR_HTTP2_INVALID_HEADER_VALUE
+
+Used to indicate that an invalid HTTP/2 header value has been specified.
+
+<a id="ERR_HTTP2_INVALID_INFO_STATUS"></a>
+### ERR_HTTP2_INVALID_INFO_STATUS
+
+An invalid HTTP informational status code has been specified. Informational
+status codes must be an integer between `100` and `199` (inclusive).
+
+<a id="ERR_HTTP2_INVALID_PACKED_SETTINGS_LENGTH"></a>
+
+Input `Buffer` and `Uint8Array` instances passed to the
+`http2.getUnpackedSettings()` API must have a length that is a multiple of
+six.
+
+<a id="ERR_HTTP2_INVALID_PSEUDOHEADER"></a>
+### ERR_HTTP2_INVALID_PSEUDOHEADER
+
+Only valid HTTP/2 pseudoheaders (`:status`, `:path`, `:authority`, `:scheme`,
+and `:method`) may be used.
+
+<a id="ERR_HTTP2_INVALID_SESSION"></a>
+### ERR_HTTP2_INVALID_SESSION
+
+Used when any action is performed on an `Http2Session` object that has already
+been destroyed.
+
+<a id="ERR_HTTP2_INVALID_SETTING_VALUE"></a>
+### ERR_HTTP2_INVALID_SETTING_VALUE
+
+An invalid value has been specified for an HTTP/2 setting.
+
+<a id="ERR_HTTP2_INVALID_STREAM"></a>
+### ERR_HTTP2_INVALID_STREAM
+
+Used when an operation has been performed on a stream that has already been
+destroyed.
+
+<a id="ERR_HTTP2_MAX_PENDING_SETTINGS_ACK"></a>
+### ERR_HTTP2_MAX_PENDING_SETTINGS_ACK
+
+Whenever an HTTP/2 `SETTINGS` frame is sent to a connected peer, the peer is
+required to send an acknowledgement that it has received and applied the new
+SETTINGS. By default, a maximum number of un-acknowledged `SETTINGS` frame may
+be sent at any given time. This error code is used when that limit has been
+reached.
+
+<a id="ERR_HTTP2_OUT_OF_STREAMS"></a>
+### ERR_HTTP2_OUT_OF_STREAMS
+
+Used when the maximum number of streams on a single HTTP/2 session have been
+created.
+
+<a id="ERR_HTTP2_PAYLOAD_FORBIDDEN"></a>
+### ERR_HTTP2_PAYLOAD_FORBIDDEN
+
+Used when a message payload is specified for an HTTP response code for which
+a payload is forbidden.
+
+<a id="ERR_HTTP2_PSEUDOHEADER_NOT_ALLOWED"></a>
+### ERR_HTTP2_PSEUDOHEADER_NOT_ALLOWED
+
+Used to indicate that an HTTP/2 pseudo-header has been used inappropriately.
+Pseudo-headers are header key names that begin with the `:` prefix.
+
+<a id="ERR_HTTP2_PUSH_DISABLED"></a>
+### ERR_HTTP2_PUSH_DISABLED
+
+Used when push streams have been disabled by the client but an attempt to
+create a push stream is made.
+
+<a id="ERR_HTTP2_SEND_FILE"></a>
+### ERR_HTTP2_SEND_FILE
+
+Used when an attempt is made to use the
+`Http2Stream.prototype.responseWithFile()` API to send a non-regular file.
+
+<a id="ERR_HTTP2_SOCKET_BOUND"></a>
+### ERR_HTTP2_SOCKET_BOUND
+
+Used when an attempt is made to connect a `Http2Session` object to a
+`net.Socket` or `tls.TLSSocket` that has already been bound to another
+`Http2Session` object.
+
+<a id="ERR_HTTP2_STATUS_101"></a>
+### ERR_HTTP2_STATUS_101
+
+Use of the `101` Informational status code is forbidden in HTTP/2.
+
+<a id="ERR_HTTP2_STATUS_INVALID"></a>
+### ERR_HTTP2_STATUS_INVALID
+
+An invalid HTTP status code has been specified. Status codes must be an integer
+between `100` and `599` (inclusive).
+
+<a id="ERR_HTTP2_STREAM_CLOSED"></a>
+### ERR_HTTP2_STREAM_CLOSED
+
+Used when an action has been performed on an HTTP/2 Stream that has already
+been closed.
+
+<a id="ERR_HTTP2_STREAM_ERROR"></a>
+### ERR_HTTP2_STREAM_ERROR
+
+Used when a non-zero error code has been specified in an RST_STREAM frame.
+
+<a id="ERR_HTTP2_STREAM_SELF_DEPENDENCY"></a>
+### ERR_HTTP2_STREAM_SELF_DEPENDENCY
+
+When setting the priority for an HTTP/2 stream, the stream may be marked as
+a dependency for a parent stream. This error code is used when an attempt is
+made to mark a stream and dependent of itself.
+
+<a id="ERR_HTTP2_UNSUPPORTED_PROTOCOL"></a>
+### ERR_HTTP2_UNSUPPORTED_PROTOCOL
+
+Used when `http2.connect()` is passed a URL that uses any protocol other than
+`http:` or `https:`.
+
<a id="ERR_INDEX_OUT_OF_RANGE"></a>
### ERR_INDEX_OUT_OF_RANGE
diff --git a/doc/api/http2.md b/doc/api/http2.md
new file mode 100755
index 0000000000..ca696de81e
--- /dev/null
+++ b/doc/api/http2.md
@@ -0,0 +1,1704 @@
+# HTTP2
+
+> Stability: 1 - Experimental
+
+The `http2` module provides an implementation of the [HTTP/2][] protocol. It
+can be accessed using:
+
+```js
+const http2 = require('http2');
+```
+
+*Note*: Node.js must be launched with the `--expose-http2` command line flag
+in order to use the `'http2'` module.
+
+## Core API
+
+The Core API provides a low-level interface designed specifically around
+support for HTTP/2 protocol features. It is specifically *not* designed for
+compatibility with the existing [HTTP/1][] module API.
+
+The following illustrates a simple, plain-text HTTP/2 server:
+
+```js
+const http2 = require('http2');
+
+// Create a plain-text HTTP/2 server
+const server = http2.createServer();
+
+server.on('stream', (stream, headers) => {
+ stream.respond({
+ 'content-type': 'text/html',
+ ':status': 200
+ });
+ stream.end('<h1>Hello World</h1>');
+});
+
+server.listen(80);
+```
+
+The following illustrates an HTTP/2 client:
+
+```js
+const http2 = require('http2');
+
+const client = http2.connect('http://localhost:80');
+
+const req = client.request({ ':path': '/' });
+
+req.on('response', (headers) => {
+ console.log(headers[':status']);
+ console.log(headers['date']);
+});
+
+let data = '';
+req.setEncoding('utf8');
+req.on('data', (d) => data += d);
+req.on('end', () => client.destroy());
+req.end();
+```
+
+### Class: Http2Session
+<!-- YAML
+added: REPLACEME
+-->
+
+* Extends: {EventEmitter}
+
+Instances of the `http2.Http2Session` class represent an active communications
+session between an HTTP/2 client and server. Instances of this class are *not*
+intended to be constructed directly by user code.
+
+Each `Http2Session` instance will exhibit slightly different behaviors
+depending on whether it is operating as a server or a client. The
+`http2session.type` property can be used to determine the mode in which an
+`Http2Session` is operating. On the server side, user code should rarely
+have occasion to work with the `Http2Session` object directly, with most
+actions typically taken through interactions with either the `Http2Server` or
+`Http2Stream` objects.
+
+#### Http2Session and Sockets
+
+Every `Http2Session` instance is associated with exactly one [`net.Socket`][] or
+[`tls.TLSSocket`][] when it is created. When either the `Socket` or the
+`Http2Session` are destroyed, both will be destroyed.
+
+Because the of the specific serialization and processing requirements imposed
+by the HTTP/2 protocol, it is not recommended for user code to read data from
+or write data to a `Socket` instance bound to a `Http2Session`. Doing so can
+put the HTTP/2 session into an indeterminate state causing the session and
+the socket to become unusable.
+
+Once a `Socket` has been bound to an `Http2Session`, user code should rely
+solely on the API of the `Http2Session`.
+
+#### Event: 'close'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'close'` event is emitted once the `Http2Session` has been terminated.
+
+#### Event: 'connect'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'connect'` event is emitted once the `Http2Session` has been successfully
+connected to the remote peer and communication may begin.
+
+*Note*: User code will typically not listen for this event directly.
+
+#### Event: 'error'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'error'` event is emitted when an error occurs during the processing of
+an `Http2Session`.
+
+#### Event: 'frameError'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'frameError'` event is emitted when an error occurs while attempting to
+send a frame on the session. If the frame that could not be sent is associated
+with a specific `Http2Stream`, an attempt to emit `'frameError'` event on the
+`Http2Stream` is made.
+
+When invoked, the handler function will receive three arguments:
+
+* An integer identifying the frame type.
+* An integer identifying the error code.
+* An integer identifying the stream (or 0 if the frame is not associated with
+ a stream).
+
+If the `'frameError'` event is associated with a stream, the stream will be
+closed and destroyed immediately following the `'frameError'` event. If the
+event is not associated with a stream, the `Http2Session` will be shutdown
+immediately following the `'frameError'` event.
+
+#### Event: 'goaway'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'goaway'` event is emitted when a GOAWAY frame is received. When invoked,
+the handler function will receive three arguments:
+
+* `errorCode` {number} The HTTP/2 error code specified in the GOAWAY frame.
+* `lastStreamID` {number} The ID of the last stream the remote peer successfully
+ processed (or `0` if no ID is specified).
+* `opaqueData` {Buffer} If additional opaque data was included in the GOAWAY
+ frame, a `Buffer` instance will be passed containing that data.
+
+*Note*: The `Http2Session` instance will be shutdown automatically when the
+`'goaway'` event is emitted.
+
+#### Event: 'localSettings'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'localSettings'` event is emitted when an acknowledgement SETTINGS frame
+has been received. When invoked, the handler function will receive a copy of
+the local settings.
+
+*Note*: When using `http2session.settings()` to submit new settings, the
+modified settings do not take effect until the `'localSettings'` event is
+emitted.
+
+```js
+session.settings({ enablePush: false });
+
+session.on('localSettings', (settings) => {
+ /** use the new settings **/
+});
+```
+
+#### Event: 'remoteSettings'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'remoteSettings'` event is emitted when a new SETTINGS frame is received
+from the connected peer. When invoked, the handle function will receive a copy
+of the remote settings.
+
+```js
+session.on('remoteSettings', (settings) => {
+ /** use the new settings **/
+});
+```
+
+#### Event: 'stream'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'stream'` event is emitted when a new `Http2Stream` is created. When
+invoked, the handler function will receive a reference to the `Http2Stream`
+object, a [Headers Object][], and numeric flags associated with the creation
+of the stream.
+
+```js
+const http2 = require('http2');
+const {
+ HTTP2_HEADER_METHOD,
+ HTTP2_HEADER_PATH,
+ HTTP2_HEADER_STATUS,
+ HTTP2_HEADER_CONTENT_TYPE
+} = http2.constants;
+session.on('stream', (stream, headers, flags) => {
+ const method = headers[HTTP2_HEADER_METHOD];
+ const path = headers[HTTP2_HEADER_PATH];
+ // ...
+ stream.respond({
+ [HTTP2_HEADER_STATUS]: 200,
+ [HTTP2_HEADER_CONTENT_TYPE]: 'text/plain'
+ });
+ stream.write('hello ');
+ stream.end('world');
+});
+```
+
+On the server side, user code will typically not listen for this event directly,
+and would instead register a handler for the `'stream'` event emitted by the
+`net.Server` or `tls.Server` instances returned by `http2.createServer()` and
+`http2.createSecureServer()`, respectively, as in the example below:
+
+```js
+const http2 = require('http2');
+
+// Create a plain-text HTTP/2 server
+const server = http2.createServer();
+
+server.on('stream', (stream, headers) => {
+ stream.respond({
+ 'content-type': 'text/html',
+ ':status': 200
+ });
+ stream.end('<h1>Hello World</h1>');
+});
+
+server.listen(80);
+```
+
+#### Event: 'socketError'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'socketError'` event is emitted when an `'error'` is emitted on the
+`Socket` instance bound to the `Http2Session`. If this event is not handled,
+the `'error'` event will be re-emitted on the `Socket`.
+
+Likewise, when an `'error'` event is emitted on the `Http2Session`, a
+`'sessionError'` event will be emitted on the `Socket`. If that event is
+not handled, the `'error'` event will be re-emitted on the `Http2Session`.
+
+#### Event: 'timeout'
+<!-- YAML
+added: REPLACEME
+-->
+
+After the `http2session.setTimeout()` method is used to set the timeout period
+for this `Http2Session`, the `'timeout'` event is emitted if there is no
+activity on the `Http2Session` after the configured number of milliseconds.
+
+```js
+session.setTimeout(2000);
+session.on('timeout', () => { /** .. **/ });
+```
+
+#### http2session.destroy()
+<!-- YAML
+added: REPLACEME
+-->
+
+* Returns: {undefined}
+
+Immediately terminates the `Http2Session` and the associated `net.Socket` or
+`tls.TLSSocket`.
+
+#### http2session.destroyed
+<!-- YAML
+added: REPLACEME
+-->
+
+* Value: {boolean}
+
+Will be `true` if this `Http2Session` instance has been destroyed and must no
+longer be used, otherwise `false`.
+
+#### http2session.localSettings
+<!-- YAML
+added: REPLACEME
+-->
+
+* Value: {[Settings Object][]}
+
+A prototype-less object describing the current local settings of this
+`Http2Session`. The local settings are local to *this* `Http2Session` instance.
+
+#### http2session.pendingSettingsAck
+<!-- YAML
+added: REPLACEME
+-->
+
+* Value: {boolean}
+
+Indicates whether or not the `Http2Session` is currently waiting for an
+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.remoteSettings
+<!-- YAML
+added: REPLACEME
+-->
+
+* Value: {[Settings Object][]}
+
+A prototype-less object describing the current remote settings of this
+`Http2Session`. The remote settings are set by the *connected* HTTP/2 peer.
+
+#### http2session.request(headers[, options])
+<!-- YAML
+added: REPLACEME
+-->
+
+* `headers` {[Headers Object][]}
+* `options` {Object}
+ * `endStream` {boolean} `true` if the `Http2Stream` *writable* side should
+ be closed initially, such as when sending a `GET` request that should not
+ expect a payload body.
+ * `exclusive` {boolean} When `true` and `parent` identifies a parent Stream,
+ the created stream is made the sole direct dependency of the parent, with
+ all other existing dependents made a dependent of the newly created stream.
+ Defaults to `false`.
+ * `parent` {number} Specifies the numeric identifier of a stream the newly
+ created 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).
+* Returns: {ClientHttp2Stream}
+
+For HTTP/2 Client `Http2Session` instances only, the `http2session.request()`
+creates and returns an `Http2Stream` instance that can be used to send an
+HTTP/2 request to the connected server.
+
+This method is only available if `http2session.type` is equal to
+`http2.constants.NGHTTP2_SESSION_CLIENT`.
+
+```js
+const http2 = require('http2');
+const clientSession = http2.connect('https://localhost:1234');
+const {
+ HTTP2_HEADER_PATH,
+ HTTP2_HEADER_STATUS
+} = http2.constants;
+
+const req = clientSession.request({ [HTTP2_HEADER_PATH]: '/' });
+req.on('response', (headers) => {
+ console.log(HTTP2_HEADER_STATUS);
+ req.on('data', (chunk) => { /** .. **/ });
+ req.on('end', () => { /** .. **/ });
+});
+```
+
+#### http2session.rstStream(stream, code)
+<!-- YAML
+added: REPLACEME
+-->
+
+* stream {Http2Stream}
+* code {number} Unsigned 32-bit integer identifying the error code. Defaults to
+ `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)
+<!-- YAML
+added: REPLACEME
+-->
+
+* `msecs` {number}
+* `callback` {Function}
+* Returns: {undefined}
+
+Used to set a callback function that is called when there is no activity on
+the `Http2Session` after `msecs` milliseconds. The given `callback` is
+registered as a listener on the `'timeout'` event.
+
+#### http2session.shutdown(options[, callback])
+<!-- YAML
+added: REPLACEME
+-->
+
+* `options` {Object}
+ * `graceful` {boolean} `true` to attempt a polite shutdown of the
+ `Http2Session`.
+ * `errorCode` {number} The HTTP/2 [error code][] to return. Note that this is
+ *not* the same thing as an HTTP Response Status Code. Defaults to `0x00`
+ (No Error).
+ * `lastStreamID` {number} The Stream ID of the last successfully processed
+ `Http2Stream` on this `Http2Session`.
+ * `opaqueData` {Buffer} A `Buffer` instance containing arbitrary additional
+ data to send to the peer upon disconnection. This is used, typically, to
+ provide additional data for debugging failures, if necessary.
+* `callback` {Function} A callback that is invoked after the session shutdown
+ has been completed.
+* Returns: {undefined}
+
+Attempts to shutdown this `Http2Session` using HTTP/2 defined procedures.
+If specified, the given `callback` function will be invoked once the shutdown
+process has completed.
+
+Note that calling `http2session.shutdown()` does *not* destroy the session or
+tear down the `Socket` connection. It merely prompts both sessions to begin
+preparing to cease activity.
+
+During a "graceful" shutdown, the session will first send a `GOAWAY` frame to
+the connected peer identifying the last processed stream as 2<sup>32</sup>-1.
+Then, on the next tick of the event loop, a second `GOAWAY` frame identifying
+the most recently processed stream identifier is sent. This process allows the
+remote peer to begin preparing for the connection to be terminated.
+
+```js
+session.shutdown({
+ graceful: true,
+ opaqueData: Buffer.from('add some debugging data here')
+}, () => session.destroy());
+```
+
+#### http2session.socket
+<!-- YAML
+added: REPLACEME
+-->
+
+* Value: {net.Socket|tls.TLSSocket}
+
+A reference to the [`net.Socket`][] or [`tls.TLSSocket`][] to which this
+`Http2Session` instance is bound.
+
+*Note*: It is not recommended for user code to interact directly with a
+`Socket` bound to an `Http2Session`. See [Http2Session and Sockets][] for
+details.
+
+#### http2session.state
+<!-- YAML
+added: REPLACEME
+-->
+
+* Value: {Object}
+ * `effectiveLocalWindowSize` {number}
+ * `effectiveRecvDataLength` {number}
+ * `nextStreamID` {number}
+ * `localWindowSize` {number}
+ * `lastProcStreamID` {number}
+ * `remoteWindowSize` {number}
+ * `outboundQueueSize` {number}
+ * `deflateDynamicTableSize` {number}
+ * `inflateDynamicTableSize` {number}
+
+An object describing the current status of this `Http2Session`.
+
+#### http2session.priority(stream, options)
+<!-- YAML
+added: REPLACEME
+-->
+
+* `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. Defaults
+ to `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)
+<!-- YAML
+added: REPLACEME
+-->
+
+* `settings` {[Settings Object][]}
+* Returns {undefined}
+
+Updates the current local settings for this `Http2Session` and sends a new
+`SETTINGS` frame to the connected HTTP/2 peer.
+
+Once called, the `http2session.pendingSettingsAck` property will be `true`
+while the session is waiting for the remote peer to acknowledge the new
+settings.
+
+*Note*: The new settings will not become effective until the SETTINGS
+acknowledgement is received and the `'localSettings'` event is emitted. It
+is possible to send multiple SETTINGS frames while acknowledgement is still
+pending.
+
+#### http2session.type
+<!-- YAML
+added: REPLACEME
+-->
+
+* Value: {number}
+
+The `http2session.type` will be equal to
+`http2.constants.NGHTTP2_SESSION_SERVER` if this `Http2Session` instance is a
+server, and `http2.constants.NGHTTP2_SESSION_CLIENT` if the instance is a
+client.
+
+### Class: Http2Stream
+<!-- YAML
+added: REPLACEME
+-->
+
+* Extends: {Duplex}
+
+Each instance of the `Http2Stream` class represents a bidirectional HTTP/2
+communications stream over an `Http2Session` instance. Any single `Http2Session`
+may have up to 2<sup>31</sup>-1 `Http2Stream` instances over its lifetime.
+
+User code will not construct `Http2Stream` instances directly. Rather, these
+are created, managed, and provided to user code through the `Http2Session`
+instance. On the server, `Http2Stream` instances are created either in response
+to an incoming HTTP request (and handed off to user code via the `'stream'`
+event), or in response to a call to the `http2stream.pushStream()` method.
+On the client, `Http2Stream` instances are created and returned when either the
+`http2session.request()` method is called, or in response to an incoming
+`'push'` event.
+
+*Note*: The `Http2Stream` class is a base for the [`ServerHttp2Stream`][] and
+[`ClientHttp2Stream`][] classes, each of which are used specifically by either
+the Server or Client side, respectively.
+
+All `Http2Stream` instances are [`Duplex`][] streams. The `Writable` side of the
+`Duplex` is used to send data to the connected peer, while the `Readable` side
+is used to receive data sent by the connected peer.
+
+#### Http2Stream Lifecycle
+
+##### Creation
+
+On the server side, instances of [`ServerHttp2Stream`][] are created either
+when:
+
+* A new HTTP/2 `HEADERS` frame with a previously unused stream ID is received;
+* The `http2stream.pushStream()` method is called.
+
+On the client side, instances of [`ClientHttp2Stream`[] are created when the
+`http2session.request()` method is called.
+
+*Note*: On the client, the `Http2Stream` instance returned by
+`http2session.request()` may not be immediately ready for use if the parent
+`Http2Session` has not yet been fully established. In such cases, operations
+called on the `Http2Stream` will be buffered until the `'ready'` event is
+emitted. User code should rarely, if ever, have need to handle the `'ready'`
+event directly. The ready status of an `Http2Stream` can be determined by
+checking the value of `http2stream.id`. If the value is `undefined`, the stream
+is not yet ready for use.
+
+##### Destruction
+
+All [`Http2Stream`][] instances are destroyed either when:
+
+* An `RST_STREAM` frame for the stream is received by the connected peer.
+* The `http2stream.rstStream()` or `http2session.rstStream()` methods are
+ called.
+* The `http2stream.destroy()` or `http2session.destroy()` methods are called.
+
+When an `Http2Stream` instance is destroyed, an attempt will be made to send an
+`RST_STREAM` frame will be sent to the connected peer.
+
+Once the `Http2Stream` instance is destroyed, the `'streamClosed'` event will
+be emitted. Because `Http2Stream` is an instance of `stream.Duplex`, the
+`'end'` event will also be emitted if the stream data is currently flowing.
+The `'error'` event may also be emitted if `http2stream.destroy()` was called
+with an `Error` passed as the first argument.
+
+After the `Http2Stream` has been destroyed, the `http2stream.destroyed`
+property will be `true` and the `http2stream.rstCode` property will specify the
+`RST_STREAM` error code. The `Http2Stream` instance is no longer usable once
+destroyed.
+
+#### Event: 'aborted'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'aborted'` event is emitted whenever a `Http2Stream` instance is
+abnormally aborted in mid-communication.
+
+*Note*: The `'aborted'` event will only be emitted if the `Http2Stream`
+writable side has not been ended.
+
+#### Event: 'error'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'error'` event is emitted when an error occurs during the processing of
+an `Http2Stream`.
+
+#### Event: 'fetchTrailers'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'fetchTrailers'` event is emitted by the `Http2Stream` immediately after
+queuing the last chunk of payload data to be sent. The listener callback is
+passed a single object (with a `null` prototype) that the listener may used
+to specify the trailing header fields to send to the peer.
+
+```js
+stream.on('fetchTrailers', (trailers) => {
+ trailers['ABC'] = 'some value to send';
+});
+```
+
+*Note*: The HTTP/1 specification forbids trailers from containing HTTP/2
+"pseudo-header" fields (e.g. `':status'`, `':path'`, etc). An `'error'` event
+will be emitted if the `'fetchTrailers'` event handler attempts to set such
+header fields.
+
+#### Event: 'frameError'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'frameError'` event is emitted when an error occurs while attempting to
+send a frame. When invoked, the handler function will receive an integer
+argument identifying the frame type, and an integer argument identifying the
+error code. The `Http2Stream` instance will be destroyed immediately after the
+`'frameError'` event is emitted.
+
+#### Event: 'streamClosed'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'streamClosed'` event is emitted when the `Http2Stream` is destroyed. Once
+this event is emitted, the `Http2Stream` instance is no longer usable.
+
+The listener callback is passed a single argument specifying the HTTP/2 error
+code specified when closing the stream. If the code is any value other than
+`NGHTTP2_NO_ERROR` (`0`), an `'error'` event will also be emitted.
+
+#### Event: 'timeout'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'timeout'` event is emitted after no activity is received for this
+`'Http2Stream'` within the number of millseconds set using
+`http2stream.setTimeout()`.
+
+#### Event: 'trailers'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'trailers'` event is emitted when a block of headers associated with
+trailing header fields is received. The listener callback is passed the
+[Headers Object][] and flags associated with the headers.
+
+```js
+stream.on('trailers', (headers, flags) => {
+ console.log(headers);
+});
+```
+
+#### http2stream.aborted
+<!-- YAML
+added: REPLACEME
+-->
+
+* Value: {boolean}
+
+Set to `true` if the `Http2Stream` instance was aborted abnormally. When set,
+the `'aborted'` event will have been emitted.
+
+#### http2stream.destroyed
+<!-- YAML
+added: REPLACEME
+-->
+
+* Value: {boolean}
+
+Set to `true` if the `Http2Stream` instance has been destroyed and is no longer
+usable.
+
+#### http2stream.priority(options)
+<!-- YAML
+added: REPLACEME
+-->
+
+* `options` {Object}
+ * `exclusive` {boolean} When `true` and `parent` identifies a parent Stream,
+ this stream is made the sole direct dependency of the parent, with
+ all other existing dependents made a dependent of this stream. Defaults
+ to `false`.
+ * `parent` {number} Specifies the numeric identifier of a stream this 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 this `Http2Stream` instance.
+
+#### http2stream.rstCode
+<!-- YAML
+added: REPLACEME
+-->
+
+* Value: {number}
+
+Set to the `RST_STREAM` [error code][] reported when the `Http2Stream` is
+destroyed after either receiving an `RST_STREAM` frame from the connected peer,
+calling `http2stream.rstStream()`, or `http2stream.destroy()`. Will be
+`undefined` if the `Http2Stream` has not been closed.
+
+#### http2stream.rstStream(code)
+<!-- YAML
+added: REPLACEME
+-->
+
+* code {number} Unsigned 32-bit integer identifying the error code. Defaults to
+ `http2.constant.NGHTTP2_NO_ERROR` (`0x00`)
+* Returns: {undefined}
+
+Sends an `RST_STREAM` frame to the connected HTTP/2 peer, causing this
+`Http2Stream` to be closed on both sides using [error code][] `code`.
+
+#### http2stream.rstWithNoError()
+<!-- YAML
+added: REPLACEME
+-->
+
+* Returns: {undefined}
+
+Shortcut for `http2stream.rstStream()` using error code `0x00` (No Error).
+
+#### http2stream.rstWithProtocolError() {
+<!-- YAML
+added: REPLACEME
+-->
+
+* Returns: {undefined}
+
+Shortcut for `http2stream.rstStream()` using error code `0x01` (Protocol Error).
+
+#### http2stream.rstWithCancel() {
+<!-- YAML
+added: REPLACEME
+-->
+
+* Returns: {undefined}
+
+Shortcut for `http2stream.rstStream()` using error code `0x08` (Cancel).
+
+#### http2stream.rstWithRefuse() {
+<!-- YAML
+added: REPLACEME
+-->
+
+* Returns: {undefined}
+
+Shortcut for `http2stream.rstStream()` using error code `0x07` (Refused Stream).
+
+#### http2stream.rstWithInternalError() {
+<!-- YAML
+added: REPLACEME
+-->
+
+* Returns: {undefined}
+
+Shortcut for `http2stream.rstStream()` using error code `0x02` (Internal Error).
+
+#### http2stream.session
+<!-- YAML
+added: REPLACEME
+-->
+
+* Value: {Http2Sesssion}
+
+A reference to the `Http2Session` instance that owns this `Http2Stream`. The
+value will be `undefined` after the `Http2Stream` instance is destroyed.
+
+#### http2stream.setTimeout(msecs, callback)
+<!-- YAML
+added: REPLACEME
+-->
+
+* `msecs` {number}
+* `callback` {Function}
+* Returns: {undefined}
+
+```js
+const http2 = require('http2');
+const client = http2.connect('http://example.org:8000');
+
+const req = client.request({ ':path': '/' });
+
+// Cancel the stream if there's no activity after 5 seconds
+req.setTimeout(5000, () => req.rstStreamWithCancel());
+```
+
+#### http2stream.state
+<!-- YAML
+added: REPLACEME
+-->
+
+* Value: {Object}
+ * `localWindowSize` {number}
+ * `state` {number}
+ * `streamLocalClose` {number}
+ * `streamRemoteClose` {number}
+ * `sumDependencyWeight` {number}
+ * `weight` {number}
+
+A current state of this `Http2Stream`.
+
+### Class: ClientHttp2Stream
+<!-- YAML
+added: REPLACEME
+-->
+
+* Extends {Http2Stream}
+
+The `ClientHttp2Stream` class is an extension of `Http2Stream` that is
+used exclusively on HTTP/2 Clients. `Http2Stream` instances on the client
+provide events such as `'response'` and `'push'` that are only relevant on
+the client.
+
+#### Event: 'headers'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'headers'` event is emitted when an additional block of headers is received
+for a stream, such as when a block of `1xx` informational headers are received.
+The listener callback is passed the [Headers Object][] and flags associated with
+the headers.
+
+```js
+stream.on('headers', (headers, flags) => {
+ console.log(headers);
+});
+```
+
+#### Event: 'push'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'push'` event is emitted when response headers for a Server Push stream
+are received. The listener callback is passed the [Headers Object][] and flags
+associated with the headers.
+
+```js
+stream.on('push', (headers, flags) => {
+ console.log(headers);
+});
+```
+
+#### Event: 'response'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'response'` event is emitted when a response `HEADERS` frame has been
+received for this stream from the connected HTTP/2 server. The listener is
+invoked with two arguments: an Object containing the received
+[Headers Object][], and flags associated with the headers.
+
+For example:
+
+```js
+const http2 = require('http');
+const client = http2.connect('https://localhost');
+const req = client.request({ ':path': '/' });
+req.on('response', (headers, flags) => {
+ console.log(headers[':status']);
+});
+```
+
+### Class: ServerHttp2Stream
+<!-- YAML
+added: REPLACEME
+-->
+
+* Extends: {Http2Stream}
+
+The `ServerHttp2Stream` class is an extension of [`Http2Stream`][] that is
+used exclusively on HTTP/2 Servers. `Http2Stream` instances on the server
+provide additional methods such as `http2stream.pushStream()` and
+`http2stream.respond()` that are only relevant on the server.
+
+#### http2stream.additionalHeaders(headers)
+<!-- YAML
+added: REPLACEME
+-->
+
+* `headers` {[Headers Object][]}
+* Returns: {undefined}
+
+Sends an additional informational `HEADERS` frame to the connected HTTP/2 peer.
+
+#### http2stream.headersSent
+<!-- YAML
+added: REPLACEME
+-->
+
+* Value: {boolean}
+
+Boolean (read-only). True if headers were sent, false otherwise.
+
+#### http2stream.pushAllowed
+<!-- YAML
+added: REPLACEME
+-->
+
+* Value: {boolean}
+
+Read-only property mapped to the `SETTINGS_ENABLE_PUSH` flag of the remote
+client's most recent `SETTINGS` frame. Will be `true` if the remote peer
+accepts push streams, `false` otherwise. Settings are the same for every
+`Http2Stream` in the same `Http2Session`.
+
+#### http2stream.pushStream(headers[, options], callback)
+<!-- YAML
+added: REPLACEME
+-->
+
+* `headers` {[Headers Object][]}
+* `options` {Object}
+ * `exclusive` {boolean} When `true` and `parent` identifies a parent Stream,
+ the created stream is made the sole direct dependency of the parent, with
+ all other existing dependents made a dependent of the newly created stream.
+ Defaults to `false`.
+ * `parent` {number} Specifies the numeric identifier of a stream the newly
+ created 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).
+* `callback` {Function} Callback that is called once the push stream has been
+ initiated.
+* Returns: {undefined}
+
+Initiates a push stream. The callback is invoked with the new `Htt2Stream`
+instance created for the push stream.
+
+```js
+const http2 = require('http2');
+const server = http2.createServer();
+server.on('stream', (stream) => {
+ stream.respond({ ':status': 200 });
+ stream.pushStream({ ':path': '/' }, (pushStream) => {
+ pushStream.respond({ ':status': 200 });
+ pushStream.end('some pushed data');
+ });
+ stream.end('some data');
+});
+```
+
+#### http2stream.respond([headers[, options]])
+<!-- YAML
+added: REPLACEME
+-->
+
+* `headers` {[Headers Object][]}
+* `options` {Object}
+ * `endStream` {boolean} Set to `true` to indicate that the response will not
+ include payload data.
+* Returns: {undefined}
+
+```js
+const http2 = require('http2');
+const server = http2.createServer();
+server.on('stream', (stream) => {
+ stream.respond({ ':status': 200 });
+ stream.end('some data');
+});
+```
+
+#### http2stream.respondWithFD(fd[, headers])
+<!-- YAML
+added: REPLACEME
+-->
+
+* `fd` {number} A readable file descriptor
+* `headers` {[Headers Object][]}
+
+Initiates a response whose data is read from the given file descriptor. No
+validation is performed on the given file descriptor. If an error occurs while
+attempting to read data using the file descriptor, the `Http2Stream` will be
+closed using an `RST_STREAM` frame using the standard `INTERNAL_ERROR` code.
+
+When used, the `Http2Stream` object's Duplex interface will be closed
+automatically. HTTP trailer fields cannot be sent. The `'fetchTrailers'` event
+will *not* be emitted.
+
+```js
+const http2 = require('http2');
+const fs = require('fs');
+
+const fd = fs.openSync('/some/file', 'r');
+
+const server = http2.createServer();
+server.on('stream', (stream) => {
+ const stat = fs.fstatSync(fd);
+ const headers = {
+ 'content-length': stat.size,
+ 'last-modified': stat.mtime.toUTCString(),
+ 'content-type': 'text/plain'
+ };
+ stream.respondWithFD(fd, headers);
+});
+server.on('close', () => fs.closeSync(fd));
+```
+
+#### http2stream.respondWithFile(path[, headers[, options]])
+<!-- YAML
+added: REPLACEME
+-->
+
+* `path` {string|Buffer|URL}
+* `headers` {[Headers Object][]}
+* `options` {Object}
+ * `statCheck` {Function}
+
+Sends a regular file as the response. The `path` must specify a regular file
+or an `'error'` event will be emitted on the `Http2Stream` object.
+
+When used, the `Http2Stream` object's Duplex interface will be closed
+automatically. HTTP trailer fields cannot be sent. The `'fetchTrailers'` event
+will *not* be emitted.
+
+The optional `options.statCheck` function may be specified to give user code
+an opportunity to set additional content headers based on the `fs.Stat` details
+of the given file:
+
+If an error occurs while attempting to read the file data, the `Http2Stream`
+will be closed using an `RST_STREAM` frame using the standard `INTERNAL_ERROR`
+code.
+
+Example using a file path:
+
+```js
+const http2 = require('http2');
+const server = http2.createServer();
+server.on('stream', (stream) => {
+ function statCheck(stat, headers) {
+ headers['last-modified'] = stat.mtime.toUTCString();
+ }
+ stream.respondWithFile('/some/file',
+ { 'content-type': 'text/plain' },
+ { statCheck });
+});
+```
+
+The `options.statCheck` function may also be used to cancel the send operation
+by returning `false`. For instance, a conditional request may check the stat
+results to determine if the file has been modified to return an appropriate
+`304` response:
+
+```js
+const http2 = require('http2');
+const server = http2.createServer();
+server.on('stream', (stream) => {
+ function statCheck(stat, headers) {
+ // Check the stat here...
+ stream.respond({ ':status': 304 });
+ return false; // Cancel the send operation
+ }
+ stream.respondWithFile('/some/file',
+ { 'content-type': 'text/plain' },
+ { statCheck });
+});
+```
+
+The `content-length` header field will be automatically set.
+
+### Class: Http2Server
+<!-- YAML
+added: REPLACEME
+-->
+
+* Extends: {net.Server}
+
+#### Event: 'sessionError'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'sessionError'` event is emitted when an `'error'` event is emitted by
+an `Http2Session` object. If no listener is registered for this event, an
+`'error'` event is emitted.
+
+#### Event: 'socketError'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'socketError'` event is emitted when an `'error'` event is emitted by
+a `Socket` associated with the server. If no listener is registered for this
+event, an `'error'` event is emitted.
+
+#### Event: 'stream'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'stream'` event is emitted when a `'stream'` event has been emitted by
+an `Http2Session` associated with the server.
+
+```js
+const http2 = require('http2');
+const {
+ HTTP2_HEADER_METHOD,
+ HTTP2_HEADER_PATH,
+ HTTP2_HEADER_STATUS,
+ HTTP2_HEADER_CONTENT_TYPE
+} = http2.constants;
+
+const server = http.createServer();
+server.on('stream', (stream, headers, flags) => {
+ const method = headers[HTTP2_HEADER_METHOD];
+ const path = headers[HTTP2_HEADER_PATH];
+ // ...
+ stream.respond({
+ [HTTP2_HEADER_STATUS]: 200,
+ [HTTP2_HEADER_CONTENT_TYPE]: 'text/plain'
+ });
+ stream.write('hello ');
+ stream.end('world');
+});
+```
+
+#### Event: 'timeout'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'timeout'` event is emitted when there is no activity on the Server for
+a given number of milliseconds set using `http2server.setTimeout()`.
+
+### Class: Http2SecureServer
+<!-- YAML
+added: REPLACEME
+-->
+
+* Extends: {tls.Server}
+
+#### Event: 'sessionError'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'sessionError'` event is emitted when an `'error'` event is emitted by
+an `Http2Session` object. If no listener is registered for this event, an
+`'error'` event is emitted on the `Http2Session` instance instead.
+
+#### Event: 'socketError'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'socketError'` event is emitted when an `'error'` event is emitted by
+a `Socket` associated with the server. If no listener is registered for this
+event, an `'error'` event is emitted on the `Socket` instance instead.
+
+#### Event: 'unknownProtocol'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'unknownProtocol'` event is emitted when a connecting client fails to
+negotiate an allowed protocol (i.e. HTTP/2 or HTTP/1.1). The event handler
+receives the socket for handling. If no listener is registered for this event,
+the connection is terminated. See the
+
+#### Event: 'stream'
+<!-- YAML
+added: REPLACEME
+-->
+
+The `'stream'` event is emitted when a `'stream'` event has been emitted by
+an `Http2Session` associated with the server.
+
+```js
+const http2 = require('http2');
+const {
+ HTTP2_HEADER_METHOD,
+ HTTP2_HEADER_PATH,
+ HTTP2_HEADER_STATUS,
+ HTTP2_HEADER_CONTENT_TYPE
+} = http2.constants;
+
+const options = getOptionsSomehow();
+
+const server = http.createSecureServer(options);
+server.on('stream', (stream, headers, flags) => {
+ const method = headers[HTTP2_HEADER_METHOD];
+ const path = headers[HTTP2_HEADER_PATH];
+ // ...
+ stream.respond({
+ [HTTP2_HEADER_STATUS]: 200,
+ [HTTP2_HEADER_CONTENT_TYPE]: 'text/plain'
+ });
+ stream.write('hello ');
+ stream.end('world');
+});
+```
+
+#### Event: 'timeout'
+<!-- YAML
+added: REPLACEME
+-->
+
+### http2.createServer(options[, onRequestHandler])
+<!-- YAML
+added: REPLACEME
+-->
+
+* `options` {Object}
+ * `maxDeflateDynamicTableSize` {number} Sets the maximum dynamic table size
+ for deflating header fields. Defaults to 4Kib.
+ * `maxSendHeaderBlockLength` {number} Sets the maximum allowed size for a
+ serialized, compressed block of headers. Attempts to send headers that
+ exceed this limit will result in a `'frameError'` event being emitted
+ and the stream being closed and destroyed.
+ * `paddingStrategy` {number} Identifies the strategy used for determining the
+ amount of padding to use for HEADERS and DATA frames. Defaults to
+ `http2.constants.PADDING_STRATEGY_NONE`. Value may be one of:
+ * `http2.constants.PADDING_STRATEGY_NONE` - Specifies that no padding is
+ to be applied.
+ * `http2.constants.PADDING_STRATEGY_MAX` - Specifies that the maximum
+ amount of padding, as determined by the internal implementation, is to
+ be applied.
+ * `http2.constants.PADDING_STRATEGY_CALLBACK` - Specifies that the user
+ provided `options.selectPadding` callback is to be used to determine the
+ amount of padding.
+ * `peerMaxConcurrentStreams` {number} Sets the maximum number of concurrent
+ streams for the remote peer as if a SETTINGS frame had been received. Will
+ be overridden if the remote peer sets its own value for
+ `maxConcurrentStreams`. Defaults to 100.
+ * `selectPadding` {Function} When `options.paddingStrategy` is equal to
+ `http2.constants.PADDING_STRATEGY_CALLBACK`, provides the callback function
+ used to determine the padding. See [Using options.selectPadding][].
+ * `settings` {[Settings Object][]} The initial settings to send to the
+ remote peer upon connection.
+* `onRequestHandler` {Function} See [Compatibility API][]
+* Returns: {Http2Server}
+
+Returns a `net.Server` instance that creates and manages `Http2Session`
+instances.
+
+```js
+const http2 = require('http2');
+
+// Create a plain-text HTTP/2 server
+const server = http2.createServer();
+
+server.on('stream', (stream, headers) => {
+ stream.respond({
+ 'content-type': 'text/html',
+ ':status': 200
+ });
+ stream.end('<h1>Hello World</h1>');
+});
+
+server.listen(80);
+```
+
+### http2.createSecureServer(options[, onRequestHandler])
+<!-- YAML
+added: REPLACEME
+-->
+
+* `options` {Object}
+ * `allowHTTP1` {boolean} Incoming client connections that do not support
+ HTTP/2 will be downgraded to HTTP/1.x when set to `true`. The default value
+ is `false`. See the [`'unknownProtocol'`][] event.
+ * `maxDeflateDynamicTableSize` {number} Sets the maximum dynamic table size
+ for deflating header fields. Defaults to 4Kib.
+ * `maxSendHeaderBlockLength` {number} Sets the maximum allowed size for a
+ serialized, compressed block of headers. Attempts to send headers that
+ exceed this limit will result in a `'frameError'` event being emitted
+ and the stream being closed and destroyed.
+ * `paddingStrategy` {number} Identifies the strategy used for determining the
+ amount of padding to use for HEADERS and DATA frames. Defaults to
+ `http2.constants.PADDING_STRATEGY_NONE`. Value may be one of:
+ * `http2.constants.PADDING_STRATEGY_NONE` - Specifies that no padding is
+ to be applied.
+ * `http2.constants.PADDING_STRATEGY_MAX` - Specifies that the maximum
+ amount of padding, as determined by the internal implementation, is to
+ be applied.
+ * `http2.constants.PADDING_STRATEGY_CALLBACK` - Specifies that the user
+ provided `options.selectPadding` callback is to be used to determine the
+ amount of padding.
+ * `peerMaxConcurrentStreams` {number} Sets the maximum number of concurrent
+ streams for the remote peer as if a SETTINGS frame had been received. Will
+ be overridden if the remote peer sets its own value for
+ `maxConcurrentStreams`. Defaults to 100.
+ * `selectPadding` {Function} When `options.paddingStrategy` is equal to
+ `http2.constants.PADDING_STRATEGY_CALLBACK`, provides the callback function
+ used to determine the padding. See [Using options.selectPadding][].
+ * `settings` {[Settings Object][]} The initial settings to send to the
+ remote peer upon connection.
+ * ...: Any [`tls.createServer()`][] options can be provided. For
+ servers, the identity options (`pfx` or `key`/`cert`) are usually required.
+* `onRequestHandler` {Function} See [Compatibility API][]
+* Returns {Http2SecureServer}
+
+Returns a `tls.Server` instance that creates and manages `Http2Session`
+instances.
+
+```js
+const http2 = require('http2');
+
+const options = {
+ key: fs.readFileSync('server-key.pem'),
+ cert: fs.readFileSync('server-cert.pem')
+};
+
+// Create a plain-text HTTP/2 server
+const server = http2.createSecureServer(options);
+
+server.on('stream', (stream, headers) => {
+ stream.respond({
+ 'content-type': 'text/html',
+ ':status': 200
+ });
+ stream.end('<h1>Hello World</h1>');
+});
+
+server.listen(80);
+```
+
+### http2.connect(authority[, options][, listener])
+<!-- YAML
+added: REPLACEME
+-->
+
+* `authority` {string|URL}
+* `options` {Object}
+ * `maxDeflateDynamicTableSize` {number} Sets the maximum dynamic table size
+ for deflating header fields. Defaults to 4Kib.
+ * `maxReservedRemoteStreams` {number} Sets the maximum number of reserved push
+ streams the client will accept at any given time. Once the current number of
+ currently reserved push streams exceeds reaches this limit, new push streams
+ sent by the server will be automatically rejected.
+ * `maxSendHeaderBlockLength` {number} Sets the maximum allowed size for a
+ serialized, compressed block of headers. Attempts to send headers that
+ exceed this limit will result in a `'frameError'` event being emitted
+ and the stream being closed and destroyed.
+ * `paddingStrategy` {number} Identifies the strategy used for determining the
+ amount of padding to use for HEADERS and DATA frames. Defaults to
+ `http2.constants.PADDING_STRATEGY_NONE`. Value may be one of:
+ * `http2.constants.PADDING_STRATEGY_NONE` - Specifies that no padding is
+ to be applied.
+ * `http2.constants.PADDING_STRATEGY_MAX` - Specifies that the maximum
+ amount of padding, as determined by the internal implementation, is to
+ be applied.
+ * `http2.constants.PADDING_STRATEGY_CALLBACK` - Specifies that the user
+ provided `options.selectPadding` callback is to be used to determine the
+ amount of padding.
+ * `peerMaxConcurrentStreams` {number} Sets the maximum number of concurrent
+ streams for the remote peer as if a SETTINGS frame had been received. Will
+ be overridden if the remote peer sets its own value for
+ `maxConcurrentStreams`. Defaults to 100.
+ * `selectPadding` {Function} When `options.paddingStrategy` is equal to
+ `http2.constants.PADDING_STRATEGY_CALLBACK`, provides the callback function
+ used to determine the padding. See [Using options.selectPadding][].
+ * `settings` {[Settings Object][]} The initial settings to send to the
+ remote peer upon connection.
+* `listener` {Function}
+* Returns {Http2Session}
+
+Returns a HTTP/2 client `Http2Session` instance.
+
+```js
+const http2 = require('http2');
+const client = http2.connect('https://localhost:1234');
+
+/** use the client **/
+
+client.destroy();
+```
+
+### http2.constants
+<!-- YAML
+added: REPLACEME
+-->
+
+#### Error Codes for RST_STREAM and GOAWAY
+<a id="error_codes"></a>
+
+| Value | Name | Constant |
+|-------|---------------------|-----------------------------------------------|
+| 0x00 | No Error | `http2.constants.NGHTTP2_NO_ERROR` |
+| 0x01 | Protocol Error | `http2.constants.NGHTTP2_PROTOCOL_ERROR` |
+| 0x02 | Internal Error | `http2.constants.NGHTTP2_INTERNAL_ERROR` |
+| 0x03 | Flow Control Error | `http2.constants.NGHTTP2_FLOW_CONTROL_ERROR` |
+| 0x04 | Settings Timeout | `http2.constants.NGHTTP2_SETTINGS_TIMEOUT` |
+| 0x05 | Stream Closed | `http2.constants.NGHTTP2_STREAM_CLOSED` |
+| 0x06 | Frame Size Error | `http2.constants.NGHTTP2_FRAME_SIZE_ERROR` |
+| 0x07 | Refused Stream | `http2.constants.NGHTTP2_REFUSED_STREAM` |
+| 0x08 | Cancel | `http2.constants.NGHTTP2_CANCEL` |
+| 0x09 | Compression Error | `http2.constants.NGHTTP2_COMPRESSION_ERROR` |
+| 0x0a | Connect Error | `http2.constants.NGHTTP2_CONNECT_ERROR` |
+| 0x0b | Enhance Your Calm | `http2.constants.NGHTTP2_ENHANCE_YOUR_CALM` |
+| 0x0c | Inadequate Security | `http2.constants.NGHTTP2_INADEQUATE_SECURITY` |
+| 0x0d | HTTP/1.1 Required | `http2.constants.NGHTTP2_HTTP_1_1_REQUIRED` |
+
+The `'timeout'` event is emitted when there is no activity on the Server for
+a given number of milliseconds set using `http2server.setTimeout()`.
+
+### http2.getDefaultSettings()
+<!-- YAML
+added: REPLACEME
+-->
+
+* Returns: {[Settings Object][]}
+
+Returns an object containing the default settings for an `Http2Session`
+instance. This method returns a new object instance every time it is called
+so instances returned may be safely modified for use.
+
+### http2.getPackedSettings(settings)
+<!-- YAML
+added: REPLACEME
+-->
+
+* `settings` {[Settings Object][]}
+* Returns: {Buffer}
+
+Returns a [Buffer][] instance containing serialized representation of the given
+HTTP/2 settings as specified in the [HTTP/2][] specification. This is intended
+for use with the `HTTP2-Settings` header field.
+
+```js
+const http2 = require('http2');
+
+const packed = http2.getPackedSettings({ enablePush: false });
+
+console.log(packed.toString('base64'));
+// Prints: AAIAAAAA
+```
+
+### http2.getUnpackedSettings(buf)
+<!-- YAML
+added: REPLACEME
+-->
+
+* `buf` {Buffer|Uint8Array} The packed settings
+* Returns: {[Settings Object][]}
+
+Returns a [Settings Object][] containing the deserialized settings from the
+given `Buffer` as generated by `http2.getPackedSettings()`.
+
+### Headers Object
+
+Headers are represented as own-properties on JavaScript objects. The property
+keys will be serialized to lower-case. Property values should be strings (if
+they are not they will be coerced to strings) or an Array of strings (in order
+to send more than one value per header field).
+
+For example:
+
+```js
+const headers = {
+ ':status': '200',
+ 'content-type': 'text-plain',
+ 'ABC': ['has', 'more', 'than', 'one', 'value']
+};
+
+stream.respond(headers);
+```
+
+*Note*: Header objects passed to callback functions will have a `null`
+prototype. This means that normal JavaScript object methods such as
+`Object.prototype.toString()` and `Object.prototype.hasOwnProperty()` will
+not work.
+
+```js
+const http2 = require('http2');
+const server = http2.createServer();
+server.on('stream', (stream, headers) => {
+ console.log(headers[':path']);
+ console.log(headers.ABC);
+});
+```
+
+### Settings Object
+
+The `http2.getDefaultSettings()`, `http2.getPackedSettings()`,
+`http2.createServer()`, `http2.createSecureServer()`,
+`http2session.settings()`, `http2session.localSettings`, and
+`http2session.remoteSettings` APIs either return or receive as input an
+object that defines configuration settings for an `Http2Session` object.
+These objects are ordinary JavaScript objects containing the following
+properties.
+
+* `headerTableSize` {number} Specifies the maximum number of bytes used for
+ header compression. The default value is 4,096 octets. The minimum allowed
+ value is 0. The maximum allowed value is 2<sup>32</sup>-1.
+* `enablePush` {boolean} Specifies `true` if HTTP/2 Push Streams are to be
+ permitted on the `Http2Session` instances.
+* `initialWindowSize` {number} Specifies the *senders* initial window size
+ for stream-level flow control. The default value is 65,535 bytes. The minimum
+ allowed value is 0. The maximum allowed value is 2<sup>32</sup>-1.
+* `maxFrameSize` {number} Specifies the size of the largest frame payload.
+ The default and the minimum allowed value is 16,384 bytes. The maximum
+ allowed value is 2<sup>24</sup>-1.
+* `maxConcurrentStreams` {number} Specifies the maximum number of concurrent
+ streams permitted on an `Http2Session`. There is no default value which
+ implies, at least theoretically, 2<sup>31</sup>-1 streams may be open
+ concurrently at any given time in an `Http2Session`. The minimum value is
+ 0. The maximum allowed value is 2<sup>31</sup>-1.
+* `maxHeaderListSize` {number} Specifies the maximum size (uncompressed octets)
+ of header list that will be accepted. There is no default value. The minimum
+ allowed value is 0. The maximum allowed value is 2<sup>32</sup>-1.
+
+All additional properties on the settings object are ignored.
+
+### Using `options.selectPadding`
+
+When `options.paddingStrategy` is equal to
+`http2.constants.PADDING_STRATEGY_CALLBACK`, the the HTTP/2 implementation will
+consult the `options.selectPadding` callback function, if provided, to determine
+the specific amount of padding to use per HEADERS and DATA frame.
+
+The `options.selectPadding` function receives two numeric arguments,
+`frameLen` and `maxFrameLen` and must return a number `N` such that
+`frameLen <= N <= maxFrameLen`.
+
+```js
+const http2 = require('http2');
+const server = http2.createServer({
+ paddingStrategy: http2.constants.PADDING_STRATEGY_CALLBACK,
+ selectPadding(frameLen, maxFrameLen) {
+ return maxFrameLen;
+ }
+});
+```
+
+*Note*: The `options.selectPadding` function is invoked once for *every*
+HEADERS and DATA frame. This has a definite noticeable impact on
+performance.
+
+### Error Handling
+
+There are several types of error conditions that may arise when using the
+`http2` module:
+
+Validation Errors occur when an incorrect argument, option or setting value is
+passed in. These will always be reported by a synchronous `throw`.
+
+State Errors occur when an action is attempted at an incorrect time (for
+instance, attempting to send data on a stream after it has closed). These will
+be repoorted using either a synchronous `throw` or via an `'error'` event on
+the `Http2Stream`, `Http2Session` or HTTP/2 Server objects, depending on where
+and when the error occurs.
+
+Internal Errors occur when an HTTP/2 session fails unexpectedly. These will be
+reported via an `'error'` event on the `Http2Session` or HTTP/2 Server objects.
+
+Protocol Errors occur when various HTTP/2 protocol constraints are violated.
+These will be reported using either a synchronous `throw` or via an `'error'`
+event on the `Http2Stream`, `Http2Session` or HTTP/2 Server objects, depending
+on where and when the error occurs.
+
+### Push streams on the client
+
+To receive pushed streams on the client, set a listener for the `'stream'`
+event on the `ClientHttp2Session`:
+
+```js
+const http2 = require('http2');
+
+const client = http2.connect('http://localhost');
+
+client.on('stream', (pushedStream, requestHeaders) => {
+ pushedStream.on('push', (responseHeaders) => {
+ // process response headers
+ });
+ pushedStream.on('data', (chunk) => { /* handle pushed data */ });
+});
+
+const req = client.request({ ':path': '/' });
+```
+
+### Supporting the CONNECT method
+
+The `CONNECT` method is used to allow an HTTP/2 server to be used as a proxy
+for TCP/IP connections.
+
+A simple TCP Server:
+```js
+const net = require('net');
+
+const server = net.createServer((socket) => {
+ let name = '';
+ socket.setEncoding('utf8');
+ socket.on('data', (chunk) => name += chunk);
+ socket.on('end', () => socket.end(`hello ${name}`));
+});
+
+server.listen(8000);
+```
+
+An HTTP/2 CONNECT proxy:
+
+```js
+const http2 = require('http2');
+const net = require('net');
+const { URL } = require('url');
+
+const proxy = http2.createServer();
+proxy.on('stream', (stream, headers) => {
+ if (headers[':method'] !== 'CONNECT') {
+ // Only accept CONNECT requests
+ stream.rstWithRefused();
+ return;
+ }
+ const auth = new URL(`tcp://${headers[':authority']}`);
+ // It's a very good idea to verify that hostname and port are
+ // things this proxy should be connecting to.
+ const socket = net.connect(auth.port, auth.hostname, () => {
+ stream.respond();
+ socket.pipe(stream);
+ stream.pipe(socket);
+ });
+ socket.on('error', (error) => {
+ stream.rstStream(http2.constants.NGHTTP2_CONNECT_ERROR);
+ });
+});
+
+proxy.listen(8001);
+```
+
+An HTTP/2 CONNECT client:
+
+```js
+const http2 = require('http2');
+
+const client = http2.connect('http://localhost:8001');
+
+// Must not specify the ':path' and ':scheme' headers
+// for CONNECT requests or an error will be thrown.
+const req = client.request({
+ ':method': 'CONNECT',
+ ':authority': `localhost:${port}`
+});
+
+req.on('response', common.mustCall());
+let data = '';
+req.setEncoding('utf8');
+req.on('data', (chunk) => data += chunk);
+req.on('end', () => {
+ console.log(`The server says: ${data}`);
+ client.destroy();
+});
+req.end('Jane');
+```
+
+## Compatibility API
+
+TBD
+
+
+[HTTP/2]: https://tools.ietf.org/html/rfc7540
+[HTTP/1]: http.html
+[`net.Socket`]: net.html
+[`tls.TLSSocket`]: tls.html
+[`tls.createServer()`]: tls.html#tls_tls_createserver_options_secureconnectionlistener
+[ClientHttp2Stream]: #http2_class_clienthttp2stream
+[Compatibility API: #http2_compatibility_api
+[`Duplex`]: stream.html#stream_class_stream_duplex
+[Headers Object]: #http2_headers_object
+[Http2Stream]: #http2_class_http2stream
+[Http2Session and Sockets]: #http2_http2sesion_and_sockets
+[ServerHttp2Stream]: #http2_class_serverhttp2stream
+[Settings Object]: #http2_settings_object
+[Using options.selectPadding]: #http2_using_options_selectpadding
+[error code]: #error_codes
+[`'unknownProtocol'`]: #http2_event_unknownprotocol
diff --git a/doc/guides/writing-and-running-benchmarks.md b/doc/guides/writing-and-running-benchmarks.md
index 3135f2115d..7aeb9728aa 100644
--- a/doc/guides/writing-and-running-benchmarks.md
+++ b/doc/guides/writing-and-running-benchmarks.md
@@ -41,6 +41,14 @@ benchmarker to be used should be specified by providing it as an argument:
`node benchmark/http/simple.js benchmarker=autocannon`
+#### HTTP/2 Benchmark Requirements
+
+To run the `http2` benchmarks, the `h2load` benchmarker must be used. The
+`h2load` tool is a component of the `nghttp2` project and may be installed
+from [nghttp.org][] or built from source.
+
+`node benchmark/http2/simple.js benchmarker=autocannon`
+
### Benchmark Analysis Requirements
To analyze the results, `R` should be installed. Use one of the available
@@ -423,3 +431,4 @@ Supported options keys are:
[wrk]: https://github.com/wg/wrk
[t-test]: https://en.wikipedia.org/wiki/Student%27s_t-test#Equal_or_unequal_sample_sizes.2C_unequal_variances
[git-for-windows]: http://git-scm.com/download/win
+[nghttp2.org]: http://nghttp2.org
diff --git a/doc/node.1 b/doc/node.1
index ca142a2cab..c97a9d812d 100644
--- a/doc/node.1
+++ b/doc/node.1
@@ -131,6 +131,10 @@ Emit pending deprecation warnings.
Silence all process warnings (including deprecations).
.TP
+.BR \-\-expose\-http2
+Enable the experimental `'http2'` module.
+
+.TP
.BR \-\-napi\-modules
Enable loading native modules compiled with the ABI-stable Node.js API (N-API)
(experimental).