修正 Pingora 高端口重定向验收
direct live 支持独立 redirect base URL 预期 release readiness 和切换证据链透传 redirect base URL 直连启用脚本透传高端口 rehearsal 参数 补充 direct live guard、运维门禁和文档示例
This commit is contained in:
@@ -558,6 +558,11 @@ function assertScriptShape() {
|
||||
'--apply 必须同时提供 --direct-host',
|
||||
'启用脚本 apply 时必须强制正式域名 Host/SNI 参数。',
|
||||
);
|
||||
assertIncludes(
|
||||
content,
|
||||
'--direct-redirect-base-url',
|
||||
'启用脚本必须支持 direct live redirect base URL 覆盖,用于高端口 rehearsal。',
|
||||
);
|
||||
assertIncludes(
|
||||
content,
|
||||
'--apply 必须同时提供 --direct-redirect-host',
|
||||
@@ -653,6 +658,11 @@ function assertScriptShape() {
|
||||
'print_redacted_command node "${direct_live_args[@]}"',
|
||||
'启用脚本展示 direct live smoke 命令时必须隐藏 probe token。',
|
||||
);
|
||||
assertIncludes(
|
||||
content,
|
||||
'direct_live_args+=(--redirect-base-url "${DIRECT_REDIRECT_BASE_URL}")',
|
||||
'启用脚本必须把 direct redirect base URL 透传给 direct live smoke。',
|
||||
);
|
||||
assertIncludes(
|
||||
content,
|
||||
'drop-in 目录不能是符号链接',
|
||||
|
||||
@@ -50,6 +50,13 @@ function main() {
|
||||
'--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',
|
||||
@@ -87,6 +94,33 @@ function main() {
|
||||
]);
|
||||
}
|
||||
|
||||
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(),
|
||||
|
||||
@@ -41,6 +41,8 @@ Options:
|
||||
--http-base-url <url> Optional HTTP base URL that should 301 to HTTPS.
|
||||
--host <host> Optional Host header for local --resolve style checks.
|
||||
--redirect-host <host> Optional expected Location host for HTTP redirects.
|
||||
--redirect-base-url <url>
|
||||
Optional expected HTTPS base URL for HTTP redirects.
|
||||
--probe-token <token> Optional Pingora shadow probe token.
|
||||
--spacetime-database <name>
|
||||
SpacetimeDB database for WSS subscribe smoke, default genarrative-prod.
|
||||
@@ -60,6 +62,7 @@ Environment aliases:
|
||||
GENARRATIVE_PINGORA_DIRECT_HTTP_BASE_URL
|
||||
GENARRATIVE_PINGORA_DIRECT_HOST
|
||||
GENARRATIVE_PINGORA_DIRECT_REDIRECT_HOST
|
||||
GENARRATIVE_PINGORA_DIRECT_REDIRECT_BASE_URL
|
||||
GENARRATIVE_PINGORA_DIRECT_PROBE_TOKEN
|
||||
GENARRATIVE_PINGORA_DIRECT_SPACETIME_DATABASE
|
||||
GENARRATIVE_PINGORA_DIRECT_REQUIRE_WSS_UPGRADE
|
||||
@@ -77,6 +80,8 @@ function parseArgs(argv) {
|
||||
httpBaseUrl: process.env.GENARRATIVE_PINGORA_DIRECT_HTTP_BASE_URL || '',
|
||||
host: process.env.GENARRATIVE_PINGORA_DIRECT_HOST || '',
|
||||
redirectHost: process.env.GENARRATIVE_PINGORA_DIRECT_REDIRECT_HOST || '',
|
||||
redirectBaseUrl:
|
||||
process.env.GENARRATIVE_PINGORA_DIRECT_REDIRECT_BASE_URL || '',
|
||||
probeToken: process.env.GENARRATIVE_PINGORA_DIRECT_PROBE_TOKEN || '',
|
||||
spacetimeDatabase:
|
||||
process.env.GENARRATIVE_PINGORA_DIRECT_SPACETIME_DATABASE ||
|
||||
@@ -133,6 +138,9 @@ function parseArgs(argv) {
|
||||
case '--redirect-host':
|
||||
result.redirectHost = requireValue(argv, ++index, arg);
|
||||
break;
|
||||
case '--redirect-base-url':
|
||||
result.redirectBaseUrl = requireValue(argv, ++index, arg);
|
||||
break;
|
||||
case '--probe-token':
|
||||
result.probeToken = requireValue(argv, ++index, arg);
|
||||
break;
|
||||
@@ -197,6 +205,9 @@ function parseArgs(argv) {
|
||||
if (result.redirectHost) {
|
||||
validateHostOption(result.redirectHost, '--redirect-host');
|
||||
}
|
||||
if (result.redirectBaseUrl) {
|
||||
validateHttpsBaseUrl(result.redirectBaseUrl, '--redirect-base-url');
|
||||
}
|
||||
if (result.probeToken) {
|
||||
validateNoControlCharacters(result.probeToken, '--probe-token');
|
||||
}
|
||||
@@ -255,6 +266,26 @@ function validateHostOption(value, flag) {
|
||||
}
|
||||
}
|
||||
|
||||
function validateHttpsBaseUrl(value, flag) {
|
||||
validateNoControlCharacters(value, flag);
|
||||
const parsed = new URL(value);
|
||||
if (parsed.protocol !== 'https:') {
|
||||
throw new Error(`${flag} 必须使用 https://`);
|
||||
}
|
||||
if (
|
||||
!parsed.hostname ||
|
||||
parsed.pathname !== '/' ||
|
||||
parsed.search ||
|
||||
parsed.hash ||
|
||||
parsed.username ||
|
||||
parsed.password
|
||||
) {
|
||||
throw new Error(
|
||||
`${flag} 只能是 HTTPS base URL,不能包含路径、查询、片段或认证信息。`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function validateSafeAbsoluteFilePath(filePath, label) {
|
||||
validateNoControlCharacters(filePath, label);
|
||||
if (!nodePath.isAbsolute(filePath)) {
|
||||
@@ -1065,6 +1096,9 @@ function assertPingoraGatewayHeader(check, response) {
|
||||
}
|
||||
|
||||
function directHttpsLocation(httpsBaseUrl, path) {
|
||||
if (config.redirectBaseUrl) {
|
||||
return joinUrl(config.redirectBaseUrl, path);
|
||||
}
|
||||
if (!config.redirectHost) {
|
||||
return joinUrl(httpsBaseUrl, path);
|
||||
}
|
||||
|
||||
@@ -86,6 +86,8 @@ function parseArgs(argv) {
|
||||
directHost: process.env.GENARRATIVE_PINGORA_DIRECT_HOST || '',
|
||||
directRedirectHost:
|
||||
process.env.GENARRATIVE_PINGORA_DIRECT_REDIRECT_HOST || '',
|
||||
directRedirectBaseUrl:
|
||||
process.env.GENARRATIVE_PINGORA_DIRECT_REDIRECT_BASE_URL || '',
|
||||
directProbeToken: process.env.GENARRATIVE_PINGORA_DIRECT_PROBE_TOKEN || '',
|
||||
directPingoraAccessLog:
|
||||
process.env.GENARRATIVE_PINGORA_DIRECT_PINGORA_ACCESS_LOG || '',
|
||||
@@ -228,6 +230,9 @@ function parseArgs(argv) {
|
||||
case '--direct-redirect-host':
|
||||
result.directRedirectHost = requireValue(argv, ++index, arg);
|
||||
break;
|
||||
case '--direct-redirect-base-url':
|
||||
result.directRedirectBaseUrl = requireValue(argv, ++index, arg);
|
||||
break;
|
||||
case '--direct-probe-token':
|
||||
result.directProbeToken = requireValue(argv, ++index, arg);
|
||||
break;
|
||||
@@ -412,6 +417,24 @@ function parseArgs(argv) {
|
||||
if (result.directRedirectHost) {
|
||||
validateHostOption(result.directRedirectHost, '--direct-redirect-host');
|
||||
}
|
||||
if (result.directRedirectBaseUrl) {
|
||||
validateHttpUrl(result.directRedirectBaseUrl, '--direct-redirect-base-url');
|
||||
const parsed = new URL(result.directRedirectBaseUrl);
|
||||
if (parsed.protocol !== 'https:') {
|
||||
throw new Error('--direct-redirect-base-url 必须使用 https://。');
|
||||
}
|
||||
if (
|
||||
parsed.pathname !== '/' ||
|
||||
parsed.search ||
|
||||
parsed.hash ||
|
||||
parsed.username ||
|
||||
parsed.password
|
||||
) {
|
||||
throw new Error(
|
||||
'--direct-redirect-base-url 只能是 HTTPS base URL,不能包含路径、查询、片段或认证信息。',
|
||||
);
|
||||
}
|
||||
}
|
||||
if (result.requireDirect && !result.directPingoraAccessLog) {
|
||||
throw new Error(
|
||||
'启用 --require-direct 时必须提供 --direct-pingora-access-log 或 GENARRATIVE_PINGORA_DIRECT_PINGORA_ACCESS_LOG',
|
||||
@@ -661,6 +684,8 @@ Options:
|
||||
--direct-http-base-url <url> direct HTTP redirect base URL;也可用 GENARRATIVE_PINGORA_DIRECT_HTTP_BASE_URL。
|
||||
--direct-host <host> direct live Host header 和 TLS SNI;也可用 GENARRATIVE_PINGORA_DIRECT_HOST。--require-direct 时必须显式提供。
|
||||
--direct-redirect-host <host> direct redirect Location host;也可用 GENARRATIVE_PINGORA_DIRECT_REDIRECT_HOST。--require-direct 时必须显式提供,cutover runbook 中必须和 --direct-host 使用同一 hostname。
|
||||
--direct-redirect-base-url <url>
|
||||
可选 direct redirect Location HTTPS base URL;用于高端口 rehearsal 访问 127.0.0.1:18443 但期望 Location 指向正式 HTTPS 入口。
|
||||
--direct-probe-token <token> direct live shadow probe token;也可用 GENARRATIVE_PINGORA_DIRECT_PROBE_TOKEN。
|
||||
--direct-pingora-access-log <path>
|
||||
direct live 后 Pingora access log 落盘校验路径;--require-direct 时必须显式提供。
|
||||
@@ -971,6 +996,9 @@ function buildCutoverPlan(config) {
|
||||
config.directHost,
|
||||
'--direct-redirect-host',
|
||||
config.directRedirectHost,
|
||||
...(config.directRedirectBaseUrl
|
||||
? ['--direct-redirect-base-url', config.directRedirectBaseUrl]
|
||||
: []),
|
||||
'--direct-spacetime-database',
|
||||
config.directSpacetimeDatabase,
|
||||
'--direct-pingora-access-log',
|
||||
@@ -1023,6 +1051,7 @@ function buildCutoverPlan(config) {
|
||||
`cutover-run-id=${config.cutoverRunId}`,
|
||||
`direct-host=${config.directHost}`,
|
||||
`direct-redirect-host=${config.directRedirectHost}`,
|
||||
`direct-redirect-base-url=${config.directRedirectBaseUrl || '-'}`,
|
||||
`health-patrol-public-host=${config.directHost}`,
|
||||
`rollback-nginx-smoke-host=${config.rollbackNginxSmokeHost}`,
|
||||
`rollback-nginx-smoke-expect-body=${config.rollbackNginxSmokeExpectBody}`,
|
||||
@@ -1229,6 +1258,9 @@ function buildCutoverPlan(config) {
|
||||
config.directHost,
|
||||
'--direct-redirect-host',
|
||||
config.directRedirectHost,
|
||||
...(config.directRedirectBaseUrl
|
||||
? ['--direct-redirect-base-url', config.directRedirectBaseUrl]
|
||||
: []),
|
||||
...(config.directProbeToken
|
||||
? ['--direct-probe-token', config.directProbeToken]
|
||||
: []),
|
||||
@@ -1485,6 +1517,9 @@ function readinessArgs(config, { includeDirect }) {
|
||||
config.directHost,
|
||||
'--direct-redirect-host',
|
||||
config.directRedirectHost,
|
||||
...(config.directRedirectBaseUrl
|
||||
? ['--direct-redirect-base-url', config.directRedirectBaseUrl]
|
||||
: []),
|
||||
...(config.directProbeToken
|
||||
? ['--direct-probe-token', config.directProbeToken]
|
||||
: []),
|
||||
@@ -1718,6 +1753,9 @@ function buildSteps(config) {
|
||||
...(config.directRedirectHost
|
||||
? ['--redirect-host', config.directRedirectHost]
|
||||
: []),
|
||||
...(config.directRedirectBaseUrl
|
||||
? ['--redirect-base-url', config.directRedirectBaseUrl]
|
||||
: []),
|
||||
...(config.directProbeToken
|
||||
? ['--probe-token', config.directProbeToken]
|
||||
: []),
|
||||
@@ -1910,6 +1948,9 @@ function appendTargetDirectSteps(steps, config, scriptPath) {
|
||||
...(config.directRedirectHost
|
||||
? ['--redirect-host', config.directRedirectHost]
|
||||
: []),
|
||||
...(config.directRedirectBaseUrl
|
||||
? ['--redirect-base-url', config.directRedirectBaseUrl]
|
||||
: []),
|
||||
...(config.directProbeToken
|
||||
? ['--probe-token', config.directProbeToken]
|
||||
: []),
|
||||
|
||||
@@ -2933,6 +2933,12 @@ const checks = [
|
||||
reason:
|
||||
'Pingora direct live smoke 环境示例必须暴露 HTTP redirect Location host。',
|
||||
},
|
||||
{
|
||||
file: 'deploy/env/pingora-direct-live.env.example',
|
||||
includes: 'GENARRATIVE_PINGORA_DIRECT_REDIRECT_BASE_URL',
|
||||
reason:
|
||||
'Pingora direct live smoke 环境示例必须暴露高端口 rehearsal 的 redirect Location base URL 覆盖。',
|
||||
},
|
||||
{
|
||||
file: 'deploy/env/pingora-direct-live.env.example',
|
||||
includes: '只填域名或 host:port',
|
||||
@@ -3106,6 +3112,12 @@ const checks = [
|
||||
reason:
|
||||
'Pingora direct live smoke 必须提前拒绝非法 redirect Location host 参数。',
|
||||
},
|
||||
{
|
||||
file: 'scripts/check-pingora-direct-live.mjs',
|
||||
includes: 'validateHttpsBaseUrl(result.redirectBaseUrl,',
|
||||
reason:
|
||||
'Pingora direct live smoke 必须提前拒绝非法 redirect Location base URL 参数。',
|
||||
},
|
||||
{
|
||||
file: 'scripts/check-pingora-direct-live.mjs',
|
||||
includes: 'parseRequiredPositiveInt',
|
||||
@@ -3638,6 +3650,12 @@ const checks = [
|
||||
includes: '--apply 必须同时提供 --direct-redirect-host',
|
||||
reason: 'Pingora 直连启用 apply 后必须验证 redirect Location host。',
|
||||
},
|
||||
{
|
||||
file: 'scripts/deploy/pingora-direct-enable.sh',
|
||||
includes: '--direct-redirect-base-url',
|
||||
reason:
|
||||
'Pingora 直连启用脚本必须支持把高端口 rehearsal 的 redirect base URL 透传给 direct live smoke。',
|
||||
},
|
||||
{
|
||||
file: 'scripts/deploy/pingora-direct-enable.sh',
|
||||
includes: '--apply 必须同时提供 --direct-spacetime-database',
|
||||
|
||||
@@ -26,6 +26,7 @@ DIRECT_HTTPS_BASE_URL="${GENARRATIVE_PINGORA_DIRECT_HTTPS_BASE_URL:-}"
|
||||
DIRECT_HTTP_BASE_URL="${GENARRATIVE_PINGORA_DIRECT_HTTP_BASE_URL:-}"
|
||||
DIRECT_HOST="${GENARRATIVE_PINGORA_DIRECT_HOST:-}"
|
||||
DIRECT_REDIRECT_HOST="${GENARRATIVE_PINGORA_DIRECT_REDIRECT_HOST:-}"
|
||||
DIRECT_REDIRECT_BASE_URL="${GENARRATIVE_PINGORA_DIRECT_REDIRECT_BASE_URL:-}"
|
||||
DIRECT_PROBE_TOKEN="${GENARRATIVE_PINGORA_DIRECT_PROBE_TOKEN:-}"
|
||||
DIRECT_PINGORA_ACCESS_LOG="${GENARRATIVE_PINGORA_DIRECT_PINGORA_ACCESS_LOG:-}"
|
||||
DIRECT_ACCESS_LOG_SINCE_LINES="${GENARRATIVE_PINGORA_DIRECT_ACCESS_LOG_SINCE_LINES:-}"
|
||||
@@ -39,7 +40,7 @@ usage() {
|
||||
cat <<'EOF'
|
||||
用法:
|
||||
scripts/deploy/pingora-direct-enable.sh [--apply] [--preflight-env-file <path>] [--preflight-systemd] [--preflight-check-cert-readable] [--preflight-check-service-env-file] [--preflight-check-service-user-cert-readable] [--preflight-check-service-binary-executable] [--preflight-check-ports-free]
|
||||
[--direct-https-base-url <url>] [--direct-http-base-url <url>] [--direct-host <host>] [--direct-redirect-host <host>]
|
||||
[--direct-https-base-url <url>] [--direct-http-base-url <url>] [--direct-host <host>] [--direct-redirect-host <host>] [--direct-redirect-base-url <url>]
|
||||
[--direct-spacetime-database <name>] [--direct-probe-token <token>] [--direct-pingora-access-log <path>] [--direct-access-log-since-lines <count>] [--direct-timeout-ms <ms>] [--direct-live-script <path>] [--no-postcheck]
|
||||
[--current-release-audit-script <path>] [--current-release-root <path>] [--current-release-audit-timeout-ms <ms>]
|
||||
[--service <name>] [--service-unit-path <path>] [--template-path <path>] [--dropin-path <path>]
|
||||
@@ -211,6 +212,14 @@ while [[ $# -gt 0 ]]; do
|
||||
fi
|
||||
shift 2
|
||||
;;
|
||||
--direct-redirect-base-url)
|
||||
DIRECT_REDIRECT_BASE_URL="${2:-}"
|
||||
if [[ -z "${DIRECT_REDIRECT_BASE_URL}" ]]; then
|
||||
echo "[pingora-direct-enable] --direct-redirect-base-url 缺少参数" >&2
|
||||
exit 1
|
||||
fi
|
||||
shift 2
|
||||
;;
|
||||
--direct-probe-token)
|
||||
DIRECT_PROBE_TOKEN="${2:-}"
|
||||
if [[ -z "${DIRECT_PROBE_TOKEN}" ]]; then
|
||||
@@ -297,6 +306,7 @@ reject_control_characters "--direct-https-base-url" "${DIRECT_HTTPS_BASE_URL}"
|
||||
reject_control_characters "--direct-http-base-url" "${DIRECT_HTTP_BASE_URL}"
|
||||
reject_control_characters "--direct-host" "${DIRECT_HOST}"
|
||||
reject_control_characters "--direct-redirect-host" "${DIRECT_REDIRECT_HOST}"
|
||||
reject_control_characters "--direct-redirect-base-url" "${DIRECT_REDIRECT_BASE_URL}"
|
||||
reject_control_characters "--direct-probe-token" "${DIRECT_PROBE_TOKEN}"
|
||||
reject_control_characters "--direct-pingora-access-log" "${DIRECT_PINGORA_ACCESS_LOG}"
|
||||
reject_control_characters "--direct-access-log-since-lines" "${DIRECT_ACCESS_LOG_SINCE_LINES}"
|
||||
@@ -732,6 +742,9 @@ run_direct_live_smoke_after_enable() {
|
||||
if [[ -n "${DIRECT_REDIRECT_HOST}" ]]; then
|
||||
direct_live_args+=(--redirect-host "${DIRECT_REDIRECT_HOST}")
|
||||
fi
|
||||
if [[ -n "${DIRECT_REDIRECT_BASE_URL}" ]]; then
|
||||
direct_live_args+=(--redirect-base-url "${DIRECT_REDIRECT_BASE_URL}")
|
||||
fi
|
||||
if [[ -n "${DIRECT_PROBE_TOKEN}" ]]; then
|
||||
direct_live_args+=(--probe-token "${DIRECT_PROBE_TOKEN}")
|
||||
fi
|
||||
@@ -905,5 +918,5 @@ cat <<EOF
|
||||
- systemctl is-active ${SERVICE_NAME} 为 active
|
||||
- node ${CURRENT_RELEASE_AUDIT_SCRIPT} --release-root ${CURRENT_RELEASE_ROOT} --require-pingora-gateway --systemd-show --systemd-service ${SERVICE_NAME} 已通过
|
||||
- npm run check:pingora-direct-preflight -- --env-file /etc/genarrative/pingora-gateway.env --require-live-env --systemd-cat --check-cert-readable --check-service-env-file --check-service-user-cert-readable --check-service-binary-executable --check-ports-free 已通过
|
||||
- node ${DIRECT_LIVE_SCRIPT} --https-base-url ${DIRECT_HTTPS_BASE_URL:-<direct-https-base-url>} --http-base-url ${DIRECT_HTTP_BASE_URL:-<direct-http-base-url>} --host ${DIRECT_HOST:-<direct-host>} --redirect-host ${DIRECT_REDIRECT_HOST:-<direct-redirect-host>} --pingora-access-log ${DIRECT_PINGORA_ACCESS_LOG:-<pingora-access-log>} --spacetime-database ${DIRECT_SPACETIME_DATABASE:-<database>} --require-wss-upgrade --json 已通过,且 direct-access-log 结构化证据 matched=checked、missing=0、mismatches=0
|
||||
- node ${DIRECT_LIVE_SCRIPT} --https-base-url ${DIRECT_HTTPS_BASE_URL:-<direct-https-base-url>} --http-base-url ${DIRECT_HTTP_BASE_URL:-<direct-http-base-url>} --host ${DIRECT_HOST:-<direct-host>} --redirect-host ${DIRECT_REDIRECT_HOST:-<direct-redirect-host>} ${DIRECT_REDIRECT_BASE_URL:+--redirect-base-url ${DIRECT_REDIRECT_BASE_URL} }--pingora-access-log ${DIRECT_PINGORA_ACCESS_LOG:-<pingora-access-log>} --spacetime-database ${DIRECT_SPACETIME_DATABASE:-<database>} --require-wss-upgrade --json 已通过,且 direct-access-log 结构化证据 matched=checked、missing=0、mismatches=0
|
||||
EOF
|
||||
|
||||
@@ -442,6 +442,8 @@ function parseArgs(argv) {
|
||||
directHost: process.env.GENARRATIVE_PINGORA_DIRECT_HOST || '',
|
||||
directRedirectHost:
|
||||
process.env.GENARRATIVE_PINGORA_DIRECT_REDIRECT_HOST || '',
|
||||
directRedirectBaseUrl:
|
||||
process.env.GENARRATIVE_PINGORA_DIRECT_REDIRECT_BASE_URL || '',
|
||||
directProbeToken: process.env.GENARRATIVE_PINGORA_DIRECT_PROBE_TOKEN || '',
|
||||
directSpacetimeDatabase:
|
||||
process.env.GENARRATIVE_PINGORA_DIRECT_SPACETIME_DATABASE || '',
|
||||
@@ -521,6 +523,9 @@ function parseArgs(argv) {
|
||||
case '--direct-redirect-host':
|
||||
result.directRedirectHost = requireValue(argv, ++index, arg);
|
||||
break;
|
||||
case '--direct-redirect-base-url':
|
||||
result.directRedirectBaseUrl = requireValue(argv, ++index, arg);
|
||||
break;
|
||||
case '--direct-probe-token':
|
||||
result.directProbeToken = requireValue(argv, ++index, arg);
|
||||
break;
|
||||
@@ -597,6 +602,7 @@ Options:
|
||||
--direct-http-base-url <url> 透传给 direct live smoke 的 HTTP redirect / ACME 入口。
|
||||
--direct-host <host> 透传给 direct live smoke 的正式 Host/SNI。
|
||||
--direct-redirect-host <host> 透传给 direct live smoke 的 redirect Location host。
|
||||
--direct-redirect-base-url <url> 可选,透传给 direct live smoke 的 redirect Location HTTPS base URL。
|
||||
--direct-probe-token <token> 可选,透传给 direct live smoke 的内部探针 token;证据中会脱敏。
|
||||
--direct-spacetime-database <db> 透传给 direct live smoke 的 SpacetimeDB 数据库名。
|
||||
--direct-pingora-access-log <path>
|
||||
@@ -681,6 +687,9 @@ function validateDirectLiveConfig(config) {
|
||||
throw new Error('--run-direct-live 必须提供 --direct-redirect-host。');
|
||||
}
|
||||
validateHostOption(config.directRedirectHost, '--direct-redirect-host');
|
||||
if (config.directRedirectBaseUrl) {
|
||||
validateHttpsBaseUrl(config.directRedirectBaseUrl, '--direct-redirect-base-url');
|
||||
}
|
||||
if (!config.directSpacetimeDatabase) {
|
||||
throw new Error('--run-direct-live 必须提供 --direct-spacetime-database。');
|
||||
}
|
||||
@@ -807,6 +816,22 @@ function validateHttpsUrl(value, label) {
|
||||
}
|
||||
}
|
||||
|
||||
function validateHttpsBaseUrl(value, label) {
|
||||
validateHttpsUrl(value, label);
|
||||
const parsed = new URL(value);
|
||||
if (
|
||||
parsed.pathname !== '/' ||
|
||||
parsed.search ||
|
||||
parsed.hash ||
|
||||
parsed.username ||
|
||||
parsed.password
|
||||
) {
|
||||
throw new Error(
|
||||
`${label} 只能是 HTTPS base URL,不能包含路径、查询、片段或认证信息。`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function validateHttpOnlyUrl(value, label) {
|
||||
validateHttpUrl(value, label);
|
||||
if (new URL(value).protocol !== 'http:') {
|
||||
@@ -961,6 +986,9 @@ function buildDirectLiveArgs(config) {
|
||||
config.directHost,
|
||||
'--redirect-host',
|
||||
config.directRedirectHost,
|
||||
...(config.directRedirectBaseUrl
|
||||
? ['--redirect-base-url', config.directRedirectBaseUrl]
|
||||
: []),
|
||||
...(config.directProbeToken
|
||||
? ['--probe-token', config.directProbeToken]
|
||||
: []),
|
||||
|
||||
Reference in New Issue
Block a user