实现 Pingora 发行网关路由并关闭两处路由漂移待办
Project CI / AI game creator shell Rust crates (push) Failing after 1m17s
Project CI / AI game creator shell Rust smoke (push) Successful in 2m1s
Project CI / AI game creator shell Rust lane 2/2 (push) Has been cancelled
Project CI / Backend tests (push) Has been cancelled
Project CI / Frontend tests (push) Has been cancelled
Project CI / Repository checks (push) Has been cancelled
Project CI / AI game creator shell web tests (push) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (push) Has been cancelled
Project CI / Native shell tests (push) Has been cancelled
Project CI / AI game creator shell Rust crates (push) Failing after 1m17s
Project CI / AI game creator shell Rust smoke (push) Successful in 2m1s
Project CI / AI game creator shell Rust lane 2/2 (push) Has been cancelled
Project CI / Backend tests (push) Has been cancelled
Project CI / Frontend tests (push) Has been cancelled
Project CI / Repository checks (push) Has been cancelled
Project CI / AI game creator shell web tests (push) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (push) Has been cancelled
Project CI / Native shell tests (push) Has been cancelled
- 新增 RouteDecision::ReleaseGateway:/games/game_<32 位小写十六进制 id>/… 重写上游路径到 /api/game-distribution/releases/<gameId><asset>、清空 Cookie、不进 SPA fallback、不套接流保护分组、不受维护闸拦截,与 nginx 同名 location 同口径(只认小写 32 位十六进制) - 路由矩阵新增 games_release_gateway 用例(含 upstreamPath 期望值)与对应断言;parity 门禁支持 release_gateway 并把 games_spa_fallback、games_release_gateway 列入必查清单 - check:pingora-gateway-smoke 新增三条运行时断言:重写到发行网关且上游拿不到 Cookie、/games/detail 仍走 SPA、/games/game/index.html 仍是真实 404 - 文档:Pingora 试点文档补「平台同源发行入口」语义;pitfalls 记录 SPA allowlist 三处真相源与「发行入口不是 SPA」;按 docs/project-memory/README.md 删除两份已关闭待办,关闭记录写入开放事项索引第五节 - 验证:网关 39 passed、check:pingora-route-parity OK(23 路由)、check:nginx-spa-routes OK(12 路由 / 3 模板)、check:pingora-gateway-smoke 通过、cargo fmt --all --check、check:production-ops、encoding / doc-index / diff 检查全绿;变异验证:矩阵 upstreamPath 写错或拿掉 /games/detail 都会立刻变红
This commit is contained in:
@@ -1011,6 +1011,55 @@ async function runSmokeCases(
|
||||
`API 上游 X-Real-IP 未使用 TCP 对端 IP:${apiPayload.realIp}`,
|
||||
);
|
||||
|
||||
// 平台同源发行入口:/games/game_<32 位小写十六进制 id>/… 重写到发行网关并清空 Cookie,
|
||||
// 形状不符的路径不许被吞进发行网关(SPA 深链仍是 SPA,`/games/game/...` 仍是真实 404)。
|
||||
const releaseGameId = 'game_0123456789abcdef0123456789abcdef';
|
||||
const releaseUpstreamPath = `/api/game-distribution/releases/${releaseGameId}/index.html`;
|
||||
const releaseBeforeCount = api.state.requests.length;
|
||||
const releaseResponse = await expectHttp(
|
||||
baseUrl,
|
||||
`/games/${releaseGameId}/index.html`,
|
||||
200,
|
||||
'"upstream":"api"',
|
||||
'平台同源发行入口转发到发行网关',
|
||||
{
|
||||
headers: {
|
||||
'X-Request-Id': 'smoke-release-request-id',
|
||||
Host: 'example.test',
|
||||
Cookie: 'session=smoke-must-not-reach-release-gateway',
|
||||
},
|
||||
},
|
||||
);
|
||||
const releasePayload = JSON.parse(releaseResponse.body);
|
||||
ensure(
|
||||
releasePayload.url === releaseUpstreamPath,
|
||||
`发行入口上游路径没有重写:${releasePayload.url}`,
|
||||
);
|
||||
const releaseUpstreamRequests = api.state.requests.slice(releaseBeforeCount);
|
||||
ensure(
|
||||
releaseUpstreamRequests.length === 1 &&
|
||||
releaseUpstreamRequests[0].url === releaseUpstreamPath,
|
||||
`发行入口上游请求不符:${describeRequests(releaseUpstreamRequests)}`,
|
||||
);
|
||||
ensure(
|
||||
releaseUpstreamRequests[0]?.headers.cookie === undefined,
|
||||
`发行入口没有清空 Cookie:${describeRequests(releaseUpstreamRequests)}`,
|
||||
);
|
||||
await expectHttp(
|
||||
baseUrl,
|
||||
'/games/detail',
|
||||
200,
|
||||
'site-shell',
|
||||
'发行入口形状不符时 SPA 深链照常回退',
|
||||
);
|
||||
await expectHttp(
|
||||
baseUrl,
|
||||
'/games/game/index.html',
|
||||
404,
|
||||
'',
|
||||
'发行入口形状不符时仍是真实 404',
|
||||
);
|
||||
|
||||
await expectHttp(
|
||||
baseUrl,
|
||||
'/api/upload',
|
||||
|
||||
@@ -14,6 +14,7 @@ const PINGORA_GATEWAY_SOURCE = 'server-rs/crates/pingora-gateway/src/main.rs';
|
||||
const VALID_KINDS = new Set([
|
||||
'proxy',
|
||||
'static',
|
||||
'release_gateway',
|
||||
'redirect_permanent',
|
||||
'shadow_probe',
|
||||
'not_found',
|
||||
@@ -39,6 +40,8 @@ const REQUIRED_ROUTE_IDS = [
|
||||
'generated_assets_forbidden',
|
||||
'web_spa_fallback',
|
||||
'profile_spa_fallback',
|
||||
'games_spa_fallback',
|
||||
'games_release_gateway',
|
||||
'web_spa_case_trailing_slash',
|
||||
'web_unknown_path_exact',
|
||||
'creation_unknown_path_exact',
|
||||
@@ -108,6 +111,15 @@ function validateExpectation(route) {
|
||||
fail(`${context} 非 proxy 路由不能配置 protectionClass。`);
|
||||
}
|
||||
|
||||
if (expect.kind !== 'release_gateway' && hasOwn(expect, 'upstreamPath')) {
|
||||
fail(`${context} 只有 release_gateway 路由才能配置 upstreamPath。`);
|
||||
}
|
||||
|
||||
if (expect.kind === 'release_gateway') {
|
||||
requireString(expect.upstreamPath, `${context} upstreamPath`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (expect.kind === 'static') {
|
||||
if (!VALID_STATIC_ROOTS.has(expect.root)) {
|
||||
fail(`${context} static root 不支持: ${expect.root}`);
|
||||
|
||||
Reference in New Issue
Block a user