@@ -35,34 +35,13 @@ const assert = require('assert'); |
35 | 35 | const tls = require('tls'); |
36 | 36 | const fixtures = require('../common/fixtures'); |
37 | 37 |
|
38 | | -const key = fixtures.readKey('rsa_private.pem'); |
39 | | -const cert = fixtures.readKey('rsa_cert.crt'); |
40 | | - |
41 | | -{ |
42 | | - // Node.js should not allow setting negative timeouts since new versions of |
43 | | - // OpenSSL do not handle those as users might expect |
44 | | - |
45 | | - for (const sessionTimeout of [-1, -100, -(2 ** 31)]) { |
46 | | - assert.throws(() => { |
47 | | - tls.createServer({ |
48 | | - key: key, |
49 | | - cert: cert, |
50 | | - ca: [cert], |
51 | | - sessionTimeout, |
52 | | - maxVersion: 'TLSv1.2', |
53 | | - }); |
54 | | - }, { |
55 | | - code: 'ERR_OUT_OF_RANGE', |
56 | | - message: 'The value of "options.sessionTimeout" is out of range. It ' + |
57 | | - `must be >= 0 && <= ${2 ** 31 - 1}. Received ${sessionTimeout}`, |
58 | | - }); |
59 | | - } |
60 | | -} |
61 | | - |
62 | 38 | if (!opensslCli) { |
63 | 39 | common.skip('node compiled without OpenSSL CLI.'); |
64 | 40 | } |
65 | 41 |
|
| 42 | +const key = fixtures.readKey('rsa_private.pem'); |
| 43 | +const cert = fixtures.readKey('rsa_cert.crt'); |
| 44 | + |
66 | 45 | doTest(); |
67 | 46 |
|
68 | 47 | // This test consists of three TLS requests -- |
@@ -77,40 +56,34 @@ function doTest() { |
77 | 56 | const fs = require('fs'); |
78 | 57 | const spawn = require('child_process').spawn; |
79 | 58 |
|
80 | | - const SESSION_TIMEOUT = 1; |
| 59 | + const SESSION_TIMEOUT = 5; |
81 | 60 |
|
82 | 61 | const options = { |
83 | 62 | key: key, |
84 | 63 | cert: cert, |
85 | 64 | ca: [cert], |
86 | 65 | sessionTimeout: SESSION_TIMEOUT, |
87 | 66 | maxVersion: 'TLSv1.2', |
| 67 | + sessionIdContext: 'test-session-timeout', |
88 | 68 | }; |
89 | 69 |
|
90 | | - // We need to store a sample session ticket in the fixtures directory because |
91 | | - // `s_client` behaves incorrectly if we do not pass in both the `-sess_in` |
92 | | - // and the `-sess_out` flags, and the `-sess_in` argument must point to a |
93 | | - // file containing a proper serialization of a session ticket. |
94 | | - // To avoid a source control diff, we copy the ticket to a temporary file. |
95 | | - |
96 | | - const sessionFileName = (function() { |
97 | | - const ticketFileName = 'tls-session-ticket.txt'; |
98 | | - const tmpPath = tmpdir.resolve(ticketFileName); |
99 | | - fs.writeFileSync(tmpPath, fixtures.readSync(ticketFileName)); |
100 | | - return tmpPath; |
101 | | - }()); |
102 | | - |
103 | | - // Expects a callback -- cb(connectionType : enum ['New'|'Reused']) |
104 | | - |
105 | | - function Client(cb) { |
| 70 | + const sessionFileName = tmpdir.resolve('tls-session-ticket.txt'); |
| 71 | + // Expects a callback -- cb() |
| 72 | + function Client(port, sessIn, sessOut, expectedType, cb) { |
106 | 73 | const flags = [ |
107 | 74 | 's_client', |
108 | | - '-connect', `localhost:${common.PORT}`, |
109 | | - '-sess_in', sessionFileName, |
110 | | - '-sess_out', sessionFileName, |
| 75 | + '-connect', `localhost:${port}`, |
| 76 | + '-CAfile', fixtures.path('keys', 'rsa_cert.crt'), |
| 77 | + '-servername', 'localhost', |
111 | 78 | ]; |
| 79 | + if (sessIn) { |
| 80 | + flags.push('-sess_in', sessIn); |
| 81 | + } |
| 82 | + if (sessOut) { |
| 83 | + flags.push('-sess_out', sessOut); |
| 84 | + } |
112 | 85 | const client = spawn(opensslCli, flags, { |
113 | | - stdio: ['ignore', 'pipe', 'ignore'] |
| 86 | + stdio: ['ignore', 'pipe', 'inherit'] |
114 | 87 | }); |
115 | 88 |
|
116 | 89 | let clientOutput = ''; |
@@ -119,6 +92,20 @@ function doTest() { |
119 | 92 | }); |
120 | 93 | client.on('exit', (code) => { |
121 | 94 | let connectionType; |
| 95 | + // Log the output for debugging purposes. Don't remove them or otherwise |
| 96 | + // the CI output is useless when this test flakes. |
| 97 | + console.log(' ----- [COMMAND] ---'); |
| 98 | + console.log(`${opensslCli}, ${flags.join(' ')}`); |
| 99 | + console.log(' ----- [STDOUT] ---'); |
| 100 | + console.log(clientOutput); |
| 101 | + console.log(' ----- [SESSION FILE] ---'); |
| 102 | + try { |
| 103 | + const stat = fs.statSync(sessionFileName); |
| 104 | + console.log(`Session file size: ${stat.size} bytes`); |
| 105 | + } catch (err) { |
| 106 | + console.log('Error reading session file:', err); |
| 107 | + } |
| 108 | + |
122 | 109 | const grepConnectionType = (line) => { |
123 | 110 | const matches = line.match(/(New|Reused), /); |
124 | 111 | if (matches) { |
@@ -131,6 +118,7 @@ function doTest() { |
131 | 118 | throw new Error('unexpected output from openssl client'); |
132 | 119 | } |
133 | 120 | assert.strictEqual(code, 0); |
| 121 | + assert.strictEqual(connectionType, expectedType); |
134 | 122 | cb(connectionType); |
135 | 123 | }); |
136 | 124 | } |
@@ -143,18 +131,18 @@ function doTest() { |
143 | 131 | cleartext.end(); |
144 | 132 | }); |
145 | 133 |
|
146 | | - server.listen(common.PORT, () => { |
147 | | - Client((connectionType) => { |
148 | | - assert.strictEqual(connectionType, 'New'); |
149 | | - Client((connectionType) => { |
150 | | - assert.strictEqual(connectionType, 'Reused'); |
151 | | - setTimeout(() => { |
152 | | - Client((connectionType) => { |
153 | | - assert.strictEqual(connectionType, 'New'); |
154 | | - server.close(); |
155 | | - }); |
156 | | - }, (SESSION_TIMEOUT + 1) * 1000); |
157 | | - }); |
| 134 | + server.listen(0, () => { |
| 135 | + const port = server.address().port; |
| 136 | + Client(port, undefined, sessionFileName, 'New', () => { |
| 137 | + setTimeout(() => { |
| 138 | + Client(port, sessionFileName, sessionFileName, 'Reused', () => { |
| 139 | + setTimeout(() => { |
| 140 | + Client(port, sessionFileName, sessionFileName, 'New', () => { |
| 141 | + server.close(); |
| 142 | + }); |
| 143 | + }, (SESSION_TIMEOUT + 1) * 1000); |
| 144 | + }); |
| 145 | + }, 100); // Wait a bit to ensure the session ticket is saved. |
158 | 146 | }); |
159 | 147 | }); |
160 | 148 | } |