Try to fix whois

This commit is contained in:
Raven Scott
2026-04-27 21:00:49 -04:00
parent 9074978c83
commit 60e2efa64a
10 changed files with 60 additions and 32 deletions
+16 -8
View File
@@ -309,12 +309,18 @@ async function run(ctx, argv) {
ctx.exitCode = 1
return
}
/** Total wall-clock budget for bootstrap + optional ipv6 bootstrap + RDAP GET (shared across hops). */
const DEFAULT_RDAP_MS = 120000
const MAX_RDAP_MS = 600000
const timeoutRaw = Number.parseInt(
String(ctx.vfs?.env?.BARE_OS_WHOIS_TIMEOUT_MS || '10000'),
String(ctx.vfs?.env?.BARE_OS_WHOIS_TIMEOUT_MS || String(DEFAULT_RDAP_MS)),
10
)
const timeoutMs =
Number.isFinite(timeoutRaw) && timeoutRaw > 0 ? Math.min(timeoutRaw, 60000) : 10000
const totalBudgetMs = Number.isFinite(timeoutRaw) && timeoutRaw > 0
? Math.min(timeoutRaw, MAX_RDAP_MS)
: DEFAULT_RDAP_MS
const deadlineMs = Date.now() + totalBudgetMs
const hopTimeoutMs = () => Math.max(1, deadlineMs - Date.now())
let bootstrapUrl = ''
let rdapPath = ''
@@ -330,13 +336,13 @@ async function run(ctx, argv) {
}
try {
const bootstrap = await fetchJson(fetchFn, bootstrapUrl, timeoutMs)
const bootstrap = await fetchJson(fetchFn, bootstrapUrl, hopTimeoutMs())
let base = pickBaseUrlFromBootstrap(target.kind, target.query, bootstrap)
if (!base && target.kind === 'ip' && isIpv6(target.query)) {
const ipv6Bootstrap = await fetchJson(
fetchFn,
'https://data.iana.org/rdap/ipv6.json',
timeoutMs
hopTimeoutMs()
)
base = pickBaseUrlFromBootstrap(target.kind, target.query, ipv6Bootstrap)
}
@@ -345,13 +351,15 @@ async function run(ctx, argv) {
ctx.exitCode = 1
return
}
const rdap = await fetchJson(fetchFn, joinUrl(base, rdapPath), timeoutMs)
const rdap = await fetchJson(fetchFn, joinUrl(base, rdapPath), hopTimeoutMs())
if (parsed.json) ctx.console.log(JSON.stringify(rdap, null, 2))
else printSummary(ctx, target.kind, target.query, rdap)
} catch (err) {
const msg = String((err && err.message) || err || '')
if ((err && err.name === 'AbortError') || /abort|timeout/i.test(msg)) {
ctx.console.error('whois: network timeout after ' + timeoutMs + 'ms')
if (err && err.name === 'AbortError') {
ctx.console.error(
'whois: network timeout (RDAP lookup exceeded ' + totalBudgetMs + 'ms)'
)
} else if (/allowlist|denylist|HTTP blocked/i.test(msg)) {
ctx.console.error('whois: blocked by HTTP policy: ' + msg)
} else if (/ENOTFOUND|EAI_AGAIN|ENETUNREACH|EHOSTUNREACH/i.test(msg)) {
@@ -98,11 +98,15 @@ test('whois reports bounded timeout message', async (t) => {
new Promise((resolve, reject) => {
const sig = opts && opts.signal
if (sig && typeof sig.addEventListener === 'function') {
sig.addEventListener('abort', () => reject(new Error('AbortError')))
sig.addEventListener('abort', () => {
reject(Object.assign(new Error('The operation was aborted'), { name: 'AbortError' }))
})
}
void resolve
})
await run(ctx, ['whois', 'google.com'])
t.is(ctx.exitCode, 1)
t.ok(ctx._errs.join('\n').includes('network timeout'))
const errJoined = ctx._errs.join('\n')
t.ok(errJoined.includes('network timeout'))
t.ok(errJoined.includes('exceeded 20ms'))
})