fix(netflow): сохранить неизвестные координаты RIPE без ложных нулей
This commit is contained in:
1 parent
af66faaae4
commit
c718654bc7
10 files changed
+330
-18
No files matched your search
@@ -220,3 +220,40 @@ resetRipeCacheForTests()
|
||||
assert.equal(lookupRipeCached("2606:4700:4700::1111"), null, "Invalidation clears IPv6 indexes")
|
||||
|
||||
console.log("traffic-flow-ripe.test.ts: ok (including IPv6 indexes and database pause/resume)")
|
||||
|
||||
for (const { name, location, expected } of [
|
||||
{ name: "normal", location: { country: "US", latitude: 37.4, longitude: -122.1 }, expected: [37.4, -122.1] },
|
||||
{ name: "equator", location: { country: "BR", latitude: 0, longitude: -50 }, expected: [0, -50] },
|
||||
{ name: "meridian", location: { country: "GB", latitude: 51, longitude: 0 }, expected: [51, 0] },
|
||||
{ name: "explicit zero", location: { country: "GH", latitude: 0, longitude: 0 }, expected: [0, 0] },
|
||||
{ name: "unknown placeholder", location: { country: "?", latitude: 0, longitude: 0 }, expected: [null, null] },
|
||||
{ name: "missing country placeholder", location: { latitude: 0, longitude: 0 }, expected: [null, null] },
|
||||
{ name: "unknown country real coordinates", location: { country: "?", latitude: 1, longitude: 2 }, expected: [1, 2] },
|
||||
{ name: "missing coordinates", location: { country: "US" }, expected: [null, null] },
|
||||
{ name: "null coordinates", location: { country: "US", latitude: null, longitude: null }, expected: [null, null] },
|
||||
{ name: "empty strings", location: { country: "US", latitude: "", longitude: "" }, expected: [null, null] },
|
||||
{ name: "boolean", location: { country: "US", latitude: false, longitude: false }, expected: [null, null] },
|
||||
{ name: "numeric strings", location: { country: "US", latitude: "0", longitude: "0" }, expected: [null, null] },
|
||||
{ name: "partial", location: { country: "US", latitude: 37 }, expected: [null, null] },
|
||||
{ name: "invalid latitude", location: { country: "US", latitude: 91, longitude: 1 }, expected: [null, null] },
|
||||
{ name: "invalid longitude", location: { country: "US", latitude: 1, longitude: -181 }, expected: [null, null] },
|
||||
{ name: "boundary", location: { country: "US", latitude: -90, longitude: 180 }, expected: [-90, 180] },
|
||||
]) {
|
||||
resetRipeCacheForTests()
|
||||
disableRipePersistForTests()
|
||||
setRipeFetchForTests(async input => {
|
||||
const url = String(input)
|
||||
const body = url.includes("network-info") ? { data: { prefix: "8.8.8.0/24", asns: [15169] } }
|
||||
: url.includes("maxmind-geo-lite") ? { data: { located_resources: [{ locations: [location] }] } }
|
||||
: { data: { holder: "GOOGLE, US" } }
|
||||
return new Response(JSON.stringify(body), { status: 200 })
|
||||
})
|
||||
enqueueRipeMisses(["8.8.8.8"])
|
||||
await flushRipeQueueForTests()
|
||||
const result = lookupRipeCached("8.8.8.8")
|
||||
assert.equal(result?.ok, true, name)
|
||||
assert.equal(result?.asn, 15169, name)
|
||||
assert.deepEqual([result?.lat, result?.lng], expected, name)
|
||||
if (location.country === "?" || !("country" in location)) assert.equal(result?.country, "US", "ASN country fallback is independent of coordinate validity")
|
||||
}
|
||||
console.log("traffic-flow-ripe.test.ts: coordinate provenance cases passed")
|
||||
@@ -383,18 +383,22 @@ function pickGeo(data: unknown): { country: string; lat: number | null; lng: num
|
||||
const d = data as {
|
||||
data?: {
|
||||
located_resources?: Array<{
|
||||
locations?: Array<{ country?: string; latitude?: number; longitude?: number }>
|
||||
locations?: Array<{ country?: string; latitude?: unknown; longitude?: unknown }>
|
||||
}>
|
||||
}
|
||||
}
|
||||
const loc = d?.data?.located_resources?.[0]?.locations?.[0]
|
||||
const country = resolveRipeCountry(String(loc?.country ?? ""), 0, "")
|
||||
const lat = loc?.latitude == null ? null : Number(loc.latitude)
|
||||
const lng = loc?.longitude == null ? null : Number(loc.longitude)
|
||||
const coordinate = (value: unknown, limit: number) => typeof value === "number" && Number.isFinite(value) && Math.abs(value) <= limit ? value : null
|
||||
const lat = coordinate(loc?.latitude, 90)
|
||||
const lng = coordinate(loc?.longitude, 180)
|
||||
// RIPE can return unknown country + 0/0 as a placeholder. ASN country fallback
|
||||
// must not turn that placeholder into a confirmed map location.
|
||||
const located = lat !== null && lng !== null && (Boolean(country) || lat !== 0 || lng !== 0)
|
||||
return {
|
||||
country: country || "—",
|
||||
lat: Number.isFinite(lat) ? lat : null,
|
||||
lng: Number.isFinite(lng) ? lng : null,
|
||||
lat: located ? lat : null,
|
||||
lng: located ? lng : null,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user