Skip to content

Add P2P privacy proxy, per-user VPN, speed optimizations, and reliability - #116

Merged
peterdsp merged 4 commits into
mainfrom
feat/privacy-proxy-and-speed-improvements
Aug 4, 2026
Merged

Add P2P privacy proxy, per-user VPN, speed optimizations, and reliability#116
peterdsp merged 4 commits into
mainfrom
feat/privacy-proxy-and-speed-improvements

Conversation

@peterdsp

@peterdsp peterdsp commented Aug 4, 2026

Copy link
Copy Markdown
Owner

Summary

  • P2P Privacy Proxy: Server-side torrent streaming via torrent-stream so user IPs never touch torrent swarms. LRU engine pool (max 3 for Raspberry Pi), HTTP Range support for seeking, optional SOCKS5 proxy for outbound connections
  • Per-user VPN/SOCKS5: Each user can configure their own SOCKS5 proxy URL in the addon settings — torrent traffic routes through their VPN, not the server's IP. Engines are keyed per-user proxy
  • P2P exposure warning: Landing page warns when no debrid service is configured, explaining IP risks and VPN mitigation
  • Stale-while-revalidate cache: Cached content returns instantly (<50ms), background refresh happens async — biggest single UX improvement
  • Speed tuning: Doubled scraper concurrency (6→12), halved timeouts (25s→15s), faster early return (6s→3s), relaxed per-provider throttling
  • Tracker init race fix: Server no longer accepts requests before trackers are loaded (fixes empty P2P streams on cold start)
  • fileIdx fix: No longer defaults to 0 on single-file torrents — fixes Android P2P streams (Issue P2P streams do not appear on Android clients (official and self-hosted instances) #111)
  • Dynamic subtitle translation: No longer hardcoded to Greek — derives from user's subtitle language preferences
  • Docker resource limits: scraper 512M/1CPU, addon 768M/1.5CPU, redis 256M/0.5CPU (Raspberry Pi safety)
  • Graceful shutdown: Both addon and scraper handle SIGTERM/SIGINT cleanly, destroying torrent engines and closing connections
  • Vulnerability fixes: ws 1.x→8.21.2, ip 1.x→2.0.1, scoped overrides for path-to-regexp, send, uuid, tmp
  • Dead code removal: Removed unused SERVICE constants from all 8 debrid modules and chunkArray from realdebrid

Test plan

  • All 30 addon tests pass (npm test)
  • npm audit — scraper: 0 vulnerabilities; addon: only unfixable ip advisory (affects all versions, used only for torrent peer discovery)
  • Verify landing page P2P warning appears when no debrid keys are set
  • Verify proxy URL field shows when Privacy Proxy is enabled
  • Verify streams show "🛡️ VPN Proxy" label when user proxy URL is configured
  • Docker compose build and health checks pass on Raspberry Pi
  • Stream loading time improved on cached content

Generated with Claude Code

- Server-side torrent streaming proxy hides user IPs from torrent swarms
- Stale-while-revalidate cache returns instant results for cached content
- Doubled scraper concurrency, halved timeouts for faster stream loading
- Fix tracker init race condition and fileIdx default breaking Android P2P
- Dynamic subtitle translation language (was hardcoded to Greek)
- Docker resource limits for Raspberry Pi safety
- Graceful shutdown handlers for both addon and scraper
- Fix ws/ip/path-to-regexp/send/uuid vulnerabilities via scoped overrides
- Remove dead code across all debrid modules

Generated with Claude Code
- Users can provide their own SOCKS5 proxy URL in the config page so
  torrent traffic routes through their VPN instead of the server's IP
- P2P warning banner shows when no debrid service is configured,
  explaining IP exposure risks and how to mitigate with VPN/proxy
- Proxy URL field and help text appear when Privacy Proxy is enabled
- Stream labels show "VPN Proxy" when user has their own proxy configured
- Torrent engines are keyed by infoHash + proxy URL to isolate per-user

Generated with Claude Code
Copilot AI lite review requested due to automatic review settings August 4, 2026 15:44

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a server-side torrent streaming “Privacy Proxy” (optionally routed through a per-user SOCKS5 proxy/VPN), alongside scraper/addon performance tuning, cache behavior improvements, and operational hardening (startup/shutdown, dependency updates, Docker config).

Changes:

  • Introduces a new /proxy/stream/:infoHash/:fileIdx endpoint and torrent-stream-based engine pool to stream torrents via the server (with optional SOCKS5 proxy support).
  • Speeds up scraping and stream fetching via higher concurrency, lower timeouts, and stale-while-revalidate caching.
  • Improves operational reliability via graceful shutdown handlers, dependency overrides/updates, and Docker compose resource limit configuration.

Reviewed changes

Copilot reviewed 24 out of 26 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
scraper/providers/index.js Makes scraper concurrency/timeouts configurable and more aggressive for faster throughput.
scraper/package-lock.json Updates locked dependencies (incl. brace-expansion), impacting Node engine compatibility.
scraper/lib/httpClient.js Relaxes per-provider throttling to increase request rate/concurrency.
scraper/index.js Adds graceful shutdown handling for the scraper service.
docker-compose.yml Adds resource limit configuration for scraper/addon/redis containers.
addon/serverless.js Adds a proxy streaming route for torrent HTTP streaming via the addon server.
addon/package.json Adds torrent-stream and extends overrides for vulnerability mitigation.
addon/package-lock.json Locks new dependency tree for torrent proxying and updated overrides.
addon/moch/torbox.js Removes unused constant as part of dead-code cleanup.
addon/moch/realdebrid.js Removes unused constant and helper as part of dead-code cleanup.
addon/moch/putio.js Removes unused constant as part of dead-code cleanup.
addon/moch/premiumize.js Removes unused constant as part of dead-code cleanup.
addon/moch/offcloud.js Removes unused constant as part of dead-code cleanup.
addon/moch/easydebrid.js Removes unused constant as part of dead-code cleanup.
addon/moch/debridlink.js Removes unused constant as part of dead-code cleanup.
addon/moch/alldebrid.js Removes unused constant as part of dead-code cleanup.
addon/lib/translatedSubtitles.js Makes translation target derive from user language preferences instead of being hardcoded.
addon/lib/torrentProxy.js New torrent streaming engine pool implementation with HTTP Range support.
addon/lib/streamInfo.js Switches streams to proxy URLs when enabled; adjusts fileIdx behavior and labeling.
addon/lib/repository.js Tweaks scraper request timeout and retries once on empty results.
addon/lib/landingTemplate.js Adds landing-page UX for P2P exposure warning and proxy configuration fields.
addon/lib/configuration.js Adds parsing/defaults for proxy-related configuration fields.
addon/lib/cache.js Implements stale-while-revalidate caching semantics and in-flight refresh deduplication.
addon/index.js Ensures trackers are initialized before listening; adds graceful shutdown cleanup for torrent engines.
addon/Dockerfile Adds build dependencies to support builds with new native/tooling requirements.
addon/.env.example Documents environment variables for the privacy proxy / engine limits.
Files not reviewed (2)
  • addon/package-lock.json: Generated file
  • scraper/package-lock.json: Generated file
Suppressed comments (3)

addon/lib/torrentProxy.js:96

  • selectFile() sorts engine.files in-place and then uses engine.files[fileIdx]. If fileIdx comes from the original torrent file ordering, sorting mutates that ordering and can cause the wrong file to be streamed.
function selectFile(engine, fileIdx) {
  const files = engine.files.sort((a, b) => b.length - a.length);
  if (fileIdx != null && fileIdx < engine.files.length) {
    return engine.files[fileIdx];
  }

addon/lib/torrentProxy.js:104

  • The torrent engine is created with an empty tracker list (getOrCreateEngine(infoHash, [], …)), so magnet URIs are built without trackers. This can significantly slow peer discovery or fail on torrents that rely on trackers (especially when DHT is unavailable).
export async function streamTorrent(infoHash, fileIdx, req, res, proxyUrl) {
  const { entry, engineKey } = getOrCreateEngine(infoHash, [], proxyUrl);
  try {

addon/lib/torrentProxy.js:133

  • Range handling does not validate parsed start/end values (e.g., suffix ranges like bytes=-500, non-numeric values, or start >= total). This can generate invalid Content-Range/Content-Length and cause errors or unexpected reads. Consider returning 416 with Content-Range: bytes */<total> for invalid ranges.
  const range = req.headers.range;
  if (range) {
    const parts = range.replace(/bytes=/, '').split('-');
    const start = parseInt(parts[0], 10);
    const end = parts[1] ? parseInt(parts[1], 10) : total - 1;

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread addon/serverless.js Outdated
Comment thread addon/lib/torrentProxy.js Outdated
Comment thread addon/serverless.js
Comment thread addon/lib/streamInfo.js
Comment thread docker-compose.yml
Comment thread scraper/providers/index.js Outdated
Comment thread addon/package-lock.json
Comment thread scraper/package-lock.json
npm ci in npm 10 fails when package.json uses npm overrides —
it considers overridden transitive dependency versions as "missing"
from the lock file (known npm bug). Switching to npm install resolves
this while still validating the dependency tree.

Generated with Claude Code
- Add rate limiter for proxy stream endpoint
- Fix NaN validation for PROXY_MAX_ENGINES and SCRAPER_CONCURRENCY
- Fix sort mutation in selectFile (copy array before sorting)
- Add HTTP 416 range validation for proxy streams
- Import getBestTrackers for torrent engine initialization
- Add Stremio + Nuvio feature card to landing page

Generated with Claude Code
@peterdsp
peterdsp merged commit c4ae556 into main Aug 4, 2026
5 checks passed
@peterdsp
peterdsp deleted the feat/privacy-proxy-and-speed-improvements branch August 4, 2026 16:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants