feat(cloudflare): add linearvoid-media edge worker for R2 HLS delivery
Replace the ad-hoc `worker.js` with a self-contained `linearvoid-media` worker under `infrastructure/cloudflare/` that owns `media.linearvoid.tv`. It serves HLS objects from the R2 bucket, enforcing immutable Cache-Control on segments, a short TTL on live manifests, plus HLS CORS, OPTIONS preflight, Range support, and a `/health` probe. Includes wrapper config with production domain, Vitest unit tests, Miniflare R2 integration tests, automated deploy workflow, and docs updates.
This commit is contained in:
1 parent
5f1f796a20
commit
8c5e70959b
16 files changed
+3359
-42
No files matched your search
@@ -0,0 +1,65 @@
|
||||
# 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
|
||||
|
||||
```text
|
||||
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
|
||||
|
||||
```bash
|
||||
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`):
|
||||
|
||||
```bash
|
||||
cd infrastructure/cloudflare
|
||||
npx wrangler deploy
|
||||
```
|
||||
|
||||
**Production** (attaches `media.linearvoid.tv` as a custom domain on this worker):
|
||||
|
||||
```bash
|
||||
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`](../../.gitea/workflows/workers-media-deploy.yml)
|
||||
after CI succeeds on `main`.
|
||||
|
||||
## Verify
|
||||
|
||||
```bash
|
||||
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",...}
|
||||
```
|
||||
Reference in new issue
Block a user