| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| const LOGIN_PATH = "/admin/login" |
| const CHECK_ALL_PATH = "/admin/proxies/check-all" |
|
|
| function vercelHeaders(env) { |
| const headers = {} |
| const bypass = env.VERCEL_BYPASS_TOKEN |
| if (bypass) { |
| headers["x-vercel-protection-bypass"] = bypass |
| } |
| return headers |
| } |
|
|
| async function login(baseURL, adminKey, extraHeaders) { |
| const res = await fetch(`${baseURL}${LOGIN_PATH}`, { |
| method: "POST", |
| headers: { "Content-Type": "application/json", ...extraHeaders }, |
| body: JSON.stringify({ admin_key: adminKey, expire_hours: 1 }), |
| }) |
| if (!res.ok) { |
| const text = await res.text() |
| throw new Error(`login failed (${res.status}): ${text}`) |
| } |
| const data = await res.json() |
| return data.token |
| } |
|
|
| async function checkAll(baseURL, token, extraHeaders) { |
| const res = await fetch(`${baseURL}${CHECK_ALL_PATH}`, { |
| method: "POST", |
| headers: { |
| "Content-Type": "application/json", |
| Authorization: `Bearer ${token}`, |
| ...extraHeaders, |
| }, |
| }) |
| if (!res.ok) { |
| const text = await res.text() |
| throw new Error(`check-all failed (${res.status}): ${text}`) |
| } |
| return res.json() |
| } |
|
|
| async function runCheck(env) { |
| const baseURL = (env.DS2API_BASE_URL || "").replace(/\/+$/, "") |
| const adminKey = env.ADMIN_KEY || "" |
|
|
| if (!baseURL || !adminKey) { |
| throw new Error("DS2API_BASE_URL and ADMIN_KEY secrets must be set") |
| } |
|
|
| const extraHeaders = vercelHeaders(env) |
| const token = await login(baseURL, adminKey, extraHeaders) |
| const result = await checkAll(baseURL, token, extraHeaders) |
| return result |
| } |
|
|
| export default { |
| async scheduled(event, env, ctx) { |
| ctx.waitUntil( |
| runCheck(env) |
| .then((result) => { |
| const items = result.items || [] |
| const healthy = items.filter((i) => i.healthy && !i.disabled).length |
| const banned = items.filter((i) => i.disabled).length |
| console.log( |
| `proxy health check done: ${healthy}/${items.length} healthy, ${banned} banned` |
| ) |
| }) |
| .catch((err) => { |
| console.error(`proxy health check failed: ${err.message}`) |
| }) |
| ) |
| }, |
|
|
| async fetch(request, env) { |
| const url = new URL(request.url) |
| if (url.pathname !== "/check") { |
| return new Response("not found", { status: 404 }) |
| } |
|
|
| try { |
| const result = await runCheck(env) |
| return Response.json(result) |
| } catch (err) { |
| return Response.json({ error: err.message }, { status: 500 }) |
| } |
| }, |
| } |
|
|