Skip to content

Commit e17698f

Browse files
devoto13Jonathan Ginsburg
authored and
Jonathan Ginsburg
committed
fix: prefer IPv4 addresses when resolving domains
Node 17+ changed the DNS resolution (see nodejs/node#40702), so now it resolves `localhost` according to the OS settings instead of IPv4-address first. The Karma server only listens on IPv4 address (127.0.0.1) by default, but the requests are sent to `localhost` in several places and `localhost` is resolved into IPv6 address (`::`) in Node 17+. So the run/stop/proxy request is unable to reach the Karma server and produces an error. This commit configures karma to use the IPv4-address first approach in newer Node version as well. In the future major release, we may consider changing defaults to listen on IPv6 address instead, but IPv6 is not supported in Docker on macOS and Windows, so I think we should not rush such a change to make sure karma works there out of the box. Fixes #3730
1 parent 60f4f79 commit e17698f

File tree

5 files changed

+23
-4
lines changed

5 files changed

+23
-4
lines changed

lib/middleware/proxy.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const { Agent: httpAgent } = require('http')
33
const { Agent: httpsAgent } = require('https')
44
const httpProxy = require('http-proxy')
55
const _ = require('lodash')
6+
const { lookup } = require('../utils/dns-utils')
67

78
const log = require('../logger').create('proxy')
89

@@ -41,7 +42,10 @@ function parseProxyConfig (proxies, config) {
4142
const port = proxyDetails.port || defaultPorts[proxyDetails.protocol] || config.port
4243
const changeOrigin = proxyConfiguration.changeOrigin || false
4344
const Agent = protocol === 'https:' ? httpsAgent : httpAgent
44-
const agent = new Agent({ keepAlive: true })
45+
const agent = new Agent({
46+
keepAlive: true,
47+
lookup
48+
})
4549
const proxy = httpProxy.createProxyServer({
4650
target: { host: hostname, port, protocol },
4751
xfwd: true,

lib/runner.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const EventEmitter = require('events').EventEmitter
77
const helper = require('./helper')
88
const cfg = require('./config')
99
const logger = require('./logger')
10+
const { lookup } = require('./utils/dns-utils')
1011
const log = logger.create('runner')
1112

1213
function parseExitCode (buffer, defaultExitCode, failOnEmptyTestSuite) {
@@ -74,7 +75,8 @@ function run (cliOptionsOrConfig, done) {
7475
method: 'POST',
7576
headers: {
7677
'Content-Type': 'application/json'
77-
}
78+
},
79+
lookup
7880
}
7981

8082
const request = http.request(options, function (response) {

lib/stopper.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const http = require('http')
22
const cfg = require('./config')
33
const logger = require('./logger')
44
const helper = require('./helper')
5+
const { lookup } = require('./utils/dns-utils')
56

67
exports.stop = function (cliOptionsOrConfig, done) {
78
cliOptionsOrConfig = cliOptionsOrConfig || {}
@@ -42,7 +43,8 @@ exports.stop = function (cliOptionsOrConfig, done) {
4243
hostname: config.hostname,
4344
path: config.urlRoot + 'stop',
4445
port: config.port,
45-
method: 'GET'
46+
method: 'GET',
47+
lookup
4648
})
4749

4850
request.on('response', function (response) {

lib/utils/dns-utils.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const dns = require('dns')
2+
3+
// Node >=17 has different DNS resolution (see
4+
// https://github.com/nodejs/node/issues/40702), it resolves domains
5+
// according to the OS settings instead of IPv4-address first. The Karma server
6+
// only listens on IPv4 address (127.0.0.1) by default, but the requests are
7+
// sent to `localhost` in several places and `localhost` is resolved into IPv6
8+
// address (`::`). So the run/stop/proxy request is unable to reach the Karma
9+
// server and produces an error. To mitigate this issue karma force the
10+
// IPv4-address first approach in Node >=17 as well.
11+
module.exports.lookup = (hostname, options, callback) => dns.lookup(hostname, { ...options, verbatim: false }, callback)

test/e2e/support/proxy.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ module.exports = class Proxy {
88
this.proxyPathRegExp = null
99

1010
this.proxy = httpProxy.createProxyServer({
11-
target: 'http://localhost:9876'
11+
target: 'http://127.0.0.1:9876'
1212
})
1313

1414
this.proxy.on('error', (err) => {

0 commit comments

Comments
 (0)