Skip to content
This repository was archived by the owner on Jul 6, 2018. It is now read-only.

Commit 0bce796

Browse files
committed
http2: additiona cleanups, fixes and docs
* Follow the model of the existing http code and pass the headers in to js as an array. Building the array on the native side then converting it to an object on the js side is generally faster than building the object on the native side. This also allows us to eliminate some duplicated checks. * Fill in additional doc details * Work on timeouts
1 parent f43597b commit 0bce796

File tree

8 files changed

+360
-266
lines changed

8 files changed

+360
-266
lines changed

doc/api/http2.md

Lines changed: 155 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,9 @@ session.on('stream', (stream, headers, flags) => {
130130
});
131131
```
132132

133-
*Note*: User code will typically not listen for this event directly, and would
134-
instead register a handler for the `'stream'` event emitted by the `net.Server`
135-
or `tls.Server` instances returned by `http2.createServer()` and
133+
On the server side, user code will typically not listen for this event directly,
134+
and would instead register a handler for the `'stream'` event emitted by the
135+
`net.Server` or `tls.Server` instances returned by `http2.createServer()` and
136136
`http2.createSecureServer()`, respectively, as in the example below:
137137

138138
```js
@@ -164,7 +164,16 @@ not handled, the `'error'` event will be re-emitted on the `Http2Session`.
164164

165165
#### Event: 'timeout'
166166

167-
(TODO: fill in detail)
167+
After the `http2session.setTimeout()` method is used to set the timeout period
168+
for this `Http2Session`, the `'timeout'` event is emitted if there is no
169+
activity on the `Http2Session` after the configured number of milliseconds.
170+
171+
```js
172+
const session = /** get session somehow **/;
173+
174+
session.setTimeout(2000);
175+
session.on('timeout', () => { /** .. **/ });
176+
```
168177

169178
#### http2session.destroy()
170179

@@ -182,15 +191,15 @@ longer be used, otherwise `false`.
182191

183192
* Value: {[Settings Object][]}
184193

185-
An object describing the current local settings of this `Http2Session`. The
186-
local settings are local to *this* `Http2Session` instance.
194+
A prototype-less object describing the current local settings of this
195+
`Http2Session`. The local settings are local to *this* `Http2Session` instance.
187196

188197
#### http2session.remoteSettings
189198

190199
* Value: {[Settings Object][]}
191200

192-
An object describing the current remote settings of this `Http2Session`. The
193-
remote settings are set by the *connected* HTTP/2 peer.
201+
A prototype-less object describing the current remote settings of this
202+
`Http2Session`. The remote settings are set by the *connected* HTTP/2 peer.
194203

195204
#### http2session.request(headers[, options])
196205

@@ -216,41 +225,79 @@ HTTP/2 request to the connected server.
216225
This method is only available if `http2session.type` is equal to
217226
`http2.constants.NGHTTP2_SESSION_CLIENT`.
218227

219-
(TODO: fill in detail)
228+
```js
229+
const http2 = require('http2');
230+
const clientSession = http2.connect('https://localhost:1234');
231+
const {
232+
HTTP2_HEADER_PATH,
233+
HTTP2_HEADER_STATUS
234+
} = http2.constants;
235+
236+
const req = clientSession.request({ [HTTP2_HEADER_PATH]: '/' });
237+
req.on('response', (headers) => {
238+
console.log(HTTP2_HEADER_STATUS);
239+
req.on('data', (chunk) => { /** .. **/ });
240+
req.on('end', () => { /** .. **/ });
241+
});
242+
```
220243

221244
#### http2session.rstStream(stream, code)
222245

223246
* stream {Http2Stream}
224-
* code {number}
247+
* code {number} Unsigned 32-bit integer identifying the error code. Defaults to
248+
`http2.constant.NGHTTP2_NO_ERROR` (`0x00`)
225249

226250
Sends an `RST_STREAM` frame to the connected HTTP/2 peer, causing the given
227-
`Http2Stream` to be closed on both sides using error code `code`.
251+
`Http2Stream` to be closed on both sides using [error code][] `code`.
228252

229253
#### http2session.setTimeout(msecs, callback)
230254

231255
* `msecs` {number}
232256
* `callback` {Function}
233257

