From 49aeca90609dec6a46b141218e95ffd6afea4a1c Mon Sep 17 00:00:00 2001 From: "planetrenox@protonmail.com" Date: Mon, 26 Oct 2026 19:45:55 +0000 Subject: [PATCH] Fix: Log image requests the rewrite rules changed The WAF rule runs after the rewrites, so it matches on the raw path. Co-Authored-By: Claude Opus 5.5 --- scripts/rules.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/scripts/rules.js b/scripts/rules.js index 46e1248..8c3a0af 100644 --- a/scripts/rules.js +++ b/scripts/rules.js @@ -10,22 +10,23 @@ import { MAX_PLUSES } from "../src/_utils/keys.js"; const env = process.env, hosts = process.argv.slice(2), ZONE = env.ZONE || "direct-img.link", TAG = "direct-img fold:"; -const PATH = "http.request.uri.path", ARG = n => `http.request.uri.args["${n}"][0]`; +// Conditions use the raw (original) path, since the WAF rule runs after the rewrites and would see theirs +const PATH = "http.request.uri.path", RAW = "raw.http.request.uri.path", ARG = n => `http.request.uri.args["${n}"][0]`; const api = (path, init) => fetch(`https://api.cloudflare.com/client/v4${path}`, { ...init, headers: { Authorization: `Bearer ${env.CLOUDFLARE_API_TOKEN}`, "Content-Type": "application/json" } }).then(r => r.json()); // An image request: not the homepage, assets/, robots.txt, probes like /wp-admin/x.php or an already rewritten path -const IMAGE = `http.host in {${hosts.map(h => JSON.stringify(h)).join(" ")}} and ${PATH} ne "/" and not ${PATH} contains "." and not ${PATH} wildcard "/*/*"`; +const IMAGE = `http.host in {${hosts.map(h => JSON.stringify(h)).join(" ")}} and ${RAW} ne "/" and not ${RAW} contains "." and not ${RAW} wildcard "/*/*"`; // Folded only with no params but i and src (others get bad.webp from the worker), and without a literal + (%2B), since // a static file's %2B stands for a space -const FOLDABLE = `${IMAGE} and (http.request.uri.query eq "" or all(http.request.uri.args.names[*] in {"i" "src"})) and not lower(${PATH}) contains "%2b"`; +const FOLDABLE = `${IMAGE} and (http.request.uri.query eq "" or all(http.request.uri.args.names[*] in {"i" "src"})) and not lower(${RAW}) contains "%2b"`; const pluses = n => `"${"*+".repeat(n)}*"`; const rules = { - // A rule's condition sees the original path, and the free plan has no regex_replace and allows one wildcard_replace + // A rule can't see an earlier one's rewrite, and the free plan has no regex_replace and allows one wildcard_replace // per rule, so each rule handles an exact number of +s; a query with more always runs the worker. A missing param is // empty, so a bare query is i-. http_request_transform: hosts.length ? Array.from({ length: MAX_PLUSES + 1 }, (_, n) => ({ description: `${TAG} query with ${n} +`, - expression: `${FOLDABLE} and ${n ? `${PATH} wildcard ${pluses(n)}` : `not ${PATH} contains "+"`} and not ${PATH} wildcard ${pluses(n + 1)}`, + expression: `${FOLDABLE} and ${n ? `${RAW} wildcard ${pluses(n)}` : `not ${RAW} contains "+"`} and not ${RAW} wildcard ${pluses(n + 1)}`, action: "rewrite", action_parameters: { uri: { path: { expression: `concat("/", http.host, ${n ? `wildcard_replace(lower(${PATH}), ${pluses(n)}, "${Array.from({ length: n }, (_, k) => `\${${k + 1}}%2B`).join("")}\${${n + 1}}")` : `lower(${PATH})`}, "/i", ${ARG("i")}, "-", ${ARG("src")})` } } }, })) : [],