#!/usr/bin/env node import { spawnSync } from 'node:child_process'; import { mkdtempSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import path from 'node:path'; const DIRECT_LIVE_SCRIPT = 'scripts/check-pingora-direct-live.mjs'; const failures = []; const tmpRoot = mkdtempSync( path.join(tmpdir(), 'genarrative-pingora-direct-live-guard-'), ); try { main(); } finally { rmSync(tmpRoot, { recursive: true, force: true }); } if (failures.length > 0) { console.error('[check:pingora-direct-live-guard] FAILED'); for (const failure of failures) { console.error(`- ${failure}`); } process.exit(1); } console.log('[check:pingora-direct-live-guard] OK'); function main() { assertRejectsControlCharacter('--https-base-url', [ '--https-base-url', 'https://127.0.0.1\n--fake-flag', ]); assertRejectsControlCharacter('--http-base-url', [ '--https-base-url', 'https://127.0.0.1', '--http-base-url', 'http://127.0.0.1\r--fake-flag', ]); assertRejectsControlCharacter('--host', [ '--https-base-url', 'https://127.0.0.1', '--host', 'example.com\nX-Injected: yes', ]); assertRejectsControlCharacter('--redirect-host', [ '--https-base-url', 'https://127.0.0.1', '--redirect-host', 'example.com\nhidden', ]); assertRejectsControlCharacter('--redirect-base-url', [ '--https-base-url', 'https://127.0.0.1', '--redirect-base-url', 'https://example.com\nhidden', ]); assertRejectsInvalidRedirectBaseUrl(); assertRejectsControlCharacter('--probe-token', [ '--https-base-url', 'https://127.0.0.1', '--probe-token', 'probe\nX-Injected: yes', '--skip-wss', ]); assertRejectsControlCharacter('--path', [ '--https-base-url', 'https://127.0.0.1', '--path', '/api/health\nX-Injected: yes', '--skip-wss', ]); assertRejectsControlCharacter('--pingora-access-log', [ '--https-base-url', 'https://127.0.0.1', '--pingora-access-log', `${path.join(tmpRoot, 'pingora.access.log')}\n--fake-flag`, '--skip-wss', ]); assertRejectsControlCharacter('--spacetime-database', [ '--https-base-url', 'https://127.0.0.1', '--spacetime-database', 'genarrative\nprod', '--skip-wss', ]); assertRejectsControlCharacter('--timeout-ms', [ '--https-base-url', 'https://127.0.0.1', '--timeout-ms', '5000\n1', '--skip-wss', ]); } function assertRejectsInvalidRedirectBaseUrl() { const result = spawnSync( 'node', [ DIRECT_LIVE_SCRIPT, '--https-base-url', 'https://127.0.0.1', '--redirect-base-url', 'http://example.com', ], { cwd: process.cwd(), encoding: 'utf8', env: process.env, }, ); if ((result.status ?? 0) === 0) { failures.push('--redirect-base-url 必须拒绝非 HTTPS base URL。'); return; } assertIncludes( `${result.stdout}\n${result.stderr}`, '--redirect-base-url 必须使用 https://', '--redirect-base-url 非 HTTPS 时必须给出明确错误。', ); } function assertRejectsControlCharacter(label, args) { const result = spawnSync('node', [DIRECT_LIVE_SCRIPT, ...args], { cwd: process.cwd(), encoding: 'utf8', env: process.env, }); if ((result.status ?? 0) === 0) { failures.push(`${label} 带控制字符时必须在发起 live 请求前失败。`); return; } assertIncludes( `${result.stdout}\n${result.stderr}`, `${label} 不能包含换行或 NUL 字符`, `${label} 带控制字符时必须给出明确错误。`, ); } function assertIncludes(value, expected, reason) { if (!String(value).includes(expected)) { failures.push(`${reason} 缺少: ${expected}`); } }