Add outbound proxy support for Nostr relay connections#217
Conversation
Add Nix flake support
chore(deps): update actions/checkout digest to 8e8c483
chore(deps): update actions/checkout action to v6.0.1
Replaces the outdated ygg.to domain with the current yggtorrent.ch domain to ensure proper connectivity and domain resolution. Fixes #84
Changes the git-cliff action argument from `--current` to `--latest` to generate changelog entries for the most recent release instead of the current working state. This ensures the release workflow produces accurate changelog content that reflects the latest tagged version.
Reorganizes build and compilation scripts into a more conventional scripts directory structure for better project organization. Updates internal script references to reflect the new location.
Adds a new checklist item requiring users to confirm they have updated the configuration file from the repository for Prowlarr/Jackett integrations. Helps ensure users are working with the latest configuration before submitting issues, reducing reports caused by outdated configurations.
Streamlines the release workflow by removing the `publish-release` dependency from the `sign` job and adding it to the `publish-release` job itself along with `verify`, ensuring proper execution order. Updates all SBOM attestation types from the full URL format (`https://cyclonedx.org/bom/v1.7`) to the shorthand `cyclonedx` format for both creation and verification steps, improving readability and following cosign conventions. Adds missing permissions (`packages: read` and `id-token: write`) to the `verify` job to ensure proper authentication when verifying attestations.
Major documentation overhaul: - Set up Docusaurus 3.9.2 with bilingual support (French/English) - Migrate all user documentation from root docs/ to website/docs/ - Keep developer documentation in root docs/ folder - Add comprehensive installation guides (Docker, Binary, Source) - Configure custom domain (ygege.lila.ws) with CNAME Documentation structure: - Introduction and getting started guide - Installation guides (Docker, Binary, Manual compilation) - Configuration documentation - Integration guides (Prowlarr, Jackett) - TMDB/IMDB metadata setup - Complete API reference - FAQ section Internationalization (i18n): - Full French and English translations - Locale-specific routing (/ for French, /en/ for English) - Translated sidebar categories and navigation - JSON translation files for UI elements Developer documentation: - Contribution guidelines - CI/CD implementation guide - PR preview workflow - Release workflow documentation Infrastructure: - GitHub Actions workflow for automated deployment - Custom domain configuration (ygege.lila.ws) - Build optimizations with Bun package manager Dependencies: - Updated React to 19.2.1 - Updated TypeScript to 5.9.3 - Updated all Docusaurus dependencies to latest versions Breaking changes: - Documentation moved from /docs/ to root (/) - README links updated to point to ygege.lila.ws - Removed duplicate documentation files - Renamed ygege-fr.yml to ygege-en.yml for consistency
Replaces the existing logo image file with an updated version to reflect current branding standards
Reorganizes documentation to reduce redundancy and enhance clarity: - Pins dependency versions in bun.lock instead of using "latest" tags - Consolidates "What is Ygégé" content in intro.md to avoid duplication - Streamlines getting-started.md by removing redundant intro section - Enhances intro.md with better navigation structure and quick start - Adds structured documentation sections (Installation, Integrations, Developer, Support) - Improves user onboarding with 30-second installation snippet Applies changes to both French and English documentation for consistency.
Added language selection options to README.
Removes beta branch references across all GitHub Actions workflows and documentation, simplifying the branching strategy to only develop and master branches. Updates CI/CD pipelines to trigger only on develop (development testing) and master (production releases), eliminating the intermediate beta testing stage. Adjusts Docker image tagging logic accordingly, removing beta-specific tags and conditions. Updates documentation to reflect the streamlined workflow, changing pre-release examples from alpha/beta to release candidates (rc), and updating default log level from "info" to "debug" across configuration examples. Enhances API documentation for the /status endpoint to include detailed health check fields for authentication, domain resolution, reachability, and component status.
Restructures GitHub issue templates from JSON to YAML format with improved user guidance and categorization. Expands config.yml contact links to include documentation, discussions, contributing guidelines, and security reporting instead of just a single help link. Transforms feature_request.yml into a comprehensive form with: - Prerequisites checklist to reduce duplicates - Feature categorization dropdown (search, APIs, Docker, etc.) - Priority assessment and contribution willingness fields - Structured sections for problem statement, proposed solution, and implementation notes Removes issue_report.yml in favor of a more streamlined approach. Improves contributor experience by providing clearer guidance, reducing ambiguity, and establishing better issue triage workflow.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
updates documentation for ygg.gratis nostr relay transition removes cloudflare bypass and account authentication guides adds tor proxy configuration details documents updated api endpoints and magnet resolution simplifies installation by removing legacy session requirements
switches the feature flag from rustls-tls to rustls for the reqwest dependency to follow the current crate feature naming conventions
enables procedural macro support to allow for automatic implementation of serialization and deserialization traits on data structures
pin github actions to specific commit hashes to improve supply chain security. update workflow scripts to use environment variables and context objects instead of direct interpolation to prevent potential script injection. remove the logging of tmdb account usernames to improve privacy and reduce console output noise.
pass tags to the shell script via environment variables instead of direct interpolation. this approach improves security and ensures that tags are handled safely by avoiding potential script injection issues.
123456789012345678901234567890123456789012345678
It's 48 characters. Good.
Actually, for CC, the description is the part *after* the colon.
"updates rust and debian base images" -> 35 chars.
Wait, the rule about third-person singular ("Updates") vs imperative ("Update").
The user's instruction 3 says "third-person singular present tense (e.g. 'Fixes', 'Updates')".
The Conventional Commit
removes manual pull commands to streamline the automation workflows as modern build actions handle image caching natively simplifying the workflow configuration reduces maintenance overhead and avoids version mismatches
removes redundant build tools from workflows and the dockerfile to optimize pipeline duration. updates the windows upx installation to version 5.0.0 and refines docker layer caching for better performance.
pins crate versions in the project manifest to ensure reproducible builds. replaces the logging implementation and adds gzip compression support to the http client. implements dependency caching in the dockerfile to significantly reduce build times. improves container security and efficiency by refining user management and minimizing layer size.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
updates the exclusion list to minimize the build context size and improve build performance. reorganizes ignored files into logical categories and includes additional patterns for documentation, ci configurations, nix files, and testing artifacts.
updates dependency specifications from exact matches to tilde requirements to allow for compatible updates increments package version to 0.9.1
removes the manual layer for caching cargo dependencies to simplify the dockerfile. this streamlines the build process and reduces complexity in the image construction.
GITHUB_TOKEN cannot trigger other workflows via push events. Adds workflow_dispatch trigger to release.yml and updates auto-tag to explicitly dispatch the release workflow after pushing the tag.
prevents failed workflow runs on every master commit by removing master from the deploy-docs push and pull_request triggers.
…pdate documentation
📝 WalkthroughWalkthroughThis pull request introduces HTTP outbound proxy support for Ygégé. Changes include adding a base64 dependency, creating a new Changes
Sequence Diagram(s)sequenceDiagram
participant App as Application
participant Config as Configuration
participant Relay as Relay Ranker
participant Proxy as HTTP Proxy
participant NostrRelay as Nostr Relay
App->>Config: Load outbound_proxy config
Config-->>App: OutboundProxyConfig
App->>Relay: rank_relays(use_tor, tor_proxy, relay_proxy)
activate Relay
Relay->>Relay: probe_relay(url, timeout, relay_proxy)
alt HTTP Proxy Configured
Relay->>Proxy: CONNECT tunnel<br/>(with Basic Auth)
Proxy-->>Relay: TcpStream
Relay->>Relay: WebSocket upgrade via proxy
else No Proxy (Tor/Direct)
Relay->>Relay: Standard probe path
end
Relay-->>App: Ranked relay list
deactivate Relay
App->>App: NostrClient::new(relays, use_tor, tor_proxy, relay_proxy)
App->>NostrRelay: REQ/WS via relay_proxy
alt HTTP Proxy Active
NostrRelay->>Proxy: CONNECT + WebSocket upgrade
Proxy-->>NostrRelay: Proxied connection
else Direct/Tor
NostrRelay-->>NostrRelay: Direct/Tor connection
end
Estimated Code Review Effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment Tip CodeRabbit can enforce grammar and style rules using `languagetool`.Configure the |
There was a problem hiding this comment.
Actionable comments posted: 10
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
website/docs/configuration.md (1)
102-109:⚠️ Potential issue | 🟡 MinorEnvironment variables table is incomplete.
The proxy-related environment variables are missing from this table.
📝 Proposed addition
| `USE_TOR` | `use_tor` | | `TOR_PROXY` | `tor_proxy` | +| `PROXY_URL` | `proxy_url` | +| `PROXY_USERNAME` | `proxy_username` | +| `PROXY_PASSWORD` | `proxy_password` |🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@website/docs/configuration.md` around lines 102 - 109, The environment variables proxy entries are missing from the table; add rows for HTTP_PROXY, HTTPS_PROXY, ALL_PROXY and NO_PROXY mapping to their config.json equivalents (http_proxy, https_proxy, all_proxy, no_proxy) so the table includes all proxy-related variables alongside existing entries like TOR_PROXY and USE_TOR; update the table rows for the variables `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` and ensure the config.json column uses `http_proxy`, `https_proxy`, `all_proxy`, `no_proxy` respectively.src/config.rs (1)
27-91:⚠️ Potential issue | 🔴 CriticalEnvironment variable loading is incomplete for proxy configuration.
The
load_config_from_envfunction does not read thePROXY_URL,PROXY_USERNAME, orPROXY_PASSWORDenvironment variables. Even after adding the fields to theConfigstruct, users won't be able to configure the proxy via environment variables.🐛 Proposed fix
Update
ENV_KEYSand add proxy variable reading:fn load_config_from_env() -> Result<Config, std::io::Error> { const ENV_KEYS: &[&str] = &[ "BIND_IP", "BIND_PORT", "LOG_LEVEL", "TMDB_TOKEN", "USE_TOR", "TOR_PROXY", + "PROXY_URL", + "PROXY_USERNAME", + "PROXY_PASSWORD", ];Add before the
Ok(Config { ... })block:let proxy_url = std::env::var("PROXY_URL").ok().filter(|s| !s.is_empty()); let proxy_username = std::env::var("PROXY_USERNAME").ok().filter(|s| !s.is_empty()); let proxy_password = std::env::var("PROXY_PASSWORD").ok().filter(|s| !s.is_empty());And include them in the returned
Config:Ok(Config { bind_ip, bind_port, log_level, tmdb_token, use_tor, tor_proxy, + proxy_url, + proxy_username, + proxy_password, })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/config.rs` around lines 27 - 91, The env loader load_config_from_env is missing PROXY_URL/PROXY_USERNAME/PROXY_PASSWORD support: add those keys to the ENV_KEYS array and read them into Option<String> values (e.g., proxy_url, proxy_username, proxy_password) using std::env::var(...).ok().filter(|s| !s.is_empty()) just before constructing the Config, then include these variables in the returned Config struct so the new Config fields are populated from environment variables.website/i18n/en/docusaurus-plugin-content-docs/current/configuration.md (1)
100-109:⚠️ Potential issue | 🟡 MinorEnvironment variables table is incomplete.
The new proxy-related environment variables (
PROXY_URL,PROXY_USERNAME,PROXY_PASSWORD) are documented in the "Outbound HTTP Proxy" section but missing from the environment variables mapping table.📝 Proposed addition to the table
| `USE_TOR` | `use_tor` | | `TOR_PROXY` | `tor_proxy` | +| `PROXY_URL` | `proxy_url` | +| `PROXY_USERNAME` | `proxy_username` | +| `PROXY_PASSWORD` | `proxy_password` |🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@website/i18n/en/docusaurus-plugin-content-docs/current/configuration.md` around lines 100 - 109, Add the three missing proxy environment variables to the existing env var table: insert rows for `PROXY_URL` => `proxy_url`, `PROXY_USERNAME` => `proxy_username`, and `PROXY_PASSWORD` => `proxy_password` in the same markdown table structure (near the other env vars shown between the table header and the ":::tip Priority" marker) so the table matches the "Outbound HTTP Proxy" section.
🧹 Nitpick comments (1)
src/nostr.rs (1)
173-201: Extract shared probe read/write loop to one helper.The Tor and HTTP-proxy branches duplicate the same REQ-send and EVENT/EOSE read logic. This is easy to drift and hard to maintain as probe behavior evolves.
Also applies to: 249-277
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/nostr.rs` around lines 173 - 201, Extract the duplicated WebSocket probe logic into a helper (e.g., send_req_and_wait_for_event) that accepts the split sink/stream or the raw WebSocket stream, the req_text string, start Instant and timeout_dur and returns Option<Duration>; move the code that does write.send(Message::Text(req_text.into())).await, the read loop that parses Message::Text, matches "EVENT"/"EOSE", handles Close/Err, and finally closes the writer into that helper and call it from both the Tor and HTTP-proxy branches (the blocks around the current snippet using variables write, read, req_text, start, timeout_dur and the similar code at lines ~249-277) so behavior is centralized and reused.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docker/compose.yml`:
- Around line 13-18: The file contains unresolved Git merge conflict markers
(e.g., "<<<<<<< HEAD", ">>>>>>> fd3f5c5") which break the docker/compose.yml
YAML; remove the conflict markers and keep the intended configuration block (the
commented PROXY_URL, PROXY_USERNAME, PROXY_PASSWORD lines) or the correct
variant you want to retain so the YAML is valid; ensure only one consistent set
of keys (PROXY_URL, PROXY_USERNAME, PROXY_PASSWORD) remains and no "<<<<<<<",
"=======", or ">>>>>>>" tokens are left in the file.
In `@README-en.md`:
- Around line 67-91: Remove the unresolved Git conflict markers (<<<<<<< HEAD,
=======, >>>>>>> fd3f5c5) from README-en.md and merge the intended "HTTP Proxy
Support" section into a single clean block; ensure the proxy table, Docker
Compose example, and the note about Nostr relay behavior (including USE_TOR)
remain intact and correctly formatted, deleting the conflict marker lines and
any duplicated fragments so the documentation renders correctly.
In `@README.md`:
- Around line 77-101: Remove the Git conflict markers (<<<<<<<, =======,
>>>>>>>) from the README and keep the intended "Support proxy HTTP" section
content: retain the header, the environment variables table (PROXY_URL,
PROXY_USERNAME, PROXY_PASSWORD), the Docker Compose example, and the NOTE about
proxy behavior (including USE_TOR guidance) so the documentation reads cleanly
without merge artifacts.
In `@src/config.rs`:
- Around line 130-138: The Config struct is missing the fields used by
outbound_proxy(); add proxy_url: Option<String>, proxy_username: Option<String>,
and proxy_password: Option<String> to the Config struct declaration, and
initialize them in Config::default() (or the appropriate constructor) with None
(or appropriate defaults) so outbound_proxy() can compile and return an
OutboundProxyConfig using those fields; ensure names match exactly (Config,
outbound_proxy, OutboundProxyConfig, Config::default).
In `@src/main.rs`:
- Around line 71-77: The http_client returned by build_http_client(&config) is
constructed but never used; either propagate it into the components that make
outbound requests (e.g., pass the client into the TMDB/IMDB client constructors
or the server app state) or store it on a shared state object so it’s reused.
Locate the let http_client = ... statement and modify initialization code that
creates external API clients (or the app state/struct used to start the server)
to accept an argument for the http_client (e.g., pass http_client into the
TMDB/IMDB client factory functions or into AppState), or remove the build if
truly unnecessary; ensure references to build_http_client, http_client, and
config are updated accordingly so the client is used rather than discarded.
- Around line 67-88: Remove the git conflict markers (<<<<<<<, =======, >>>>>>>)
in main.rs and resolve the merged block, then either implement the missing
build_http_client(&config) function (used to create the outbound HTTP client) or
remove that call and the unused http_client variable; if you choose to implement
it, ensure it returns Result<Client, Error> (or your project’s HTTP client type)
and is invoked where outbound_proxy() is referenced. Also update the Config
struct to include the fields referenced by outbound_proxy() and the proxy
checks—add proxy_url, proxy_username, and proxy_password (or remove their usage
and the outbound_proxy() method if you prefer not to support them). Finally,
ensure any newly-created http_client is actually used for outbound proxy logic
or removed to avoid dead code.
In `@src/nostr.rs`:
- Line 203: The debug statements log proxy.url directly which can leak embedded
credentials; update both occurrences (the debug!("Probing relay {} via HTTP
proxy {}", url, proxy.url) call and the similar log at the other location) to
log a redacted/sanitized proxy identifier instead of proxy.url. Implement or
call a small sanitizer (e.g., sanitize_proxy_url or use the Url type to remove
username/password and only emit host:port or the scheme+host) and replace
proxy.url in those debug! calls with the sanitized result so credentials are
never logged.
- Around line 583-597: The proxy CONNECT and subsequent WebSocket handshake in
send_req_to (calls to connect_via_http_proxy, client_async_tls, client_async)
currently have no deadline; wrap the CONNECT call and both
client_async_tls/client_async handshakes in tokio::time::timeout using a
reasonable constant or config value (e.g., PROXY_CONNECT_TIMEOUT) and map
timeout errors to a clear Err message mentioning relay_url; similarly protect
the async I/O read/write loops that follow (the code handling ws_stream.split
and the event loop around collect_events! / read/write futures) by applying
timeouts to the individual await points or the entire loop (so stalled proxies
cannot block indefinitely), and ensure timeout cases close the socket/stream and
return a descriptive error instead of hanging.
In `@website/docs/configuration.md`:
- Around line 83-97: Remove the Git conflict markers (<<<<<<< HEAD, =======,
>>>>>>> fd3f5c5) from the documentation and keep the intended "### Proxy HTTP
sortant" section with its parameter table and info block; ensure the table rows
for proxy_url, proxy_username, proxy_password and the :::info block are
preserved exactly and there are no leftover conflict markers in
configuration.md.
In `@website/i18n/en/docusaurus-plugin-content-docs/current/configuration.md`:
- Around line 81-95: Remove the Git merge conflict markers (<<<<<<< HEAD,
=======, >>>>>>> fd3f5c5) from the documentation and leave the intended
"Outbound HTTP Proxy" section intact; specifically, delete the conflict markers
and any duplicate or stray content so the table of parameters (`proxy_url`,
`proxy_username`, `proxy_password`) and the :::info block about proxy usage for
HTTP(S) and Nostr relays remain as a single clean section in configuration.md
(locate the block around the existing "Outbound HTTP Proxy" heading to apply the
fix).
---
Outside diff comments:
In `@src/config.rs`:
- Around line 27-91: The env loader load_config_from_env is missing
PROXY_URL/PROXY_USERNAME/PROXY_PASSWORD support: add those keys to the ENV_KEYS
array and read them into Option<String> values (e.g., proxy_url, proxy_username,
proxy_password) using std::env::var(...).ok().filter(|s| !s.is_empty()) just
before constructing the Config, then include these variables in the returned
Config struct so the new Config fields are populated from environment variables.
In `@website/docs/configuration.md`:
- Around line 102-109: The environment variables proxy entries are missing from
the table; add rows for HTTP_PROXY, HTTPS_PROXY, ALL_PROXY and NO_PROXY mapping
to their config.json equivalents (http_proxy, https_proxy, all_proxy, no_proxy)
so the table includes all proxy-related variables alongside existing entries
like TOR_PROXY and USE_TOR; update the table rows for the variables
`HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` and ensure the config.json
column uses `http_proxy`, `https_proxy`, `all_proxy`, `no_proxy` respectively.
In `@website/i18n/en/docusaurus-plugin-content-docs/current/configuration.md`:
- Around line 100-109: Add the three missing proxy environment variables to the
existing env var table: insert rows for `PROXY_URL` => `proxy_url`,
`PROXY_USERNAME` => `proxy_username`, and `PROXY_PASSWORD` => `proxy_password`
in the same markdown table structure (near the other env vars shown between the
table header and the ":::tip Priority" marker) so the table matches the
"Outbound HTTP Proxy" section.
---
Nitpick comments:
In `@src/nostr.rs`:
- Around line 173-201: Extract the duplicated WebSocket probe logic into a
helper (e.g., send_req_and_wait_for_event) that accepts the split sink/stream or
the raw WebSocket stream, the req_text string, start Instant and timeout_dur and
returns Option<Duration>; move the code that does
write.send(Message::Text(req_text.into())).await, the read loop that parses
Message::Text, matches "EVENT"/"EOSE", handles Close/Err, and finally closes the
writer into that helper and call it from both the Tor and HTTP-proxy branches
(the blocks around the current snippet using variables write, read, req_text,
start, timeout_dur and the similar code at lines ~249-277) so behavior is
centralized and reused.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 26ccd223-f094-4e39-a690-2f03a2b4a805
📒 Files selected for processing (9)
Cargo.tomlREADME-en.mdREADME.mddocker/compose.ymlsrc/config.rssrc/main.rssrc/nostr.rswebsite/docs/configuration.mdwebsite/i18n/en/docusaurus-plugin-content-docs/current/configuration.md
📝 Description
Cette PR ajoute la prise en charge d'un proxy sortant configurable pour les connexions HTTP et pour les connexions WebSocket vers les relais Nostr.
Changements inclus :
PROXY_URL,PROXY_USERNAMEetPROXY_PASSWORDUSE_TORest désactivéUSE_TOR=true🎯 Type de changement
Cochez les options pertinentes :
🔗 Issue liée
Aucune issue liée.
🧪 Comment cela a-t-il été testé ?
Décrivez les tests effectués :
cargo checkConfiguration de test :
📸 Captures d'écran (si applicable)
N/A
📋 Checklist
Code Quality
Documentation
docs/api-documentation.mdetdocs/api-documentation-fr.mdmis à jourdocs/mis à jourTests
Dépendances
🔄 Changements majeurs (si applicable)
Aucun breaking change prévu.
Migration requise
Aucune migration requise.
Les nouvelles options sont facultatives.
📌 Notes supplémentaires
Point important :
http://...Note pour les reviewers :
Je souhaite surtout un retour sur :
PROXY_URLetUSE_TORSummary by CodeRabbit
New Features
Chores
Documentation