234-
(TODO: fill in detail)
258+
Used to set a callback function that is called when there is no activity on
259+
the `Http2Session` after `msecs` milliseconds. The given `callback` is
260+
registered as a listener on the `'timeout'` event.
235261

236262
#### http2session.shutdown(options[, callback])
237263

238264
* `options` {Object}
239265
* `graceful` {boolean} `true` to attempt a polite shutdown of the
240266
`Http2Session`.
241-
* `errorCode` {number} The HTTP/2 Error Code to return. Note that this is
242-
*not* the same thing as an HTTP Response Status Code.
267+
* `errorCode` {number} The HTTP/2 [error code][] to return. Note that this is
268+
*not* the same thing as an HTTP Response Status Code. Defaults to `0x00`
269+
(No Error).
243270
* `lastStreamID` {number} The Stream ID of the last successfully processed
244271
`Http2Stream` on this `Http2Session`.
245272
* `opaqueData` {Buffer} A `Buffer` instance containing arbitrary additional
246273
data to send to the peer upon disconnection. This is used, typically, to
247274
provide additional data for debugging failures, if necessary.
248-
* `callback` {Function}
275+
* `callback` {Function} A callback that is invoked after the session shutdown
276+
has been completed.
249277

250278
Attempts to shutdown this `Http2Session` using HTTP/2 defined procedures.
251279
If specified, the given `callback` function will be invoked once the shutdown
252280
process has completed.
253281

282+
Note that calling `http2session.shutdown()` does *not* destroy the session or
283+
tear down the `Socket` connection. It merely prompts both sessions to begin
284+
preparing to cease activity.
285+
286+
During a "graceful" shutdown, the session will first send a `GOAWAY` frame to
287+
the connected peer identifying the last processed stream as 2<sup>32</sup>-1.
288+
Then, on the next tick of the event loop, a second `GOAWAY` frame identifying
289+
the most recently processed stream identifier is sent. This process allows the
290+
remote peer to begin preparing for the connection to be terminated.
291+
292+
```js
293+
const session = /** get session somehow **/
294+
295+
session.shutdown({
296+
graceful: true,
297+
opaqueData: Buffer.from('add some debugging data here')
298+
}, () => session.destroy());
299+
```
300+
254301
#### http2session.socket
255302

256303
* Value: {net.Socket|tls.TLSSocket}
@@ -417,7 +464,9 @@ this event is emitted, the `Http2Stream` instance is no longer usable.
417464

418465
#### Event: 'timeout'
419466

420-
(TODO: fill in detail)
467+
The `'timeout'` event is emitted after no activity is received for this
468+
`'Http2Stream'` within the number of millseconds set using
469+
`http2stream.setTimeout()`.
421470

422471
#### Event: 'trailers'
423472

@@ -427,7 +476,7 @@ trailing header fields is received. The listener callback is passed the
427476

428477
```js
429478
stream.on('trailers', (headers, flags) => {
430-
// TODO(jasnell): Fill in example
479+
console.log(headers);
431480
});
432481
```
433482

@@ -459,36 +508,38 @@ peer.
459508

460509
* Value: {number}
461510

462-
Set to the `RST_STREAM` error code when the `Http2Stream` is destroyed after
463-
either receiving an `RST_STREAM` frame from the connected peer, calling
464-
`http2stream.rstStream()`, or `http2stream.destroy()`.
511+
Set to the `RST_STREAM` [error code][] reported when the `Http2Stream` is
512+
destroyed after either receiving an `RST_STREAM` frame from the connected peer,
513+
calling `http2stream.rstStream()`, or `http2stream.destroy()`. Will be
514+
`undefined` if the `Http2Stream` has not been closed.
465515

466516
#### http2stream.rstStream(code)
467517

468-
* `code` {number}
518+
* code {number} Unsigned 32-bit integer identifying the error code. Defaults to
519+
`http2.constant.NGHTTP2_NO_ERROR` (`0x00`)
469520

470521
Sends an `RST_STREAM` frame to the connected HTTP/2 peer, causing this
471-
`Http2Stream` to be closed on both sides using error code `code`.
522+
`Http2Stream` to be closed on both sides using [error code][] `code`.
472523

473524
#### http2stream.rstWithNoError()
474525

