diff --git a/lib/_http_agent.js b/lib/_http_agent.js index 2a5c33b551f5f8..bac10c4dabf49b 100644 --- a/lib/_http_agent.js +++ b/lib/_http_agent.js @@ -102,6 +102,11 @@ Agent.prototype.getName = function(options) { if (options.localAddress) name += options.localAddress; + // Pacify parallel/test-http-agent-getname by only appending + // the ':' when options.family is set. + if (options.family === 4 || options.family === 6) + name += ':' + options.family; + return name; }; diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index cdb5817fa6f223..b7669532406491 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -1025,6 +1025,7 @@ exports.connect = function(/* [port, host], options, cb */) { connect_opt = { port: options.port, host: options.host, + family: options.family, localAddress: options.localAddress }; } diff --git a/test/parallel/parallel.status b/test/parallel/parallel.status index 792f036ec0abee..e3a8e345f732a7 100644 --- a/test/parallel/parallel.status +++ b/test/parallel/parallel.status @@ -12,6 +12,13 @@ test-tick-processor : PASS,FLAKY [$system==linux] test-tick-processor : PASS,FLAKY +# Flaky until https://github.com/nodejs/build/issues/415 is resolved. +# On some of the buildbots, AAAA queries for localhost don't resolve +# to an address and neither do any of the alternatives from the +# localIPv6Hosts list from test/common.js. +test-https-connect-address-family : PASS,FLAKY +test-tls-connect-address-family : PASS,FLAKY + [$system==macos] [$system==solaris] # Also applies to SmartOS diff --git a/test/parallel/test-http-agent-getname.js b/test/parallel/test-http-agent-getname.js index 1b80b5c36e1e64..45e1817cf5ee1e 100644 --- a/test/parallel/test-http-agent-getname.js +++ b/test/parallel/test-http-agent-getname.js @@ -1,13 +1,13 @@ 'use strict'; require('../common'); -var assert = require('assert'); -var http = require('http'); +const assert = require('assert'); +const http = require('http'); -var agent = new http.Agent(); +const agent = new http.Agent(); // default to localhost -assert.equal( +assert.strictEqual( agent.getName({ port: 80, localAddress: '192.168.1.1' @@ -16,13 +16,13 @@ assert.equal( ); // empty -assert.equal( +assert.strictEqual( agent.getName({}), 'localhost::' ); // pass all arguments -assert.equal( +assert.strictEqual( agent.getName({ host: '0.0.0.0', port: 80, @@ -30,3 +30,9 @@ assert.equal( }), '0.0.0.0:80:192.168.1.1' ); + +for (const family of [0, null, undefined, 'bogus']) + assert.strictEqual(agent.getName({ family }), 'localhost::'); + +for (const family of [4, 6]) + assert.strictEqual(agent.getName({ family }), 'localhost:::' + family); diff --git a/test/parallel/test-https-connect-address-family.js b/test/parallel/test-https-connect-address-family.js new file mode 100644 index 00000000000000..b2f3c233cfd720 --- /dev/null +++ b/test/parallel/test-https-connect-address-family.js @@ -0,0 +1,28 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const https = require('https'); + +if (!common.hasIPv6) { + common.skip('no IPv6 support'); + return; +} + +const ciphers = 'AECDH-NULL-SHA'; +https.createServer({ ciphers }, function(req, res) { + this.close(); + res.end(); +}).listen(common.PORT, '::1', function() { + const options = { + host: 'localhost', + port: common.PORT, + family: 6, + ciphers: ciphers, + rejectUnauthorized: false, + }; + // Will fail with ECONNREFUSED if the address family is not honored. + https.get(options, common.mustCall(function() { + assert.strictEqual('::1', this.socket.remoteAddress); + this.destroy(); + })); +}); diff --git a/test/parallel/test-tls-connect-address-family.js b/test/parallel/test-tls-connect-address-family.js new file mode 100644 index 00000000000000..665a71dfe666d9 --- /dev/null +++ b/test/parallel/test-tls-connect-address-family.js @@ -0,0 +1,27 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const tls = require('tls'); + +if (!common.hasIPv6) { + common.skip('no IPv6 support'); + return; +} + +const ciphers = 'AECDH-NULL-SHA'; +tls.createServer({ ciphers }, function() { + this.close(); +}).listen(common.PORT, '::1', function() { + const options = { + host: 'localhost', + port: common.PORT, + family: 6, + ciphers: ciphers, + rejectUnauthorized: false, + }; + // Will fail with ECONNREFUSED if the address family is not honored. + tls.connect(options).once('secureConnect', common.mustCall(function() { + assert.strictEqual('::1', this.remoteAddress); + this.destroy(); + })); +});