Spaces:
Sleeping
Sleeping
File size: 3,693 Bytes
0e1ee2c 51ec4bc d41fe21 51ec4bc db80bd1 0e1ee2c 51ec4bc 0e1ee2c 51ec4bc 0e1ee2c 51ec4bc 0e1ee2c d41fe21 51ec4bc 0e1ee2c db80bd1 0e1ee2c 51ec4bc 0e1ee2c 51ec4bc 0e1ee2c 51ec4bc 0e1ee2c 51ec4bc d41fe21 0e1ee2c 51ec4bc d41fe21 3373012 | 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 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | /**
* DNS fix preload script for HF Spaces.
*
* Patches Node.js dns.lookup to:
* 1. Try system DNS first
* 2. Fall back to DNS-over-HTTPS (Cloudflare) if system DNS fails
* (This is needed because HF Spaces intercepts/blocks some domains like
* WhatsApp web or Telegram API via standard UDP DNS).
*
* Loaded via: NODE_OPTIONS="--require /opt/dns-fix.js"
*/
"use strict";
const dns = require("dns");
const https = require("https");
// --- UPDATED: TELEGRAM PROXY CONFIG ---
// This redirects blocked api.telegram.org to a working mirror
const TG_PROXY_HOST = "api.telegram-proxy.org";
// In-memory cache for runtime DoH resolutions
const runtimeCache = new Map(); // hostname -> { ip, expiry }
// DNS-over-HTTPS resolver
function dohResolve(hostname, callback) {
// Check runtime cache
const cached = runtimeCache.get(hostname);
if (cached && cached.expiry > Date.now()) {
return callback(null, cached.ip);
}
const url = `https://1.1.1.1/dns-query?name=${encodeURIComponent(hostname)}&type=A`;
const req = https.get(
url,
{ headers: { Accept: "application/dns-json" }, timeout: 15000 },
(res) => {
let body = "";
res.on("data", (c) => (body += c));
res.on("end", () => {
try {
const data = JSON.parse(body);
const aRecords = (data.Answer || []).filter((a) => a.type === 1);
if (aRecords.length === 0) {
return callback(new Error(`DoH: no A record for ${hostname}`));
}
const ip = aRecords[0].data;
const ttl = Math.max((aRecords[0].TTL || 300) * 1000, 60000);
runtimeCache.set(hostname, { ip, expiry: Date.now() + ttl });
callback(null, ip);
} catch (e) {
callback(new Error(`DoH parse error: ${e.message}`));
}
});
}
);
req.on("error", (e) => callback(new Error(`DoH request failed: ${e.message}`)));
req.on("timeout", () => {
req.destroy();
callback(new Error("DoH request timed out"));
});
}
// Monkey-patch dns.lookup
const origLookup = dns.lookup;
dns.lookup = function patchedLookup(hostname, options, callback) {
// Normalize arguments (options is optional, can be number or object)
if (typeof options === "function") {
callback = options;
options = {};
}
if (typeof options === "number") {
options = { family: options };
}
options = options || {};
// --- UPDATED: FORCE REDIRECT TELEGRAM ---
if (hostname === "api.telegram.org") {
console.log("⚡ Redirecting Telegram API through Proxy...");
return origLookup.call(dns, TG_PROXY_HOST, options, callback);
}
// Skip patching for localhost, IPs, and internal domains
if (
!hostname ||
hostname === "localhost" ||
hostname === "0.0.0.0" ||
hostname === "127.0.0.1" ||
hostname === "::1" ||
/^\d+\.\d+\.\d+\.\d+$/.test(hostname) ||
/^::/.test(hostname)
) {
return origLookup.call(dns, hostname, options, callback);
}
// 1) Try system DNS first
origLookup.call(dns, hostname, options, (err, address, family) => {
if (!err && address) {
return callback(null, address, family);
}
// 2) System DNS failed with ENOTFOUND or EAI_AGAIN — fall back to DoH
if (err && (err.code === "ENOTFOUND" || err.code === "EAI_AGAIN")) {
dohResolve(hostname, (dohErr, ip) => {
if (dohErr || !ip) {
return callback(err); // Return original error
}
if (options.all) {
return callback(null, [{ address: ip, family: 4 }]);
}
callback(null, ip, 4);
});
} else {
// Other DNS errors — pass through
callback(err, address, family);
}
});
}; |