CoolFace
Apppublic

rahmad7/hermes-openmodel

sourceHugging Facemitupdated 3mo agoView on Hugging Face
0likes
dns-fix.cjs121 linesDownload Raw Back to scripts
1/**2 * DNS fix preload script for HF Spaces (Node.js side).3 *4 * Patches Node.js dns.lookup to:5 *   1. Check pre-resolved domains from /tmp/dns-resolved.json (populated by dns-resolve.py)6 *   2. Fall back to DNS-over-HTTPS (Cloudflare) for any other unresolvable domain7 *8 * Loaded via: NODE_OPTIONS="--require /path/to/dns-fix.cjs"9 *10 * Hermes Agent is primarily Python, but Node processes (playwright, whatsapp-bridge,11 * web dashboard build) benefit from this preload when launched from bash.12 */13"use strict";14 15const dns = require("dns");16const https = require("https");17const fs = require("fs");18 19let preResolved = {};20try {21  const raw = fs.readFileSync("/tmp/dns-resolved.json", "utf8");22  preResolved = JSON.parse(raw);23  const count = Object.keys(preResolved).length;24  if (count > 0) {25    console.log(`[dns-fix] Loaded ${count} pre-resolved domains`);26  }27} catch {28  // File not found or parse error — proceed without pre-resolved cache29}30 31const runtimeCache = new Map();32 33function dohResolve(hostname, callback) {34  const cached = runtimeCache.get(hostname);35  if (cached && cached.expiry > Date.now()) {36    return callback(null, cached.ip);37  }38 39  const url = `https://1.1.1.1/dns-query?name=${encodeURIComponent(hostname)}&type=A`;40  const req = https.get(41    url,42    { headers: { Accept: "application/dns-json" }, timeout: 15000 },43    (res) => {44      let body = "";45      res.on("data", (c) => (body += c));46      res.on("end", () => {47        try {48          const data = JSON.parse(body);49          const aRecords = (data.Answer || []).filter((a) => a.type === 1);50          if (aRecords.length === 0) {51            return callback(new Error(`DoH: no A record for ${hostname}`));52          }53          const ip = aRecords[0].data;54          const ttl = Math.max((aRecords[0].TTL || 300) * 1000, 60000);55          runtimeCache.set(hostname, { ip, expiry: Date.now() + ttl });56          callback(null, ip);57        } catch (e) {58          callback(new Error(`DoH parse error: ${e.message}`));59        }60      });61    }62  );63  req.on("error", (e) => callback(new Error(`DoH request failed: ${e.message}`)));64  req.on("timeout", () => {65    req.destroy();66    callback(new Error("DoH request timed out"));67  });68}69 70const origLookup = dns.lookup;71 72dns.lookup = function patchedLookup(hostname, options, callback) {73  if (typeof options === "function") {74    callback = options;75    options = {};76  }77  if (typeof options === "number") {78    options = { family: options };79  }80  options = options || {};81 82  if (83    !hostname ||84    hostname === "localhost" ||85    hostname === "0.0.0.0" ||86    hostname === "127.0.0.1" ||87    hostname === "::1" ||88    /^\d+\.\d+\.\d+\.\d+$/.test(hostname) ||89    /^::/.test(hostname)90  ) {91    return origLookup.call(dns, hostname, options, callback);92  }93 94  if (preResolved[hostname]) {95    const ip = preResolved[hostname];96    if (options.all) {97      return process.nextTick(() => callback(null, [{ address: ip, family: 4 }]));98    }99    return process.nextTick(() => callback(null, ip, 4));100  }101 102  origLookup.call(dns, hostname, options, (err, address, family) => {103    if (!err && address) {104      return callback(null, address, family);105    }106    if (err && (err.code === "ENOTFOUND" || err.code === "EAI_AGAIN")) {107      dohResolve(hostname, (dohErr, ip) => {108        if (dohErr || !ip) {109          return callback(err);110        }111        if (options.all) {112          return callback(null, [{ address: ip, family: 4 }]);113        }114        callback(null, ip, 4);115      });116    } else {117      callback(err, address, family);118    }119  });120};121