Enhance RDAP and WHOIS functionality with referral handling

Added support for following registrar WHOIS referrals with configurable hop limits. Introduced new options in LookupOptions for maximum referral hops and RDAP link handling. Updated README to reflect these changes and improved the lookupDomain function to utilize the new referral logic. Added utility functions for merging RDAP documents and extracting related links.
This commit is contained in:
2025-10-08 19:25:51 -04:00
parent 27b3187d33
commit f8280508ff
7 changed files with 294 additions and 51 deletions
+43
View File
@@ -0,0 +1,43 @@
import type { LookupOptions } from "../types";
import type { WhoisQueryResult } from "./client";
import { whoisQuery } from "./client";
import { extractWhoisReferral } from "./discovery";
/**
* Follow registrar WHOIS referrals up to a configured hop limit.
* Returns the last successful WHOIS response (best-effort; keeps original on failures).
*/
export async function followWhoisReferrals(
initialServer: string,
domain: string,
opts?: LookupOptions,
): Promise<WhoisQueryResult> {
const maxHops = Math.max(0, opts?.maxWhoisReferralHops ?? 2);
// First query against the provided server
let current = await whoisQuery(initialServer, domain, opts);
if (opts?.followWhoisReferral === false || maxHops === 0) return current;
const visited = new Set<string>([normalize(current.serverQueried)]);
let hops = 0;
// Iterate while we see a new referral and are under hop limit
while (hops < maxHops) {
const next = extractWhoisReferral(current.text);
if (!next) break;
const normalized = normalize(next);
if (visited.has(normalized)) break; // cycle protection / same as current
visited.add(normalized);
try {
const res = await whoisQuery(next, domain, opts);
current = res; // adopt the newer, more specific result
} catch {
// If referral server fails, stop following and keep the last good response
break;
}
hops += 1;
}
return current;
}
function normalize(server: string): string {
return server.replace(/^whois:\/\//i, "").toLowerCase();
}