Skip to content

Commit cdc6713

Browse files
mfdebiantargos
authored andcommitted
doc: add esm examples to node:https
PR-URL: #54399 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
1 parent 4f421b3 commit cdc6713

File tree

1 file changed

+187
-26
lines changed

1 file changed

+187
-26
lines changed

doc/api/https.md

Lines changed: 187 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -243,14 +243,30 @@ added: v0.3.4
243243
* `requestListener` {Function} A listener to be added to the `'request'` event.
244244
* Returns: {https.Server}
245245

246-
```js
246+
```mjs
247+
// curl -k https://localhost:8000/
248+
import { createServer } from 'node:https';
249+
import { readFileSync } from 'node:fs';
250+
251+
const options = {
252+
key: readFileSync('private-key.pem'),
253+
cert: readFileSync('certificate.pem'),
254+
};
255+
256+
createServer(options, (req, res) => {
257+
res.writeHead(200);
258+
res.end('hello world\n');
259+
}).listen(8000);
260+
```
261+
262+
```cjs
247263
// curl -k https://localhost:8000/
248264
const https = require('node:https');
249265
const fs = require('node:fs');
250266

251267
const options = {
252-
key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
253-
cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem'),
268+
key: fs.readFileSync('private-key.pem'),
269+
cert: fs.readFileSync('certificate.pem'),
254270
};
255271

