fixed API and stopping delay

This commit is contained in:
Marco Mooren
2026-05-27 12:54:56 +02:00
parent 470d4e8e76
commit 7b8d78ddaf
22 changed files with 495 additions and 98 deletions

View File

@@ -117,7 +117,7 @@ router.get('/:id/proxy', requireUser, async (req, res) => {
if (resolved.format === 'hls') return res.status(415).json({ error: 'hls not proxied' });
const controller = new AbortController();
req.on('close', () => controller.abort());
req.on('close', () => { try { controller.abort(); } catch { } });
let upstream;
try {
@@ -127,7 +127,9 @@ router.get('/:id/proxy', requireUser, async (req, res) => {
headers: { 'User-Agent': 'oradio-kiosk/1.0', 'Icy-MetaData': '0' }
});
} catch (err) {
return res.status(502).json({ error: `upstream: ${err.message || err}` });
if (err.name === 'AbortError') { res.end(); return; }
if (!res.headersSent) res.status(502).json({ error: `upstream: ${err.message || err}` });
return;
}
if (!upstream.ok || !upstream.body) {
return res.status(502).json({ error: `upstream HTTP ${upstream.status}` });
@@ -141,7 +143,11 @@ router.get('/:id/proxy', requireUser, async (req, res) => {
res.set('Access-Control-Expose-Headers', 'Content-Type');
// Pipe the WHATWG ReadableStream into the Express response.
// We cancel the reader directly on client-close — equivalent to aborting
// the fetch but without the AbortController rejection that escapes the
// async route in older Node/Electron versions.
const reader = upstream.body.getReader();
req.on('close', () => { reader.cancel().catch(() => {}); });
const pump = async () => {
try {
while (true) {
@@ -151,13 +157,13 @@ router.get('/:id/proxy', requireUser, async (req, res) => {
await new Promise((r) => res.once('drain', r));
}
}
} catch { /* client disconnect or upstream abort */ }
} catch { /* client disconnect or upstream error */ }
finally {
try { reader.cancel(); } catch { }
res.end();
try { res.end(); } catch { }
}
};
pump();
pump().catch(() => {});
});
function guessContentType(format) {