• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# HTTPS
2
3<!--introduced_in=v0.10.0-->
4
5> Stability: 2 - Stable
6
7<!-- source_link=lib/https.js -->
8
9HTTPS is the HTTP protocol over TLS/SSL. In Node.js this is implemented as a
10separate module.
11
12## Determining if crypto support is unavailable
13
14It is possible for Node.js to be built without including support for the
15`node:crypto` module. In such cases, attempting to `import` from `https` or
16calling `require('node:https')` will result in an error being thrown.
17
18When using CommonJS, the error thrown can be caught using try/catch:
19
20<!-- eslint-skip -->
21
22```cjs
23let https;
24try {
25  https = require('node:https');
26} catch (err) {
27  console.error('https support is disabled!');
28}
29```
30
31When using the lexical ESM `import` keyword, the error can only be
32caught if a handler for `process.on('uncaughtException')` is registered
33_before_ any attempt to load the module is made (using, for instance,
34a preload module).
35
36When using ESM, if there is a chance that the code may be run on a build
37of Node.js where crypto support is not enabled, consider using the
38[`import()`][] function instead of the lexical `import` keyword:
39
40```mjs
41let https;
42try {
43  https = await import('node:https');
44} catch (err) {
45  console.error('https support is disabled!');
46}
47```
48
49## Class: `https.Agent`
50
51<!-- YAML
52added: v0.4.5
53changes:
54  - version: v5.3.0
55    pr-url: https://github.com/nodejs/node/pull/4252
56    description: support `0` `maxCachedSessions` to disable TLS session caching.
57  - version: v2.5.0
58    pr-url: https://github.com/nodejs/node/pull/2228
59    description: parameter `maxCachedSessions` added to `options` for TLS
60                 sessions reuse.
61-->
62
63An [`Agent`][] object for HTTPS similar to [`http.Agent`][]. See
64[`https.request()`][] for more information.
65
66### `new Agent([options])`
67
68<!-- YAML
69changes:
70  - version: v12.5.0
71    pr-url: https://github.com/nodejs/node/pull/28209
72    description: do not automatically set servername if the target host was
73                 specified using an IP address.
74-->
75
76* `options` {Object} Set of configurable options to set on the agent.
77  Can have the same fields as for [`http.Agent(options)`][], and
78  * `maxCachedSessions` {number} maximum number of TLS cached sessions.
79    Use `0` to disable TLS session caching. **Default:** `100`.
80  * `servername` {string} the value of
81    [Server Name Indication extension][sni wiki] to be sent to the server. Use
82    empty string `''` to disable sending the extension.
83    **Default:** host name of the target server, unless the target server
84    is specified using an IP address, in which case the default is `''` (no
85    extension).
86
87    See [`Session Resumption`][] for information about TLS session reuse.
88
89#### Event: `'keylog'`
90
91<!-- YAML
92added:
93 - v13.2.0
94 - v12.16.0
95-->
96
97* `line` {Buffer} Line of ASCII text, in NSS `SSLKEYLOGFILE` format.
98* `tlsSocket` {tls.TLSSocket} The `tls.TLSSocket` instance on which it was
99  generated.
100
101The `keylog` event is emitted when key material is generated or received by a
102connection managed by this agent (typically before handshake has completed, but
103not necessarily). This keying material can be stored for debugging, as it
104allows captured TLS traffic to be decrypted. It may be emitted multiple times
105for each socket.
106
107A typical use case is to append received lines to a common text file, which is
108later used by software (such as Wireshark) to decrypt the traffic:
109
110```js
111// ...
112https.globalAgent.on('keylog', (line, tlsSocket) => {
113  fs.appendFileSync('/tmp/ssl-keys.log', line, { mode: 0o600 });
114});
115```
116
117## Class: `https.Server`
118
119<!-- YAML
120added: v0.3.4
121-->
122
123* Extends: {tls.Server}
124
125See [`http.Server`][] for more information.
126
127### `server.close([callback])`
128
129<!-- YAML
130added: v0.1.90
131-->
132
133* `callback` {Function}
134* Returns: {https.Server}
135
136See [`server.close()`][] in the `node:http` module.
137
138### `server.closeAllConnections()`
139
140<!-- YAML
141added: v18.2.0
142-->
143
144See [`server.closeAllConnections()`][] in the `node:http` module.
145
146### `server.closeIdleConnections()`
147
148<!-- YAML
149added: v18.2.0
150-->
151
152See [`server.closeIdleConnections()`][] in the `node:http` module.
153
154### `server.headersTimeout`
155
156<!-- YAML
157added: v11.3.0
158-->
159
160* {number} **Default:** `60000`
161
162See [`server.headersTimeout`][] in the `node:http` module.
163
164### `server.listen()`
165
166Starts the HTTPS server listening for encrypted connections.
167This method is identical to [`server.listen()`][] from [`net.Server`][].
168
169### `server.maxHeadersCount`
170
171* {number} **Default:** `2000`
172
173See [`server.maxHeadersCount`][] in the `node:http` module.
174
175### `server.requestTimeout`
176
177<!-- YAML
178added: v14.11.0
179changes:
180  - version: v18.0.0
181    pr-url: https://github.com/nodejs/node/pull/41263
182    description: The default request timeout changed
183                 from no timeout to 300s (5 minutes).
184-->
185
186* {number} **Default:** `300000`
187
188See [`server.requestTimeout`][] in the `node:http` module.
189
190### `server.setTimeout([msecs][, callback])`
191
192<!-- YAML
193added: v0.11.2
194-->
195
196* `msecs` {number} **Default:** `120000` (2 minutes)
197* `callback` {Function}
198* Returns: {https.Server}
199
200See [`server.setTimeout()`][] in the `node:http` module.
201
202### `server.timeout`
203
204<!-- YAML
205added: v0.11.2
206changes:
207  - version: v13.0.0
208    pr-url: https://github.com/nodejs/node/pull/27558
209    description: The default timeout changed from 120s to 0 (no timeout).
210-->
211
212* {number} **Default:** 0 (no timeout)
213
214See [`server.timeout`][] in the `node:http` module.
215
216### `server.keepAliveTimeout`
217
218<!-- YAML
219added: v8.0.0
220-->
221
222* {number} **Default:** `5000` (5 seconds)
223
224See [`server.keepAliveTimeout`][] in the `node:http` module.
225
226## `https.createServer([options][, requestListener])`
227
228<!-- YAML
229added: v0.3.4
230-->
231
232* `options` {Object} Accepts `options` from [`tls.createServer()`][],
233  [`tls.createSecureContext()`][] and [`http.createServer()`][].
234* `requestListener` {Function} A listener to be added to the `'request'` event.
235* Returns: {https.Server}
236
237```js
238// curl -k https://localhost:8000/
239const https = require('node:https');
240const fs = require('node:fs');
241
242const options = {
243  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
244  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem'),
245};
246
247https.createServer(options, (req, res) => {
248  res.writeHead(200);
249  res.end('hello world\n');
250}).listen(8000);
251```
252
253Or
254
255```js
256const https = require('node:https');
257const fs = require('node:fs');
258
259const options = {
260  pfx: fs.readFileSync('test/fixtures/test_cert.pfx'),
261  passphrase: 'sample',
262};
263
264https.createServer(options, (req, res) => {
265  res.writeHead(200);
266  res.end('hello world\n');
267}).listen(8000);
268```
269
270## `https.get(options[, callback])`
271
272## `https.get(url[, options][, callback])`
273
274<!-- YAML
275added: v0.3.6
276changes:
277  - version: v10.9.0
278    pr-url: https://github.com/nodejs/node/pull/21616
279    description: The `url` parameter can now be passed along with a separate
280                 `options` object.
281  - version: v7.5.0
282    pr-url: https://github.com/nodejs/node/pull/10638
283    description: The `options` parameter can be a WHATWG `URL` object.
284-->
285
286* `url` {string | URL}
287* `options` {Object | string | URL} Accepts the same `options` as
288  [`https.request()`][], with the method set to GET by default.
289* `callback` {Function}
290
291Like [`http.get()`][] but for HTTPS.
292
293`options` can be an object, a string, or a [`URL`][] object. If `options` is a
294string, it is automatically parsed with [`new URL()`][]. If it is a [`URL`][]
295object, it will be automatically converted to an ordinary `options` object.
296
297```js
298const https = require('node:https');
299
300https.get('https://encrypted.google.com/', (res) => {
301  console.log('statusCode:', res.statusCode);
302  console.log('headers:', res.headers);
303
304  res.on('data', (d) => {
305    process.stdout.write(d);
306  });
307
308}).on('error', (e) => {
309  console.error(e);
310});
311```
312
313## `https.globalAgent`
314
315<!-- YAML
316added: v0.5.9
317-->
318
319Global instance of [`https.Agent`][] for all HTTPS client requests.
320
321## `https.request(options[, callback])`
322
323## `https.request(url[, options][, callback])`
324
325<!-- YAML
326added: v0.3.6
327changes:
328  - version:
329      - v16.7.0
330      - v14.18.0
331    pr-url: https://github.com/nodejs/node/pull/39310
332    description: When using a `URL` object parsed username
333                 and password will now be properly URI decoded.
334  - version:
335      - v14.1.0
336      - v13.14.0
337    pr-url: https://github.com/nodejs/node/pull/32786
338    description: The `highWaterMark` option is accepted now.
339  - version: v10.9.0
340    pr-url: https://github.com/nodejs/node/pull/21616
341    description: The `url` parameter can now be passed along with a separate
342                 `options` object.
343  - version: v9.3.0
344    pr-url: https://github.com/nodejs/node/pull/14903
345    description: The `options` parameter can now include `clientCertEngine`.
346  - version: v7.5.0
347    pr-url: https://github.com/nodejs/node/pull/10638
348    description: The `options` parameter can be a WHATWG `URL` object.
349-->
350
351* `url` {string | URL}
352* `options` {Object | string | URL} Accepts all `options` from
353  [`http.request()`][], with some differences in default values:
354  * `protocol` **Default:** `'https:'`
355  * `port` **Default:** `443`
356  * `agent` **Default:** `https.globalAgent`
357* `callback` {Function}
358* Returns: {http.ClientRequest}
359
360Makes a request to a secure web server.
361
362The following additional `options` from [`tls.connect()`][] are also accepted:
363`ca`, `cert`, `ciphers`, `clientCertEngine`, `crl`, `dhparam`, `ecdhCurve`,
364`honorCipherOrder`, `key`, `passphrase`, `pfx`, `rejectUnauthorized`,
365`secureOptions`, `secureProtocol`, `servername`, `sessionIdContext`,
366`highWaterMark`.
367
368`options` can be an object, a string, or a [`URL`][] object. If `options` is a
369string, it is automatically parsed with [`new URL()`][]. If it is a [`URL`][]
370object, it will be automatically converted to an ordinary `options` object.
371
372`https.request()` returns an instance of the [`http.ClientRequest`][]
373class. The `ClientRequest` instance is a writable stream. If one needs to
374upload a file with a POST request, then write to the `ClientRequest` object.
375
376```js
377const https = require('node:https');
378
379const options = {
380  hostname: 'encrypted.google.com',
381  port: 443,
382  path: '/',
383  method: 'GET',
384};
385
386const req = https.request(options, (res) => {
387  console.log('statusCode:', res.statusCode);
388  console.log('headers:', res.headers);
389
390  res.on('data', (d) => {
391    process.stdout.write(d);
392  });
393});
394
395req.on('error', (e) => {
396  console.error(e);
397});
398req.end();
399```
400
401Example using options from [`tls.connect()`][]:
402
403```js
404const options = {
405  hostname: 'encrypted.google.com',
406  port: 443,
407  path: '/',
408  method: 'GET',
409  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
410  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem'),
411};
412options.agent = new https.Agent(options);
413
414const req = https.request(options, (res) => {
415  // ...
416});
417```
418
419Alternatively, opt out of connection pooling by not using an [`Agent`][].
420
421```js
422const options = {
423  hostname: 'encrypted.google.com',
424  port: 443,
425  path: '/',
426  method: 'GET',
427  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
428  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem'),
429  agent: false,
430};
431
432const req = https.request(options, (res) => {
433  // ...
434});
435```
436
437Example using a [`URL`][] as `options`:
438
439```js
440const options = new URL('https://abc:xyz@example.com');
441
442const req = https.request(options, (res) => {
443  // ...
444});
445```
446
447Example pinning on certificate fingerprint, or the public key (similar to
448`pin-sha256`):
449
450```js
451const tls = require('node:tls');
452const https = require('node:https');
453const crypto = require('node:crypto');
454
455function sha256(s) {
456  return crypto.createHash('sha256').update(s).digest('base64');
457}
458const options = {
459  hostname: 'github.com',
460  port: 443,
461  path: '/',
462  method: 'GET',
463  checkServerIdentity: function(host, cert) {
464    // Make sure the certificate is issued to the host we are connected to
465    const err = tls.checkServerIdentity(host, cert);
466    if (err) {
467      return err;
468    }
469
470    // Pin the public key, similar to HPKP pin-sha256 pinning
471    const pubkey256 = 'pL1+qb9HTMRZJmuC/bB/ZI9d302BYrrqiVuRyW+DGrU=';
472    if (sha256(cert.pubkey) !== pubkey256) {
473      const msg = 'Certificate verification error: ' +
474        `The public key of '${cert.subject.CN}' ` +
475        'does not match our pinned fingerprint';
476      return new Error(msg);
477    }
478
479    // Pin the exact certificate, rather than the pub key
480    const cert256 = '25:FE:39:32:D9:63:8C:8A:FC:A1:9A:29:87:' +
481      'D8:3E:4C:1D:98:DB:71:E4:1A:48:03:98:EA:22:6A:BD:8B:93:16';
482    if (cert.fingerprint256 !== cert256) {
483      const msg = 'Certificate verification error: ' +
484        `The certificate of '${cert.subject.CN}' ` +
485        'does not match our pinned fingerprint';
486      return new Error(msg);
487    }
488
489    // This loop is informational only.
490    // Print the certificate and public key fingerprints of all certs in the
491    // chain. Its common to pin the public key of the issuer on the public
492    // internet, while pinning the public key of the service in sensitive
493    // environments.
494    do {
495      console.log('Subject Common Name:', cert.subject.CN);
496      console.log('  Certificate SHA256 fingerprint:', cert.fingerprint256);
497
498      hash = crypto.createHash('sha256');
499      console.log('  Public key ping-sha256:', sha256(cert.pubkey));
500
501      lastprint256 = cert.fingerprint256;
502      cert = cert.issuerCertificate;
503    } while (cert.fingerprint256 !== lastprint256);
504
505  },
506};
507
508options.agent = new https.Agent(options);
509const req = https.request(options, (res) => {
510  console.log('All OK. Server matched our pinned cert or public key');
511  console.log('statusCode:', res.statusCode);
512  // Print the HPKP values
513  console.log('headers:', res.headers['public-key-pins']);
514
515  res.on('data', (d) => {});
516});
517
518req.on('error', (e) => {
519  console.error(e.message);
520});
521req.end();
522```
523
524Outputs for example:
525
526```text
527Subject Common Name: github.com
528  Certificate SHA256 fingerprint: 25:FE:39:32:D9:63:8C:8A:FC:A1:9A:29:87:D8:3E:4C:1D:98:DB:71:E4:1A:48:03:98:EA:22:6A:BD:8B:93:16
529  Public key ping-sha256: pL1+qb9HTMRZJmuC/bB/ZI9d302BYrrqiVuRyW+DGrU=
530Subject Common Name: DigiCert SHA2 Extended Validation Server CA
531  Certificate SHA256 fingerprint: 40:3E:06:2A:26:53:05:91:13:28:5B:AF:80:A0:D4:AE:42:2C:84:8C:9F:78:FA:D0:1F:C9:4B:C5:B8:7F:EF:1A
532  Public key ping-sha256: RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho=
533Subject Common Name: DigiCert High Assurance EV Root CA
534  Certificate SHA256 fingerprint: 74:31:E5:F4:C3:C1:CE:46:90:77:4F:0B:61:E0:54:40:88:3B:A9:A0:1E:D0:0B:A6:AB:D7:80:6E:D3:B1:18:CF
535  Public key ping-sha256: WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=
536All OK. Server matched our pinned cert or public key
537statusCode: 200
538headers: max-age=0; pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="; pin-sha256="RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho="; pin-sha256="k2v657xBsOVe1PQRwOsHsw3bsGT2VzIqz5K+59sNQws="; pin-sha256="K87oWBWM9UZfyddvDfoxL+8lpNyoUB2ptGtn0fv6G2Q="; pin-sha256="IQBnNBEiFuhj+8x6X8XLgh01V9Ic5/V3IRQLNFFc7v4="; pin-sha256="iie1VXtL7HzAMF+/PVPR9xzT80kQxdZeJ+zduCB3uj0="; pin-sha256="LvRiGEjRqfzurezaWuj8Wie2gyHMrW5Q06LspMnox7A="; includeSubDomains
539```
540
541[`Agent`]: #class-httpsagent
542[`Session Resumption`]: tls.md#session-resumption
543[`URL`]: url.md#the-whatwg-url-api
544[`http.Agent(options)`]: http.md#new-agentoptions
545[`http.Agent`]: http.md#class-httpagent
546[`http.ClientRequest`]: http.md#class-httpclientrequest
547[`http.Server`]: http.md#class-httpserver
548[`http.createServer()`]: http.md#httpcreateserveroptions-requestlistener
549[`http.get()`]: http.md#httpgetoptions-callback
550[`http.request()`]: http.md#httprequestoptions-callback
551[`https.Agent`]: #class-httpsagent
552[`https.request()`]: #httpsrequestoptions-callback
553[`import()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import
554[`net.Server`]: net.md#class-netserver
555[`new URL()`]: url.md#new-urlinput-base
556[`server.close()`]: http.md#serverclosecallback
557[`server.closeAllConnections()`]: http.md#servercloseallconnections
558[`server.closeIdleConnections()`]: http.md#servercloseidleconnections
559[`server.headersTimeout`]: http.md#serverheaderstimeout
560[`server.keepAliveTimeout`]: http.md#serverkeepalivetimeout
561[`server.listen()`]: net.md#serverlisten
562[`server.maxHeadersCount`]: http.md#servermaxheaderscount
563[`server.requestTimeout`]: http.md#serverrequesttimeout
564[`server.setTimeout()`]: http.md#serversettimeoutmsecs-callback
565[`server.timeout`]: http.md#servertimeout
566[`tls.connect()`]: tls.md#tlsconnectoptions-callback
567[`tls.createSecureContext()`]: tls.md#tlscreatesecurecontextoptions
568[`tls.createServer()`]: tls.md#tlscreateserveroptions-secureconnectionlistener
569[sni wiki]: https://en.wikipedia.org/wiki/Server_Name_Indication
570