Files
zwitschi d8cf853842
Release / release (push) Successful in 1m15s
CI / test (push) Successful in 2m53s
CI / docker (push) Successful in 2m0s
chore(release): 1.1.0
- playout: run-scoped R2 manifest URIs (candidate a rewrite via rewriteManifestToRun)
- tests: playlist_rewrite_test.go (rewrite + publish integration + slate guard)
- docs: STREAMING, cloudflare-workers-setup, architecture (incl. Level-2 diagram)
- release housekeeping: TODO->DONE, CHANGELOG 1.1.0, version bump
2026-09-03 09:27:38 +02:00
..
2026-09-03 09:27:38 +02:00

linearvoid-media Worker

Cloudflare Worker that owns media.linearvoid.tv and serves the HLS objects stored in the linearvoid-media R2 bucket, applying the edge cache policy in code:

Object Cache-Control
.m4s / .ts / .mp4 / .m4a (segments) public, max-age=31536000, immutable
.m3u8 (live manifest) public, max-age=1, s-maxage=2, must-revalidate

It also adds HLS CORS (Access-Control-Allow-Origin: *), OPTIONS preflight, a /health probe, and Range-request support. This worker replaces direct R2 custom-domain serving on the media host so cache headers/CORS are controlled in code (cache rules on the same host remain the origin baseline).

Layout

infrastructure/cloudflare/
├── wrangler.toml        # name/binding + production custom-domain route
├── package.json
├── src/worker.js        # worker module (exports default.fetch + pure helpers)
└── test/                # Vitest unit tests + Miniflare (workerd) R2 tests

Local dev / test

cd infrastructure/cloudflare
npm install
npm test                 # unit + Miniflare R2 integration tests
npx wrangler dev         # run locally against your account's R2 bucket

Deploy

Preview / test target (default environment → *.workers.dev):

cd infrastructure/cloudflare
npx wrangler deploy

Production (attaches media.linearvoid.tv as a custom domain on this worker):

cd infrastructure/cloudflare
npx wrangler deploy --env production

Both need CLOUDFLARE_API_TOKEN (Workers Scripts/Routes edit) and CLOUDFLARE_ACCOUNT_ID in the environment. The media host must first be removed from the R2 bucket's direct custom-domain binding, otherwise the route collides.

Automated production deploys run via .gitea/workflows/workers-media-deploy.yml after CI succeeds on main.

Verify

curl -I https://media.linearvoid.tv/hls/playlist.m3u8   # short TTL
curl -I https://media.linearvoid.tv/hls/<segment>.m4s   # immutable + CORS
curl https://media.linearvoid.tv/health                 # {"status":"ok",...}