feat(funnel): cloudflare quick tunnel embedded subprocess (0.9.5)
Gives the daemon a public HTTPS hostname (`https://<random>.trycloudflare.com`)
so the in-browser player on torrentclaw.com plays cross-network without
Tailscale or port forwarding — the mixed-content block that was breaking
HTTPS-page → HTTP-daemon fetches is gone. Bytes proxy through CloudFlare,
never through TorrentClaw infra (preserves the aggregator legal posture).
New surface:
• `internal/funnel/` package: subprocess wrapper + auto-download for
cloudflared. Linux amd64/arm64/armhf/386 fetched from GitHub releases
on first run, validated by ELF magic + size sanity, O_EXCL partial
write so concurrent daemons don't clobber each other.
• `unarr funnel on/off/status` cobra command (sibling of `unarr vpn`).
• Daemon supervisor goroutine keeps cloudflared up across crashes + CF's
~6h Quick Tunnel rotation. Exponential backoff (2 s → 5 min). On exit
the reported URL is cleared so the web stops handing out a dead host.
• Wire: agent registers/syncs a FunnelURL field; web prefers it over
Tailscale/LAN for in-browser playback (HlsStreamPlayer + Stremio
addon).
Default ON for fresh installs (NAS/Docker get it without terminal-in);
existing configs that pre-date the feature stay off until the operator
opts in with `unarr funnel on`.
Docker image now bundles cloudflared (built per TARGETARCH via buildx).
Also fixed: libx264 'frame MB size > level limit' on anamorphic >16:9
sources. The level we hint to libx264 was derived from height alone,
which busted on 720p cinemascope (1728×720 = 4860 MBs > level 3.1's
3600). Bumped each tier: 720p → 4.0, 1080p → 4.1.
Version: 0.9.4 → 0.9.5.
This commit is contained in:
parent
ca7de23a56
commit
88316e7017
15 changed files with 778 additions and 13 deletions
|
|
@ -53,6 +53,16 @@ type DownloadConfig struct {
|
|||
CORSExtraOrigins []string `toml:"cors_extra_origins"` // extra browser origins added on top of the baked-in allowlist (torrentclaw.com, app.torrentclaw.com, localhost:3030)
|
||||
Transcode TranscodeConfig `toml:"transcode"`
|
||||
VPN VPNConfig `toml:"vpn"`
|
||||
Funnel FunnelConfig `toml:"funnel"`
|
||||
}
|
||||
|
||||
// FunnelConfig gates the optional CloudFlare Quick Tunnel that exposes the
|
||||
// daemon's HLS server over a public HTTPS hostname (https://<random>.try
|
||||
// cloudflare.com). Enabling it lets the web player on torrentclaw.com play
|
||||
// from this daemon across any network without Tailscale or a public IP —
|
||||
// the cost is that bytes proxy through CloudFlare's network. Off by default.
|
||||
type FunnelConfig struct {
|
||||
Enabled bool `toml:"enabled"`
|
||||
}
|
||||
|
||||
// VPNConfig gates the managed-VPN add-on split-tunnel. When enabled, the daemon
|
||||
|
|
@ -139,6 +149,13 @@ func Default() Config {
|
|||
AudioBitrate: "192k",
|
||||
MaxConcurrent: 2,
|
||||
},
|
||||
Funnel: FunnelConfig{
|
||||
// On by default so headless installs (NAS / Docker) get cross-network
|
||||
// HTTPS playback without anyone having to terminal in. Users who
|
||||
// don't want bytes proxied through CloudFlare can opt out with
|
||||
// `unarr funnel off` (sets enabled=false in the TOML).
|
||||
Enabled: true,
|
||||
},
|
||||
},
|
||||
Organize: OrganizeConfig{
|
||||
Enabled: true,
|
||||
|
|
@ -227,6 +244,12 @@ func applyDefaults(cfg *Config, meta toml.MetaData) {
|
|||
if !meta.IsDefined("downloads", "transcode", "max_concurrent") {
|
||||
cfg.Download.Transcode.MaxConcurrent = 2
|
||||
}
|
||||
// NOTE: Funnel default-ON only applies to fresh installs (no config file →
|
||||
// Default() returns Funnel.Enabled=true straight off). When an existing
|
||||
// config file lacks `[downloads.funnel]` entirely we intentionally do NOT
|
||||
// flip it on here — that would silently route an upgraded operator's
|
||||
// traffic through CloudFlare without their consent. They opt in with
|
||||
// `unarr funnel on` whenever they're ready.
|
||||
}
|
||||
|
||||
// Save writes config to the default or specified path using atomic write.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue