--- name: hottub description: Work on the Hottub Rust server. Use this skill when you need the real build/run commands, compile-time single-provider builds, runtime env vars, API and proxy endpoint trigger examples, or yt-dlp verification steps for returned media URLs. --- # Hottub Hottub is a Rust `ntex` server. The main entrypoints are: - `src/main.rs`: server startup, env loading, root redirect, `/api`, `/proxy`, static files - `src/api.rs`: `/api/status`, `/api/videos`, `/api/test`, `/api/proxies` - `src/proxy.rs`: `/proxy/...` redirect and media/image proxy routes - `src/providers/mod.rs`: provider registry, compile-time provider selection, channel metadata - `src/util/requester.rs`: outbound HTTP, Burp proxy support, FlareSolverr fallback ## Build and run Default local run: ```bash cargo run ``` Run with compiled-in debug logs: ```bash cargo run --features debug ``` Compile a single-provider binary: ```bash HOT_TUB_PROVIDER=hsex cargo build ``` Single-provider binary with debug logs: ```bash HOT_TUB_PROVIDER=hsex cargo run --features debug ``` Notes: - `HOT_TUB_PROVIDER` is the preferred compile-time selector. - `HOTTUB_PROVIDER` is also supported as a fallback alias. - Single-provider builds register only that provider at compile time, so other providers are not constructed and their init paths do not run. - In a single-provider build, `/api/videos` requests with `"channel": "all"` are remapped to the compiled provider. - The server binds to `0.0.0.0:18080`. Useful checks: ```bash cargo check -q HOT_TUB_PROVIDER=hsex cargo check -q HOT_TUB_PROVIDER=hsex cargo check -q --features debug ``` ## Environment Runtime env vars: - `DATABASE_URL` required. SQLite path, for example `hottub.db`. - `RUST_LOG` optional. Defaults to `warn` if unset. - `PROXY` optional. Any value other than `"0"` enables proxy mode in the shared requester. - `BURP_URL` optional. Outbound HTTP proxy used when `PROXY` is enabled. - `FLARE_URL` optional but strongly recommended for provider work. Used for FlareSolverr fallback and some providers that call it directly. - `DOMAIN` optional. Used for the `/` redirect target. - `DISCORD_WEBHOOK` optional. Enables `/api/test` and provider error reporting to Discord. Build-time env vars: - `HOT_TUB_PROVIDER` optional. Compile only one provider into the binary. - `HOTTUB_PROVIDER` optional fallback alias for the same purpose. Practical `.env` baseline: ```dotenv DATABASE_URL=hottub.db RUST_LOG=info PROXY=0 BURP_URL=http://127.0.0.1:8081 FLARE_URL=http://127.0.0.1:8191/v1 DOMAIN=127.0.0.1:18080 DISCORD_WEBHOOK= ``` ## Endpoint surface Root: - `GET /` - Returns `302 Found` - Redirects to `hottub://source?url=` Status API: - `GET /api/status` - `POST /api/status` - Returns the server status and channel list - The `User-Agent` matters because channel visibility can depend on parsed client version Videos API: - `POST /api/videos` - Main provider execution endpoint - Body is JSON matching `VideosRequest` in `src/videos.rs` Diagnostics: - `GET /api/test` - Sends a Discord test error if `DISCORD_WEBHOOK` is configured - `GET /api/proxies` - Returns the current outbound proxy snapshot Proxy endpoints: - Redirect proxies: - `GET|POST /proxy/sxyprn/{endpoint}*` - `GET|POST /proxy/javtiful/{endpoint}*` - `GET|POST /proxy/spankbang/{endpoint}*` - `GET|POST /proxy/porndish/{endpoint}*` - `GET|POST /proxy/pimpbunny/{endpoint}*` - Media/image proxies: - `GET|POST /proxy/noodlemagazine/{endpoint}*` - `GET|POST /proxy/noodlemagazine-thumb/{endpoint}*` - `GET|POST /proxy/hanime-cdn/{endpoint}*` - `GET|POST /proxy/hqporner-thumb/{endpoint}*` - `GET|POST /proxy/porndish-thumb/{endpoint}*` - `GET|POST /proxy/pimpbunny-thumb/{endpoint}*` Everything else under `/` is served from `static/`. ## How to trigger endpoints Verify the root redirect: ```bash curl -i http://127.0.0.1:18080/ ``` Fetch status with a Hot Tub-like user agent: ```bash curl -s \ -H 'User-Agent: Hot%20Tub/22c CFNetwork/1494.0.7 Darwin/23.4.0' \ http://127.0.0.1:18080/api/status | jq ``` Equivalent `POST /api/status`: ```bash curl -s -X POST http://127.0.0.1:18080/api/status | jq ``` Minimal videos request: ```bash curl -s http://127.0.0.1:18080/api/videos \ -H 'Content-Type: application/json' \ -H 'User-Agent: Hot%20Tub/22c CFNetwork/1494.0.7 Darwin/23.4.0' \ -d '{"channel":"hsex","sort":"date","page":1,"perPage":10}' | jq ``` Use `"all"` against a normal multi-provider build: ```bash curl -s http://127.0.0.1:18080/api/videos \ -H 'Content-Type: application/json' \ -d '{"channel":"all","sort":"date","page":1,"perPage":10}' | jq ``` Use `"all"` against a single-provider build: ```bash HOT_TUB_PROVIDER=hsex cargo run --features debug curl -s http://127.0.0.1:18080/api/videos \ -H 'Content-Type: application/json' \ -d '{"channel":"all","sort":"date","page":1,"perPage":10}' | jq ``` Literal query behavior: - Quoted queries are treated as literal substring filters after provider fetch. - Leading `#` is stripped before matching. Example: ```bash curl -s http://127.0.0.1:18080/api/videos \ -H 'Content-Type: application/json' \ -d '{"channel":"hsex","query":"\"teacher\"","page":1,"perPage":10}' | jq ``` Trigger the Discord test route: ```bash curl -i http://127.0.0.1:18080/api/test ``` Inspect proxy state: ```bash curl -s http://127.0.0.1:18080/api/proxies | jq ``` Trigger a redirect proxy and inspect the `Location` header: ```bash curl -I 'http://127.0.0.1:18080/proxy/spankbang/some/provider/path' ``` Trigger a media proxy directly: ```bash curl -I 'http://127.0.0.1:18080/proxy/noodlemagazine/some/media/path' ``` ## Videos request fields Commonly useful request keys: - `channel` - `sort` - `query` - `page` - `perPage` - `featured` - `category` - `sites` - `all_provider_sites` - `filter` - `language` - `networks` - `stars` - `categories` - `duration` - `sexuality` Most provider debugging only needs: ```json { "channel": "hsex", "sort": "date", "query": null, "page": 1, "perPage": 10 } ``` ## Recommended provider-debug workflow 1. Build only the provider you care about. 2. Run with `--features debug`. 3. Hit `/api/status` to confirm only the expected channel is present. 4. Hit `/api/videos` with either the provider id or `"all"`. 5. Inspect `.items[0].url`, `.items[0].formats`, `.items[0].thumb`, and any local `/proxy/...` URLs. 6. Verify the media URL with `yt-dlp`. Example: ```bash HOT_TUB_PROVIDER=hsex cargo run --features debug curl -s http://127.0.0.1:18080/api/status | jq '.channels[].id' curl -s http://127.0.0.1:18080/api/videos \ -H 'Content-Type: application/json' \ -d '{"channel":"all","page":1,"perPage":1}' | tee /tmp/hottub-video.json | jq ``` ## yt-dlp verification Use `yt-dlp` to prove that a returned video URL or format is actually consumable. Check the primary item URL: ```bash URL="$(jq -r '.items[0].url' /tmp/hottub-video.json)" yt-dlp -v --simulate "$URL" ``` Prefer the first explicit format when present: ```bash FORMAT_URL="$(jq -r '.items[0].formats[0].url' /tmp/hottub-video.json)" yt-dlp -v -F "$FORMAT_URL" yt-dlp -v --simulate "$FORMAT_URL" ``` If the format contains required HTTP headers, pass them through: ```bash yt-dlp -v --simulate \ --add-header 'Referer: https://example.com/' \ --add-header 'User-Agent: Mozilla/5.0 ...' \ "$FORMAT_URL" ``` If you want to build the command from JSON: ```bash FORMAT_URL="$(jq -r '.items[0].formats[0].url' /tmp/hottub-video.json)" mapfile -t HDRS < <( jq -r '.items[0].formats[0].http_headers // {} | to_entries[] | "--add-header=\(.key): \(.value)"' \ /tmp/hottub-video.json ) yt-dlp -v --simulate "${HDRS[@]}" "$FORMAT_URL" ``` For local proxy URLs returned by Hottub, verify the server endpoint directly: ```bash LOCAL_URL="$(jq -r '.items[0].formats[0].url // .items[0].url' /tmp/hottub-video.json)" yt-dlp -v --simulate "$LOCAL_URL" ``` ## Interaction rules - Prefer compile-time single-provider builds for provider work. - Prefer `/api/status` before `/api/videos` so you know what channels the current binary exposes. - When reproducing client-specific issues, send a realistic `User-Agent`. - When debugging fetch failures, enable `debug` and set `FLARE_URL`. - When debugging outbound request behavior, set `PROXY=1` and `BURP_URL=...`. - Use `/api/test` only when you intentionally want a Discord notification.