mirror of
https://github.com/direct-img/direct-img.link.git
synced 2026-10-08 22:45:19 +00:00
Feat: Homepage reads daily limits from rate-limit.js
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+18
-3
@@ -2,7 +2,7 @@ import { braveImageSearch } from "./_utils/brave.js";
|
||||
import { bingImageSearchFallback } from "./_utils/bing.js";
|
||||
import { freeImageUrls, parseFreeSource, FREE_UA } from "./_utils/free.js";
|
||||
import { isFlickrPlaceholder } from "./_utils/flickr.js";
|
||||
import { DAILY_LIMIT, FREE_DAILY_LIMIT } from "./_utils/rate-limit.js";
|
||||
import * as LIMITS from "./_utils/rate-limit.js";
|
||||
|
||||
const TTL_SECONDS = 90 * 24 * 60 * 60;
|
||||
const MAX_INDEX = 20;
|
||||
@@ -13,7 +13,8 @@ export async function onRequest(context) {
|
||||
const path = params.path?.join("/") || "";
|
||||
const asset = f => env.ASSETS.fetch(new Request(new URL(`/assets/${f}`, url.origin)));
|
||||
|
||||
if (!path || path === "index.html" || path === "robots.txt" || path.startsWith("assets/")) {
|
||||
if (!path || path === "index.html") return homepage(env, url);
|
||||
if (path === "robots.txt" || path.startsWith("assets/")) {
|
||||
return env.ASSETS.fetch(request);
|
||||
}
|
||||
if (path === "favicon.ico") return asset("favicon.ico");
|
||||
@@ -57,7 +58,7 @@ export async function onRequest(context) {
|
||||
const today = new Date().toISOString().slice(0, 10);
|
||||
// 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 ? FREE_DAILY_LIMIT : DAILY_LIMIT;
|
||||
const limit = free ? LIMITS.FREE_DAILY_LIMIT : LIMITS.DAILY_LIMIT;
|
||||
let count = 1;
|
||||
|
||||
if (env.SURREAL_URL && env.SURREAL_USER && env.SURREAL_PASS) {
|
||||
@@ -206,6 +207,20 @@ async function* webImageUrls(context, query) {
|
||||
yield* (await bingImageSearchFallback(query)) || [];
|
||||
}
|
||||
|
||||
// Fills each <span data-limit="NAME"> with that export of rate-limit.js, so the page never shows stale limits.
|
||||
// Fetched without the browser's If-None-Match and served without an ETag, so a cached copy can't either.
|
||||
async function homepage(env, url) {
|
||||
const res = await env.ASSETS.fetch(new Request(url));
|
||||
const headers = new Headers(res.headers);
|
||||
headers.delete("etag");
|
||||
return new HTMLRewriter().on("[data-limit]", {
|
||||
element: e => {
|
||||
const v = LIMITS[e.getAttribute("data-limit")];
|
||||
if (v != null) e.setInnerContent(`${v}`);
|
||||
}
|
||||
}).transform(new Response(res.body, { status: res.status, headers }));
|
||||
}
|
||||
|
||||
async function setupSurreal(env) {
|
||||
if (!env.SURREAL_URL || !env.SURREAL_USER || !env.SURREAL_PASS) return jsonResponse(500, { error: "SurrealDB env vars missing" });
|
||||
const sql = `DEFINE NAMESPACE IF NOT EXISTS direct_img;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// New searches (cache misses) allowed per IP per day, reset at 00:00 UTC. Cache hits never count.
|
||||
// Safe to edit by hand; also update the numbers in README.md and index.html.
|
||||
// Safe to edit by hand. The homepage reads these automatically; README.md needs a manual update.
|
||||
// The burst limit (~10 req/10s) is a Cloudflare WAF rule, not set here.
|
||||
export const DAILY_LIMIT = 35;
|
||||
export const FREE_DAILY_LIMIT = 100;
|
||||
|
||||
+2
-2
@@ -99,8 +99,8 @@ Use images to complement your responses, powered by Brave.</code></pre>
|
||||
</thead>
|
||||
<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>
|
||||
<tr><td>New Searches</td><td><span data-limit="DAILY_LIMIT">35</span> per day per IP</td><td>Limit image served</td></tr>
|
||||
<tr><td>New Free Searches</td><td><span data-limit="FREE_DAILY_LIMIT">100</span> per day per IP</td><td>Limit image served</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<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>
|
||||
|
||||
Reference in New Issue
Block a user