Cache the serialized /json fields per MMDB record. Every field except
`ip` depends only on the record, and many IPs share one record, so the
response is now the cached fields with the address prepended. The cache
is keyed by data-section offset, capped at 16 MiB, and owned by the
loaded database so a hot-swapped DB never serves stale entries. A hit
costs ~0.27us instead of ~2.5us for decode + serialize; a miss is no
slower than before thanks to a pre-sized serialization buffer.
Trim per-request framework overhead shared by all endpoints:
- Dispatch by Host with a plain HostRouter service instead of an outer
Router wrapping a service_fn, skipping a second route match and box.
- Apply security headers via tower's MapResponseLayer instead of
middleware::from_fn, and reserve header capacity up front.
- Add a RequestedIp extractor that reads headers in place instead of
cloning the whole HeaderMap.
On a 1 CPU / 1 GB Alpine (musl) container, /json throughput rose from
76.5k to 123.5k rps for a single IP (+61%) and from 84.9k to 130.5k rps
across 20k random IPs (+54%); p50 latency fell from 0.85ms to 0.52ms.
Responses are byte-identical to before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The /proxy, /hosting, /tor, /vpn endpoints and the /json response embed
live MMDB classifications for 45.77.77.77 that flip as the Merged-IP
dataset is updated. Replace hard-coded expected values with shape checks
(boolean / "true"|"false") so the tests verify endpoint plumbing without
coupling to transient upstream data.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wipe the target color's database volume before starting the container so
each push re-downloads the latest Merged-IP.mmdb. Gate /health on DB
readiness (503 until loaded) so HAProxy blue-green only flips traffic
once the new backend has a usable DB, and raise the Ansible health-wait
window from 120s to 360s to cover the download.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Remove disruptive alert() on error pages, rely on role="alert" banner
- Add skip navigation link for keyboard users (WCAG 2.4.1)
- Fix heading hierarchy on error page (sr-only status text in h1)
- Add "opens in a new tab" screen reader hint on external links
- Wrap language selector in form with noscript submit button (WCAG 3.2.2)
- Add aria-label to copy-to-clipboard buttons and footer landmarks
- Use h2 for alt-IP section to maintain single h1 per page
- Add persistent underline on links for non-color identification (WCAG 1.4.1)
- Fix footer attribution contrast ratio to ~5.5:1 (WCAG 1.4.3)
- Add aria-busy/role=status loading announcements for skeleton state
- Add translations for new accessibility strings across all 14 locales
- Update integration tests to assert role="alert" instead of alert()
- Add i18n module with Locale enum, PO parser, and Accept-Language negotiation
- Create gettext .po translation files for en, es, de, ja, ko, id, fr, ru, pt, it, zh-Hant, zh-Hans, nl, ar
- Route HTML pages under /{lang}/ prefix using IETF language tags
- Auto-detect browser language and redirect from / to /{lang}/
- Add language selector dropdown in footer
- Localize geo names (country, city) from MMDB where available
- Add hreflang alternate links and multilingual sitemap for SEO
- Support RTL layout for Arabic
- Update integration tests for new routing structure