33 lines
2.7 KiB
JavaScript
33 lines
2.7 KiB
JavaScript
// Podcast proxy: only the allowed Podgrab calls get through, the Podgrab password is added server-side, audio ranges and redirects work.
|
|
const http = require('http'), assert = require('assert');
|
|
const seen = [];
|
|
const fake = http.createServer((req, res) => {
|
|
let b = ''; req.on('data', c => b += c); req.on('end', () => {
|
|
seen.push({ m: req.method, u: req.url, auth: req.headers.authorization, range: req.headers.range, b });
|
|
if (req.url === '/podcasts') { res.writeHead(200, { 'content-type': 'application/json' }); return res.end('[{"ID":"p1","Title":"Show"}]'); }
|
|
if (req.url === '/podcastitems/e1/file') { res.writeHead(206, { 'content-type': 'audio/mpeg', 'content-range': 'bytes 0-3/10', 'content-length': '4' }); return res.end('abcd'); }
|
|
if (req.url === '/podcastitems/e2/file') { res.writeHead(302, { location: 'https://cdn.example.com/a.mp3' }); return res.end(); }
|
|
res.writeHead(200, { 'content-type': 'application/json' }); res.end('{}');
|
|
});
|
|
}).listen(0, async () => {
|
|
process.env.PODCAST_URL = 'http://127.0.0.1:' + fake.address().port + '/'; process.env.PODGRAB_PASSWORD = 'secret';
|
|
const podcast = require('../podcast');
|
|
const hub = http.createServer((req, res) => podcast.handle(req, res)).listen(0, async () => {
|
|
const base = 'http://127.0.0.1:' + hub.address().port, get = (p, o = {}) => fetch(base + '/api/podcast' + p, { redirect: 'manual', ...o });
|
|
try {
|
|
let r = await get('/podcasts'); assert.equal(r.status, 200); assert.equal((await r.json())[0].Title, 'Show');
|
|
assert.equal(seen[0].auth, 'Basic ' + Buffer.from('podgrab:secret').toString('base64'), 'password added by the server');
|
|
r = await get('/podcastitems/e1/file', { headers: { range: 'bytes=0-3' } }); assert.equal(r.status, 206); assert.equal(await r.text(), 'abcd'); assert.equal(seen.at(-1).range, 'bytes=0-3');
|
|
r = await get('/podcastitems/e2/file'); assert.equal(r.status, 302); assert.equal(r.headers.get('location'), 'https://cdn.example.com/a.mp3');
|
|
r = await get('/podcasts', { method: 'POST', body: '{"url":"https://x.test/feed"}' }); assert.equal(r.status, 200); assert.equal(seen.at(-1).b, '{"url":"https://x.test/feed"}');
|
|
const n = seen.length;
|
|
for (const [m, p] of [['GET', '/settings'], ['POST', '/settings'], ['GET', '/opml'], ['DELETE', '/tags/1'], ['GET', '/backups'], ['GET', '/podcasts/../settings'], ['DELETE', '/podcastitems/e1']]) {
|
|
r = await get(p, { method: m }); assert.equal(r.status, 404, m + ' ' + p);
|
|
}
|
|
assert.equal(seen.length, n, 'blocked calls never reach Podgrab');
|
|
console.log('podcast ok');
|
|
} catch (e) { console.error(e); process.exitCode = 1; }
|
|
hub.close(); fake.close();
|
|
});
|
|
});
|