Skip to content

feat(streaming): standalone media proxy server, footer, and configurable proxy origin - #19

Closed
harusharu wants to merge 1 commit into
mainfrom
feat/standalone-streaming-proxy
Closed

feat(streaming): standalone media proxy server, footer, and configurable proxy origin#19
harusharu wants to merge 1 commit into
mainfrom
feat/standalone-streaming-proxy

Conversation

@harusharu

Copy link
Copy Markdown
Owner

Summary

This PR makes the streaming app able to play sources from provider CDNs that block Vercel's datacenter IPs (e.g. the Aliyun OSS host behind themoviebox.org returns 403 Forbidden for cloud IPs). It adds a self-contained, Node-only media proxy server that can run on a VPS/home server with a residential IP, reusing the exact same /api/proxy protocol the player already speaks. It also introduces a compact site footer and tidies up a few tooling configs.

What's included

1. Standalone proxy server — server/proxy.ts

  • Exposes /api/proxy with the same query contract as the in-function route handler (url + optional referer / origin / userAgent / cookie header params), plus a /health endpoint.
  • Reuses proxyStream() from src/lib/media/streamProxy so manifest rewriting and header injection live in one place.
  • Supports Range requests, HEAD requests, and cancels the upstream fetch (AbortController) when the client disconnects so long streams don't leak connections.
  • Rewrites HLS manifests to absolute URLs pointing back at the proxy origin (new origin option) so segments/keys resolve correctly in the standalone deployment.
  • Maps upstream failures to meaningful status codes (passes through 4xx/5xx, defaults to 502).

2. esbuild bundling — scripts/build-proxy.mjs

  • Bundles server/proxy.ts into a single self-contained dist/proxy-server.cjs (Node 22 target, @/ alias resolved to src/). The artifact runs with just Node — no node_modules, no Next.js.
  • New pnpm scripts: pnpm build:proxy and pnpm start:proxy.
  • esbuild added to devDependencies and its build script allowed in pnpm-workspace.yaml (allowBuilds).

3. Configurable proxy origin

  • playbackUrl() in src/lib/media/playback.ts now honors NEXT_PUBLIC_STREAM_PROXY_URL. When set, generated media URLs point at the external proxy; when unset, playback stays same-origin (/api/proxy).
  • proxiedUrl() / rewriteHlsManifest() in streamProxy.ts accept an origin param to emit absolute rewritten HLS URLs for the standalone deployment.
  • .env.example documents the new optional variable.

4. Site footer — src/components/layout/Footer.tsx

  • Compact two-row footer with links to the GitHub repo, "Report an issue", and the AGPL-3.0 license, plus a copyright line noting content streams from third-party providers.
  • Rendered once from App.tsx, animated with the existing viewFadeUp / VIEWPORT primitives.

5. Tooling & housekeeping

  • biome.json: ignore the .agents directory (vendored skill data shouldn't be linted/formatted).
  • .gitignore: ignore dist/ (proxy build artifact).
  • next-env.d.ts: refreshed to the .next/types route types.
  • skills-lock.json + pnpm-lock.yaml regenerated.
  • Skill data fixtures under .agents re-generated by their update tooling (large data churn is expected/intentional).

Testing / how to verify

  • Same-origin path (unchanged): run pnpm dev — playback uses /api/proxy as before. No behavior change without env config.
  • Standalone proxy path:
    pnpm build:proxy
    NODE_ENV=production PORT=8787 node dist/proxy-server.cjs
    curl -s "http://localhost:8787/health"   # -> {"ok":true,"service":"harustream-proxy"}
    Then point the app at it with NEXT_PUBLIC_STREAM_PROXY_URL=https://your-host.example.
  • Run pnpm typecheck and pnpm lint to confirm nothing regressed.

Notes

  • No breaking changes; existing deployments are unaffected unless the new env var is set.
  • The proxy must run behind a public origin (real hostname/TLS) for absolute HLS URL rewriting to work from the browser.

…ble proxy origin

Overview
--------
This change lets the streaming app work around provider CDNs that reject
Vercel's datacenter IPs (e.g. the Aliyun OSS host behind themoviebox.org
returns HTTP 403 for cloud IPs). It introduces a self-contained, Node-only
media proxy server that can run on a VPS or home server with a residential
(non-blocked) IP, while keeping the exact same /api/proxy protocol the
player already uses. In addition, it adds a compact site footer and tidies
up tooling config.

Highlights
----------
1. Standalone proxy server (server/proxy.ts)
   - Implements /api/proxy with the same query contract as the Next.js
     route handler (url + referer/origin/userAgent/cookie header params),
     plus a /health endpoint for uptime checks.
   - Reuses the shared proxyStream() module from src/lib/media so rewrite
     and header-injection logic stays in a single place.
   - Supports Range requests, HEAD requests, upstream AbortController
     cancellation on client disconnect, and absolute URL rewriting of HLS
     manifests via a new `origin` option so segments/keys resolve back to
     the proxy server (not the app origin).
   - Maps upstream failures to meaningful status codes (502 by default,
     passes through 4xx/5xx from the provider).

2. esbuild bundling script (scripts/build-proxy.mjs)
   - Bundles server/proxy.ts into a single self-contained
     dist/proxy-server.cjs with the `@/` alias resolved to src/, targeting
     Node 22. The artifact needs no node_modules or Next.js at runtime.
   - Adds pnpm scripts: build:proxy and start:proxy; wires esbuild into
     pnpm-workspace allowBuilds.

3. Configurable proxy origin
   - playbackUrl() in src/lib/media/playback.ts now honors
     NEXT_PUBLIC_STREAM_PROXY_URL; when set, generated /api/proxy URLs
     point at the external proxy, otherwise they stay same-origin.
   - proxiedUrl() and rewriteHlsManifest() in streamProxy.ts accept an
     `origin` param to emit absolute rewritten HLS URLs for the standalone
     deployment.
   - .env.example documents the new optional var.

4. Site footer (src/components/layout/Footer.tsx)
   - Compact, two-row footer with GitHub repo, "Report an issue", and
     license links, plus an AGPL-3.0 copyright line noting third-party
     streaming sources. Rendered once in App.tsx using the existing
     viewFadeUp animation primitives.

5. Tooling & housekeeping
   - biome.json now ignores the .agents directory (vendored skills data
     shouldn't be linted/formatted).
   - .gitignore ignores dist/ (proxy build artifact).
   - next-env.d.ts refreshed to the .next/types route types.
   - Regenerated skills-lock.json hash and pnpm-lock.yaml entries.

Notes
-----
- No runtime behavior changes for existing deployments unless
  NEXT_PUBLIC_STREAM_PROXY_URL is set.
- The .agents data fixtures were re-generated by their skill update tooling
  (large data churn is expected and intentional).
@vercel

vercel Bot commented Aug 20, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
harustream Ready Ready Preview Aug 20, 2026 9:47am

@harusharu

Copy link
Copy Markdown
Owner Author

Abandoning this approach; will rework streaming proxy strategy separately.

@harusharu harusharu closed this Aug 20, 2026
@harusharu
harusharu deleted the feat/standalone-streaming-proxy branch August 20, 2026 10:23
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.

1 participant