From 25b7657a79d6e74e401ce30b534ff8c29b0e1b63 Mon Sep 17 00:00:00 2001 From: ajnart Date: Sun, 16 Aug 2026 13:04:13 +0200 Subject: [PATCH] feat(http): set custom User-Agent on outbound integration requests Set a default 'User-Agent: Homarr/ (+https://homarr.dev)' header on all outbound HTTP requests made via fetchWithTrustedCertificatesAsync, so Homarr's integration traffic is distinguishable in reverse-proxy, WAF, and security-monitoring logs instead of appearing as generic undici. Closes #6604 --- packages/core/src/infrastructure/http/request.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/core/src/infrastructure/http/request.ts b/packages/core/src/infrastructure/http/request.ts index b3c3ea354..20af8232f 100644 --- a/packages/core/src/infrastructure/http/request.ts +++ b/packages/core/src/infrastructure/http/request.ts @@ -14,6 +14,10 @@ import { UndiciHttpAgent } from "@homarr/core/infrastructure/http"; import type { TrustedCertificateHostname } from "../certificates/hostnames"; import { withTimeoutAsync } from "./timeout"; +import packageJson from "../../../../../package.json"; + +export const getDefaultUserAgent = () => `Homarr/${packageJson.version} (+https://homarr.dev)`; + export const createCustomCheckServerIdentity = ( trustedHostnames: TrustedCertificateHostname[], ): typeof checkServerIdentity => { @@ -79,6 +83,10 @@ export const fetchWithTrustedCertificatesAsync = async ( async (signal) => fetch(url, { ...fetchOptions, + headers: { + "User-Agent": getDefaultUserAgent(), + ...fetchOptions.headers, + }, signal, dispatcher: agent, }), @@ -89,6 +97,10 @@ export const fetchWithTrustedCertificatesAsync = async ( const { bodyTimeout: _bodyTimeout, dispatcher: _dispatcher, ...fetchOptions } = options ?? {}; return fetch(url, { ...fetchOptions, + headers: { + "User-Agent": getDefaultUserAgent(), + ...fetchOptions.headers, + }, dispatcher: agent, }); };