fix(worker): omit Globalping ipVersion for IP targets (#177)
Globalping rejects measurementOptions.ipVersion when the measurement target is an IP address. Add an IP-target guard so ipVersion is only sent for domain targets, preventing validation errors when checking IP:port monitors.pull/180/head
parent
da4bfb888d
commit
5512912b22
|
|
@ -1,6 +1,28 @@
|
||||||
import { MonitorTarget } from '../../types/config'
|
import { MonitorTarget } from '../../types/config'
|
||||||
import { withTimeout, fetchTimeout } from './util'
|
import { withTimeout, fetchTimeout } from './util'
|
||||||
|
|
||||||
|
function isIpAddress(hostname: string): boolean {
|
||||||
|
// `URL.hostname` strips brackets for IPv6, so a `:` reliably indicates an IPv6 literal here.
|
||||||
|
if (hostname.includes(':')) return true
|
||||||
|
|
||||||
|
const parts = hostname.split('.')
|
||||||
|
if (parts.length !== 4) return false
|
||||||
|
|
||||||
|
return parts.every((part) => {
|
||||||
|
if (!/^\d{1,3}$/.test(part)) return false
|
||||||
|
const value = Number(part)
|
||||||
|
return value >= 0 && value <= 255
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDomainOnlyIpVersionOption(hostname: string, gpUrl: URL): { ipVersion?: number } {
|
||||||
|
// Globalping only allows `measurementOptions.ipVersion` when `target` is a domain (it controls DNS resolution).
|
||||||
|
if (isIpAddress(hostname)) return {}
|
||||||
|
|
||||||
|
// Keep the original behavior for domain targets.
|
||||||
|
return { ipVersion: Number(gpUrl.searchParams.get('ipVersion') || 4) }
|
||||||
|
}
|
||||||
|
|
||||||
async function httpResponseBasicCheck(
|
async function httpResponseBasicCheck(
|
||||||
monitor: MonitorTarget,
|
monitor: MonitorTarget,
|
||||||
code: number,
|
code: number,
|
||||||
|
|
@ -66,6 +88,7 @@ export async function getStatusWithGlobalPing(
|
||||||
|
|
||||||
if (monitor.method === 'TCP_PING') {
|
if (monitor.method === 'TCP_PING') {
|
||||||
const targetUrl = new URL('https://' + monitor.target) // dummy https:// to parse hostname & port
|
const targetUrl = new URL('https://' + monitor.target) // dummy https:// to parse hostname & port
|
||||||
|
const ipVersionOption = getDomainOnlyIpVersionOption(targetUrl.hostname, gpUrl)
|
||||||
globalPingRequest = {
|
globalPingRequest = {
|
||||||
type: 'ping',
|
type: 'ping',
|
||||||
target: targetUrl.hostname,
|
target: targetUrl.hostname,
|
||||||
|
|
@ -81,11 +104,12 @@ export async function getStatusWithGlobalPing(
|
||||||
port: targetUrl.port,
|
port: targetUrl.port,
|
||||||
packets: 1,
|
packets: 1,
|
||||||
protocol: 'tcp', // TODO: icmp?
|
protocol: 'tcp', // TODO: icmp?
|
||||||
ipVersion: Number(gpUrl.searchParams.get('ipVersion') || 4),
|
...ipVersionOption,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const targetUrl = new URL(monitor.target)
|
const targetUrl = new URL(monitor.target)
|
||||||
|
const ipVersionOption = getDomainOnlyIpVersionOption(targetUrl.hostname, gpUrl)
|
||||||
if (monitor.body !== undefined) {
|
if (monitor.body !== undefined) {
|
||||||
throw 'custom body not supported'
|
throw 'custom body not supported'
|
||||||
}
|
}
|
||||||
|
|
@ -119,7 +143,7 @@ export async function getStatusWithGlobalPing(
|
||||||
: 443
|
: 443
|
||||||
: Number(targetUrl.port),
|
: Number(targetUrl.port),
|
||||||
protocol: targetUrl.protocol.replace(':', ''),
|
protocol: targetUrl.protocol.replace(':', ''),
|
||||||
ipVersion: Number(gpUrl.searchParams.get('ipVersion') || 4),
|
...ipVersionOption,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue