Compare commits

..

3 Commits

Author SHA1 Message Date
Fallenbagel
46e95317f6 fix(proxy): add connection limits and IPv4 support to undici agents 2026-01-17 07:07:56 +05:00
fallenbagel
b55c49c360 fix(proxy): pass forceIpv4First option to custom proxy agent 2026-01-16 09:39:46 +08:00
fallenbagel
f46773ec8f fix: configure axios proxy agent socket limits to prevent connection leaks
Add socket pool configuration to HttpProxyAgent and HttpsProxyAgent to
prevent connection leaks.

fix #2297
2026-01-16 09:26:01 +08:00
7 changed files with 24 additions and 46 deletions

View File

@@ -24,10 +24,6 @@ Set this to the username and password for your ntfy.sh server.
Set this to the token for your ntfy.sh server.
### Priority (optional)
Set the priority level for notifications. Options range from Minimum (1) to Urgent (5), with Default (3) being the standard level. Higher priority notifications may bypass Do Not Disturb settings on some devices.
:::info
Please refer to the [ntfy.sh API documentation](https://docs.ntfy.sh/) for more details on configuring these notifications.
:::

View File

@@ -97,7 +97,10 @@ app
// Register HTTP proxy
if (settings.network.proxy.enabled) {
await createCustomProxyAgent(settings.network.proxy);
await createCustomProxyAgent(
settings.network.proxy,
settings.network.forceIpv4First
);
}
// Migrate library types

View File

@@ -27,7 +27,7 @@ class NtfyAgent
const { embedPoster } = settings.notifications.agents.ntfy;
const topic = this.getSettings().options.topic;
const priority = this.getSettings().options.priority ?? 3;
const priority = 3;
const title = payload.event
? `${payload.event} - ${payload.subject}`

View File

@@ -296,7 +296,6 @@ export interface NotificationAgentNtfy extends NotificationAgentConfig {
password?: string;
authMethodToken?: boolean;
token?: string;
priority?: number;
};
}
@@ -530,7 +529,6 @@ class Settings {
options: {
url: '',
topic: '',
priority: 3,
},
},
},

View File

