feat(sites): 出口统一与 Cloudflare 过挑战级联(CF-2)

- 出口:站点请求不再隐式继承 HTTP(S)_PROXY,没开代理明确直连(创建客户端时临时拿掉代理环境变量,Deno 2.9 语义见 egress.ts),
  开了走站点代理;TMDB / Brave / 图片改为显式按环境变量(行为不变)
- CloudflareGate:浏览器代理期直接代抓 → HTTP(可复用时带 cf_clearance)→ 挑战 → 浏览器过挑战(同站 30 分钟一次、单飞)
  → cf_clearance 仅在 UA 跟随浏览器且两端同出口时给 HTTP,重试 1 次记 cfReuse → 仍被挑战则浏览器代抓并进入 6 小时代理期
- 浏览器:solveSiteChallenge(自动放行 ≤15s / 系统发起视觉子流程最多 2 次 / 真验证码转人工待处理)、fetchSiteHtml(profile 锁 + 站点令牌)、
  交还后读回 cf_clearance 继续;site.config.cloudflare 状态契约

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-30 21:26:54 +08:00
1 parent 6b14b0da45
commit 16083942c0
14 files changed
+1711 -43

No files matched your search

+3 -1
View File
@@ -10,6 +10,7 @@ import {
} from "@umt/contracts";
import type { z } from "zod";
import { dataPaths } from "../../config.ts";
import { externalFetch } from "../../egress.ts";
import { requireScope } from "../../http/auth.ts";
import { errorBody } from "../../http/errors.ts";
import { CACHE_REGIONS, sharedCache, storageSettings, tmdbCachePolicy } from "../../shared-cache.ts";
@@ -73,7 +74,8 @@ export function createCacheModule(opts: CacheModuleOptions = {}): ServerModule &
if (!c) {
c = new ImageCache({
dir: opts.imageDir ?? join(dataPaths(ctx.config).dataDir, "cache", "images"),
...(opts.imageFetch ? { fetch: opts.imageFetch } : {}),
// 外网请求:显式按环境变量走代理(CF-2 出口表)
fetch: opts.imageFetch ?? externalFetch,
...(opts.imageUpstreamBase ? { upstreamBase: opts.imageUpstreamBase } : {}),
});
imageCaches.set(ctx, c);