fix(download): LiteLoader 不再套 bmclapi 改写,Central 库接上 bmclapi/maven
bmclapi-liteloader 改成 enabled=false(规则保留作形状留档):2026-11-10 实探 `apply()` 的真实产物 https://bmclapi2.bangbang93.com/maven/versions.json 404 / 9 B、 /maven/com/mumfrey/liteloader/1.7.10/liteloader-1.7.10_04.jar 404 / 9 B、 /maven/com/mumfrey/liteloader/{maven-metadata.xml,1.12.2-SNAPSHOT/maven-metadata.xml} 全 404 / 9 B;官方 dl.liteloader.com 的 versions.json 200 / 49129 B、artifact 200 / 533903 B。引擎遇 404 只会白丢一次请求再前进(NotFound 不重试),官方不可达时 更是直接失败,所以镜像优先用户不该再为每个 LiteLoader 文件试一次镜像。 新增 bmclapi-maven-central(repo1.maven.org/maven2 → bmclapi/maven):bmclapi 的 /maven 不只是 libraries.minecraft.net 的镜像,Central 的路径逐字节一致(asm-all 5.2 247787 B、gson 2.10.1 283367 B、log4j-core 2.17.1 1790452 B,sha1 逐一相同),不存在 的坐标两侧都是 404(镜像回 9 B 纯文本,没有「200 + HTML」假阳性)。 快照仓 repo.mumfrey.com 不加规则:bmclapi /maven、maven.aliyun.com/repository/central、 repo.huaweicloud.com/repository/maven 对 com/mumfrey/liteloader/1.12.2-SNAPSHOT/ maven-metadata.xml 全是 404,只有官方 200 / 358 B,所以只登记探测结果、不铺未验证的规则。 测试:新增 liteloader_urls_stay_official_only(镜像优先模式也只出官方一条,把 enabled 翻回 true 的变异实测会红);library_urls_expand_to_the_maven_subpath_on_bmclapi 补 Central 用例;形态判据的 EXPECTED 表加 bmclapi-maven-central。不探外网。 version 保持 3 不升 4:download/jdk_sources.rs 与 tests/game/java_vendor_chain.rs 两处 pin 了 version == 3,后者不在本 mission 的 scope(第一轮 workspace test 就是被这条 pin 抓红的),升版留给专门一轮;规则改动与探测记录写进 mirrors.json 的 notes。
This commit is contained in:
1 parent
54995a4af8
commit
146eb3d8db
2 files changed
+55
-33
No files matched your search
@@ -30,29 +30,21 @@ fn prefix_rule_preserves_sub_path() {
|
||||
.expect("libraries 规则缺失");
|
||||
let candidate = rule.apply(LIBRARIES_URL).expect("重写失败");
|
||||
assert_eq!(candidate.source, "bmclapi");
|
||||
// 子路径逐字保留(`/maven` 是镜像侧的固定前缀,不属于子路径)。
|
||||
//
|
||||
// M210/D1:这条断言此前写的是「换成 `https://bmclapi2.bangbang93.com` 就完事」,等于把
|
||||
// **丢 inject 的 bug 钉成了期望**——实测 70/70 个库 404(无 `/maven` 回 404 + 9 B,
|
||||
// 带 `/maven` 回 200、sha1 与官方逐字节一致)。现在把 `/maven` 写进期望值。
|
||||
assert_eq!(
|
||||
candidate.url,
|
||||
LIBRARIES_URL.replace(
|
||||
"https://libraries.minecraft.net",
|
||||
"https://bmclapi2.bangbang93.com/maven"
|
||||
)
|
||||
// 子路径逐字保留(`/maven` 是镜像侧的固定前缀,不属于子路径)。M210/D1:这条断言此前写成
|
||||
// 「换成 `https://bmclapi2.bangbang93.com` 就完事」,把**丢 inject 的 bug 钉成了期望**——实测
|
||||
// 无 `/maven` 是 70/70 个库 404 + 9 B,带 `/maven` 回 200 且 sha1 与官方逐字节一致。
|
||||
let expected = LIBRARIES_URL.replace(
|
||||
"https://libraries.minecraft.net",
|
||||
"https://bmclapi2.bangbang93.com/maven",
|
||||
);
|
||||
assert_eq!(candidate.url, expected);
|
||||
}
|
||||
|
||||
/// **守卫(M210/D1)**:每一条「给 libraries 用」的镜像规则,镜像前缀都必须带 `/maven`。
|
||||
///
|
||||
/// 官方库域名(`libraries.minecraft.net`)与各 loader 的 maven 在 BMCLAPI 上统一挂在 `/maven`
|
||||
/// 下;`apply()` 是纯前缀替换,`to` 里少了这一段就会把 `com/google/guava/...` 直接拼到镜像根上。
|
||||
///
|
||||
/// 抓得住:删掉/改错任一条库镜像规则的 `inject`(本用例对 `bmclapi-libraries` 的变异会红)。
|
||||
/// 抓不住:`/maven` **写歪**(如 `/maven2`、`/maven/` 之外的等价路径)只能靠行为用例
|
||||
/// [`library_urls_expand_to_the_maven_subpath_on_bmclapi`];路径结构本就不同的镜像表(资源对象走
|
||||
/// `/assets`、元数据走 `/fabric-meta`)不在此判据内;新增但 `from` 不像 maven 仓库的库镜像也不在此列。
|
||||
/// **守卫(M210/D1)**:每一条「给 libraries 用」的镜像规则,镜像前缀都必须带 `/maven`。官方库域名与
|
||||
/// 各 loader 的 maven 在 BMCLAPI 上都挂在 `/maven` 下,而 `apply()` 是纯前缀替换——`to` 里少了这一段
|
||||
/// 就会把 `com/google/guava/...` 直接拼到镜像根上。抓得住:删掉/改错任一条库镜像规则的 `inject`;
|
||||
/// 抓不住:`/maven` **写歪**(如 `/maven2`)只能靠行为用例 [`library_urls_expand_to_the_maven_subpath_on_bmclapi`];
|
||||
/// `/assets`、`/fabric-meta` 这类结构本就不同的镜像表,以及 `from` 不像 maven 仓库的新库镜像,都不在列。
|
||||
#[test]
|
||||
fn every_library_mirror_rule_carries_the_maven_segment() {
|
||||
let table = MirrorTable::builtin();
|
||||
@@ -63,14 +55,14 @@ fn every_library_mirror_rule_carries_the_maven_segment() {
|
||||
|| from.contains("maven")
|
||||
|| host_of(from) == Some("libraries.minecraft.net")
|
||||
}
|
||||
// 判据覆盖的规则 id(内置表里就是这 5 条;`bmclapi-liteloader` 的 `from` 不像 maven 仓库,不在列,
|
||||
// 它指向的镜像路径另有一个「镜像上不存在」的观察,见 M210 报告的 §5)。
|
||||
const EXPECTED: [&str; 5] = [
|
||||
// 判据覆盖的规则 id(内置表里就是这 6 条;`bmclapi-liteloader` 的 `from` 不像 maven 仓库,且已因 M225 关闭,不在列)。
|
||||
const EXPECTED: [&str; 6] = [
|
||||
"bmclapi-libraries",
|
||||
"bmclapi-forge-maven",
|
||||
"bmclapi-forge-maven-net",
|
||||
"bmclapi-neoforge",
|
||||
"bmclapi-fabric-maven",
|
||||
"bmclapi-maven-central",
|
||||
];
|
||||
let mut checked: Vec<&str> = Vec::new();
|
||||
for rule in table.rules.iter().filter(|rule| serves_maven(&rule.from)) {
|
||||
@@ -99,11 +91,10 @@ fn every_library_mirror_rule_carries_the_maven_segment() {
|
||||
);
|
||||
}
|
||||
|
||||
/// **行为守卫(M210/D1)**:真实库 URL 展开后必须落在镜像的 `/maven/<子路径>` 上。
|
||||
///
|
||||
/// 与上一条互为补充:那条看规则形态,这条看用户实际会请求到的 URL。
|
||||
/// 抓得住:`inject` 丢失、`to` 里手写 `/maven` 被删、或 `from`/`to` 被改成拼不出 `/maven` 的形态。
|
||||
/// 抓不住:只覆盖这 4 个官方 maven 根(各处未必都写全);镜像侧真实可达性(要网络,留给 e2e)。
|
||||
/// **行为守卫(M210/D1)**:真实库 URL 展开后必须落在镜像的 `/maven/<子路径>` 上。与上一条互为
|
||||
/// 补充:那条看规则形态,这条看用户实际会请求到的 URL。抓得住:`inject` 丢失、`to` 里手写 `/maven`
|
||||
/// 被删、或 `from`/`to` 被改成拼不出 `/maven` 的形态;抓不住:只覆盖这 5 个官方 maven 根(各处未必
|
||||
/// 都写全),镜像侧真实可达性要网络(留给 e2e)。
|
||||
#[test]
|
||||
fn library_urls_expand_to_the_maven_subpath_on_bmclapi() {
|
||||
let table = MirrorTable::builtin();
|
||||
@@ -125,6 +116,11 @@ fn library_urls_expand_to_the_maven_subpath_on_bmclapi() {
|
||||
"https://maven.neoforged.net/releases/net/neoforged/neoforge/21.1.80/neoforge-21.1.80-installer.jar",
|
||||
"https://bmclapi2.bangbang93.com/maven/net/neoforged/neoforge/21.1.80/neoforge-21.1.80-installer.jar",
|
||||
),
|
||||
// M225:LiteLoader 的库来自 Central(`net.minecraft:launchwrapper` 才是 Mojang 库仓)。
|
||||
(
|
||||
"https://repo1.maven.org/maven2/org/ow2/asm/asm-all/5.2/asm-all-5.2.jar",
|
||||
"https://bmclapi2.bangbang93.com/maven/org/ow2/asm/asm-all/5.2/asm-all-5.2.jar",
|
||||
),
|
||||
];
|
||||
for (official, expected) in cases {
|
||||
let candidates = table.expand(official, ResourceKind::Library, ®ion);
|
||||
@@ -139,6 +135,22 @@ fn library_urls_expand_to_the_maven_subpath_on_bmclapi() {
|
||||
}
|
||||
}
|
||||
|
||||
/// **守卫(M225)**:LiteLoader 不套 bmclapi 改写——镜像侧 `versions.json` 与 artifact 实测 404 / 9 B,
|
||||
/// 官方 200(curl 记录见 `mirrors.json` 的 notes)。抓得住:`bmclapi-liteloader.enabled` 被翻回 true、
|
||||
/// 或有人给快照仓补来源不明的镜像规则;抓不住:镜像侧哪天真的补上了(那时改期望与 notes,别删测试)。
|
||||
#[test]
|
||||
fn liteloader_urls_stay_official_only() {
|
||||
let (table, region) = (MirrorTable::builtin(), RegionProfile::mirror_first(0));
|
||||
for url in [
|
||||
"https://dl.liteloader.com/versions/versions.json",
|
||||
"https://dl.liteloader.com/versions/com/mumfrey/liteloader/1.7.10/liteloader-1.7.10_04.jar",
|
||||
"https://repo.mumfrey.com/content/repositories/snapshots/com/mumfrey/liteloader/1.12.2-SNAPSHOT/maven-metadata.xml",
|
||||
] {
|
||||
let got = table.expand(url, ResourceKind::Library, ®ion);
|
||||
assert_eq!(got.len(), 1, "{url} 不该有镜像候选:{got:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn asset_rule_injects_path_prefix() {
|
||||
let table = MirrorTable::builtin();
|
||||
@@ -222,9 +234,8 @@ fn pinned_or_disabled_gh_proxy_is_respected() {
|
||||
.expect("自定义前缀未生效");
|
||||
assert_eq!(proxy.url, format!("https://proxy.example/{GITHUB_URL}"));
|
||||
|
||||
// 「默认前缀」的唯一真相源是**地区档案**(M193:`MirrorTable::set_gh_proxy` /
|
||||
// `default_gh_proxy` 已删除——它们改/读的是表里的前缀目录,而 `expand()` 读档案,
|
||||
// 属于「看起来能改、其实没人读」。这条断言从此钉在档案上)。
|
||||
// 「默认前缀」的唯一真相源是**地区档案**(M193:`MirrorTable::set_gh_proxy` / `default_gh_proxy`
|
||||
// 已删除——它们改/读的是表里的前缀目录,而 `expand()` 读档案,属于「看起来能改、其实没人读」)。
|
||||
assert_eq!(
|
||||
RegionProfile::mirror_first(0).gh_proxy.as_deref(),
|
||||
Some(unlucky_core::download::region::DEFAULT_GH_PROXY)
|
||||
|
||||
Reference in new issue
Block a user