import { createRouter } from '../../create-router'; import { getMusicServerUrl } from './sidecar-server'; // Thin reverse-proxy for /api/music/*. Auth is handled upstream by userMiddleware (this router mounts // under the protected /api tree, so the media `?token=` path works). Everything else — path resolution, // byte-range streaming, ffprobe duration — is done by the officer-music sidecar's audio server. We only // forward the subpath + query + Range and stream the response back. export const musicRouter = createRouter(); const PREFIX = '/api/music'; musicRouter.all('/*', async (ctx) => { const baseUrl = getMusicServerUrl(); if (!baseUrl) return ctx.text('Music sidecar not available', 503); const url = new URL(ctx.req.url); const subpath = url.pathname.slice(PREFIX.length) || '/'; const target = `${baseUrl}${subpath}${url.search}`; const range = ctx.req.header('range'); let upstream: Response; try { upstream = await fetch(target, { method: ctx.req.method, headers: range ? { Range: range } : {}, }); } catch (err) { console.error('[music] proxy fetch failed', { target, error: String(err) }); return ctx.text('Music sidecar unreachable', 502); } // Pass status + headers through and stream the body (206/Content-Range/X-Audio-Duration included). return new Response(upstream.body, { status: upstream.status, headers: new Headers(upstream.headers) }); });