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