475-
Shortcut for `http2stream.rstStream()` using error code `NO_ERROR`.
526+
Shortcut for `http2stream.rstStream()` using error code `0x00` (No Error).
476527

477528
#### http2stream.rstWithProtocolError() {
478529

479-
Shortcut for `http2stream.rstStream()` using error code `PROTOCOL_ERROR`.
530+
Shortcut for `http2stream.rstStream()` using error code `0x01` (Protocol Error).
480531

481532
#### http2stream.rstWithCancel() {
482533

483-
Shortcut for `http2stream.rstStream()` using error code `CANCEL`.
534+
Shortcut for `http2stream.rstStream()` using error code `0x08` (Cancel).
484535

485536
#### http2stream.rstWithRefuse() {
486537

487-
Shortcut for `http2stream.rstStream()` using error code `REFUSED_STREAM`.
538+
Shortcut for `http2stream.rstStream()` using error code `0x07` (Refused Stream).
488539

489540
#### http2stream.rstWithInternalError() {
490541

491-
Shortcut for `http2stream.rstStream()` using error code `INTERNAL_ERROR`.
542+
Shortcut for `http2stream.rstStream()` using error code `0x02` (Internal Error).
492543

493544
#### http2stream.session
494545

@@ -502,7 +553,15 @@ value will be `undefined` after the `Http2Stream` instance is destroyed.
502553
* `msecs` {number}
503554
* `callback` {Function}
504555

505-
(TODO: fill in detail)
556+
```js
557+
const http2 = require('http2');
558+
const client = http2.connect('http://example.org:8000');
559+
560+
const req = client.request({':path': '/'});
561+
562+
// Cancel the stream if there's no activity after 5 seconds
563+
req.setTimeout(5000, () => req.rstStreamWithCancel());
564+
```
506565

507566
#### http2stream.state
508567

@@ -534,7 +593,7 @@ the headers.
534593

535594
```js
536595
stream.on('headers', (headers, flags) => {
537-
// TODO(jasnell): Fill in example
596+
console.log(headers);
538597
});
539598
```
540599

@@ -546,7 +605,7 @@ associated with the headers.
546605

547606
```js
548607
stream.on('push', (headers, flags) => {
549-
// TODO(jasnell): Fill in example
608+
console.log(headers);
550609
});
551610
```
552611

@@ -577,18 +636,6 @@ used exclusively on HTTP/2 Servers. `Http2Stream` instances on the server
577636
provide additional methods such as `http2stream.pushStream()` and
578637
`http2stream.respond()` that are only relevant on the server.
579638

580-
#### Event: 'request'
581-
582-
The `'request'` event is emitted when a block of headers associated with an
583-
HTTP request is received. The listener callback is passed the [Headers Object][]
584-
and flags associated with the headers.
585-
586-
```js
587-
stream.on('request', (headers, flags) => {
588-
// TODO(jasnell): Fill in example
589-
});
590-
```
591-
592639
#### http2stream.additionalHeaders(headers)
593640

594641
* `headers` {[Headers Object][]}
@@ -608,18 +655,38 @@ Sends an additional informational `HEADERS` frame to the connected HTTP/2 peer.
608655
* `weight` {number} Specifies the relative dependency of a stream in relation
609656
to other streams with the same `parent`. The value is a number between `1`
610657
and `256` (inclusive).
611-
* `callback` {Function}
658+
* `callback` {Function} Callback that is called once the push stream has been
659+
initiated.
612660

613-
Initiates a push stream.
614-
(TODO: fill in detail)
661+
Initiates a push stream. The callback is invoked with the new `Htt2Stream`
662+
instance created for the push stream.
663+
664+
```js
665+
const http2 = require('http2');
666+
const server = http2.createServer();
667+
server.on('stream', (stream) => {
668+
stream.respond({':status': 200});
669+
stream.pushStream({':path': '/'}, (pushStream) => {
670+
pushStream.respond({':status': 200});
671+
pushStream.end('some pushed data');
672+
});
673+
stream.end('some data');
674+
});
675+
```
615676

616677
#### http2stream.respond([headers[, options]])
617678

618679
* `headers` {[Headers Object][]}
619680
* `options` {Object}
620681

