mirror of
https://git.proxmox.com/git/package-rebuilds
synced 2025-08-21 21:19:51 +00:00
199 lines
5.2 KiB
JavaScript
199 lines
5.2 KiB
JavaScript
'use strict'
|
|
|
|
const { test, skip } = require('tap')
|
|
const dgram = require('dgram')
|
|
const { Resolver } = require('dns')
|
|
const dnsPacket = require('dns-packet')
|
|
const { createServer } = require('http')
|
|
const { Client, Agent, request } = require('..')
|
|
const { nodeHasAutoSelectFamily } = require('../lib/core/util')
|
|
|
|
/*
|
|
* IMPORTANT
|
|
*
|
|
* As only some version of Node have autoSelectFamily enabled by default (>= 20), make sure the option is always
|
|
* explicitly passed in tests in this file to avoid compatibility problems across release lines.
|
|
*
|
|
*/
|
|
|
|
if (!nodeHasAutoSelectFamily) {
|
|
skip('autoSelectFamily is not supportee')
|
|
process.exit()
|
|
}
|
|
|
|
function _lookup (resolver, hostname, options, cb) {
|
|
resolver.resolve(hostname, 'ANY', (err, replies) => {
|
|
if (err) {
|
|
return cb(err)
|
|
}
|
|
|
|
const hosts = replies
|
|
.map((r) => ({ address: r.address, family: r.type === 'AAAA' ? 6 : 4 }))
|
|
.sort((a, b) => b.family - a.family)
|
|
|
|
if (options.all === true) {
|
|
return cb(null, hosts)
|
|
}
|
|
|
|
return cb(null, hosts[0].address, hosts[0].family)
|
|
})
|
|
}
|
|
|
|
function createDnsServer (ipv6Addr, ipv4Addr, cb) {
|
|
// Create a DNS server which replies with a AAAA and a A record for the same host
|
|
const socket = dgram.createSocket('udp4')
|
|
|
|
socket.on('message', (msg, { address, port }) => {
|
|
const parsed = dnsPacket.decode(msg)
|
|
|
|
const response = dnsPacket.encode({
|
|
type: 'answer',
|
|
id: parsed.id,
|
|
questions: parsed.questions,
|
|
answers: [
|
|
{ type: 'AAAA', class: 'IN', name: 'example.org', data: '::1', ttl: 123 },
|
|
{ type: 'A', class: 'IN', name: 'example.org', data: '127.0.0.1', ttl: 123 }
|
|
]
|
|
})
|
|
|
|
socket.send(response, port, address)
|
|
})
|
|
|
|
socket.bind(0, () => {
|
|
const resolver = new Resolver()
|
|
resolver.setServers([`127.0.0.1:${socket.address().port}`])
|
|
|
|
cb(null, { dnsServer: socket, lookup: _lookup.bind(null, resolver) })
|
|
})
|
|
}
|
|
|
|
test('with autoSelectFamily enable the request succeeds when using request', (t) => {
|
|
t.plan(3)
|
|
|
|
createDnsServer('::1', '127.0.0.1', function (_, { dnsServer, lookup }) {
|
|
const server = createServer((req, res) => {
|
|
res.end('hello')
|
|
})
|
|
|
|
t.teardown(() => {
|
|
server.close()
|
|
dnsServer.close()
|
|
})
|
|
|
|
server.listen(0, '127.0.0.1', () => {
|
|
const agent = new Agent({ connect: { lookup }, autoSelectFamily: true })
|
|
|
|
request(
|
|
`http://example.org:${server.address().port}/`, {
|
|
method: 'GET',
|
|
dispatcher: agent
|
|
}, (err, { statusCode, body }) => {
|
|
t.error(err)
|
|
|
|
let response = Buffer.alloc(0)
|
|
|
|
body.on('data', chunk => {
|
|
response = Buffer.concat([response, chunk])
|
|
})
|
|
|
|
body.on('end', () => {
|
|
t.strictSame(statusCode, 200)
|
|
t.strictSame(response.toString('utf-8'), 'hello')
|
|
})
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
test('with autoSelectFamily enable the request succeeds when using a client', (t) => {
|
|
t.plan(3)
|
|
|
|
createDnsServer('::1', '127.0.0.1', function (_, { dnsServer, lookup }) {
|
|
const server = createServer((req, res) => {
|
|
res.end('hello')
|
|
})
|
|
|
|
t.teardown(() => {
|
|
server.close()
|
|
dnsServer.close()
|
|
})
|
|
|
|
server.listen(0, '127.0.0.1', () => {
|
|
const client = new Client(`http://example.org:${server.address().port}`, { connect: { lookup }, autoSelectFamily: true })
|
|
|
|
t.teardown(client.destroy.bind(client))
|
|
|
|
client.request({
|
|
path: '/',
|
|
method: 'GET'
|
|
}, (err, { statusCode, body }) => {
|
|
t.error(err)
|
|
|
|
let response = Buffer.alloc(0)
|
|
|
|
body.on('data', chunk => {
|
|
response = Buffer.concat([response, chunk])
|
|
})
|
|
|
|
body.on('end', () => {
|
|
t.strictSame(statusCode, 200)
|
|
t.strictSame(response.toString('utf-8'), 'hello')
|
|
})
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
test('with autoSelectFamily disabled the request fails when using request', (t) => {
|
|
t.plan(1)
|
|
|
|
createDnsServer('::1', '127.0.0.1', function (_, { dnsServer, lookup }) {
|
|
const server = createServer((req, res) => {
|
|
res.end('hello')
|
|
})
|
|
|
|
t.teardown(() => {
|
|
server.close()
|
|
dnsServer.close()
|
|
})
|
|
|
|
server.listen(0, '127.0.0.1', () => {
|
|
const agent = new Agent({ connect: { lookup, autoSelectFamily: false } })
|
|
|
|
request(`http://example.org:${server.address().port}`, {
|
|
method: 'GET',
|
|
dispatcher: agent
|
|
}, (err, { statusCode, body }) => {
|
|
t.ok(['ECONNREFUSED', 'EAFNOSUPPORT'].includes(err.code))
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
test('with autoSelectFamily disabled the request fails when using a client', (t) => {
|
|
t.plan(1)
|
|
|
|
createDnsServer('::1', '127.0.0.1', function (_, { dnsServer, lookup }) {
|
|
const server = createServer((req, res) => {
|
|
res.end('hello')
|
|
})
|
|
|
|
t.teardown(() => {
|
|
server.close()
|
|
dnsServer.close()
|
|
})
|
|
|
|
server.listen(0, '127.0.0.1', () => {
|
|
const client = new Client(`http://example.org:${server.address().port}`, { connect: { lookup, autoSelectFamily: false } })
|
|
t.teardown(client.destroy.bind(client))
|
|
|
|
client.request({
|
|
path: '/',
|
|
method: 'GET'
|
|
}, (err, { statusCode, body }) => {
|
|
t.ok(['ECONNREFUSED', 'EAFNOSUPPORT'].includes(err.code))
|
|
})
|
|
})
|
|
})
|
|
})
|