CRUMB a card from devarno-cloud

Edge Redirect Flow

smo1 intermediate 6 min read

ELI5

When you click a short link, the edge worker asks the API what it points to, checks whether it needs a PIN or password, whether it is switched off or past its expiry date, and then tells your browser where to go. It records the click in the background so you are never kept waiting for the bookkeeping.

Technical Deep Dive

Source: zoomies-edge src/handlers/redirect.ts:66-191 and src/lib/url-builder.ts, src/index.ts:71-108, wrangler.toml:39, 50-63 (origin/main 5bdde59); purr-api internal/handler/redirect_handler.go:140-202 (bb6cfc2); live probe of https://smo1.io/88mph, read 2026-10-25.

Sequence as deployed

sequenceDiagram
autonumber
actor U as User
participant Z as zoomies-edge
participant API as purr-api
U->>Z: GET smo1.io/slug
Z->>Z: rate limit, bot check on User-Agent
Z->>API: GET /api/links/slug/slug for the mode probe
API-->>Z: link JSON or 404
Z->>API: GET /api/links/resolve?host=smo1.io and slug
API-->>Z: link JSON, destination empty unless allowed
alt protected and no valid smo1_session_linkId cookie
Z-->>U: 200 protection prompt HTML
else is_active false
Z-->>U: 410 inactive page
else expires_at in the past
Z-->>U: 410 expired page
else allowed
Z-)API: POST /api/analytics/track in waitUntil
Z-->>U: 302 Location destination plus UTM params
end

Lookup

The Worker’s first lookup source is purr-api, not KV. Both code paths would read env.LINKS_CACHE first, but the binding is absent in lion (wrangler.toml:50-63), so the if (env.LINKS_CACHE) branches are skipped. If it were bound, handleRedirect would cache under link:{host}:{slug} with expirationTtl: 300 (redirect.ts:86, 113-120).

purr-api’s resolve answer is shaped for the edge (SlugLookupResponse): id, slug, destination, user_id, is_active, expires_at, protection_type, protection_hint, content_classification, redirect_mode. destination is filled only when AuthorizeRedirect allows the link, so a protected link’s URL never leaves origin before the secret is verified (redirect_handler.go:140-178). UTM fields are not part of this response, so the UTM-append step has nothing to add on the resolve path. The UTM columns reach analytics through purr-api’s click insert instead (smo1-008).

Outcomes

ConditionWorker responseLine
resolve 404null, then landing proxyredirect.ts:103-107
resolve non-200, non-404500 branded error pageredirect.ts:108, 187-190
protected, no valid session cookie200 HTML prompt (<meta> OG card, never names the destination)redirect.ts:129-148
is_active=false410 inactive pageredirect.ts:151-153
expires_at past410 expired pageredirect.ts:156-161
allowed302 Locationredirect.ts:173-186

Order matters: protection is checked before active and expiry, so a protected link that is also paused shows the prompt first.

Response headers

The 302 carries only Location plus the rate-limit headers the middleware adds (X-RateLimit-Limit: 120, -Remaining, -Reset). There is no Cache-Control header on it (probe 2026-10-25). The earlier claim of Cache-Control: private, no-store was not true.

Click tracking does not block

trackClick is started without await and handed to ctx.waitUntil so Cloudflare keeps it alive after the 302 is sent (redirect.ts:163-171). Bots detected by User-Agent skip it (smo1-007).

Key Terms

  • resolve — GET /api/links/resolve?host=&slug=, purr-api’s host-aware lookup for the edge
  • SlugLookupResponse — the edge-shaped JSON purr-api returns; destination blank unless allowed
  • waitUntil — Workers API that keeps background work alive after the response
  • LINKS_CACHE — the KV binding the code supports and production does not bind

Q&A

Q: What is the first place the worker looks for link data? A: purr-api. In production the KV branch is skipped because LINKS_CACHE is not bound, so the mode probe GET /api/links/slug/:slug and then GET /api/links/resolve both go to origin.

Q: What status code does a redirect-mode link return? A: 302 Found with a Location header (redirect.ts:181-186).

Q: How long is link data cached in KV? A: Not at all in production today. The code would write 300-second entries if LINKS_CACHE were bound; it is commented out in wrangler.toml.

Q: What does the worker show for an inactive or expired link? A: Its own inactive or expired HTML page, both with status 410 Gone (redirect.ts:405-522). purr-api’s resolve answers 200 for any stored link so the edge can make that call itself; only a link that does not exist (404) falls through to the landing site.

Examples

curl -sI https://smo1.io/88mph on 2026-10-25 returned HTTP/2 302, location: https://youtu.be/..., x-ratelimit-limit: 120, no cache header. The same request to a slug whose link is paused returns the Worker’s inactive page with status 410, not a 404 and not the landing site.

neighbors on the map