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