121 lines
4.1 KiB
JavaScript
121 lines
4.1 KiB
JavaScript
const { createProxyMiddleware } = require('http-proxy-middleware');
|
|
const path = require('path');
|
|
const fs = require('fs');
|
|
|
|
/**
|
|
* Development proxy (CRA - only active with `npm start`).
|
|
*
|
|
* .env / .env.local:
|
|
* REACT_APP_CORE_URL=https://restreamer.nextream.sytes.net
|
|
* REACT_APP_YTDLP_URL=http://192.168.1.20:8282
|
|
* REACT_APP_FB_SERVER_URL=http://localhost:3002 (optional, default shown)
|
|
*/
|
|
const CORE_TARGET = process.env.REACT_APP_CORE_URL || 'http://localhost:8080';
|
|
const YTDLP_TARGET = process.env.REACT_APP_YTDLP_URL || 'http://localhost:8282';
|
|
const FB_SERVER_TARGET = process.env.REACT_APP_FB_SERVER_URL || 'http://localhost:3002';
|
|
|
|
console.log('\n[setupProxy] ─────────────────────────────────────');
|
|
console.log(`[setupProxy] Core → ${CORE_TARGET}`);
|
|
console.log(`[setupProxy] yt-dlp → ${YTDLP_TARGET}`);
|
|
console.log(`[setupProxy] fb-server → ${FB_SERVER_TARGET}`);
|
|
console.log('[setupProxy] ─────────────────────────────────────\n');
|
|
|
|
let coreUrl;
|
|
try {
|
|
coreUrl = new URL(CORE_TARGET);
|
|
} catch (e) {
|
|
console.error(`[setupProxy] Invalid REACT_APP_CORE_URL: "${CORE_TARGET}"`);
|
|
coreUrl = new URL('http://localhost:8080');
|
|
}
|
|
|
|
// Shared proxy instance for all Core paths (/api, /memfs, /diskfs)
|
|
const coreProxy = createProxyMiddleware({
|
|
target: CORE_TARGET,
|
|
changeOrigin: true,
|
|
secure: false,
|
|
ws: false,
|
|
onProxyReq: (proxyReq) => {
|
|
proxyReq.setHeader('Host', coreUrl.host);
|
|
},
|
|
onError: (err, req, res) => {
|
|
console.error(`[setupProxy] Core proxy error: ${err.code} — ${err.message}`);
|
|
if (!res.headersSent) {
|
|
res.writeHead(502, { 'Content-Type': 'application/json' });
|
|
res.end(JSON.stringify({ error: 'Proxy error', target: CORE_TARGET, message: err.message }));
|
|
}
|
|
},
|
|
});
|
|
|
|
module.exports = function (app) {
|
|
// Restreamer Core REST API
|
|
app.use('/api', coreProxy);
|
|
|
|
// Restreamer Core in-memory FS (HLS playlists, snapshots)
|
|
app.use('/memfs', coreProxy);
|
|
|
|
// Restreamer Core disk FS
|
|
app.use('/diskfs', coreProxy);
|
|
|
|
// yt-dlp stream extractor: /yt-stream/{VIDEO_ID} → /stream/{VIDEO_ID}
|
|
// yt-dlp puede tardar hasta 30-60s en extraer la URL — timeout extendido
|
|
app.use(
|
|
'/yt-stream',
|
|
createProxyMiddleware({
|
|
target: YTDLP_TARGET,
|
|
changeOrigin: true,
|
|
secure: false,
|
|
ws: false,
|
|
proxyTimeout: 120000, // 120s — yt-dlp puede tardar bastante
|
|
timeout: 120000,
|
|
pathRewrite: { '^/yt-stream': '/stream' },
|
|
onError: (err, req, res) => {
|
|
console.error(`[setupProxy] yt-dlp proxy error: ${err.code} — ${err.message}`);
|
|
if (!res.headersSent) {
|
|
res.writeHead(502, { 'Content-Type': 'application/json' });
|
|
res.end(JSON.stringify({ error: 'Proxy error', target: YTDLP_TARGET, message: err.message }));
|
|
}
|
|
},
|
|
}),
|
|
);
|
|
|
|
// Facebook OAuth server: /fb-server/* → http://localhost:3002/*
|
|
// Routes: /fb/config, /fb/accounts, /fb/exchange, /fb/refresh/:id, /fb/upgrade
|
|
app.use(
|
|
'/fb-server',
|
|
createProxyMiddleware({
|
|
target: FB_SERVER_TARGET,
|
|
changeOrigin: true,
|
|
secure: false,
|
|
pathRewrite: { '^/fb-server': '' },
|
|
onError: (err, req, res) => {
|
|
console.error(`[setupProxy] fb-server proxy error: ${err.code} — ${err.message}`);
|
|
if (!res.headersSent) {
|
|
res.writeHead(502, { 'Content-Type': 'application/json' });
|
|
res.end(JSON.stringify({ error: 'fb-server unavailable', message: err.message }));
|
|
}
|
|
},
|
|
}),
|
|
);
|
|
|
|
// OAuth2 callback: sirve el HTML de callback para YouTube y otras plataformas
|
|
app.get('/oauth2callback', (req, res) => {
|
|
const callbackFile = path.join(__dirname, '..', 'public', 'oauth2callback.html');
|
|
if (fs.existsSync(callbackFile)) {
|
|
res.sendFile(callbackFile);
|
|
} else {
|
|
res.status(404).send('oauth2callback.html not found');
|
|
}
|
|
});
|
|
|
|
// Facebook OAuth2 callback popup
|
|
app.get('/oauth/facebook/callback.html', (req, res) => {
|
|
const callbackFile = path.join(__dirname, '..', 'public', 'oauth', 'facebook', 'callback.html');
|
|
if (fs.existsSync(callbackFile)) {
|
|
res.sendFile(callbackFile);
|
|
} else {
|
|
res.status(404).send('Facebook callback.html not found');
|
|
}
|
|
});
|
|
};
|
|
|