合并 Phaser 一键发布自动构建与打包
Project CI / AI game creator shell Rust crates (push) Successful in 1m36s
Project CI / AI game creator shell Rust smoke (push) Successful in 2m9s
Project CI / Backend tests (push) Successful in 5m41s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 7m33s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 8m53s
Project CI / Native shell tests (push) Successful in 7m28s
Project CI / Frontend tests (push) Successful in 3m38s
Project CI / Repository checks (push) Successful in 3m36s
Project CI / AI game creator shell web tests (push) Successful in 2m55s

This commit was merged in pull request #481.
This commit is contained in:
2026-09-22 21:03:57 +08:00
7 changed files with 426 additions and 15 deletions
@@ -224,10 +224,29 @@ pub fn router(state: AppState) -> Router<AppState> {
"/api/game-distribution/releases/{game_id}/{*asset_path}",
get(serve_release_asset),
)
// 根路径等价于入口页:生产由发行来源(每游戏 origin)把 `/` 映射到 index.html,
// 本地直连网关或入口直接填网关地址时也必须能打开游戏。
.route(
"/api/game-distribution/releases/{game_id}",
get(serve_release_entry),
)
.route(
"/api/game-distribution/releases/{game_id}/",
get(serve_release_entry),
)
.merge(protected)
.merge(admin)
}
/// 发行网关根路径:等价于请求该游戏的 `index.html`。
async fn serve_release_entry(
state: State<AppState>,
headers: HeaderMap,
Path(game_id): Path<String>,
) -> Result<Response, AppError> {
serve_release_asset(state, headers, Path((game_id, "index.html".to_string()))).await
}
/// 公开发行网关。
///
/// 只服务当前已公开版本的游戏文件,路径必须在白名单内容类型内;私有 ZIP 对象和
@@ -1902,6 +1921,7 @@ mod tests {
// 未在白名单内的扩展名直接 404,不进入 SpacetimeDB 与对象存储。
let unknown_extension = app
.clone()
.oneshot(
Request::builder()
.uri("/api/game-distribution/releases/game_1/payload.bin")
@@ -1911,6 +1931,29 @@ mod tests {
.await
.expect("路由响应");
assert_eq!(unknown_extension.status(), StatusCode::NOT_FOUND);
// 根路径(含尾斜杠)等价于入口页:生产由发行来源映射,直接连网关时也必须能开。
for uri in [
"/api/game-distribution/releases/game_1",
"/api/game-distribution/releases/game_1/",
] {
let with_cookie = app
.clone()
.oneshot(
Request::builder()
.uri(uri)
.header("cookie", "genarrative.refresh-token=1")
.body(Body::empty())
.expect("请求"),
)
.await
.expect("路由响应");
assert_eq!(
with_cookie.status(),
StatusCode::FORBIDDEN,
"{uri} 必须先过 Cookie 拒绝门,而不是 404"
);
}
}
#[tokio::test]