File size: 2,408 Bytes
88c4c60 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | import { ProxyAgent, fetch as undiciFetch } from "undici";
const DEFAULT_TEST_URL = "https://google.com/";
const DEFAULT_TIMEOUT_MS = 8000;
function getErrorMessage(err) {
if (!err) return "Unknown error";
const base = err?.message || String(err);
const causeCode = err?.cause?.code || err?.code;
const causeMessage = err?.cause?.message;
if (causeMessage && causeMessage !== base) {
return causeCode ? `${base}: ${causeMessage} (${causeCode})` : `${base}: ${causeMessage}`;
}
if (causeCode && !base.includes(causeCode)) {
return `${base} (${causeCode})`;
}
return base;
}
function normalizeString(value) {
if (value === undefined || value === null) return "";
return String(value).trim();
}
export async function testProxyUrl({ proxyUrl, testUrl, timeoutMs } = {}) {
const normalizedProxyUrl = normalizeString(proxyUrl);
if (!normalizedProxyUrl) {
return { ok: false, status: 400, error: "proxyUrl is required" };
}
const normalizedTestUrl = normalizeString(testUrl) || DEFAULT_TEST_URL;
const timeoutMsRaw = Number(timeoutMs);
const normalizedTimeoutMs =
Number.isFinite(timeoutMsRaw) && timeoutMsRaw > 0
? Math.min(timeoutMsRaw, 30000)
: DEFAULT_TIMEOUT_MS;
let dispatcher;
try {
try {
dispatcher = new ProxyAgent({ uri: normalizedProxyUrl });
} catch (err) {
return {
ok: false,
status: 400,
error: `Invalid proxy URL: ${err?.message || String(err)}`,
};
}
const controller = new AbortController();
const startedAt = Date.now();
const timer = setTimeout(() => controller.abort(), normalizedTimeoutMs);
try {
const res = await undiciFetch(normalizedTestUrl, {
method: "HEAD",
dispatcher,
signal: controller.signal,
headers: {
"User-Agent": "9Router",
},
});
return {
ok: res.ok,
status: res.status,
statusText: res.statusText,
url: normalizedTestUrl,
elapsedMs: Date.now() - startedAt,
};
} catch (err) {
const message =
err?.name === "AbortError"
? "Proxy test timed out"
: getErrorMessage(err);
return { ok: false, status: 500, error: message };
} finally {
clearTimeout(timer);
}
} finally {
try {
await dispatcher?.close?.();
} catch {
// ignore
}
}
}
|