fix(sites): Cloudflare 挑战不算凭据错误(CF-2)
- http.ts:cf-mitigated: challenge 或 403/503/429 挑战页 → SiteError(challenge),503 不再算维护、403 不再落到 auth_invalid - 挑战页分类 classifyChallengePage:自动 / 可点(Turnstile)/ 真验证码 - 刷新登录 / 用户数据遇 Cloudflare 挑战只记 last_error,账号状态不变、不开登录失效事项 Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
d403514adc
commit
a11ef16e40
5 files changed
+221
-2
No files matched your search
@@ -1,4 +1,5 @@
|
||||
import { redactText } from "../rss/redact.ts";
|
||||
import { detectChallenge } from "./challenge.ts";
|
||||
import type { SiteRateLimiter } from "./rate-limit.ts";
|
||||
import { SiteError } from "./types.ts";
|
||||
|
||||
@@ -20,7 +21,8 @@ function retryAfterMs(res: Response, now: Date): number | undefined {
|
||||
}
|
||||
|
||||
/**
|
||||
* 站点请求:先取站点令牌,再发请求;429/503 统一映射并顺延限流器。
|
||||
* 站点请求:先取站点令牌,再发请求;Cloudflare 挑战(`cf-mitigated: challenge`,或 403 / 503 / 429 的挑战页)→ `challenge`
|
||||
* (不是凭据错误,CF-2);其余 429/503 统一映射并顺延限流器。
|
||||
* 返回的 Response 由调用方消费。错误消息只含脱敏后的 URL。
|
||||
*/
|
||||
export async function siteFetch(
|
||||
@@ -42,6 +44,15 @@ export async function siteFetch(
|
||||
const reason = timeout.aborted ? "超时" : (e as Error).message;
|
||||
throw new SiteError(ctx.siteId, "network", redactText(`请求 ${safeUrl} 失败:${reason}`));
|
||||
}
|
||||
const ch = await detectChallenge(res);
|
||||
res = ch.res;
|
||||
if (ch.rule) {
|
||||
await res.body?.cancel().catch(() => {});
|
||||
throw new SiteError(ctx.siteId, "challenge", `请求 ${safeUrl}:站点要求人机验证(Cloudflare)`, {
|
||||
httpStatus: res.status,
|
||||
detail: { reason: "challenge", rule: ch.rule, httpStatus: res.status },
|
||||
});
|
||||
}
|
||||
if (res.status === 429 || res.status === 503) {
|
||||
const ra = retryAfterMs(res, ctx.now());
|
||||
await res.body?.cancel().catch(() => {});
|
||||
|
||||
Reference in new issue
Block a user