@@ -84,7 +84,30 @@ Since there are no browsers known that support
84
84
[ ` http2.createSecureServer() ` ] [ ] is necessary when communicating
85
85
with browser clients.
86
86
87
- ``` js
87
+ ``` mjs
88
+ import { createSecureServer } from ' node:http2' ;
89
+ import { readFileSync } from ' node:fs' ;
90
+
91
+ const server = createSecureServer ({
92
+ key: readFileSync (' localhost-privkey.pem' ),
93
+ cert: readFileSync (' localhost-cert.pem' ),
94
+ });
95
+
96
+ server .on (' error' , (err ) => console .error (err));
97
+
98
+ server .on (' stream' , (stream , headers ) => {
99
+ // stream is a Duplex
100
+ stream .respond ({
101
+ ' content-type' : ' text/html; charset=utf-8' ,
102
+ ' :status' : 200 ,
103
+ });
104
+ stream .end (' <h1>Hello World</h1>' );
105
+ });
106
+
107
+ server .listen (8443 );
108
+ ```
109
+
110
+ ``` cjs
88
111
const http2 = require (' node:http2' );
89
112
const fs = require (' node:fs' );
90
113
@@ -117,9 +140,37 @@ openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \
117
140
118
141
The following illustrates an HTTP/2 client:
119
142
120
- ``` js
143
+ ``` mjs
144
+ import { connect } from ' node:http2' ;
145
+ import { readFileSync } from ' node:fs' ;
146
+
147
+ const client = connect (' https://localhost:8443' , {
148
+ ca: readFileSync (' localhost-cert.pem' ),
149
+ });
150
+ client .on (' error' , (err ) => console .error (err));
151
+
152
+ const req = client .request ({ ' :path' : ' /' });
153
+
154
+ req .on (' response' , (headers , flags ) => {
155
+ for (const name in headers) {
156
+ console .log (` ${ name} : ${ headers[name]} ` );
157
+ }
158
+ });
159
+
160
+ req .setEncoding (' utf8' );
161
+ let data = ' ' ;
162
+ req .on (' data' , (chunk ) => { data += chunk; });
163
+ req .on (' end' , () => {
164
+ console .log (` \n ${ data} ` );
165
+ client .close ();
166
+ });
167
+ req .end ();
168
+ ```
169
+
170
+ ``` cjs
121
171
const http2 = require (' node:http2' );
122
172
const fs = require (' node:fs' );
173
+
123
174
const client = http2 .connect (' https://localhost:8443' , {
124
175
ca: fs .readFileSync (' localhost-cert.pem' ),
125
176
});
@@ -320,7 +371,6 @@ added: v8.4.0
320
371
The ` 'stream' ` event is emitted when a new ` Http2Stream ` is created.
321
372
322
373
``` js
323
- const http2 = require (' node:http2' );
324
374
session .on (' stream' , (stream , headers , flags ) => {
325
375
const method = headers[' :method' ];
326
376
const path = headers[' :path' ];
@@ -339,7 +389,25 @@ and would instead register a handler for the `'stream'` event emitted by the
339
389
` net.Server ` or ` tls.Server ` instances returned by ` http2.createServer() ` and
340
390
` http2.createSecureServer() ` , respectively, as in the example below:
341
391
342
- ``` js
392
+ ``` mjs
393
+ import { createServer } from ' node:http2' ;
394
+
395
+ // Create an unencrypted HTTP/2 server
396
+ const server = createServer ();
397
+
398
+ server .on (' stream' , (stream , headers ) => {
399
+ stream .respond ({
400
+ ' content-type' : ' text/html; charset=utf-8' ,
401
+ ' :status' : 200 ,
402
+ });
403
+ stream .on (' error' , (error ) => console .error (error));
404
+ stream .end (' <h1>Hello World</h1>' );
405
+ });
406
+
407
+ server .listen (8000 );
408
+ ```
409
+
410
+ ``` cjs
343
411
const http2 = require (' node:http2' );
344
412
345
413
// Create an unencrypted HTTP/2 server
@@ -606,7 +674,19 @@ Sets the local endpoint's window size.
606
674
The ` windowSize ` is the total window size to set, not
607
675
the delta.
608
676
609
- ``` js
677
+ ``` mjs
678
+ import { createServer } from ' node:http2' ;
679
+
680
+ const server = createServer ();
681
+ const expectedWindowSize = 2 ** 20 ;
682
+ server .on (' session' , (session ) => {
683
+
684
+ // Set local window size to be 2 ** 20
685
+ session .setLocalWindowSize (expectedWindowSize);
686
+ });
687
+ ```
688
+
689
+ ``` cjs
610
690
const http2 = require (' node:http2' );
611
691
612
692
const server = http2 .createServer ();
@@ -764,7 +844,22 @@ added: v9.4.0
764
844
765
845
Submits an ` ALTSVC ` frame (as defined by [ RFC 7838] [ ] ) to the connected client.
766
846
767
- ``` js
847
+ ``` mjs
848
+ import { createServer } from ' node:http2' ;
849
+
850
+ const server = createServer ();
851
+ server .on (' session' , (session ) => {
852
+ // Set altsvc for origin https://example.org:80
853
+ session .altsvc (' h2=":8000"' , ' https://example.org:80' );
854
+ });
855
+
856
+ server .on (' stream' , (stream ) => {
857
+ // Set altsvc for a specific stream
858
+ stream .session .altsvc (' h2=":8000"' , stream .id );
859
+ });
860
+ ```
861
+
862
+ ``` cjs
768
863
const http2 = require (' node:http2' );
769
864
770
865
const server = http2 .createServer ();
@@ -830,7 +925,20 @@ Submits an `ORIGIN` frame (as defined by [RFC 8336][]) to the connected client
830
925
to advertise the set of origins for which the server is capable of providing
831
926
authoritative responses.
832
927
833
- ``` js
928
+ ``` mjs
929
+ import { createSecureServer } from ' node:http2' ;
930
+ const options = getSecureOptionsSomehow ();
931
+ const server = createSecureServer (options);
932
+ server .on (' stream' , (stream ) => {
933
+ stream .respond ();
934
+ stream .end (' ok' );
935
+ });
936
+ server .on (' session' , (session ) => {
937
+ session .origin (' https://example.com' , ' https://example.org' );
938
+ });
939
+ ```
940
+
941
+ ``` cjs
834
942
const http2 = require (' node:http2' );
835
943
const options = getSecureOptionsSomehow ();
836
944
const server = http2 .createSecureServer (options);
@@ -857,7 +965,18 @@ ASCII origin.
857
965
Alternatively, the ` origins ` option may be used when creating a new HTTP/2
858
966
server using the ` http2.createSecureServer() ` method:
859
967
860
- ``` js
968
+ ``` mjs
969
+ import { createSecureServer } from ' node:http2' ;
970
+ const options = getSecureOptionsSomehow ();
971
+ options .origins = [' https://example.com' , ' https://example.org' ];
972
+ const server = createSecureServer (options);
973
+ server .on (' stream' , (stream ) => {
974
+ stream .respond ();
975
+ stream .end (' ok' );
976
+ });
977
+ ```
978
+
979
+ ``` cjs
861
980
const http2 = require (' node:http2' );
862
981
const options = getSecureOptionsSomehow ();
863
982
options .origins = [' https://example.com' , ' https://example.org' ];
@@ -891,7 +1010,18 @@ the client. The event is emitted with the `ALTSVC` value, origin, and stream
891
1010
ID. If no ` origin ` is provided in the ` ALTSVC ` frame, ` origin ` will
892
1011
be an empty string.
893
1012
894
- ``` js
1013
+ ``` mjs
1014
+ import { connect } from ' node:http2' ;
1015
+ const client = connect (' https://example.org' );
1016
+
1017
+ client .on (' altsvc' , (alt , origin , streamId ) => {
1018
+ console .log (alt);
1019
+ console .log (origin);
1020
+ console .log (streamId);
1021
+ });
1022
+ ```
1023
+
1024
+ ``` cjs
895
1025
const http2 = require (' node:http2' );
896
1026
const client = http2 .connect (' https://example.org' );
897
1027
@@ -915,7 +1045,17 @@ the client. The event is emitted with an array of `origin` strings. The
915
1045
` http2session.originSet ` will be updated to include the received
916
1046
origins.
917
1047
918
- ``` js
1048
+ ``` mjs
1049
+ import { connect } from ' node:http2' ;
1050
+ const client = connect (' https://example.org' );
1051
+
1052
+ client .on (' origin' , (origins ) => {
1053
+ for (let n = 0 ; n < origins .length ; n++ )
1054
+ console .log (origins[n]);
1055
+ });
1056
+ ```
1057
+
1058
+ ``` cjs
919
1059
const http2 = require (' node:http2' );
920
1060
const client = http2 .connect (' https://example.org' );
921
1061
@@ -968,7 +1108,23 @@ If the `session` is closed before the actual request be executed, an
968
1108
This method is only available if ` http2session.type ` is equal to
969
1109
` http2.constants.NGHTTP2_SESSION_CLIENT ` .
970
1110
971
- ``` js
1111
+ ``` mjs
1112
+ import { connect , constants } from ' node:http2' ;
1113
+ const clientSession = connect (' https://localhost:1234' );
1114
+ const {
1115
+ HTTP2_HEADER_PATH ,
1116
+ HTTP2_HEADER_STATUS ,
1117
+ } = constants;
1118
+
1119
+ const req = clientSession .request ({ [HTTP2_HEADER_PATH ]: ' /' });
1120
+ req .on (' response' , (headers ) => {
1121
+ console .log (headers[HTTP2_HEADER_STATUS ]);
1122
+ req .on (' data' , (chunk ) => { /* .. */ });
1123
+ req .on (' end' , () => { /* .. */ });
1124
+ });
1125
+ ```
1126
+
1127
+ ``` cjs
972
1128
const http2 = require (' node:http2' );
973
1129
const clientSession = http2 .connect (' https://localhost:1234' );
974
1130
const {
@@ -1388,7 +1544,17 @@ changes:
1388
1544
* ` msecs ` {number}
1389
1545
* ` callback ` {Function}
1390
1546
1391
- ``` js
1547
+ ``` mjs
1548
+ import { connect , constants } from ' node:http2' ;
1549
+ const client = connect (' http://example.org:8000' );
1550
+ const { NGHTTP2_CANCEL } = constants;
1551
+ const req = client .request ({ ' :path' : ' /' });
1552
+
1553
+ // Cancel the stream if there's no activity after 5 seconds
1554
+ req .setTimeout (5000 , () => req .close (NGHTTP2_CANCEL ));
1555
+ ```
1556
+
1557
+ ``` cjs
1392
1558
const http2 = require (' node:http2' );
1393
1559
const client = http2 .connect (' http://example.org:8000' );
1394
1560
const { NGHTTP2_CANCEL } = http2 .constants ;
@@ -1437,7 +1603,19 @@ request or sending a response, the `options.waitForTrailers` option must be set
1437
1603
in order to keep the ` Http2Stream ` open after the final ` DATA ` frame so that
1438
1604
trailers can be sent.
1439
1605
1440
- ``` js
1606
+ ``` mjs
1607
+ import { createServer } from ' node:http2' ;
1608
+ const server = createServer ();
1609
+ server .on (' stream' , (stream ) => {
1610
+ stream .respond (undefined , { waitForTrailers: true });
1611
+ stream .on (' wantTrailers' , () => {
1612
+ stream .sendTrailers ({ xyz: ' abc' });
1613
+ });
1614
+ stream .end (' Hello World' );
1615
+ });
1616
+ ```
1617
+
1618
+ ``` cjs
1441
1619
const http2 = require (' node:http2' );
1442
1620
const server = http2 .createServer ();
1443
1621
server .on (' stream' , (stream ) => {
@@ -1528,7 +1706,16 @@ received for this stream from the connected HTTP/2 server. The listener is
1528
1706
invoked with two arguments: an ` Object ` containing the received
1529
1707
[ HTTP/2 Headers Object] [ ] , and flags associated with the headers.
1530
1708
1531
- ``` js
1709
+ ``` mjs
1710
+ import { connect } from ' node:http2' ;
1711
+ const client = connect (' https://localhost' );
1712
+ const req = client .request ({ ' :path' : ' /' });
1713
+ req .on (' response' , (headers , flags ) => {
1714
+ console .log (headers[' :status' ]);
1715
+ });
1716
+ ```
1717
+
1718
+ ``` cjs
1532
1719
const http2 = require (' node:http2' );
1533
1720
const client = http2 .connect (' https://localhost' );
1534
1721
const req = client .request ({ ' :path' : ' /' });
@@ -1614,7 +1801,21 @@ Initiates a push stream. The callback is invoked with the new `Http2Stream`
1614
1801
instance created for the push stream passed as the second argument, or an
1615
1802
` Error ` passed as the first argument.
1616
1803
1617
- ``` js
1804
+ ``` mjs
1805
+ import { createServer } from ' node:http2' ;
1806
+ const server = createServer ();
1807
+ server .on (' stream' , (stream ) => {
1808
+ stream .respond ({ ' :status' : 200 });
1809
+ stream .pushStream ({ ' :path' : ' /' }, (err , pushStream , headers ) => {
1810
+ if (err) throw err;
1811
+ pushStream .respond ({ ' :status' : 200 });
1812
+ pushStream .end (' some pushed data' );
1813
+ });
1814
+ stream .end (' some data' );
1815
+ });
1816
+ ```
1817
+
1818
+ ``` cjs
1618
1819
const http2 = require (' node:http2' );
1619
1820
const server = http2 .createServer ();
1620
1821
server .on (' stream' , (stream ) => {
@@ -1654,7 +1855,16 @@ changes:
1654
1855
* ` waitForTrailers ` {boolean} When ` true ` , the ` Http2Stream ` will emit the
1655
1856
` 'wantTrailers' ` event after the final ` DATA ` frame has been sent.
1656
1857
1657
- ``` js
1858
+ ``` mjs
1859
+ import { createServer } from ' node:http2' ;
1860
+ const server = createServer ();
1861
+ server .on (' stream' , (stream ) => {
1862
+ stream .respond ({ ' :status' : 200 });
1863
+ stream .end (' some data' );
1864
+ });
1865
+ ```
1866
+
1867
+ ``` cjs
1658
1868
const http2 = require (' node:http2' );
1659
1869
const server = http2 .createServer ();
1660
1870
server .on (' stream' , (stream ) => {
@@ -1673,7 +1883,19 @@ close when the final `DATA` frame is transmitted. User code must call either
1673
1883
` http2stream.sendTrailers() ` or ` http2stream.close() ` to close the
1674
1884
` Http2Stream ` .
1675
1885
1676
- ``` js
1886
+ ``` mjs
1887
+ import { createServer } from ' node:http2' ;
1888
+ const server = createServer ();
1889
+ server .on (' stream' , (stream ) => {
1890
+ stream .respond ({ ' :status' : 200 }, { waitForTrailers: true });
1891
+ stream .on (' wantTrailers' , () => {
1892
+ stream .sendTrailers ({ ABC : ' some value to send' });
1893
+ });
1894
+ stream .end (' some data' );
1895
+ });
1896
+ ```
1897
+
1898
+ ``` cjs
1677
1899
const http2 = require (' node:http2' );
1678
1900
const server = http2 .createServer ();
1679
1901
server .on (' stream' , (stream ) => {
@@ -1721,7 +1943,26 @@ closed using an `RST_STREAM` frame using the standard `INTERNAL_ERROR` code.
1721
1943
When used, the ` Http2Stream ` object's ` Duplex ` interface will be closed
1722
1944
automatically.
1723
1945
1724
- ``` js
1946
+ ``` mjs
1947
+ import { createServer } from ' node:http2' ;
1948
+ import { openSync , fstatSync , closeSync } from ' node:fs' ;
1949
+
1950
+ const server = createServer ();
1951
+ server .on (' stream' , (stream ) => {
1952
+ const fd = openSync (' /some/file' , ' r' );
1953
+
1954
+ const stat = fstatSync (fd);
1955
+ const headers = {
1956
+ ' content-length' : stat .size ,
1957
+ ' last-modified' : stat .mtime .toUTCString (),
1958
+ ' content-type' : ' text/plain; charset=utf-8' ,
1959
+ };
1960
+ stream .respondWithFD (fd, headers);
1961
+ stream .on (' close' , () => closeSync (fd));
1962
+ });
1963
+ ```
1964
+
1965
+ ``` cjs
1725
1966
const http2 = require (' node:http2' );
1726
1967
const fs = require (' node:fs' );
1727
1968
@@ -1766,7 +2007,30 @@ close when the final `DATA` frame is transmitted. User code _must_ call either
1766
2007
` http2stream.sendTrailers() ` or ` http2stream.close() ` to close the
1767
2008
` Http2Stream ` .
1768
2009
1769
- ``` js
2010
+ ``` mjs
2011
+ import { createServer } from ' node:http2' ;
2012
+ import { openSync , fstatSync , closeSync } from ' node:fs' ;
2013
+
2014
+ const server = createServer ();
2015
+ server .on (' stream' , (stream ) => {
2016
+ const fd = openSync (' /some/file' , ' r' );
2017
+
2018
+ const stat = fstatSync (fd);
2019
+ const headers = {
2020
+ ' content-length' : stat .size ,
2021
+ ' last-modified' : stat .mtime .toUTCString (),
2022
+ ' content-type' : ' text/plain; charset=utf-8' ,
2023
+ };
2024
+ stream .respondWithFD (fd, headers, { waitForTrailers: true });
2025
+ stream .on (' wantTrailers' , () => {
2026
+ stream .sendTrailers ({ ABC : ' some value to send' });
2027
+ });
2028
+
2029
+ stream .on (' close' , () => closeSync (fd));
2030
+ });
2031
+ ```
2032
+
2033
+ ``` cjs
1770
2034
const http2 = require (' node:http2' );
1771
2035
const fs = require (' node:fs' );
1772
2036
@@ -1833,7 +2097,37 @@ the stream will be destroyed.
1833
2097
1834
2098
Example using a file path:
1835
2099
1836
- ``` js
2100
+ ``` mjs
2101
+ import { createServer } from ' node:http2' ;
2102
+ const server = createServer ();
2103
+ server .on (' stream' , (stream ) => {
2104
+ function statCheck (stat , headers ) {
2105
+ headers[' last-modified' ] = stat .mtime .toUTCString ();
2106
+ }
2107
+
2108
+ function onError (err ) {
2109
+ // stream.respond() can throw if the stream has been destroyed by
2110
+ // the other side.
2111
+ try {
2112
+ if (err .code === ' ENOENT' ) {
2113
+ stream .respond ({ ' :status' : 404 });
2114
+ } else {
2115
+ stream .respond ({ ' :status' : 500 });
2116
+ }
2117
+ } catch (err) {
2118
+ // Perform actual error handling.
2119
+ console .error (err);
2120
+ }
2121
+ stream .end ();
2122
+ }
2123
+
2124
+ stream .respondWithFile (' /some/file' ,
2125
+ { ' content-type' : ' text/plain; charset=utf-8' },
2126
+ { statCheck, onError });
2127
+ });
2128
+ ```
2129
+
2130
+ ``` cjs
1837
2131
const http2 = require (' node:http2' );
1838
2132
const server = http2 .createServer ();
1839
2133
server .on (' stream' , (stream ) => {
@@ -1868,7 +2162,22 @@ by returning `false`. For instance, a conditional request may check the stat
1868
2162
results to determine if the file has been modified to return an appropriate
1869
2163
` 304 ` response:
1870
2164
1871
- ``` js
2165
+ ``` mjs
2166
+ import { createServer } from ' node:http2' ;
2167
+ const server = createServer ();
2168
+ server .on (' stream' , (stream ) => {
2169
+ function statCheck (stat , headers ) {
2170
+ // Check the stat here...
2171
+ stream .respond ({ ' :status' : 304 });
2172
+ return false ; // Cancel the send operation
2173
+ }
2174
+ stream .respondWithFile (' /some/file' ,
2175
+ { ' content-type' : ' text/plain; charset=utf-8' },
2176
+ { statCheck });
2177
+ });
2178
+ ```
2179
+
2180
+ ``` cjs
1872
2181
const http2 = require (' node:http2' );
1873
2182
const server = http2 .createServer ();
1874
2183
server .on (' stream' , (stream ) => {
@@ -1903,7 +2212,20 @@ close when the final `DATA` frame is transmitted. User code must call either
1903
2212
` http2stream.sendTrailers() ` or ` http2stream.close() ` to close the
1904
2213
` Http2Stream ` .
1905
2214
1906
- ``` js
2215
+ ``` mjs
2216
+ import { createServer } from ' node:http2' ;
2217
+ const server = createServer ();
2218
+ server .on (' stream' , (stream ) => {
2219
+ stream .respondWithFile (' /some/file' ,
2220
+ { ' content-type' : ' text/plain; charset=utf-8' },
2221
+ { waitForTrailers: true });
2222
+ stream .on (' wantTrailers' , () => {
2223
+ stream .sendTrailers ({ ABC : ' some value to send' });
2224
+ });
2225
+ });
2226
+ ```
2227
+
2228
+ ``` cjs
1907
2229
const http2 = require (' node:http2' );
1908
2230
const server = http2 .createServer ();
1909
2231
server .on (' stream' , (stream ) => {
@@ -2016,9 +2338,32 @@ added: v8.4.0
2016
2338
The ` 'stream' ` event is emitted when a ` 'stream' ` event has been emitted by
2017
2339
an ` Http2Session ` associated with the server.
2018
2340
2019
- See also [ ` Http2Session ` 's ` 'stream' ` event] [ ] .
2341
+ See also [ ` Http2Session ` 's ` 'stream' ` event] [ ] .
2342
+
2343
+ ``` mjs
2344
+ import { createServer , constants } from ' node:http2' ;
2345
+ const {
2346
+ HTTP2_HEADER_METHOD ,
2347
+ HTTP2_HEADER_PATH ,
2348
+ HTTP2_HEADER_STATUS ,
2349
+ HTTP2_HEADER_CONTENT_TYPE ,
2350
+ } = constants;
2351
+
2352
+ const server = createServer ();
2353
+ server .on (' stream' , (stream , headers , flags ) => {
2354
+ const method = headers[HTTP2_HEADER_METHOD ];
2355
+ const path = headers[HTTP2_HEADER_PATH ];
2356
+ // ...
2357
+ stream .respond ({
2358
+ [HTTP2_HEADER_STATUS ]: 200 ,
2359
+ [HTTP2_HEADER_CONTENT_TYPE ]: ' text/plain; charset=utf-8' ,
2360
+ });
2361
+ stream .write (' hello ' );
2362
+ stream .end (' world' );
2363
+ });
2364
+ ```
2020
2365
2021
- ``` js
2366
+ ``` cjs
2022
2367
const http2 = require (' node:http2' );
2023
2368
const {
2024
2369
HTTP2_HEADER_METHOD ,
@@ -2249,7 +2594,32 @@ an `Http2Session` associated with the server.
2249
2594
2250
2595
See also [ ` Http2Session ` 's ` 'stream' ` event] [ ] .
2251
2596
2252
- ``` js
2597
+ ``` mjs
2598
+ import { createSecureServer , constants } from ' node:http2' ;
2599
+ const {
2600
+ HTTP2_HEADER_METHOD ,
2601
+ HTTP2_HEADER_PATH ,
2602
+ HTTP2_HEADER_STATUS ,
2603
+ HTTP2_HEADER_CONTENT_TYPE ,
2604
+ } = constants;
2605
+
2606
+ const options = getOptionsSomehow ();
2607
+
2608
+ const server = createSecureServer (options);
2609
+ server .on (' stream' , (stream , headers , flags ) => {
2610
+ const method = headers[HTTP2_HEADER_METHOD ];
2611
+ const path = headers[HTTP2_HEADER_PATH ];
2612
+ // ...
2613
+ stream .respond ({
2614
+ [HTTP2_HEADER_STATUS ]: 200 ,
2615
+ [HTTP2_HEADER_CONTENT_TYPE ]: ' text/plain; charset=utf-8' ,
2616
+ });
2617
+ stream .write (' hello ' );
2618
+ stream .end (' world' );
2619
+ });
2620
+ ```
2621
+
2622
+ ``` cjs
2253
2623
const http2 = require (' node:http2' );
2254
2624
const {
2255
2625
HTTP2_HEADER_METHOD ,
@@ -2533,7 +2903,27 @@ Since there are no browsers known that support
2533
2903
[ ` http2.createSecureServer() ` ] [ ] is necessary when communicating
2534
2904
with browser clients.
2535
2905
2536
- ``` js
2906
+ ``` mjs
2907
+ import { createServer } from ' node:http2' ;
2908
+
2909
+ // Create an unencrypted HTTP/2 server.
2910
+ // Since there are no browsers known that support
2911
+ // unencrypted HTTP/2, the use of `createSecureServer()`
2912
+ // is necessary when communicating with browser clients.
2913
+ const server = createServer ();
2914
+
2915
+ server .on (' stream' , (stream , headers ) => {
2916
+ stream .respond ({
2917
+ ' content-type' : ' text/html; charset=utf-8' ,
2918
+ ' :status' : 200 ,
2919
+ });
2920
+ stream .end (' <h1>Hello World</h1>' );
2921
+ });
2922
+
2923
+ server .listen (8000 );
2924
+ ```
2925
+
2926
+ ``` cjs
2537
2927
const http2 = require (' node:http2' );
2538
2928
2539
2929
// Create an unencrypted HTTP/2 server.
@@ -2675,7 +3065,30 @@ changes:
2675
3065
Returns a ` tls.Server ` instance that creates and manages ` Http2Session `
2676
3066
instances.
2677
3067
2678
- ``` js
3068
+ ``` mjs
3069
+ import { createSecureServer } from ' node:http2' ;
3070
+ import { readFileSync } from ' node:fs' ;
3071
+
3072
+ const options = {
3073
+ key: readFileSync (' server-key.pem' ),
3074
+ cert: readFileSync (' server-cert.pem' ),
3075
+ };
3076
+
3077
+ // Create a secure HTTP/2 server
3078
+ const server = createSecureServer (options);
3079
+
3080
+ server .on (' stream' , (stream , headers ) => {
3081
+ stream .respond ({
3082
+ ' content-type' : ' text/html; charset=utf-8' ,
3083
+ ' :status' : 200 ,
3084
+ });
3085
+ stream .end (' <h1>Hello World</h1>' );
3086
+ });
3087
+
3088
+ server .listen (8443 );
3089
+ ```
3090
+
3091
+ ``` cjs
2679
3092
const http2 = require (' node:http2' );
2680
3093
const fs = require (' node:fs' );
2681
3094
@@ -2807,7 +3220,16 @@ changes:
2807
3220
2808
3221
Returns a ` ClientHttp2Session ` instance.
2809
3222
2810
- ``` js
3223
+ ``` mjs
3224
+ import { connect } from ' node:http2' ;
3225
+ const client = connect (' https://localhost:1234' );
3226
+
3227
+ /* Use the client */
3228
+
3229
+ client .close ();
3230
+ ```
3231
+
3232
+ ``` cjs
2811
3233
const http2 = require (' node:http2' );
2812
3234
const client = http2 .connect (' https://localhost:1234' );
2813
3235
@@ -2869,7 +3291,16 @@ Returns a `Buffer` instance containing serialized representation of the given
2869
3291
HTTP/2 settings as specified in the [ HTTP/2] [ ] specification. This is intended
2870
3292
for use with the ` HTTP2-Settings ` header field.
2871
3293
2872
- ``` js
3294
+ ``` mjs
3295
+ import { getPackedSettings } from ' node:http2' ;
3296
+
3297
+ const packed = getPackedSettings ({ enablePush: false });
3298
+
3299
+ console .log (packed .toString (' base64' ));
3300
+ // Prints: AAIAAAAA
3301
+ ```
3302
+
3303
+ ``` cjs
2873
3304
const http2 = require (' node:http2' );
2874
3305
2875
3306
const packed = http2 .getPackedSettings ({ enablePush: false });
@@ -2956,7 +3387,16 @@ For incoming headers:
2956
3387
* For duplicate ` cookie ` headers, the values are joined together with '; '.
2957
3388
* For all other headers, the values are joined together with ', '.
2958
3389
2959
- ``` js
3390
+ ``` mjs
3391
+ import { createServer } from ' node:http2' ;
3392
+ const server = createServer ();
3393
+ server .on (' stream' , (stream , headers ) => {
3394
+ console .log (headers[' :path' ]);
3395
+ console .log (headers .ABC );
3396
+ });
3397
+ ```
3398
+
3399
+ ``` cjs
2960
3400
const http2 = require (' node:http2' );
2961
3401
const server = http2 .createServer ();
2962
3402
server .on (' stream' , (stream , headers ) => {
@@ -3104,7 +3544,22 @@ characters, per the requirements of the HTTP specification.
3104
3544
To receive pushed streams on the client, set a listener for the ` 'stream' `
3105
3545
event on the ` ClientHttp2Session ` :
3106
3546
3107
- ``` js
3547
+ ``` mjs
3548
+ import { connect } from ' node:http2' ;
3549
+
3550
+ const client = connect (' http://localhost' );
3551
+
3552
+ client .on (' stream' , (pushedStream , requestHeaders ) => {
3553
+ pushedStream .on (' push' , (responseHeaders ) => {
3554
+ // Process response headers
3555
+ });
3556
+ pushedStream .on (' data' , (chunk ) => { /* handle pushed data */ });
3557
+ });
3558
+
3559
+ const req = client .request ({ ' :path' : ' /' });
3560
+ ```
3561
+
3562
+ ``` cjs
3108
3563
const http2 = require (' node:http2' );
3109
3564
3110
3565
const client = http2 .connect (' http://localhost' );
@@ -3126,7 +3581,20 @@ for TCP/IP connections.
3126
3581
3127
3582
A simple TCP Server:
3128
3583
3129
- ``` js
3584
+ ``` mjs
3585
+ import { createServer } from ' node:net' ;
3586
+
3587
+ const server = createServer ((socket ) => {
3588
+ let name = ' ' ;
3589
+ socket .setEncoding (' utf8' );
3590
+ socket .on (' data' , (chunk ) => name += chunk);
3591
+ socket .on (' end' , () => socket .end (` hello ${ name} ` ));
3592
+ });
3593
+
3594
+ server .listen (8000 );
3595
+ ```
3596
+
3597
+ ``` cjs
3130
3598
const net = require (' node:net' );
3131
3599
3132
3600
const server = net .createServer ((socket ) => {
@@ -3141,7 +3609,35 @@ server.listen(8000);
3141
3609
3142
3610
An HTTP/2 CONNECT proxy:
3143
3611
3144
- ``` js
3612
+ ``` mjs
3613
+ import { createServer , constants } from ' node:http2' ;
3614
+ const { NGHTTP2_REFUSED_STREAM , NGHTTP2_CONNECT_ERROR } = constants;
3615
+ import { connect } from ' node:net' ;
3616
+
3617
+ const proxy = createServer ();
3618
+ proxy .on (' stream' , (stream , headers ) => {
3619
+ if (headers[' :method' ] !== ' CONNECT' ) {
3620
+ // Only accept CONNECT requests
3621
+ stream .close (NGHTTP2_REFUSED_STREAM );
3622
+ return ;
3623
+ }
3624
+ const auth = new URL (` tcp://${ headers[' :authority' ]} ` );
3625
+ // It's a very good idea to verify that hostname and port are
3626
+ // things this proxy should be connecting to.
3627
+ const socket = connect (auth .port , auth .hostname , () => {
3628
+ stream .respond ();
3629
+ socket .pipe (stream);
3630
+ stream .pipe (socket);
3631
+ });
3632
+ socket .on (' error' , (error ) => {
3633
+ stream .close (NGHTTP2_CONNECT_ERROR );
3634
+ });
3635
+ });
3636
+
3637
+ proxy .listen (8001 );
3638
+ ```
3639
+
3640
+ ``` cjs
3145
3641
const http2 = require (' node:http2' );
3146
3642
const { NGHTTP2_REFUSED_STREAM } = http2 .constants ;
3147
3643
const net = require (' node:net' );
@@ -3171,7 +3667,32 @@ proxy.listen(8001);
3171
3667
3172
3668
An HTTP/2 CONNECT client:
3173
3669
3174
- ``` js
3670
+ ``` mjs
3671
+ import { connect , constants } from ' node:http2' ;
3672
+
3673
+ const client = connect (' http://localhost:8001' );
3674
+
3675
+ // Must not specify the ':path' and ':scheme' headers
3676
+ // for CONNECT requests or an error will be thrown.
3677
+ const req = client .request ({
3678
+ ' :method' : ' CONNECT' ,
3679
+ ' :authority' : ' localhost:8000' ,
3680
+ });
3681
+
3682
+ req .on (' response' , (headers ) => {
3683
+ console .log (headers[constants .HTTP2_HEADER_STATUS ]);
3684
+ });
3685
+ let data = ' ' ;
3686
+ req .setEncoding (' utf8' );
3687
+ req .on (' data' , (chunk ) => data += chunk);
3688
+ req .on (' end' , () => {
3689
+ console .log (` The server says: ${ data} ` );
3690
+ client .close ();
3691
+ });
3692
+ req .end (' Jane' );
3693
+ ```
3694
+
3695
+ ``` cjs
3175
3696
const http2 = require (' node:http2' );
3176
3697
3177
3698
const client = http2 .connect (' http://localhost:8001' );
@@ -3205,7 +3726,13 @@ method as a tunnel for other communication protocols (such as WebSockets).
3205
3726
The use of the Extended CONNECT Protocol is enabled by HTTP/2 servers by using
3206
3727
the ` enableConnectProtocol ` setting:
3207
3728
3208
- ``` js
3729
+ ``` mjs
3730
+ import { createServer } from ' node:http2' ;
3731
+ const settings = { enableConnectProtocol: true };
3732
+ const server = createServer ({ settings });
3733
+ ```
3734
+
3735
+ ``` cjs
3209
3736
const http2 = require (' node:http2' );
3210
3737
const settings = { enableConnectProtocol: true };
3211
3738
const server = http2 .createServer ({ settings });
@@ -3215,7 +3742,18 @@ Once the client receives the `SETTINGS` frame from the server indicating that
3215
3742
the extended CONNECT may be used, it may send ` CONNECT ` requests that use the
3216
3743
` ':protocol' ` HTTP/2 pseudo-header:
3217
3744
3218
- ``` js
3745
+ ``` mjs
3746
+ import { connect } from ' node:http2' ;
3747
+ const client = connect (' http://localhost:8080' );
3748
+ client .on (' remoteSettings' , (settings ) => {
3749
+ if (settings .enableConnectProtocol ) {
3750
+ const req = client .request ({ ' :method' : ' CONNECT' , ' :protocol' : ' foo' });
3751
+ // ...
3752
+ }
3753
+ });
3754
+ ```
3755
+
3756
+ ``` cjs
3219
3757
const http2 = require (' node:http2' );
3220
3758
const client = http2 .connect (' http://localhost:8080' );
3221
3759
client .on (' remoteSettings' , (settings ) => {
@@ -3238,7 +3776,17 @@ different implementation.
3238
3776
The following example creates an HTTP/2 server using the compatibility
3239
3777
API:
3240
3778
3241
- ``` js
3779
+ ``` mjs
3780
+ import { createServer } from ' node:http2' ;
3781
+ const server = createServer ((req , res ) => {
3782
+ res .setHeader (' Content-Type' , ' text/html' );
3783
+ res .setHeader (' X-Foo' , ' bar' );
3784
+ res .writeHead (200 , { ' Content-Type' : ' text/plain; charset=utf-8' });
3785
+ res .end (' ok' );
3786
+ });
3787
+ ```
3788
+
3789
+ ``` cjs
3242
3790
const http2 = require (' node:http2' );
3243
3791
const server = http2 .createServer ((req , res ) => {
3244
3792
res .setHeader (' Content-Type' , ' text/html' );
@@ -3267,7 +3815,31 @@ features of HTTP/2.
3267
3815
3268
3816
The following example creates a server that supports both protocols:
3269
3817
3270
- ``` js
3818
+ ``` mjs
3819
+ import { createSecureServer } from ' node:http2' ;
3820
+ import { readFileSync } from ' node:fs' ;
3821
+
3822
+ const cert = readFileSync (' ./cert.pem' );
3823
+ const key = readFileSync (' ./key.pem' );
3824
+
3825
+ const server = createSecureServer (
3826
+ { cert, key, allowHTTP1: true },
3827
+ onRequest,
3828
+ ).listen (8000 );
3829
+
3830
+ function onRequest (req , res ) {
3831
+ // Detects if it is a HTTPS request or HTTP/2
3832
+ const { socket: { alpnProtocol } } = req .httpVersion === ' 2.0' ?
3833
+ req .stream .session : req;
3834
+ res .writeHead (200 , { ' content-type' : ' application/json' });
3835
+ res .end (JSON .stringify ({
3836
+ alpnProtocol,
3837
+ httpVersion: req .httpVersion ,
3838
+ }));
3839
+ }
3840
+ ```
3841
+
3842
+ ``` cjs
3271
3843
const { createSecureServer } = require (' node:http2' );
3272
3844
const { readFileSync } = require (' node:fs' );
3273
3845
@@ -3979,7 +4551,16 @@ more information.
3979
4551
3980
4552
All other interactions will be routed directly to the socket.
3981
4553
3982
- ``` js
4554
+ ``` mjs
4555
+ import { createServer } from ' node:http2' ;
4556
+ const server = createServer ((req , res ) => {
4557
+ const ip = req .socket .remoteAddress ;
4558
+ const port = req .socket .remotePort ;
4559
+ res .end (` Your IP address is ${ ip} and your source port is ${ port} .` );
4560
+ }).listen (3000 );
4561
+ ```
4562
+
4563
+ ``` cjs
3983
4564
const http2 = require (' node:http2' );
3984
4565
const server = http2 .createServer ((req , res ) => {
3985
4566
const ip = req .socket .remoteAddress ;
@@ -4190,7 +4771,22 @@ will result in a [`TypeError`][] being thrown.
4190
4771
The [ Performance Observer] [ ] API can be used to collect basic performance
4191
4772
metrics for each ` Http2Session ` and ` Http2Stream ` instance.
4192
4773
4193
- ``` js
4774
+ ``` mjs
4775
+ import { PerformanceObserver } from ' node:perf_hooks' ;
4776
+
4777
+ const obs = new PerformanceObserver ((items ) => {
4778
+ const entry = items .getEntries ()[0 ];
4779
+ console .log (entry .entryType ); // prints 'http2'
4780
+ if (entry .name === ' Http2Session' ) {
4781
+ // Entry contains statistics about the Http2Session
4782
+ } else if (entry .name === ' Http2Stream' ) {
4783
+ // Entry contains statistics about the Http2Stream
4784
+ }
4785
+ });
4786
+ obs .observe ({ entryTypes: [' http2' ] });
4787
+ ```
4788
+
4789
+ ``` cjs
4194
4790
const { PerformanceObserver } = require (' node:perf_hooks' );
4195
4791
4196
4792
const obs = new PerformanceObserver ((items ) => {
0 commit comments