@samitouri / QOSami-HFS / commits / 020483ab

admin/internet: faster

Massimo Melina committed Aug 21, 2023 at 14:30 UTC 020483abdcec3a8747220d3651433ed245bcf670
1 file changed +27 -18
src/api.net.ts
+27 -18
@@ -38,8 +38,15 @@ async function getNatInfo() {
38
39 async function getPublicIp() {
40 const prjInfo = await getProjectInfo()
41 - for (const url of _.shuffle(prjInfo.publicIpServices))
42 - try { return (await httpsString(url)).body?.trim() }
41 + for (const urls of _.chunk(_.shuffle(prjInfo.publicIpServices), 2)) // small parallelization
42 + try {
43 + return await Promise.any(urls.map(url => httpsString(url).then(res => {
44 + const ip = res.body?.trim()
45 + if (!/[.:0-9a-fA-F]/.test(ip))
46 + throw Error("bad result: " + ip)
47 + return ip
48 + })))
49 + }
50 catch (e: any) { console.debug(String(e)) }
51 }
52
@@ -68,7 +75,6 @@ const apis: ApiHandlers = {
75 },
76
77 async check_server() {
71 - const noop = () => null
78 const { publicIp, internalPort, externalPort } = await getNatInfo()
79 if (!publicIp) return new ApiError(HTTP_SERVICE_UNAVAILABLE, 'cannot detect public ip')
80 const prjInfo = await getProjectInfo()
@@ -83,21 +89,24 @@ const apis: ApiHandlers = {
89 regexpFailure: string
90 regexpSuccess: string
91 }
86 - for (const svc of _.shuffle<PortScannerService>(prjInfo.checkServerServices)) {
87 - const service = new URL(svc.url).hostname
88 - console.log('using service', service)
89 - const api = (axios as any)[svc.method]
90 - const body = svc.body?.replace('$IP', publicIp).replace('$PORT', port) || ''
91 - const res = await api(svc.url, body, {headers: svc.headers}).catch(noop)
92 - if (!res) continue
93 - console.debug('service responded')
94 - const parsed = parse(res.data).querySelector(svc.selector)?.innerText
95 - if (!parsed) continue
96 - const success = new RegExp(svc.regexpSuccess).test(parsed)
97 - const failure = new RegExp(svc.regexpFailure).test(parsed)
98 - if (success === failure) continue // this result cannot be trusted
99 - console.log('server', success ? 'responding' : 'not responding')
100 - return { success, service }
92 + for (const services of _.chunk(_.shuffle<PortScannerService>(prjInfo.checkServerServices), 2)) {
93 + try {
94 + return Promise.any(services.map(async svc => {
95 + const service = new URL(svc.url).hostname
96 + console.log('trying service', service)
97 + const api = (axios as any)[svc.method]
98 + const body = svc.body?.replace('$IP', publicIp).replace('$PORT', port) || ''
99 + const res = await api(svc.url, body, {headers: svc.headers})
100 + console.debug(service, 'responded')
101 + const parsed = parse(res.data).querySelector(svc.selector)?.innerText
102 + if (!parsed) throw console.debug('empty:' + service)
103 + const success = new RegExp(svc.regexpSuccess).test(parsed)
104 + const failure = new RegExp(svc.regexpFailure).test(parsed)
105 + if (success === failure) throw console.debug('inconsistent:' + service) // this result cannot be trusted
106 + return { success, service }
107 + }))
108 + }
109 + catch {}
110 }
111 return new ApiError(HTTP_SERVICE_UNAVAILABLE, 'no service available to detect upnp mapping')
112 },