unjs / unenv

🕊️ Convert javaScript code to be runtime agnostic
MIT License
342 stars 18 forks source link

Partial `node:dns` implementation using DOH (via fetch) #198

Open pi0 opened 1 month ago

pi0 commented 1 month ago

Currently, we fully mock node:dns module since it depends on an OS feature however we could implement it using DNS-over-HTTPS.

async function resolveDomain(domain) {
  const dohServer = process.env.UNENV_DOH_URL || 'https://cloudflare-dns.com/dns-query';
  const url = `${dohServer}?name=${domain}&type=A`;
  try {
    const response = await fetch(url, {
      headers: {
        'Accept': 'application/dns-json'
      }
    });
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    const { Answer = [] } = await response.json();
    return Answer;
  } catch (error) {
    console.error('Error resolving domain:', error);
  }
}

// Usage example
resolveDomain('example.com').then(data => console.log(data));
IgorMinar commented 1 month ago

Interesting! Would there be an opt-out or way to configure? or do you think this should be an opt-in?

pi0 commented 1 month ago

We probably need a runtime way of configuring behavior indeed at least for DOH server. Or are you suggesting to completely opt-out of the feature? (what concerns you have?)

IgorMinar commented 1 month ago

Privacy and security mainly. Some people might not be comfortable with the polyfill making outbound http calls. Maybe it's not a big deal, but it's definitely unexpected behavior from a polyfill.

pi0 commented 1 month ago

Fair enough we could make an error and show instructions on how to enable DNS.

BTW the native functionality also make a network request all the time (and most of the time, hosting providers are in control of DNS)

IgorMinar commented 1 month ago

True. I'm not totally opposed to this, I think we should just think about the implications a bit because it's definitely unconventional.

One way to work around this possible perception of controversy is for workerd to implement this natively. I suspect that most runtimes expose a native DNS API. This implementation could still be used when targeting browsers for example.

pi0 commented 1 month ago

Good point and runtime-native is always the best indeed 👍🏼 Only in that case, the edge is still completely in control of the DNS resolver as is currently in control of resolving fetch URLs so a generic concern remains...

Made a poll tweet

(BTW this idea is mainly something to explore i have not seen any popular libs need node:dns)

IgorMinar commented 1 month ago

I agree that if your code runs in the cloud it doesn't really matter that much if the polyfill makes a fetch request. I was mainly thinking that having your app run locally during dev time and seeing it make these fetch calls could be considered problematic by some.

pi0 commented 1 month ago

According to the tweeter people also tend to prefer opt-in.

I guess we can do it per-provider btw. Ie, Cloudflare runtime (i guess :D) already benefits 1.1.1.1 so we could default config in preset.

Would it worth to initiate generic discussion about possibility of exposing DNS util from worked runtime natively @IgorMinar ?