added option to force ipv4 or ipv6 for http(s) monitor type (#5880)

Co-authored-by: Ionys <9364594+Ionys320@users.noreply.github.com>
Co-authored-by: Frank Elsinga <frank@elsinga.de>
This commit is contained in:
Fabian Triebsch 2025-06-13 08:14:55 +02:00 committed by GitHub
parent 53e83e7722
commit f282422b22
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 54 additions and 0 deletions

View file

@ -0,0 +1,13 @@
exports.up = function (knex) {
return knex.schema
.alterTable("monitor", function (table) {
table.boolean("ip_family").defaultTo(null);
});
};
exports.down = function (knex) {
return knex.schema
.alterTable("monitor", function (table) {
table.dropColumn("ip_family");
});
};

View file

@ -160,6 +160,7 @@ class Monitor extends BeanModel {
smtpSecurity: this.smtpSecurity, smtpSecurity: this.smtpSecurity,
rabbitmqNodes: JSON.parse(this.rabbitmqNodes), rabbitmqNodes: JSON.parse(this.rabbitmqNodes),
conditions: JSON.parse(this.conditions), conditions: JSON.parse(this.conditions),
ipFamily: this.ipFamily,
// ping advanced options // ping advanced options
ping_numeric: this.isPingNumeric(), ping_numeric: this.isPingNumeric(),
@ -426,10 +427,26 @@ class Monitor extends BeanModel {
} }
} }
let agentFamily = undefined;
if (this.ipFamily === "ipv4") {
agentFamily = 4;
}
if (this.ipFamily === "ipv6") {
agentFamily = 6;
}
const httpsAgentOptions = { const httpsAgentOptions = {
maxCachedSessions: 0, // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940) maxCachedSessions: 0, // Use Custom agent to disable session reuse (https://github.com/nodejs/node/issues/3940)
rejectUnauthorized: !this.getIgnoreTls(), rejectUnauthorized: !this.getIgnoreTls(),
secureOptions: crypto.constants.SSL_OP_LEGACY_SERVER_CONNECT, secureOptions: crypto.constants.SSL_OP_LEGACY_SERVER_CONNECT,
autoSelectFamily: true,
...(agentFamily ? { family: agentFamily } : {})
};
const httpAgentOptions = {
maxCachedSessions: 0,
autoSelectFamily: true,
...(agentFamily ? { family: agentFamily } : {})
}; };
log.debug("monitor", `[${this.name}] Prepare Options for axios`); log.debug("monitor", `[${this.name}] Prepare Options for axios`);
@ -491,6 +508,7 @@ class Monitor extends BeanModel {
if (proxy && proxy.active) { if (proxy && proxy.active) {
const { httpAgent, httpsAgent } = Proxy.createAgents(proxy, { const { httpAgent, httpsAgent } = Proxy.createAgents(proxy, {
httpsAgentOptions: httpsAgentOptions, httpsAgentOptions: httpsAgentOptions,
httpAgentOptions: httpAgentOptions,
}); });
options.proxy = false; options.proxy = false;
@ -499,6 +517,10 @@ class Monitor extends BeanModel {
} }
} }
if (!options.httpAgent) {
options.httpAgent = new http.Agent(httpAgentOptions);
}
if (!options.httpsAgent) { if (!options.httpsAgent) {
let jar = new CookieJar(); let jar = new CookieJar();
let httpsCookieAgentOptions = { let httpsCookieAgentOptions = {

View file

@ -792,6 +792,7 @@ let needSetup = false;
bean.url = monitor.url; bean.url = monitor.url;
bean.method = monitor.method; bean.method = monitor.method;
bean.body = monitor.body; bean.body = monitor.body;
bean.ipFamily = monitor.ipFamily;
bean.headers = monitor.headers; bean.headers = monitor.headers;
bean.basic_auth_user = monitor.basic_auth_user; bean.basic_auth_user = monitor.basic_auth_user;
bean.basic_auth_pass = monitor.basic_auth_pass; bean.basic_auth_pass = monitor.basic_auth_pass;

View file

@ -1116,6 +1116,9 @@
"Sender name": "Sender name", "Sender name": "Sender name",
"smsplanetNeedToApproveName": "Needs to be approved in the client panel", "smsplanetNeedToApproveName": "Needs to be approved in the client panel",
"Disable URL in Notification": "Disable URL in Notification", "Disable URL in Notification": "Disable URL in Notification",
"Ip Family": "IP Family",
"ipFamilyDescriptionAutoSelect": "Uses the {happyEyeballs} for determining the IP family.",
"Happy Eyeballs algorithm": "Happy Eyeballs algorithm",
"Add Another Tag": "Add Another Tag", "Add Another Tag": "Add Another Tag",
"Staged Tags for Batch Add": "Staged Tags for Batch Add", "Staged Tags for Batch Add": "Staged Tags for Batch Add",
"Clear Form": "Clear Form", "Clear Form": "Clear Form",

View file

@ -745,6 +745,20 @@
{{ $t("acceptedStatusCodesDescription") }} {{ $t("acceptedStatusCodesDescription") }}
</div> </div>
</div> </div>
<div class="my-3">
<label for="ipFamily" class="form-label">{{ $t("Ip Family") }}</label>
<select id="ipFamily" v-model="monitor.ipFamily" class="form-select">
<option :value="null">{{ $t("auto-select") }}</option>
<option value="ipv4">IPv4</option>
<option value="ipv6">IPv6</option>
</select>
<i18n-t v-if="monitor.ipFamily == null" keypath="ipFamilyDescriptionAutoSelect" tag="div" class="form-text">
<template #happyEyeballs>
<a href="https://en.wikipedia.org/wiki/Happy_Eyeballs" target="_blank">{{ $t("Happy Eyeballs algorithm") }}</a>
</template>
</i18n-t>
</div>
</template> </template>
<!-- Parent Monitor --> <!-- Parent Monitor -->
@ -1129,6 +1143,7 @@ const monitorDefaults = {
parent: null, parent: null,
url: "https://", url: "https://",
method: "GET", method: "GET",
ipFamily: null,
interval: 60, interval: 60,
retryInterval: 60, retryInterval: 60,
resendInterval: 0, resendInterval: 0,