Request Routing & Edge Resolution
smo1 beginner 6 min read
ELI5
The edge worker is a traffic cop at the door of smo1.io. Anything that looks like a file goes straight to the marketing site. Anything else is treated as a possible short code, and the worker phones the API to ask what it is. If the API has never heard of it, the visitor gets the marketing site. If it is a link, the visitor is either sent on (redirect) or shown the destination through a window (proxy). Today the worker has no memory of its own: it phones the API on every visit.
Technical Deep Dive
Source: zoomies-edge src/index.ts:30-108, 172-256 and src/handlers/redirect.ts:66-121 (origin/main 5bdde59); zoomies-edge wrangler.toml:50-55; purr-api internal/router/router.go:126-128 and internal/repository/link_repository.go:148-163 (bb6cfc2), read 2026-10-25.
Decision tree for GET /:slug
flowchart TD A["GET host/slug"] --> RL[Rate limit 120 per IP per minute] RL --> B{"slug has a dot or starts with _ ?"} B -->|Yes| L[Proxy to LANDING_ORIGIN] B -->|No| P["handleProxyMode: GET /api/links/slug/slug"] P --> PM{"redirect_mode = proxy ?"} PM -->|Yes| PX[Protection check then stream destination] PM -->|"No or not found"| R["handleRedirect: GET /api/links/resolve?host and slug"] R --> F{"404 ?"} F -->|Yes| L F -->|No| S[Protection, active and expiry checks] S --> T[Background click POST then 302 with UTM params]The order matters and is easy to misremember:
- Rate limit (
index.ts:31): 120 requests per IP per 60 s, counted in the Cloudflare Cache API. - Static asset test (
index.ts:75-77): a dot or a leading_goes to the landing origin with no lookup. - Proxy-mode probe (
index.ts:86-87, 201-231):fetchLinkDatacallsGET /api/links/slug/:slug. This lookup is host-blind: purr-api answers it withuid = $1 OR custom_slug = $1 LIMIT 1(link_repository.go:148). - Redirect (
redirect.ts:83-121): only if step 3 did not find a proxy-mode link,handleRedirectcalls the host-awareGET /api/links/resolve?host=&slug=, which matches the link whosedomain_idequals the host’scustom_domainsrow, orNULLfor the apex (link_repository.go:153-163). - A 404 from resolve returns
null, andindex.ts:103-105 proxies the path to the landing page. That is why/pricingand/aboutserve marketing pages.
No edge cache in production
Both lookups check env.LINKS_CACHE first, but the binding is commented out (wrangler.toml:50-63), so neither cache branch runs. The two code paths also disagree on the key: fetchLinkData reads link:{slug} (index.ts:239) while handleRedirect reads and writes link:{host}:{slug} (redirect.ts:86, 116). Turning KV on without reconciling these with purr-api’s bare-slug writes would serve wrong answers (smo1-015).
Proxy vs redirect
| Mode | Worker response | Click tracked? |
|---|---|---|
redirect | 302 Location: destination with stored UTM params appended | Yes, background POST /api/analytics/track |
proxy | destination fetched with redirect: 'manual' and streamed | No: handleProxyMode never calls trackClick |
Sub-paths (/slug/anything) hit app.all('/:slug/*') (index.ts:176-189), which only serves proxy-mode links and otherwise falls through to the landing page.
LANDING_ORIGIN
https://origin.smo1.io in cat and lion (wrangler.toml:34, 39). It answers server: Vercel with no Cloudflare ray (probed 2026-10-25), so the Worker’s fetch does not loop back into itself.
Key Terms
- handleProxyMode — the first lookup on every slug GET; host-blind, via
/api/links/slug/:slug - handleRedirect — the second lookup; host-aware, via
/api/links/resolve - LANDING_ORIGIN —
origin.smo1.io, the DNS-only Vercel deployment of whiskers-landing - LINKS_CACHE — the KV binding both lookups would use; absent in production
- redirect: manual — fetch option so the Worker rewrites a destination’s 3xx itself
Q&A
Q: What is the first check the edge worker makes on an incoming request?
A: The rate limiter, mounted on * (index.ts:31). For GET /:slug the first routing check after that is whether the segment contains a dot or starts with _.
Q: When does a request get proxied to whiskers-landing?
A: When the segment looks like a static asset, when the slug is not a proxy-mode link and /api/links/resolve returns 404, for any multi-segment path that is not a proxy-mode link, and for every non-GET path except POST /:slug (the protection form).
Q: What two modes can a resolved link operate in?
A: redirect (302) and proxy (streamed under the short URL), from links.redirect_mode.
Q: How many origin calls does one redirect-mode GET cost in production, and why?
A: Two lookups plus one tracking POST. handleProxyMode calls /api/links/slug/:slug to learn the mode, then handleRedirect calls /api/links/resolve, and with no KV binding neither is cached.
Examples
smo1.io/favicon.ico goes straight to the landing origin. smo1.io/88mph costs a slug lookup, a resolve, a 302 and a background track POST. smo1.io/pricing costs the slug lookup and a resolve (404) and is then proxied to origin.smo1.io/pricing.
neighbors on the map
- Deployment Topology, Proxy Conflict & CI after eu-1 finding where a smo1 component runs and how it deploys
- Proxy Mode implementing a white-label short link
- petrova.smo1.io: Custom-Domain Links for petrova.codes Artifacts provisioning or debugging petrova.smo1.io links