256272
https.createServer(options, (req, res) => {
@@ -261,12 +277,27 @@ https.createServer(options, (req, res) => {
261277

262278
Or
263279

264-
```js
280+
```mjs
281+
import { createServer } from 'node:https';
282+
import { readFileSync } from 'node:fs';
283+
284+
const options = {
285+
pfx: readFileSync('test_cert.pfx'),
286+
passphrase: 'sample',
287+
};
288+
289+
createServer(options, (req, res) => {
290+
res.writeHead(200);
291+
res.end('hello world\n');
292+
}).listen(8000);
293+
```
294+
295+
```cjs
265296
const https = require('node:https');
266297
const fs = require('node:fs');
267298

268299
const options = {
269-
pfx: fs.readFileSync('test/fixtures/test_cert.pfx'),
300+
pfx: fs.readFileSync('test_cert.pfx'),
270301
passphrase: 'sample',
271302
};
272303

@@ -276,6 +307,20 @@ https.createServer(options, (req, res) => {
276307
}).listen(8000);
277308
```
278309

310+
To generate the certificate and key for this example, run:
311+
312+
```bash
313+
openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \
314+
-keyout private-key.pem -out certificate.pem
315+
```
316+
317+
Then, to generate the `pfx` certificate for this example, run:
318+
319+
```bash
320+
openssl pkcs12 -certpbe AES-256-CBC -export -out test_cert.pfx \
321+
-inkey private-key.pem -in certificate.pem -passout pass:sample
322+
```
323+
279324
## `https.get(options[, callback])`
280325

281326
## `https.get(url[, options][, callback])`
@@ -303,7 +348,24 @@ Like [`http.get()`][] but for HTTPS.
303348
string, it is automatically parsed with [`new URL()`][]. If it is a [`URL`][]
304349
object, it will be automatically converted to an ordinary `options` object.
305350

306-
```js
351+
```mjs
352+
import { get } from 'node:https';
353+
import process from 'node:process';
354+
355+
get('https://encrypted.google.com/', (res) => {
356+
console.log('statusCode:', res.statusCode);
357+
console.log('headers:', res.headers);
358+
359+
res.on('data', (d) => {
360+
process.stdout.write(d);
361+
});
362+
363+
}).on('error', (e) => {
364+
console.error(e);
365+
});
366+
```
367+
368+
```cjs
307369
const https = require('node:https');
308370

309371
https.get('https://encrypted.google.com/', (res) => {
@@ -394,7 +456,33 @@ object, it will be automatically converted to an ordinary `options` object.
394456
class. The `ClientRequest` instance is a writable stream. If one needs to
395457
upload a file with a POST request, then write to the `ClientRequest` object.
396458

397-
```js
459+
```mjs
460+
import { request } from 'node:https';
461+
import process from 'node:process';
462+
463+
const options = {
464+
hostname: 'encrypted.google.com',
465+
port: 443,
466+
path: '/',
467+
method: 'GET',
468+
};
469+
470+
const req = request(options, (res) => {
471+
console.log('statusCode:', res.statusCode);
472+
console.log('headers:', res.headers);
473+
474+
res.on('data', (d) => {
475+
process.stdout.write(d);
476+
});
477+
});
478+
479+
req.on('error', (e) => {
480+
console.error(e);
481+
});
482+
req.end();
483+
```
484+
485+
```cjs
398486
const https = require('node:https');
399487

400488
const options = {
@@ -427,8 +515,8 @@ const options = {
427515
port: 443,
428516
path: '/',
429517
method: 'GET',
430-
key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
431-
cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem'),
518+
key: fs.readFileSync('private-key.pem'),
519+
cert: fs.readFileSync('certificate.pem'),
432520
};
433521
options.agent = new https.Agent(options);
434522

@@ -445,8 +533,8 @@ const options = {
445533
port: 443,
446534
path: '/',
447535
method: 'GET',
448-
key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
449-
cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem'),
536+
key: fs.readFileSync('private-key.pem'),
537+
cert: fs.readFileSync('certificate.pem'),
450538
agent: false,
451539
};
452540

@@ -468,7 +556,80 @@ const req = https.request(options, (res) => {
468556
Example pinning on certificate fingerprint, or the public key (similar to
469557
`pin-sha256`):
470558

471-
```js
559+
```mjs
560+
import { checkServerIdentity } from 'node:tls';
561+
import { Agent, request } from 'node:https';
562+
import { createHash } from 'node:crypto';
563+
564+
function sha256(s) {
565+
return createHash('sha256').update(s).digest('base64');
566+
}
567+
const options = {
568+
hostname: 'github.com',
569+
port: 443,
570+
path: '/',
571+
method: 'GET',
572+
checkServerIdentity: function(host, cert) {
573+
// Make sure the certificate is issued to the host we are connected to
574+
const err = checkServerIdentity(host, cert);
575+
if (err) {
576+
return err;
577+
}
578+
579+
// Pin the public key, similar to HPKP pin-sha256 pinning
580+
const pubkey256 = 'SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8=';
581+
if (sha256(cert.pubkey) !== pubkey256) {
582+
const msg = 'Certificate verification error: ' +
583+
`The public key of '${cert.subject.CN}' ` +
584+
'does not match our pinned fingerprint';
585+
return new Error(msg);
586+
}
587+
588+
// Pin the exact certificate, rather than the pub key
589+
const cert256 = 'FD:6E:9B:0E:F3:98:BC:D9:04:C3:B2:EC:16:7A:7B:' +
590+
'0F:DA:72:01:C9:03:C5:3A:6A:6A:E5:D0:41:43:63:EF:65';
591+
if (cert.fingerprint256 !== cert256) {
592+
const msg = 'Certificate verification error: ' +
593+
`The certificate of '${cert.subject.CN}' ` +
594+
'does not match our pinned fingerprint';
595+
return new Error(msg);
596+
}
597+
598+
// This loop is informational only.
599+
// Print the certificate and public key fingerprints of all certs in the
600+
// chain. Its common to pin the public key of the issuer on the public
601+
// internet, while pinning the public key of the service in sensitive
602+
// environments.
603+
let lastprint256;
604+
do {
605+
console.log('Subject Common Name:', cert.subject.CN);
606+
console.log(' Certificate SHA256 fingerprint:', cert.fingerprint256);
607+
608+
const hash = createHash('sha256');
609+
console.log(' Public key ping-sha256:', sha256(cert.pubkey));
610+
611+
lastprint256 = cert.fingerprint256;
612+
cert = cert.issuerCertificate;
613+
} while (cert.fingerprint256 !== lastprint256);
614+
615+
},
616+
};
617+
618+
options.agent = new Agent(options);
619+
const req = request(options, (res) => {
620+
console.log('All OK. Server matched our pinned cert or public key');
621+
console.log('statusCode:', res.statusCode);
622+
623+
res.on('data', (d) => {});
624+
});
625+
626+
req.on('error', (e) => {
627+
console.error(e.message);
628+
});
629+
req.end();
630+
```
631+
632+
```cjs
472633
const tls = require('node:tls');
473634
const https = require('node:https');
474635
const crypto = require('node:crypto');
@@ -489,7 +650,7 @@ const options = {
489650
}
490651

491652
// Pin the public key, similar to HPKP pin-sha256 pinning
492-
const pubkey256 = 'pL1+qb9HTMRZJmuC/bB/ZI9d302BYrrqiVuRyW+DGrU=';
653+
const pubkey256 = 'SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8=';
493654
if (sha256(cert.pubkey) !== pubkey256) {
494655
const msg = 'Certificate verification error: ' +
495656
`The public key of '${cert.subject.CN}' ` +
@@ -498,8 +659,8 @@ const options = {
498659
}
499660

500661
// Pin the exact certificate, rather than the pub key
501-
const cert256 = '25:FE:39:32:D9:63:8C:8A:FC:A1:9A:29:87:' +
502-
'D8:3E:4C:1D:98:DB:71:E4:1A:48:03:98:EA:22:6A:BD:8B:93:16';
662+
const cert256 = 'FD:6E:9B:0E:F3:98:BC:D9:04:C3:B2:EC:16:7A:7B:' +
663+
'0F:DA:72:01:C9:03:C5:3A:6A:6A:E5:D0:41:43:63:EF:65';
503664
if (cert.fingerprint256 !== cert256) {
504665
const msg = 'Certificate verification error: ' +
505666
`The certificate of '${cert.subject.CN}' ` +
@@ -530,8 +691,6 @@ options.agent = new https.Agent(options);
530691
const req = https.request(options, (res) => {
531692
console.log('All OK. Server matched our pinned cert or public key');
532693
console.log('statusCode:', res.statusCode);
533-
// Print the HPKP values
534-
console.log('headers:', res.headers['public-key-pins']);
535694

536695
res.on('data', (d) => {});
537696
});
@@ -546,17 +705,19 @@ Outputs for example:
546705

547706
```text
548707
Subject Common Name: github.com
549-
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
550-
Public key ping-sha256: pL1+qb9HTMRZJmuC/bB/ZI9d302BYrrqiVuRyW+DGrU=
551-
Subject Common Name: DigiCert SHA2 Extended Validation Server CA
552-
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
553-
Public key ping-sha256: RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho=
554-
Subject Common Name: DigiCert High Assurance EV Root CA
555-
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
556-
Public key ping-sha256: WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=
708+
Certificate SHA256 fingerprint: FD:6E:9B:0E:F3:98:BC:D9:04:C3:B2:EC:16:7A:7B:0F:DA:72:01:C9:03:C5:3A:6A:6A:E5:D0:41:43:63:EF:65
709+
Public key ping-sha256: SIXvRyDmBJSgatgTQRGbInBaAK+hZOQ18UmrSwnDlK8=
710+
Subject Common Name: Sectigo ECC Domain Validation Secure Server CA
711+
Certificate SHA256 fingerprint: 61:E9:73:75:E9:F6:DA:98:2F:F5:C1:9E:2F:94:E6:6C:4E:35:B6:83:7C:E3:B9:14:D2:24:5C:7F:5F:65:82:5F
712+
Public key ping-sha256: Eep0p/AsSa9lFUH6KT2UY+9s1Z8v7voAPkQ4fGknZ2g=
713+
Subject Common Name: USERTrust ECC Certification Authority
714+
Certificate SHA256 fingerprint: A6:CF:64:DB:B4:C8:D5:FD:19:CE:48:89:60:68:DB:03:B5:33:A8:D1:33:6C:62:56:A8:7D:00:CB:B3:DE:F3:EA
715+
Public key ping-sha256: UJM2FOhG9aTNY0Pg4hgqjNzZ/lQBiMGRxPD5Y2/e0bw=
716+
Subject Common Name: AAA Certificate Services
717+
Certificate SHA256 fingerprint: D7:A7:A0:FB:5D:7E:27:31:D7:71:E9:48:4E:BC:DE:F7:1D:5F:0C:3E:0A:29:48:78:2B:C8:3E:E0:EA:69:9E:F4
718+
Public key ping-sha256: vRU+17BDT2iGsXvOi76E7TQMcTLXAqj0+jGPdW7L1vM=
557719
All OK. Server matched our pinned cert or public key
558720
statusCode: 200
559-
headers: 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
560721
```
561722

562723
[`Agent`]: #class-httpsagent

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy