proxy WIP: fix async & TCP, addr redaction
parent
55900836d4
commit
c248bddf1c
|
|
@ -1,6 +1,7 @@
|
||||||
// This is a Node.js implementation of status monitoring
|
// This is a Node.js implementation of status monitoring
|
||||||
|
|
||||||
const location = ''
|
const location = ''
|
||||||
|
const defaultTimeout = 5000 // 5 seconds, a lower default for deployments on platforms like Vercel
|
||||||
|
|
||||||
const express = require('express')
|
const express = require('express')
|
||||||
const net = require('net')
|
const net = require('net')
|
||||||
|
|
@ -22,15 +23,6 @@ const fetchTimeout = (url, ms, options = {}) => {
|
||||||
return promise.finally(() => clearTimeout(timeout))
|
return promise.finally(() => clearTimeout(timeout))
|
||||||
}
|
}
|
||||||
|
|
||||||
function withTimeout(millis, promise) {
|
|
||||||
const timeout = new Promise((resolve, reject) =>
|
|
||||||
setTimeout(() => reject(new Error(`Promise timed out after ${millis}ms`)), millis)
|
|
||||||
)
|
|
||||||
|
|
||||||
return Promise.race([promise, timeout])
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: More code reuse here
|
// TODO: More code reuse here
|
||||||
async function getStatus(monitor) {
|
async function getStatus(monitor) {
|
||||||
let status = {
|
let status = {
|
||||||
|
|
@ -43,41 +35,49 @@ async function getStatus(monitor) {
|
||||||
|
|
||||||
if (monitor.method === 'TCP_PING') {
|
if (monitor.method === 'TCP_PING') {
|
||||||
// TCP port endpoint monitor
|
// TCP port endpoint monitor
|
||||||
|
let host, port
|
||||||
try {
|
try {
|
||||||
// This is not a real https connection, but we need to add a dummy `https://` to parse the hostname & port
|
// This is not a real https connection, but we need to add a dummy `https://` to parse the hostname & port
|
||||||
|
// TODO: ipv6 buggy
|
||||||
const parsed = new URL("https://" + monitor.target)
|
const parsed = new URL("https://" + monitor.target)
|
||||||
|
host = parsed.hostname
|
||||||
|
port = parsed.port
|
||||||
|
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
const socket = net.createConnection({ host: host, port: Number(port) })
|
||||||
|
|
||||||
const client = await net.createConnection(
|
const timer = setTimeout(() => {
|
||||||
{ host: parsed.hostname, port: Number(parsed.port) },
|
socket.destroy()
|
||||||
() => {
|
reject(new Error(`Timeout after ${monitor.timeout || defaultTimeout}ms`))
|
||||||
console.log(`${monitor.name} connected to ${monitor.target}`)
|
}, monitor.timeout || defaultTimeout)
|
||||||
status.ping = Date.now() - startTime
|
|
||||||
status.up = true
|
socket.on('connect', () => {
|
||||||
status.err = ''
|
clearTimeout(timer)
|
||||||
client.end()
|
socket.end()
|
||||||
|
resolve(null)
|
||||||
|
})
|
||||||
|
|
||||||
|
socket.on('error', (err) => {
|
||||||
|
clearTimeout(timer)
|
||||||
|
socket.destroy()
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// const socket = connect({ hostname: parsed.hostname, port: Number(parsed.port) })
|
status.up = true
|
||||||
|
status.err = ''
|
||||||
// // Now we have an `opened` promise!
|
status.ping = Date.now() - startTime
|
||||||
// // @ts-ignore
|
|
||||||
// await withTimeout(monitor.timeout || 10000, socket.opened)
|
|
||||||
// await socket.close()
|
|
||||||
|
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(`${monitor.name} errored with ${e.name}: ${e.message}`)
|
console.log(`${monitor.name} errored with ${e.name}: ${e.message}`)
|
||||||
if (e.message.includes('timed out')) {
|
|
||||||
status.ping = monitor.timeout || 10000
|
|
||||||
}
|
|
||||||
status.up = false
|
status.up = false
|
||||||
status.err = e.name + ': ' + e.message
|
status.err = e.name + ': ' + e.message.replace(host, '<redacted>').replace(port, '<redacted>')
|
||||||
|
status.ping = Date.now() - startTime
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// HTTP endpoint monitor
|
// HTTP endpoint monitor
|
||||||
try {
|
try {
|
||||||
const response = await fetchTimeout(monitor.target, monitor.timeout || 10000, {
|
const response = await fetchTimeout(monitor.target, monitor.timeout || defaultTimeout, {
|
||||||
method: monitor.method,
|
method: monitor.method,
|
||||||
headers: monitor.headers,
|
headers: monitor.headers,
|
||||||
body: monitor.body,
|
body: monitor.body,
|
||||||
|
|
@ -129,7 +129,7 @@ async function getStatus(monitor) {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(`${monitor.name} errored with ${e.name}: ${e.message}`)
|
console.log(`${monitor.name} errored with ${e.name}: ${e.message}`)
|
||||||
if (e.name === 'AbortError') {
|
if (e.name === 'AbortError') {
|
||||||
status.ping = monitor.timeout || 10000
|
status.ping = monitor.timeout || defaultTimeout
|
||||||
status.up = false
|
status.up = false
|
||||||
status.err = `Timeout after ${status.ping}ms`
|
status.err = `Timeout after ${status.ping}ms`
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -144,11 +144,11 @@ async function getStatus(monitor) {
|
||||||
|
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
|
||||||
app.post('/', (req, res) => {
|
app.post('/', async (req, res) => {
|
||||||
res.json(
|
res.json(
|
||||||
{
|
{
|
||||||
location: getWorkerLocation(),
|
location: await getWorkerLocation(),
|
||||||
status: getStatus(req.body),
|
status: await getStatus(req.body),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue