• 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## Class: `https.Agent`
13<!-- YAML
14added: v0.4.5
15changes:
16  - version: v5.3.0
17    pr-url: https://github.com/nodejs/node/pull/4252
18    description: support `0` `maxCachedSessions` to disable TLS session caching.
19  - version: v2.5.0
20    pr-url: https://github.com/nodejs/node/pull/2228
21    description: parameter `maxCachedSessions` added to `options` for TLS
22                 sessions reuse.
23-->
24
25An [`Agent`][] object for HTTPS similar to [`http.Agent`][]. See
26[`https.request()`][] for more information.
27
28### `new Agent([options])`
29<!-- YAML
30changes:
31  - version: v12.5.0
32    pr-url: https://github.com/nodejs/node/pull/28209
33    description: do not automatically set servername if the target host was
34                 specified using an IP address.
35-->
36
37* `options` {Object} Set of configurable options to set on the agent.
38  Can have the same fields as for [`http.Agent(options)`][], and
39  * `maxCachedSessions` {number} maximum number of TLS cached sessions.
40    Use `0` to disable TLS session caching. **Default:** `100`.
41  * `servername` {string} the value of
42    [Server Name Indication extension][sni wiki] to be sent to the server. Use
43    empty string `''` to disable sending the extension.
44    **Default:** host name of the target server, unless the target server
45    is specified using an IP address, in which case the default is `''` (no
46    extension).
47
48    See [`Session Resumption`][] for information about TLS session reuse.
49
50#### Event: `'keylog'`
51<!-- YAML
52added:
53 - v13.2.0
54 - v12.16.0
55-->
56
57* `line` {Buffer} Line of ASCII text, in NSS `SSLKEYLOGFILE` format.
58* `tlsSocket` {tls.TLSSocket} The `tls.TLSSocket` instance on which it was
59  generated.
60
61The `keylog` event is emitted when key material is generated or received by a
62connection managed by this agent (typically before handshake has completed, but
63not necessarily). This keying material can be stored for debugging, as it
64allows captured TLS traffic to be decrypted. It may be emitted multiple times
65for each socket.
66
67A typical use case is to append received lines to a common text file, which is
68later used by software (such as Wireshark) to decrypt the traffic:
69
70```js
71// ...
72https.globalAgent.on('keylog', (line, tlsSocket) => {
73  fs.appendFileSync('/tmp/ssl-keys.log', line, { mode: 0o600 });
74});
75```
76
77## Class: `https.Server`
78<!-- YAML
79added: v0.3.4
80-->
81
82* Extends: {tls.Server}
83
84See [`http.Server`][] for more information.
85
86### `server.close([callback])`
87<!-- YAML
88added: v0.1.90
89-->
90
91* `callback` {Function}
92* Returns: {https.Server}
93
94See [`server.close()`][`http.close()`] from the HTTP module for details.
95
96### `server.headersTimeout`
97<!-- YAML
98added: v11.3.0
99-->
100
101* {number} **Default:** `60000`
102
103See [`http.Server#headersTimeout`][].
104
105### `server.listen()`
106
107Starts the HTTPS server listening for encrypted connections.
108This method is identical to [`server.listen()`][] from [`net.Server`][].
109
110### `server.maxHeadersCount`
111
112* {number} **Default:** `2000`
113
114See [`http.Server#maxHeadersCount`][].
115
116### `server.requestTimeout`
117<!-- YAML
118added: v14.11.0
119-->
120
121* {number} **Default:** `0`
122
123See [`http.Server#requestTimeout`][].
124
125### `server.setTimeout([msecs][, callback])`
126<!-- YAML
127added: v0.11.2
128-->
129
130* `msecs` {number} **Default:** `120000` (2 minutes)
131* `callback` {Function}
132* Returns: {https.Server}
133
134See [`http.Server#setTimeout()`][].
135
136### `server.timeout`
137<!-- YAML
138added: v0.11.2
139changes:
140  - version: v13.0.0
141    pr-url: https://github.com/nodejs/node/pull/27558
142    description: The default timeout changed from 120s to 0 (no timeout).
143-->
144
145* {number} **Default:** 0 (no timeout)
146
147See [`http.Server#timeout`][].
148
149### `server.keepAliveTimeout`
150<!-- YAML
151added: v8.0.0
152-->
153
154* {number} **Default:** `5000` (5 seconds)
155
156See [`http.Server#keepAliveTimeout`][].
157
158## `https.createServer([options][, requestListener])`
159<!-- YAML
160added: v0.3.4
161-->
162
163* `options` {Object} Accepts `options` from [`tls.createServer()`][],
164  [`tls.createSecureContext()`][] and [`http.createServer()`][].
165* `requestListener` {Function} A listener to be added to the `'request'` event.
166* Returns: {https.Server}
167
168```js
169// curl -k https://localhost:8000/
170const https = require('https');
171const fs = require('fs');
172
173const options = {
174  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
175  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
176};
177
178https.createServer(options, (req, res) => {
179  res.writeHead(200);
180  res.end('hello world\n');
181}).listen(8000);
182```
183
184Or
185
186```js
187const https = require('https');
188const fs = require('fs');
189
190const options = {
191  pfx: fs.readFileSync('test/fixtures/test_cert.pfx'),
192  passphrase: 'sample'
193};
194
195https.createServer(options, (req, res) => {
196  res.writeHead(200);
197  res.end('hello world\n');
198}).listen(8000);
199```
200
201## `https.get(options[, callback])`
202## `https.get(url[, options][, callback])`
203<!-- YAML
204added: v0.3.6
205changes:
206  - version: v10.9.0
207    pr-url: https://github.com/nodejs/node/pull/21616
208    description: The `url` parameter can now be passed along with a separate
209                 `options` object.
210  - version: v7.5.0
211    pr-url: https://github.com/nodejs/node/pull/10638
212    description: The `options` parameter can be a WHATWG `URL` object.
213-->
214
215* `url` {string | URL}
216* `options` {Object | string | URL} Accepts the same `options` as
217  [`https.request()`][], with the `method` always set to `GET`.
218* `callback` {Function}
219
220Like [`http.get()`][] but for HTTPS.
221
222`options` can be an object, a string, or a [`URL`][] object. If `options` is a
223string, it is automatically parsed with [`new URL()`][]. If it is a [`URL`][]
224object, it will be automatically converted to an ordinary `options` object.
225
226```js
227const https = require('https');
228
229https.get('https://encrypted.google.com/', (res) => {
230  console.log('statusCode:', res.statusCode);
231  console.log('headers:', res.headers);
232
233  res.on('data', (d) => {
234    process.stdout.write(d);
235  });
236
237}).on('error', (e) => {
238  console.error(e);
239});
240```
241
242## `https.globalAgent`
243<!-- YAML
244added: v0.5.9
245-->
246
247Global instance of [`https.Agent`][] for all HTTPS client requests.
248
249## `https.request(options[, callback])`
250## `https.request(url[, options][, callback])`
251<!-- YAML
252added: v0.3.6
253changes:
254  - version: v14.18.0
255    pr-url: https://github.com/nodejs/node/pull/39310
256    description: When using a `URL` object parsed username
257                 and password will now be properly URI decoded.
258  - version: v14.1.0
259    pr-url: https://github.com/nodejs/node/pull/32786
260    description: The `highWaterMark` option is accepted now.
261  - version: v10.9.0
262    pr-url: https://github.com/nodejs/node/pull/21616
263    description: The `url` parameter can now be passed along with a separate
264                 `options` object.
265  - version: v9.3.0
266    pr-url: https://github.com/nodejs/node/pull/14903
267    description: The `options` parameter can now include `clientCertEngine`.
268  - version: v7.5.0
269    pr-url: https://github.com/nodejs/node/pull/10638
270    description: The `options` parameter can be a WHATWG `URL` object.
271-->
272
273* `url` {string | URL}
274* `options` {Object | string | URL} Accepts all `options` from
275  [`http.request()`][], with some differences in default values:
276  * `protocol` **Default:** `'https:'`
277  * `port` **Default:** `443`
278  * `agent` **Default:** `https.globalAgent`
279* `callback` {Function}
280* Returns: {http.ClientRequest}
281
282Makes a request to a secure web server.
283
284The following additional `options` from [`tls.connect()`][] are also accepted:
285`ca`, `cert`, `ciphers`, `clientCertEngine`, `crl`, `dhparam`, `ecdhCurve`,
286`honorCipherOrder`, `key`, `passphrase`, `pfx`, `rejectUnauthorized`,
287`secureOptions`, `secureProtocol`, `servername`, `sessionIdContext`,
288`highWaterMark`.
289
290`options` can be an object, a string, or a [`URL`][] object. If `options` is a
291string, it is automatically parsed with [`new URL()`][]. If it is a [`URL`][]
292object, it will be automatically converted to an ordinary `options` object.
293
294`https.request()` returns an instance of the [`http.ClientRequest`][]
295class. The `ClientRequest` instance is a writable stream. If one needs to
296upload a file with a POST request, then write to the `ClientRequest` object.
297
298```js
299const https = require('https');
300
301const options = {
302  hostname: 'encrypted.google.com',
303  port: 443,
304  path: '/',
305  method: 'GET'
306};
307
308const req = https.request(options, (res) => {
309  console.log('statusCode:', res.statusCode);
310  console.log('headers:', res.headers);
311
312  res.on('data', (d) => {
313    process.stdout.write(d);
314  });
315});
316
317req.on('error', (e) => {
318  console.error(e);
319});
320req.end();
321```
322
323Example using options from [`tls.connect()`][]:
324
325```js
326const options = {
327  hostname: 'encrypted.google.com',
328  port: 443,
329  path: '/',
330  method: 'GET',
331  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
332  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
333};
334options.agent = new https.Agent(options);
335
336const req = https.request(options, (res) => {
337  // ...
338});
339```
340
341Alternatively, opt out of connection pooling by not using an [`Agent`][].
342
343```js
344const options = {
345  hostname: 'encrypted.google.com',
346  port: 443,
347  path: '/',
348  method: 'GET',
349  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
350  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem'),
351  agent: false
352};
353
354const req = https.request(options, (res) => {
355  // ...
356});
357```
358
359Example using a [`URL`][] as `options`:
360
361```js
362const options = new URL('https://abc:xyz@example.com');
363
364const req = https.request(options, (res) => {
365  // ...
366});
367```
368
369Example pinning on certificate fingerprint, or the public key (similar to
370`pin-sha256`):
371
372```js
373const tls = require('tls');
374const https = require('https');
375const crypto = require('crypto');
376
377function sha256(s) {
378  return crypto.createHash('sha256').update(s).digest('base64');
379}
380const options = {
381  hostname: 'github.com',
382  port: 443,
383  path: '/',
384  method: 'GET',
385  checkServerIdentity: function(host, cert) {
386    // Make sure the certificate is issued to the host we are connected to
387    const err = tls.checkServerIdentity(host, cert);
388    if (err) {
389      return err;
390    }
391
392    // Pin the public key, similar to HPKP pin-sha25 pinning
393    const pubkey256 = 'pL1+qb9HTMRZJmuC/bB/ZI9d302BYrrqiVuRyW+DGrU=';
394    if (sha256(cert.pubkey) !== pubkey256) {
395      const msg = 'Certificate verification error: ' +
396        `The public key of '${cert.subject.CN}' ` +
397        'does not match our pinned fingerprint';
398      return new Error(msg);
399    }
400
401    // Pin the exact certificate, rather than the pub key
402    const cert256 = '25:FE:39:32:D9:63:8C:8A:FC:A1:9A:29:87:' +
403      'D8:3E:4C:1D:98:DB:71:E4:1A:48:03:98:EA:22:6A:BD:8B:93:16';
404    if (cert.fingerprint256 !== cert256) {
405      const msg = 'Certificate verification error: ' +
406        `The certificate of '${cert.subject.CN}' ` +
407        'does not match our pinned fingerprint';
408      return new Error(msg);
409    }
410
411    // This loop is informational only.
412    // Print the certificate and public key fingerprints of all certs in the
413    // chain. Its common to pin the public key of the issuer on the public
414    // internet, while pinning the public key of the service in sensitive
415    // environments.
416    do {
417      console.log('Subject Common Name:', cert.subject.CN);
418      console.log('  Certificate SHA256 fingerprint:', cert.fingerprint256);
419
420      hash = crypto.createHash('sha256');
421      console.log('  Public key ping-sha256:', sha256(cert.pubkey));
422
423      lastprint256 = cert.fingerprint256;
424      cert = cert.issuerCertificate;
425    } while (cert.fingerprint256 !== lastprint256);
426
427  },
428};
429
430options.agent = new https.Agent(options);
431const req = https.request(options, (res) => {
432  console.log('All OK. Server matched our pinned cert or public key');
433  console.log('statusCode:', res.statusCode);
434  // Print the HPKP values
435  console.log('headers:', res.headers['public-key-pins']);
436
437  res.on('data', (d) => {});
438});
439
440req.on('error', (e) => {
441  console.error(e.message);
442});
443req.end();
444```
445
446Outputs for example:
447
448```text
449Subject Common Name: github.com
450  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
451  Public key ping-sha256: pL1+qb9HTMRZJmuC/bB/ZI9d302BYrrqiVuRyW+DGrU=
452Subject Common Name: DigiCert SHA2 Extended Validation Server CA
453  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
454  Public key ping-sha256: RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho=
455Subject Common Name: DigiCert High Assurance EV Root CA
456  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
457  Public key ping-sha256: WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=
458All OK. Server matched our pinned cert or public key
459statusCode: 200
460headers: 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
461```
462
463[`Agent`]: #https_class_https_agent
464[`Session Resumption`]: tls.md#tls_session_resumption
465[`URL`]: url.md#url_the_whatwg_url_api
466[`http.Agent(options)`]: http.md#http_new_agent_options
467[`http.Agent`]: http.md#http_class_http_agent
468[`http.ClientRequest`]: http.md#http_class_http_clientrequest
469[`http.Server#headersTimeout`]: http.md#http_server_headerstimeout
470[`http.Server#keepAliveTimeout`]: http.md#http_server_keepalivetimeout
471[`http.Server#maxHeadersCount`]: http.md#http_server_maxheaderscount
472[`http.Server#requestTimeout`]: http.md#http_server_requesttimeout
473[`http.Server#setTimeout()`]: http.md#http_server_settimeout_msecs_callback
474[`http.Server#timeout`]: http.md#http_server_timeout
475[`http.Server`]: http.md#http_class_http_server
476[`http.close()`]: http.md#http_server_close_callback
477[`http.createServer()`]: http.md#http_http_createserver_options_requestlistener
478[`http.get()`]: http.md#http_http_get_options_callback
479[`http.request()`]: http.md#http_http_request_options_callback
480[`https.Agent`]: #https_class_https_agent
481[`https.request()`]: #https_https_request_options_callback
482[`net.Server`]: net.md#net_class_net_server
483[`new URL()`]: url.md#url_new_url_input_base
484[`server.listen()`]: net.md#net_server_listen
485[`tls.connect()`]: tls.md#tls_tls_connect_options_callback
486[`tls.createSecureContext()`]: tls.md#tls_tls_createsecurecontext_options
487[`tls.createServer()`]: tls.md#tls_tls_createserver_options_secureconnectionlistener
488[sni wiki]: https://en.wikipedia.org/wiki/Server_Name_Indication
489