621-
Initiates a response.
622-
(TODO: fill in detail)
682+
```js
683+
const http2 = require('http2');
684+
const server = http2.createServer();
685+
server.on('stream', (stream) => {
686+
stream.respond({':status': 200});
687+
stream.end('some data');
688+
});
689+
```
623690

624691
### Class: Http2Server
625692

@@ -667,7 +734,8 @@ server.on('stream', (stream, headers, flags) => {
667734

668735
#### Event: 'timeout'
669736

670-
(TODO: fill in detail)
737+
The `'timeout'` event is emitted when there is no activity on the Server for
738+
a given number of milliseconds set using `http2server.setTimeout()`.
671739

672740
### Class: Http2SecureServer
673741

@@ -717,7 +785,8 @@ server.on('stream', (stream, headers, flags) => {
717785

718786
#### Event: 'timeout'
719787

720-
(TODO: fill in detail)
788+
The `'timeout'` event is emitted when there is no activity on the Server for
789+
a given number of milliseconds set using `http2server.setTimeout()`.
721790

722791
### http2.getDefaultSettings()
723792

@@ -882,11 +951,37 @@ server.listen(80);
882951
* Returns `Http2Session`
883952

884953
Returns a HTTP/2 client `Http2Session` instance.
885-
(TODO: fill in detail)
954+
955+
```js
956+
const http2 = require('http2');
957+
const client = http2.connect('https://localhost:1234');
958+
959+
/** use the client **/
960+
961+
client.destroy();
962+
```
886963

887964
### http2.constants
888965

889-
(TODO: Fill in details)
966+
#### Error Codes for RST_STREAM and GOAWAY
967+
<a id="error_codes"></a>
968+
969+
| Value | Name | Constant |
970+
|-------|---------------------|-----------------------------------------------|
971+
| 0x00 | No Error | `http2.constants.NGHTTP2_NO_ERROR` |
972+
| 0x01 | Protocol Error | `http2.constants.NGHTTP2_PROTOCOL_ERROR` |
973+
| 0x02 | Internal Error | `http2.constants.NGHTTP2_INTERNAL_ERROR` |
974+
| 0x03 | Flow Control Error | `http2.constants.NGHTTP2_FLOW_CONTROL_ERROR` |
975+
| 0x04 | Settings Timeout | `http2.constants.NGHTTP2_SETTINGS_TIMEOUT` |
976+
| 0x05 | Stream Closed | `http2.constants.NGHTTP2_STREAM_CLOSED` |
977+
| 0x06 | Frame Size Error | `http2.constants.NGHTTP2_FRAME_SIZE_ERROR` |
978+
| 0x07 | Refused Stream | `http2.constants.NGHTTP2_REFUSED_STREAM` |
979+
| 0x08 | Cancel | `http2.constants.NGHTTP2_CANCEL` |
980+
| 0x09 | Compression Error | `http2.constants.NGHTTP2_COMPRESSION_ERROR` |
981+
| 0x0a | Connect Error | `http2.constants.NGHTTP2_CONNECT_ERROR` |
982+
| 0x0b | Enhance Your Calm | `http2.constants.NGHTTP2_ENHANCE_YOUR_CALM` |
983+
| 0x0c | Inadequate Security | `http2.constants.NGHTTP2_INADEQUATE_SECURITY` |
984+
| 0x0d | HTTP/1.1 Required | `http2.constants.NGHTTP2_HTTP_1_1_REQUIRED` |
890985

891986
### Headers Object
892987

@@ -912,7 +1007,14 @@ prototype. This means that normal JavaScript object methods such as
9121007
`Object.prototype.toString()` and `Object.prototype.hasOwnProperty()` will
9131008
not work.
9141009

915-
(TODO: Fill in more detail)
1010+
```js
1011+
const http2 = require('http2');
1012+
const server = http2.createServer();
1013+
server.on('stream', (stream, headers) => {
1014+
console.log(headers[':path']);
1015+
console.log(headers.ABC);
1016+
});
1017+
```
9161018

9171019
### Settings Object
9181020

@@ -1012,3 +1114,4 @@ TBD
10121114
[ServerHttp2Stream]: #http2_class_serverhttp2stream
10131115
[Settings Object]: #http2_settings_object
10141116
[Using options.selectPadding]: #http2_using_options_selectpadding
1117+
[error code]: #error_codes

0 commit comments

Comments
 (0)