diff --git a/lib/middleware/proxy.js b/lib/middleware/proxy.js index 6b0fcf730..b2e0e7f63 100644 --- a/lib/middleware/proxy.js +++ b/lib/middleware/proxy.js @@ -3,6 +3,7 @@ const { Agent: httpAgent } = require('http') const { Agent: httpsAgent } = require('https') const httpProxy = require('http-proxy') const _ = require('lodash') +const { lookup } = require('../utils/dns-utils') const log = require('../logger').create('proxy') @@ -41,7 +42,10 @@ function parseProxyConfig (proxies, config) { const port = proxyDetails.port || defaultPorts[proxyDetails.protocol] || config.port const changeOrigin = proxyConfiguration.changeOrigin || false const Agent = protocol === 'https:' ? httpsAgent : httpAgent - const agent = new Agent({ keepAlive: true }) + const agent = new Agent({ + keepAlive: true, + lookup + }) const proxy = httpProxy.createProxyServer({ target: { host: hostname, port, protocol }, xfwd: true, diff --git a/lib/runner.js b/lib/runner.js index 2e04065b6..fb67ebe92 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -7,6 +7,7 @@ const EventEmitter = require('events').EventEmitter const helper = require('./helper') const cfg = require('./config') const logger = require('./logger') +const { lookup } = require('./utils/dns-utils') const log = logger.create('runner') function parseExitCode (buffer, defaultExitCode, failOnEmptyTestSuite) { @@ -74,7 +75,8 @@ function run (cliOptionsOrConfig, done) { method: 'POST', headers: { 'Content-Type': 'application/json' - } + }, + lookup } const request = http.request(options, function (response) { diff --git a/lib/stopper.js b/lib/stopper.js index 964eb5e37..386fa5d83 100644 --- a/lib/stopper.js +++ b/lib/stopper.js @@ -2,6 +2,7 @@ const http = require('http') const cfg = require('./config') const logger = require('./logger') const helper = require('./helper') +const { lookup } = require('./utils/dns-utils') exports.stop = function (cliOptionsOrConfig, done) { cliOptionsOrConfig = cliOptionsOrConfig || {} @@ -42,7 +43,8 @@ exports.stop = function (cliOptionsOrConfig, done) { hostname: config.hostname, path: config.urlRoot + 'stop', port: config.port, - method: 'GET' + method: 'GET', + lookup }) request.on('response', function (response) { diff --git a/lib/utils/dns-utils.js b/lib/utils/dns-utils.js new file mode 100644 index 000000000..5d281ed6f --- /dev/null +++ b/lib/utils/dns-utils.js @@ -0,0 +1,11 @@ +const dns = require('dns') + +// Node >=17 has different DNS resolution (see +// https://github.com/nodejs/node/issues/40702), it resolves domains +// 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 (`::`). So the run/stop/proxy request is unable to reach the Karma +// server and produces an error. To mitigate this issue karma force the +// IPv4-address first approach in Node >=17 as well. +module.exports.lookup = (hostname, options, callback) => dns.lookup(hostname, { ...options, verbatim: false }, callback) diff --git a/test/e2e/support/proxy.js b/test/e2e/support/proxy.js index 5bf17c1fd..e78a4544c 100644 --- a/test/e2e/support/proxy.js +++ b/test/e2e/support/proxy.js @@ -8,7 +8,7 @@ module.exports = class Proxy { this.proxyPathRegExp = null this.proxy = httpProxy.createProxyServer({ - target: 'http://localhost:9876' + target: 'http://127.0.0.1:9876' }) this.proxy.on('error', (err) => {