proxy pool: spread rule34video enrichment over checked public proxies

Rework the unused ALL_PROXIES list into util/proxy_pool.rs:
- hourly sweep of the public lists, TLS-verified cloudflare trace checks,
  >=2 successes with a median under 1.5s, one proxy per exit IP; proxies
  that show our own IP are dropped, two failures in a row evict
- per-site sets checked against a site URL (rule34video: robots.txt),
  round-robin, 10-min per-site cooldown on 429/challenge pages, live
  request outcomes fed back
- started from main (PROXY_POOL=0 disables; PROXY_POOL_LISTS,
  PROXY_POOL_CONCURRENCY), /api/proxies shows its status without credentials
- wreq "socks" feature enabled: SOCKS proxies silently failed before

rule34video enrichment is back, through the pool: full detail pages
(1080p..360p formats, tags, artist), 8 concurrent, one 4s deadline per
listing; late pages keep running and land in the 2h detail cache, which
cached listings are re-merged with on every serve. No ready proxies means
no enrichment (no direct fallback). Requester::get_via sends a pooled
request with certificate checks, sharing the session's cookie jar.

Also adds an ignored live probe showing /embed/ shares the 429 limit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AEp724zDpCWNaSeCrMSvjx
This commit is contained in:
Simon
2026-11-05 21:59:28 +00:00
parent 4f83dae3fa
commit 29d526b5fc
11 changed files with 1204 additions and 211 deletions

View File

@@ -23,9 +23,10 @@ Hottub is a Rust server that exposes Hot Tub compatible endpoints for channel di
1. `main` loads `.env` and ensures `RUST_LOG` is set.
2. It creates the Diesel SQLite pool from `DATABASE_URL`.
3. It creates a shared `Requester`, enables Burp proxying when `PROXY != 0`, and builds the LRU video cache.
4. It configures provider runtime validation in `providers::configure_runtime_validation`.
5. It spawns a background thread that forces provider initialization via `providers::init_providers_now()`.
6. It starts an `ntex` HTTP server on `0.0.0.0:18080`.
4. It starts the public-proxy pool (`util::proxy_pool::start`) unless `PROXY_POOL=0`.
5. It configures provider runtime validation in `providers::configure_runtime_validation`.
6. It spawns a background thread that forces provider initialization via `providers::init_providers_now()`.
7. It starts an `ntex` HTTP server on `0.0.0.0:18080`.
## Runtime Environment
@@ -36,6 +37,9 @@ Important environment variables:
- `PROXY`: enables Burp proxying when not equal to `0`.
- `BURP_URL`: outbound proxy URL used when `PROXY` is enabled.
- `FLARE_URL`: FlareSolverr endpoint used as the last HTML-fetch fallback.
- `PROXY_POOL`: `0` disables the public-proxy pool (default on).
- `PROXY_POOL_LISTS`: comma-separated proxy list URLs replacing the default TheSpeedX lists.
- `PROXY_POOL_CONCURRENCY`: cap on concurrent proxy checks (default 500).
- `DOMAIN`: used by the `/` redirect target.
- `DISCORD_WEBHOOK`: enables `/api/test` and provider error reporting.
@@ -120,7 +124,9 @@ Sends a Discord error test if `DISCORD_WEBHOOK` is configured.
### `/api/proxies`
Returns the background-fetched outbound proxy snapshot from `src/util/proxy.rs`.
Status of the public-proxy pool in `src/util/proxy_pool.rs`: the last list sweep, the fastest exit IPs, and per site (for example `rule34video.com`) the proxies ready for it with their request counters (`ok`/`failed`/`throttled`) and any 429 cooldown. Proxy credentials are never shown.
The pool downloads public proxy lists hourly and keeps only proxies that pass a TLS-verified check against `cdn-cgi/trace` twice with a median under 1.5s, one per exit IP. Providers register a site (`proxy_pool::register_site`) with a cheap check URL; the pool checks its candidates against that URL and rotates requests over the ready ones (`next_proxy` / `report`). rule34video spreads its detail-page enrichment over it to stay under the site's per-IP 429 limit.
## Core Data Structures