Skip to content

Commit 1cf17df

Browse files
qubytervagg
authored andcommitted
tls: accept array of protocols in TLSSocket
Brings the ALPNProtocols & NPNProtocols options of TLSSocket in line with the documentation. i.e. an array of strings for protocols may be used, not only a buffer. Backport-PR-URL: #21721 PR-URL: #16655 Fixes: https://github.com/node/issues/16643 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Anatoli Papirovski <[email protected]>
1 parent d0588f1 commit 1cf17df

File tree

2 files changed

+90
-11
lines changed

2 files changed

+90
-11
lines changed

lib/_tls_wrap.js

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -262,11 +262,15 @@ function initRead(tls, wrapped) {
262262
* Provides a wrap of socket stream to do encrypted communication.
263263
*/
264264

265-
function TLSSocket(socket, options) {
266-
if (options === undefined)
267-
this._tlsOptions = {};
268-
else
269-
this._tlsOptions = options;
265+
function TLSSocket(socket, opts) {
266+
const tlsOptions = Object.assign({}, opts);
267+
268+
if (tlsOptions.NPNProtocols)
269+
tls.convertNPNProtocols(tlsOptions.NPNProtocols, tlsOptions);
270+
if (tlsOptions.ALPNProtocols)
271+
tls.convertALPNProtocols(tlsOptions.ALPNProtocols, tlsOptions);
272+
273+
this._tlsOptions = tlsOptions;
270274
this._secureEstablished = false;
271275
this._securePending = false;
272276
this._newSessionPending = false;
@@ -1044,11 +1048,8 @@ exports.connect = function(...args /* [port,] [host,] [options,] [cb] */) {
10441048
options.host ||
10451049
(options.socket && options.socket._host) ||
10461050
'localhost';
1047-
const NPN = {};
1048-
const ALPN = {};
1051+
10491052
const context = options.secureContext || tls.createSecureContext(options);
1050-
tls.convertNPNProtocols(options.NPNProtocols, NPN);
1051-
tls.convertALPNProtocols(options.ALPNProtocols, ALPN);
10521053

10531054
var socket = new TLSSocket(options.socket, {
10541055
pipe: !!options.path,
@@ -1057,8 +1058,8 @@ exports.connect = function(...args /* [port,] [host,] [options,] [cb] */) {
10571058
requestCert: true,
10581059
rejectUnauthorized: options.rejectUnauthorized !== false,
10591060
session: options.session,
1060-
NPNProtocols: NPN.NPNProtocols,
1061-
ALPNProtocols: ALPN.ALPNProtocols,
1061+
NPNProtocols: options.NPNProtocols,
1062+
ALPNProtocols: options.ALPNProtocols,
10621063
requestOCSP: options.requestOCSP
10631064
});
10641065

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
'use strict';
2+
3+
// Test that TLSSocket can take arrays of strings for ALPNProtocols and
4+
// NPNProtocols.
5+
6+
const common = require('../common');
7+
8+
if (!common.hasCrypto)
9+
common.skip('missing crypto');
10+
11+
const tls = require('tls');
12+
13+
new tls.TLSSocket(null, {
14+
ALPNProtocols: ['http/1.1'],
15+
NPNProtocols: ['http/1.1']
16+
});
17+
18+
if (!process.features.tls_npn)
19+
common.skip('node compiled without NPN feature of OpenSSL');
20+
21+
if (!process.features.tls_alpn)
22+
common.skip('node compiled without ALPN feature of OpenSSL');
23+
24+
const assert = require('assert');
25+
const net = require('net');
26+
const fixtures = require('../common/fixtures');
27+
28+
const key = fixtures.readKey('agent1-key.pem');
29+
const cert = fixtures.readKey('agent1-cert.pem');
30+
31+
const protocols = [];
32+
33+
const server = net.createServer(common.mustCall((s) => {
34+
const tlsSocket = new tls.TLSSocket(s, {
35+
isServer: true,
36+
server,
37+
key,
38+
cert,
39+
ALPNProtocols: ['http/1.1'],
40+
NPNProtocols: ['http/1.1']
41+
});
42+
43+
tlsSocket.on('secure', common.mustCall(() => {
44+
protocols.push({
45+
alpnProtocol: tlsSocket.alpnProtocol,
46+
npnProtocol: tlsSocket.npnProtocol
47+
});
48+
tlsSocket.end();
49+
}));
50+
}, 2));
51+
52+
server.listen(0, common.mustCall(() => {
53+
const alpnOpts = {
54+
port: server.address().port,
55+
rejectUnauthorized: false,
56+
ALPNProtocols: ['h2', 'http/1.1']
57+
};
58+
const npnOpts = {
59+
port: server.address().port,
60+
rejectUnauthorized: false,
61+
NPNProtocols: ['h2', 'http/1.1']
62+
};
63+
64+
tls.connect(alpnOpts, function() {
65+
this.end();
66+
67+
tls.connect(npnOpts, function() {
68+
this.end();
69+
70+
server.close();
71+
72+
assert.deepStrictEqual(protocols, [
73+
{ alpnProtocol: 'http/1.1', npnProtocol: false },
74+
{ alpnProtocol: false, npnProtocol: 'http/1.1' }
75+
]);
76+
});
77+
});
78+
}));

0 commit comments

Comments
 (0)