Compare commits

...
Author SHA1 Message Date
Manuel 3498fdaebb feat: implement cacheable lookup 2025-02-23 15:48:56 +01:00
3 changed files with 58 additions and 0 deletions

No files matched your search

+2
View File
@@ -23,6 +23,8 @@
"prettier": "@homarr/prettier-config",
"dependencies": {
"@homarr/common": "workspace:^0.1.0",
"@homarr/log": "workspace:^0.1.0",
"cacheable-lookup": "^7.0.0",
"undici": "7.3.0"
},
"devDependencies": {
+44
View File
@@ -8,6 +8,15 @@ import { fetch } from "undici";
import { env } from "@homarr/common/env";
import { LoggingAgent } from "@homarr/common/server";
import CacheableLookup from "cacheable-lookup";
import type { LookupOptions } from "node:dns";
import { logger } from "@homarr/log";
const cacheableLookup = new CacheableLookup({
maxTtl: 6_00,
errorTtl: 60,
fallbackDuration: 3600
});
const getCertificateFolder = () => {
return env.NODE_ENV === "production"
@@ -66,15 +75,50 @@ export const createCertificateAgentAsync = async () => {
return new LoggingAgent({
connect: {
ca: rootCertificates.concat(customCertificates.map((cert) => cert.content)),
// Override the DNS lookup with the https://www.npmjs.com/package/cacheable-lookup library lookup (see https://github.com/nodejs/undici/issues/2440#issuecomment-2181215481)
lookup(hostname, lookupOptions, callback) {
logger.info(`looking up ${hostname} with cacheable lookup`);
cacheableLookup.lookup(hostname, { all: lookupOptions.all, hints: lookupOptions.hints, family: convertToNodeJsIPFamily(lookupOptions.family) }, (err, address, family) => {
if (err) {
logger.error(`DNS Lookup failed for ${hostname}: ${err}`);
} else {
logger.info(`Cacheable Lookup for ${hostname}: ${JSON.stringify(address)}, family: ${family}`);
}
callback(err, address, family);
});
}
},
keepAliveTimeout: 10_000, // Keep connection open for 10s
keepAliveMaxTimeout: 30_000,
pipelining: 0
});
};
/**
* Converts the family
* @see https://nodejs.org/api/dns.html#dns_dns_lookup_hostname_options_callback
* @param lookupOptionsFamily the family that should be converted
*/
const convertToNodeJsIPFamily = (lookupOptionsFamily: LookupOptions['family']) => {
switch (lookupOptionsFamily) {
case 'IPv4': {
return 4;
}
case 'IPv6': {
return 6;
}
default: {
return undefined;
}
}
}
export const createAxiosCertificateInstanceAsync = async () => {
const customCertificates = await loadCustomRootCertificatesAsync();
return axios.create({
httpsAgent: new Agent({
ca: rootCertificates.concat(customCertificates.map((cert) => cert.content)),
keepAlive: true
}),
});
};
+12
View File
@@ -743,6 +743,12 @@ importers:
'@homarr/common':
specifier: workspace:^0.1.0
version: link:../common
'@homarr/log':
specifier: workspace:^0.1.0
version: link:../log
cacheable-lookup:
specifier: ^7.0.0
version: 7.0.0
undici:
specifier: 7.3.0
version: 7.3.0
@@ -5286,6 +5292,10 @@ packages:
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
engines: {node: '>=8'}
cacheable-lookup@7.0.0:
resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==}
engines: {node: '>=14.16'}
call-bind-apply-helpers@1.0.1:
resolution: {integrity: sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==}
engines: {node: '>= 0.4'}
@@ -13458,6 +13468,8 @@ snapshots:
cac@6.7.14: {}
cacheable-lookup@7.0.0: {}
call-bind-apply-helpers@1.0.1:
dependencies:
es-errors: 1.3.0