Skip to content

Commit 7c682f2

Browse files
princjefMylesBorins
authored andcommitted
https: add extra options to Agent#getName()
Adds the remaining options from tls.createSecureContext() to the string generated by Agent#getName(). This allows https.request() to accept the options and generate unique sockets appropriately. PR-URL: #16402 Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent d190c9a commit 7c682f2

5 files changed

+127
-64
lines changed

doc/api/https.md

+6-5
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ separate module.
1212
added: v0.4.5
1313
-->
1414

15-
An Agent object for HTTPS similar to [`http.Agent`][]. See [`https.request()`][]
15+
An [`Agent`][] object for HTTPS similar to [`http.Agent`][]. See [`https.request()`][]
1616
for more information.
1717

1818
## Class: https.Server
@@ -168,9 +168,10 @@ changes:
168168

169169
Makes a request to a secure web server.
170170

171-
The following additional `options` from [`tls.connect()`][] are also accepted
172-
when using a custom [`Agent`][]: `ca`, `cert`, `ciphers`, `clientCertEngine`,
173-
`key`, `passphrase`, `pfx`, `rejectUnauthorized`, `secureProtocol`, `servername`
171+
The following additional `options` from [`tls.connect()`][] are also accepted:
172+
`ca`, `cert`, `ciphers`, `clientCertEngine`, `crl`, `dhparam`, `ecdhCurve`,
173+
`honorCipherOrder`, `key`, `passphrase`, `pfx`, `rejectUnauthorized`,
174+
`secureOptions`, `secureProtocol`, `servername`, `sessionIdContext`
174175

175176
`options` can be an object, a string, or a [`URL`][] object. If `options` is a
176177
string, it is automatically parsed with [`url.parse()`][]. If it is a [`URL`][]
@@ -220,7 +221,7 @@ const req = https.request(options, (res) => {
220221
});
221222
```
222223

223-
Alternatively, opt out of connection pooling by not using an `Agent`.
224+
Alternatively, opt out of connection pooling by not using an [`Agent`][].
224225

225226
Example:
226227

lib/https.js

+24
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,30 @@ Agent.prototype.getName = function getName(options) {
194194
if (options.secureProtocol)
195195
name += options.secureProtocol;
196196

197+
name += ':';
198+
if (options.crl)
199+
name += options.crl;
200+
201+
name += ':';
202+
if (options.honorCipherOrder !== undefined)
203+
name += options.honorCipherOrder;
204+
205+
name += ':';
206+
if (options.ecdhCurve)
207+
name += options.ecdhCurve;
208+
209+
name += ':';
210+
if (options.dhparam)
211+
name += options.dhparam;
212+
213+
name += ':';
214+
if (options.secureOptions !== undefined)
215+
name += options.secureOptions;
216+
217+
name += ':';
218+
if (options.sessionIdContext)
219+
name += options.sessionIdContext;
220+
197221
return name;
198222
};
199223

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
'use strict';
2+
const common = require('../common');
3+
if (!common.hasCrypto)
4+
common.skip('missing crypto');
5+
6+
const assert = require('assert');
7+
const crypto = require('crypto');
8+
const https = require('https');
9+
const fixtures = require('../common/fixtures');
10+
11+
const options = {
12+
key: fixtures.readKey('agent1-key.pem'),
13+
cert: fixtures.readKey('agent1-cert.pem'),
14+
ca: fixtures.readKey('ca1-cert.pem')
15+
};
16+
17+
const server = https.Server(options, function(req, res) {
18+
res.writeHead(200);
19+
res.end('hello world\n');
20+
});
21+
22+
function getBaseOptions(port) {
23+
return {
24+
path: '/',
25+
port: port,
26+
ca: options.ca,
27+
rejectUnautorized: true,
28+
servername: 'agent1',
29+
};
30+
}
31+
32+
const updatedValues = new Map([
33+
['dhparam', fixtures.readKey('dh2048.pem')],
34+
['ecdhCurve', 'secp384r1'],
35+
['honorCipherOrder', true],
36+
['secureOptions', crypto.constants.SSL_OP_CIPHER_SERVER_PREFERENCE],
37+
['secureProtocol', 'TLSv1_method'],
38+
['sessionIdContext', 'sessionIdContext'],
39+
]);
40+
41+
function variations(iter, port, cb) {
42+
const { done, value } = iter.next();
43+
if (done) {
44+
return common.mustCall(cb);
45+
} else {
46+
const [key, val] = value;
47+
return common.mustCall(function(res) {
48+
res.resume();
49+
https.globalAgent.once('free', common.mustCall(function() {
50+
https.get(
51+
Object.assign({}, getBaseOptions(port), { [key]: val }),
52+
variations(iter, port, cb)
53+
);
54+
}));
55+
});
56+
}
57+
}
58+
59+
server.listen(0, common.mustCall(function() {
60+
const port = this.address().port;
61+
const globalAgent = https.globalAgent;
62+
globalAgent.keepAlive = true;
63+
https.get(getBaseOptions(port), variations(
64+
updatedValues.entries(),
65+
port,
66+
common.mustCall(function(res) {
67+
res.resume();
68+
globalAgent.once('free', common.mustCall(function() {
69+
// Verify that different keep-alived connections are created
70+
// for the base call and each variation
71+
const keys = Object.keys(globalAgent.freeSockets);
72+
assert.strictEqual(keys.length, 1 + updatedValues.size);
73+
let i = 1;
74+
for (const [, value] of updatedValues) {
75+
assert.ok(
76+
keys[i].startsWith(value.toString() + ':') ||
77+
keys[i].endsWith(':' + value.toString()) ||
78+
keys[i].includes(':' + value.toString() + ':')
79+
);
80+
i++;
81+
}
82+
globalAgent.destroy();
83+
server.close();
84+
}));
85+
})
86+
));
87+
}));

test/parallel/test-https-agent-getname.js

+10-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const agent = new https.Agent();
1212
// empty options
1313
assert.strictEqual(
1414
agent.getName({}),
15-
'localhost:::::::::::'
15+
'localhost:::::::::::::::::'
1616
);
1717

1818
// pass all options arguments
@@ -23,13 +23,21 @@ const options = {
2323
ca: 'ca',
2424
cert: 'cert',
2525
ciphers: 'ciphers',
26+
crl: [Buffer.from('c'), Buffer.from('r'), Buffer.from('l')],
27+
dhparam: 'dhparam',
28+
ecdhCurve: 'ecdhCurve',
29+
honorCipherOrder: false,
2630
key: 'key',
2731
pfx: 'pfx',
2832
rejectUnauthorized: false,
33+
secureOptions: 0,
34+
secureProtocol: 'secureProtocol',
2935
servername: 'localhost',
36+
sessionIdContext: 'sessionIdContext'
3037
};
3138

3239
assert.strictEqual(
3340
agent.getName(options),
34-
'0.0.0.0:443:192.168.1.1:ca:cert::ciphers:key:pfx:false:localhost:'
41+
'0.0.0.0:443:192.168.1.1:ca:cert::ciphers:key:pfx:false:localhost:' +
42+
'secureProtocol:c,r,l:false:ecdhCurve:dhparam:0:sessionIdContext'
3543
);

test/parallel/test-https-agent-secure-protocol.js

-57
This file was deleted.

0 commit comments

Comments
 (0)