From 7da39b2acb91f5dd65e63b0ec078d37259bb2950 Mon Sep 17 00:00:00 2001 From: kaffa Date: Thu, 9 Apr 2026 02:59:48 +0000 Subject: [PATCH] =?UTF-8?q?edge:=20=EC=BA=A1=EC=B1=A0=20verify=20=EA=B2=BD?= =?UTF-8?q?=EB=A1=9C=20=ED=95=AD=EC=83=81=20=EC=9D=B8=ED=84=B0=EC=85=89?= =?UTF-8?q?=ED=8A=B8=20(bloom=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20rac?= =?UTF-8?q?e=EB=A1=9C=20origin=20404=20dead-end=20=EC=88=98=EC=A0=95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- edge/middleware.ts | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/edge/middleware.ts b/edge/middleware.ts index 0309899..bb85a1e 100644 --- a/edge/middleware.ts +++ b/edge/middleware.ts @@ -316,6 +316,22 @@ BunnySDK.net.http .servePullZone() .onOriginRequest(async (ctx) => { const ip = ctx.request.headers.get("X-Real-Ip"); + const url = new URL(ctx.request.url); + + // Reserved path: always intercepted so it never reaches origin. + // Bloom filter may update between captcha serve and verify POST; + // if so, the POST would otherwise fall through to origin as 404, + // leaving the user stuck in a dead-end captcha flow. + if (url.pathname === "/__captcha/verify") { + if (!ip || ctx.request.method !== "POST") { + return new Response(null, { + status: 302, + headers: { Location: "/" }, + }); + } + return handleCaptchaVerify(ctx.request, ip); + } + if (!ip) return ctx.request; if (isCleanCached(ip)) return ctx.request; @@ -329,12 +345,6 @@ BunnySDK.net.http return ctx.request; } - const url = new URL(ctx.request.url); - - if (url.pathname === "/__captcha/verify" && ctx.request.method === "POST") { - return handleCaptchaVerify(ctx.request, ip); - } - return captchaPage(url.pathname + url.search); }