Feat: Give free.direct-img.link its own 100/day search limit

Free searches never spend Brave credits, so they no longer share the
main site's 35/day counter. Main-site rate ids are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-06 16:23:56 -07:00
co-authored by Claude Opus 5.5
parent 2941397180
commit 0ab01d6e66
3 changed files with 8 additions and 5 deletions
+1 -1
View File
@@ -133,7 +133,7 @@ Use images to complement your responses, powered by Brave.
### New Searches (Cache Misses)
- **35 new searches per day per IP** (resets at midnight UTC), then `limit.webp` is served — shared between `direct-img.link` and `free.direct-img.link`
- **35 new searches per day per IP** on `direct-img.link` and **100** on `free.direct-img.link` (separate counters, reset at midnight UTC), then `limit.webp` is served
- **Cache hits are unlimited** (within WAF limits above)
- Failed searches count toward the limit and are remembered for 24h (`bad.webp`)
- WAF counters are approximate (not shared perfectly across Cloudflare servers), so bursts may slip slightly past 10
+5 -3
View File
@@ -54,7 +54,9 @@ export async function onRequest(context) {
const ip = request.headers.get("cf-connecting-ip") || "unknown";
const today = new Date().toISOString().slice(0, 10);
const rateId = await sha256(`${ip}:${today}`);
// free.* gets its own counter (prefixed so main-site ids stay unchanged) since it never spends Brave credits
const rateId = await sha256(`${free ? "free:" : ""}${ip}:${today}`);
const limit = free ? 100 : 35;
let count = 1;
if (env.SURREAL_URL && env.SURREAL_USER && env.SURREAL_PASS) {
@@ -133,8 +135,8 @@ export async function onRequest(context) {
}));
}
if (count > 35) {
context.waitUntil(notify(env, { title: "Rate Limit Hit", message: `IP ${ip} hit limit for: ${query}`, tags: "warning,no_entry", priority: 2 }));
if (count > limit) {
context.waitUntil(notify(env, { title: free ? "Free Rate Limit Hit" : "Rate Limit Hit", message: `IP ${ip} hit limit for: ${query}`, tags: "warning,no_entry", priority: 2 }));
return asset("limit.webp");
}
+2 -1
View File
@@ -100,9 +100,10 @@ Use images to complement your responses, powered by Brave.</code></pre>
<tbody>
<tr><td>Burst</td><td>~10 req/10s per IP</td><td>HTTP 429 (~10s)</td></tr>
<tr><td>New Searches</td><td>35 per day per IP</td><td>Limit image served</td></tr>
<tr><td>New Free Searches</td><td>100 per day per IP</td><td>Limit image served</td></tr>
</tbody>
</table>
<p style="font-size:0.85rem;color:var(--text-muted);">* The daily limit is shared with free.direct-img.link. Cached images don't count toward it and keep loading after you hit it. The burst limit applies to all image requests and is enforced approximately. The daily limit resets at 00:00 UTC.</p>
<p style="font-size:0.85rem;color:var(--text-muted);">* free.direct-img.link has its own daily limit, separate from the main site's. Cached images don't count toward it and keep loading after you hit it. The burst limit applies to all image requests and is enforced approximately. The daily limit resets at 00:00 UTC.</p>
</section>
<section>