| 'use strict'; |
| const common = require('../common'); |
| |
| if (!common.hasCrypto) |
| common.skip('missing crypto'); |
| |
| // This test verifies the behavior of the tls setSecureContext() method. |
| // It also verifies that existing connections are not disrupted when the |
| // secure context is changed. |
| |
| const assert = require('assert'); |
| const events = require('events'); |
| const https = require('https'); |
| const timers = require('timers/promises'); |
| const fixtures = require('../common/fixtures'); |
| const credentialOptions = [ |
| { |
| key: fixtures.readKey('agent1-key.pem'), |
| cert: fixtures.readKey('agent1-cert.pem'), |
| ca: fixtures.readKey('ca1-cert.pem') |
| }, |
| { |
| key: fixtures.readKey('agent2-key.pem'), |
| cert: fixtures.readKey('agent2-cert.pem'), |
| ca: fixtures.readKey('ca2-cert.pem') |
| }, |
| ]; |
| let firstResponse; |
| |
| const server = https.createServer(credentialOptions[0], (req, res) => { |
| const id = +req.headers.id; |
| |
| if (id === 1) { |
| firstResponse = res; |
| firstResponse.write('multi-'); |
| return; |
| } else if (id === 4) { |
| firstResponse.write('success-'); |
| } |
| |
| res.end('success'); |
| }); |
| |
| server.listen(0, common.mustCall(() => { |
| const { port } = server.address(); |
| const firstRequest = makeRequest(port, 1); |
| |
| (async function makeRemainingRequests() { |
| // Wait until the first request is guaranteed to have been handled. |
| while (!firstResponse) { |
| await timers.setImmediate(); |
| } |
| |
| assert.strictEqual(await makeRequest(port, 2), 'success'); |
| |
| server.setSecureContext(credentialOptions[1]); |
| firstResponse.write('request-'); |
| const errorMessageRegex = common.hasOpenSSL3 ? |
| /^Error: self-signed certificate$/ : |
| /^Error: self signed certificate$/; |
| await assert.rejects(makeRequest(port, 3), errorMessageRegex); |
| |
| server.setSecureContext(credentialOptions[0]); |
| assert.strictEqual(await makeRequest(port, 4), 'success'); |
| |
| server.setSecureContext(credentialOptions[1]); |
| firstResponse.end('fun!'); |
| await assert.rejects(makeRequest(port, 5), errorMessageRegex); |
| |
| assert.strictEqual(await firstRequest, 'multi-request-success-fun!'); |
| server.close(); |
| })().then(common.mustCall()); |
| })); |
| |
| async function makeRequest(port, id) { |
| const options = { |
| rejectUnauthorized: true, |
| ca: credentialOptions[0].ca, |
| servername: 'agent1', |
| headers: { id }, |
| agent: new https.Agent() |
| }; |
| |
| const req = https.get(`https://localhost:${port}`, options); |
| |
| let errored = false; |
| req.on('error', () => errored = true); |
| req.on('finish', () => assert.strictEqual(errored, false)); |
| |
| const [res] = await events.once(req, 'response'); |
| res.setEncoding('utf8'); |
| let response = ''; |
| for await (const chunk of res) response += chunk; |
| return response; |
| } |