@@ -11,9 +11,14 @@ export let requestInterceptorFunction: (
) => InternalAxiosRequestConfig;
export default async function createCustomProxyAgent(
proxySettings: ProxySettings
proxySettings: ProxySettings,
forceIpv4First?: boolean
) {
const defaultAgent = new Agent({ keepAliveTimeout: 5000 });
const defaultAgent = new Agent({
keepAliveTimeout: 5000,
connections: 50,
connect: forceIpv4First ? { family: 4 } : undefined,
});
const skipUrl = (url: string | URL) => {
const hostname =
@@ -67,16 +72,23 @@ export default async function createCustomProxyAgent(
uri: proxyUrl,
token,
keepAliveTimeout: 5000,
connections: 50,
connect: forceIpv4First ? { family: 4 } : undefined,
});
setGlobalDispatcher(proxyAgent.compose(noProxyInterceptor));
axios.defaults.httpAgent = new HttpProxyAgent(proxyUrl, {
const agentOptions = {
headers: token ? { 'proxy-authorization': token } : undefined,
});
axios.defaults.httpsAgent = new HttpsProxyAgent(proxyUrl, {
headers: token ? { 'proxy-authorization': token } : undefined,
});
keepAlive: true,
maxSockets: 50,
maxFreeSockets: 10,
timeout: 5000,
scheduling: 'lifo' as const,
family: forceIpv4First ? 4 : undefined,
};
axios.defaults.httpAgent = new HttpProxyAgent(proxyUrl, agentOptions);
axios.defaults.httpsAgent = new HttpsProxyAgent(proxyUrl, agentOptions);
requestInterceptorFunction = (config) => {
const url = config.baseURL

View File

@@ -27,7 +27,6 @@ const messages = defineMessages(
password: 'Password',
tokenAuth: 'Token authentication',
token: 'Token',
priority: 'Priority',
ntfysettingssaved: 'Ntfy notification settings saved successfully!',
ntfysettingsfailed: 'Ntfy notification settings failed to save.',
toastNtfyTestSending: 'Sending ntfy test notification…',
@@ -35,7 +34,6 @@ const messages = defineMessages(
toastNtfyTestFailed: 'Ntfy test notification failed to send.',
validationNtfyUrl: 'You must provide a valid URL',
validationNtfyTopic: 'You must provide a topic',
validationPriorityRequired: 'You must provide a priority between 1 and 5',
validationTypes: 'You must select at least one notification type',
}
);
@@ -73,14 +71,6 @@ const NotificationsNtfy = () => {
otherwise: Yup.string().nullable(),
})
.defined(intl.formatMessage(messages.validationNtfyTopic)),
priority: Yup.number().when('enabled', {
is: true,
then: Yup.number()
.min(1)
.max(5)
.required(intl.formatMessage(messages.validationPriorityRequired)),
otherwise: Yup.number().nullable(),
}),
});
if (!data && !error) {
@@ -100,7 +90,6 @@ const NotificationsNtfy = () => {
password: data?.options.password,
authMethodToken: data?.options.authMethodToken,
token: data?.options.token,
priority: data?.options.priority,
}}
validationSchema={NotificationsNtfySchema}
onSubmit={async (values) => {
@@ -117,7 +106,6 @@ const NotificationsNtfy = () => {
password: values.password,
authMethodToken: values.authMethodToken,
token: values.token,
priority: values.priority,
},
});
@@ -169,7 +157,6 @@ const NotificationsNtfy = () => {
password: values.password,
authMethodToken: values.authMethodToken,
token: values.token,
priority: values.priority,
},
});
@@ -326,22 +313,6 @@ const NotificationsNtfy = () => {
</div>
</div>
)}
<div className="form-row">
<label htmlFor="priority" className="text-label">
{intl.formatMessage(messages.priority)}
</label>
<div className="form-input-area">
<div className="form-input-field">
<Field as="select" id="priority" name="priority">
<option value={1}>Minimum</option>
<option value={2}>Low</option>
<option value={3}>Default</option>
<option value={4}>High</option>
<option value={5}>Urgent</option>
</Field>
</div>
</div>
</div>
<NotificationTypeSelector
currentTypes={values.enabled ? values.types || 0 : 0}
onUpdate={(newTypes) => {

View File

@@ -629,7 +629,6 @@
"components.Settings.Notifications.NotificationsNtfy.ntfysettingsfailed": "Ntfy notification settings failed to save.",
"components.Settings.Notifications.NotificationsNtfy.ntfysettingssaved": "Ntfy notification settings saved successfully!",
"components.Settings.Notifications.NotificationsNtfy.password": "Password",
"components.Settings.Notifications.NotificationsNtfy.priority": "Priority",
"components.Settings.Notifications.NotificationsNtfy.toastNtfyTestFailed": "Ntfy test notification failed to send.",
"components.Settings.Notifications.NotificationsNtfy.toastNtfyTestSending": "Sending ntfy test notification…",
"components.Settings.Notifications.NotificationsNtfy.toastNtfyTestSuccess": "Ntfy test notification sent!",
@@ -641,7 +640,6 @@
"components.Settings.Notifications.NotificationsNtfy.usernamePasswordAuth": "Username + Password authentication",
"components.Settings.Notifications.NotificationsNtfy.validationNtfyTopic": "You must provide a topic",
"components.Settings.Notifications.NotificationsNtfy.validationNtfyUrl": "You must provide a valid URL",
"components.Settings.Notifications.NotificationsNtfy.validationPriorityRequired": "You must provide a priority between 1 and 5",
"components.Settings.Notifications.NotificationsNtfy.validationTypes": "You must select at least one notification type",
"components.Settings.Notifications.NotificationsPushbullet.accessToken": "Access Token",
"components.Settings.Notifications.NotificationsPushbullet.accessTokenTip": "Create a token from your <PushbulletSettingsLink>Account Settings</PushbulletSettingsLink>",