test: one-shot end-to-end probe. Issues a GET to api.ipify.org through
the configured relay and prints status + body + timing. Clear pass/fail
with specific diagnostics for 502/504 (auth_key mismatch, quota, etc).
Verified live: 3.8s round-trip returning the caller's real IP.
scan-ips: parallel TLS probe of 28 known Google frontend IPs with
SNI=front_domain. Reports which are reachable and sorts by latency.
Users pick the fastest and paste into google_ip. Verified live:
7/28 reachable (the others were Windscribe'd out), top 3 ranked.
Both subcommands share the existing config.json and require no extra
flags. Default 'mhrv-rs' with no subcommand runs the proxy as before.
Tracks relay_calls, failures, bytes, coalesced requests, cache hit rate,
and active scripts (total minus blacklisted). Logs only if there's been
traffic since the last tick. Visible when running with RUST_LOG=info or
log_level=info in config.
After the OS trust store install, also try to add the MITM CA to all
discovered Firefox profiles via NSS certutil. Silently no-ops if:
- NSS certutil is not installed (macOS ships a different certutil; linux
needs libnss3-tools; Windows needs NSS binaries)
- No Firefox profiles exist
- Firefox is currently running (lock on cert.db)
Scans profiles in:
- macOS: ~/Library/Application Support/Firefox/Profiles
- Linux: ~/.mozilla/firefox and ~/snap/firefox/common/.mozilla/firefox
- Windows: %APPDATA%\Mozilla\Firefox\Profiles
Existing CA-install error path is unchanged; this is purely additive.
SNI-rewrite tunnels (src/proxy_server.rs):
- CONNECT to youtube.com / googlevideo.com / doubleclick / etc. now bypasses
the Apps Script relay entirely and goes direct to the Google edge IP
with SNI=front_domain.
- Accepts browser TLS with our MITM cert, opens outbound TLS to
config.google_ip with SNI=config.front_domain, bridges decrypted bytes.
- Matches Python's _do_sni_rewrite_tunnel behavior. Faster than relay for
large streams (video).
- Also respects config.hosts override map (custom IP per suffix).
gzip decode fix (src/domain_fronter.rs):
- Apps Script outer response is gzipped. Previous stub always failed,
causing 'non-utf8 json' errors. Swapped in flate2::GzDecoder.
- Verified end-to-end: HTTP and HTTPS requests through apps_script
relay succeed and return real Google IPs.
When a script returns 429, 403, or a quota/rate-limit error body,
drop it from the active rotation for 10 minutes. next_script_id
skips blacklisted IDs; if all are blacklisted, picks the one
coming off cooldown soonest.
Script IDs are masked in logs (prefix...suffix) to avoid leaking
the deployment ID even at info level.
First concurrent caller for a cache key does the relay; subsequent
callers subscribe to a broadcast channel and receive the same response.
Only applies to cacheable (GET/HEAD) requests without body.
- New cache.rs: FIFO-eviction cache with max_bytes cap
- Cacheable: GET/HEAD only, no-store/no-cache/private/Set-Cookie reject
- TTL from Cache-Control: max-age=, or heuristics by extension (css/js/fonts/images -> 1h)
- Hook in DomainFronter::relay: check cache before network, store after 2xx
- 10 new unit tests (23 total)