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