diff --git a/packages/backend/src/misc/fetch.ts b/packages/backend/src/misc/fetch.ts index 403f15725..1f05b7910 100644 --- a/packages/backend/src/misc/fetch.ts +++ b/packages/backend/src/misc/fetch.ts @@ -1,6 +1,7 @@ import * as http from 'node:http'; import * as https from 'node:https'; import { URL } from 'node:url'; +import * as dns from 'node:dns'; import CacheableLookup from 'cacheable-lookup'; import fetch from 'node-fetch'; import { HttpProxyAgent, HttpsProxyAgent } from 'hpagent'; @@ -78,13 +79,38 @@ const cache = new CacheableLookup({ lookup: false, // nativeのdns.lookupにfallbackしない }); +// because `cacheable-lookup` is annoying and prefers IPv4 by default, +// we need a little wrapper setting some extra options +const cacheLookup = (host, _2, _3) => { + // do all the weird parameter shenanigans that nodejs's dns.lookup does. + let options = {}, callback; + if (_3) { + options = _2; + if (typeof options === 'number') { + options = { family: options }; + } + callback = _3; + } else { + callback = _2; + } + + // here come the shenanigans, trying to be careful not to mess up + // intentionally different behaviour + if (options.family == null && (options.hints ?? 0) === 0) { + options.family = 6; + options.hints = dns.V4MAPPED; + } + + return cache.lookup(host, options, callback); +}; + /** * Get http non-proxy agent */ const _http = new http.Agent({ keepAlive: true, keepAliveMsecs: 30 * SECOND, - lookup: cache.lookup, + lookup: cacheLookup, } as http.AgentOptions); /** @@ -93,7 +119,7 @@ const _http = new http.Agent({ const _https = new https.Agent({ keepAlive: true, keepAliveMsecs: 30 * SECOND, - lookup: cache.lookup, + lookup: cacheLookup, } as https.AgentOptions); const maxSockets = Math.max(256, config.deliverJobConcurrency);