| 284 | } |
| 285 | |
| 286 | function isProxyUrlReachable(url, token) { |
| 287 | if (!url || !token) return false; |
| 288 | try { |
| 289 | execFileSync(process.execPath, ['-e', ` |
| 290 | const fs = require('fs'); |
| 291 | const http = require('http'); |
| 292 | const url = process.argv[1]; |
| 293 | const token = fs.readFileSync(0, 'utf8').trim(); |
| 294 | if (!token) process.exit(1); |
| 295 | const req = http.get(url.replace(/\\/+$/, '') + '/proxy/status', { |
| 296 | headers: { Authorization: 'Bearer ' + token }, |
| 297 | }, (res) => { |
| 298 | let body = ''; |
| 299 | res.setEncoding('utf8'); |
| 300 | res.on('data', (chunk) => { |
| 301 | body += chunk; |
| 302 | if (body.length > 1024 * 1024) req.destroy(new Error('response too large')); |
| 303 | }); |
| 304 | res.on('end', () => { |
| 305 | if (res.statusCode < 200 || res.statusCode >= 300) process.exit(1); |
| 306 | let parsed; |
| 307 | try { parsed = JSON.parse(body); } catch (_) { process.exit(1); } |
| 308 | if (parsed && parsed.status === 'running' && (parsed.proxy_protocol_version || parsed.schema_version || parsed.node_id != null)) { |
| 309 | process.exit(0); |
| 310 | } |
| 311 | process.exit(1); |
| 312 | }); |
| 313 | }); |
| 314 | req.setTimeout(800, () => { req.destroy(new Error('timeout')); }); |
| 315 | req.on('error', () => process.exit(1)); |
| 316 | `, url], { input: String(token), stdio: ['pipe', 'ignore', 'ignore'], timeout: 1500, windowsHide: true }); |
| 317 | return true; |
| 318 | } catch (_) { |
| 319 | return false; |
| 320 | } |
| 321 | } |
| 322 | |
| 323 | function checkProxyHealth(env) { |
| 324 | if (!expectsProxy(env)) return { healthy: true, expected: false }; |