clone

push a directory of html from the terminal and get a four-character url back. a deno cli on cloudflare

codex/agent-interface
nzip / worker / src / index.ts
index.ts 1.9K
1import { api } from "./api.ts";2import { checkBearer } from "./auth.ts";3import type { Env } from "./env.ts";4import { err } from "./env.ts";5import { runGc } from "./gc.ts";6import { serve } from "./serve.ts";78function tooManyRequests(): Response {9 return new Response("rate limited — slow down\n", {10 status: 429,11 headers: { "content-type": "text/plain; charset=utf-8", "retry-after": "60" },12 });13}1415export default {16 async fetch(req: Request, env: Env): Promise<Response> {17 const url = new URL(req.url);1819 if (url.pathname === "/api" || url.pathname.startsWith("/api/")) {20 if (!checkBearer(req, env)) return err("unauthorized", 401);21 return await api(req, env, url);22 }2324 const isUnlock = req.method === "POST" && /^\/[0-9a-f]{4}\/__unlock$/.test(url.pathname);25 if (req.method !== "GET" && req.method !== "HEAD" && !isUnlock) {26 return err("method not allowed", 405);27 }2829 // Guessing defenses. The address space is only 16 bits, so throttle the two30 // enumeration surfaces per client IP. Asset subpaths (/{addr}/...) are left31 // alone — reaching them already requires knowing a live address.32 const ip = req.headers.get("cf-connecting-ip") ?? "local";33 if (isUnlock) {34 const address = url.pathname.slice(1, 5);35 const { success } = await env.RL_UNLOCK.limit({ key: `${ip}:${address}` });36 if (!success) return tooManyRequests();37 } else if (/^\/[0-9a-f]{4}\/?$/.test(url.pathname)) {38 const { success } = await env.RL_ENUM.limit({ key: ip });39 if (!success) return tooManyRequests();40 }4142 return await serve(req, env, url);43 },4445 async scheduled(_controller: ScheduledController, env: Env, ctx: ExecutionContext): Promise<void> {46 ctx.waitUntil(47 runGc(env).then((r) =>48 console.log(`gc: ${r.expiredSites} expired sites, ${r.deletedObjects} objects deleted`)49 ),50 );51 },52} satisfies ExportedHandler<Env>;