recycleactor commited on
Commit
4701327
·
verified ·
1 Parent(s): 00a1de0

Upload server.js

Browse files
Files changed (1) hide show
  1. server.js +40 -14
server.js CHANGED
@@ -60,23 +60,36 @@ function readBody(req) {
60
  }
61
 
62
  async function fetchRaw(url, headers = {}) {
63
- let retries = 2;
64
  while (retries > 0) {
65
  try {
66
  return await new Promise((resolve, reject) => {
67
- const pu = new URL(url);
 
 
 
 
 
68
  const mod = pu.protocol === 'https:' ? https : http;
69
  const req = mod.get(url, {
70
  headers: {
71
  'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
 
 
72
  'connection': 'close',
73
  ...headers
74
  },
75
- timeout: 10000
76
  }, (res) => {
77
- let data = '';
78
- res.on('data', (chunk) => data += chunk);
79
- res.on('end', () => resolve(data));
 
 
 
 
 
 
80
  });
81
  req.on('error', reject);
82
  req.on('timeout', () => { req.destroy(); reject(new Error('timeout')); });
@@ -85,7 +98,7 @@ async function fetchRaw(url, headers = {}) {
85
  console.log(`[fetchRaw] error for ${url}: ${e.message}, retries left: ${retries - 1}`);
86
  retries--;
87
  if (retries === 0) throw e;
88
- await new Promise(r => setTimeout(r, 1000));
89
  }
90
  }
91
  }
@@ -392,10 +405,14 @@ function handleHls(req, res) {
392
  port: pu.port || (pu.protocol === 'https:' ? 443 : 80),
393
  path: pu.pathname + pu.search,
394
  headers: {
395
- 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36',
396
  'accept': '*/*',
397
- 'origin': isCinemap ? 'https://uakinogo.io' : isObrut ? 'https://kinojump.com' : isAlloha ? 'https://streamalloha.live' : isRstprg ? 'https://veoveo.ru' : 'https://streamalloha.live',
398
- 'referer': isCinemap ? 'https://uakinogo.io/' : isObrut ? 'https://kinojump.com/' : isAlloha ? 'https://streamalloha.live/' : isRstprg ? 'https://veoveo.ru/' : 'https://streamalloha.live/',
 
 
 
 
399
  },
400
  };
401
  if (req.headers['range']) opts.headers['range'] = req.headers['range'];
@@ -466,12 +483,18 @@ const server = http.createServer(async (req, res) => {
466
  if (!embedUrl || !embedUrl.includes('kinoserial')) {
467
  jsonResp(res, { ok: false, error: 'invalid url' }, 400); return;
468
  }
 
469
  fetchRaw(embedUrl, {
470
- 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
471
  'referer': 'https://veoveo.ru/',
472
  'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
473
- 'connection': 'keep-alive'
 
 
474
  }).then(text => {
 
 
 
 
475
  res.writeHead(200, {
476
  'Access-Control-Allow-Origin': '*',
477
  'Content-Type': 'text/html; charset=utf-8'
@@ -487,10 +510,13 @@ const server = http.createServer(async (req, res) => {
487
  if (pathname === '/veoveo/balancer') {
488
  const contentId = query.id;
489
  if (!contentId) { jsonResp(res, { ok: false, error: 'no id' }, 400); return; }
 
490
  fetchRaw('https://api.rstprgapipt.com/balancer-api/proxy/playlists/catalog-api/episodes?content-id=' + contentId, {
491
  'referer': 'https://veoveo.ru/',
492
- 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
493
- 'accept': 'application/json, text/plain, */*'
 
 
494
  }).then(text => {
495
  res.writeHead(200, {
496
  'Access-Control-Allow-Origin': '*',
 
60
  }
61
 
62
  async function fetchRaw(url, headers = {}) {
63
+ let retries = 3;
64
  while (retries > 0) {
65
  try {
66
  return await new Promise((resolve, reject) => {
67
+ let pu;
68
+ try {
69
+ pu = new URL(url);
70
+ } catch (e) {
71
+ return reject(new Error('Invalid URL: ' + url));
72
+ }
73
  const mod = pu.protocol === 'https:' ? https : http;
74
  const req = mod.get(url, {
75
  headers: {
76
  'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
77
+ 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
78
+ 'accept-language': 'ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7',
79
  'connection': 'close',
80
  ...headers
81
  },
82
+ timeout: 15000
83
  }, (res) => {
84
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
85
+ let loc = res.headers.location;
86
+ if (!loc.startsWith('http')) loc = new URL(loc, url).href;
87
+ resolve(fetchRaw(loc, headers));
88
+ return;
89
+ }
90
+ let data = [];
91
+ res.on('data', (chunk) => data.push(chunk));
92
+ res.on('end', () => resolve(Buffer.concat(data).toString('utf8')));
93
  });
94
  req.on('error', reject);
95
  req.on('timeout', () => { req.destroy(); reject(new Error('timeout')); });
 
98
  console.log(`[fetchRaw] error for ${url}: ${e.message}, retries left: ${retries - 1}`);
99
  retries--;
100
  if (retries === 0) throw e;
101
+ await new Promise(r => setTimeout(r, 1500));
102
  }
103
  }
104
  }
 
405
  port: pu.port || (pu.protocol === 'https:' ? 443 : 80),
406
  path: pu.pathname + pu.search,
407
  headers: {
408
+ 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
409
  'accept': '*/*',
410
+ 'accept-language': 'ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7',
411
+ 'origin': isCinemap ? 'https://uakinogo.io' : isObrut ? 'https://kinojump.com' : isAlloha ? 'https://streamalloha.live' : isRstprg ? 'https://tv-1-kinoserial.net' : 'https://streamalloha.live',
412
+ 'referer': isCinemap ? 'https://uakinogo.io/' : isObrut ? 'https://kinojump.com/' : isAlloha ? 'https://streamalloha.live/' : isRstprg ? 'https://tv-1-kinoserial.net/' : 'https://streamalloha.live/',
413
+ 'sec-fetch-dest': isRstprg ? 'video' : 'empty',
414
+ 'sec-fetch-mode': 'cors',
415
+ 'sec-fetch-site': 'cross-site',
416
  },
417
  };
418
  if (req.headers['range']) opts.headers['range'] = req.headers['range'];
 
483
  if (!embedUrl || !embedUrl.includes('kinoserial')) {
484
  jsonResp(res, { ok: false, error: 'invalid url' }, 400); return;
485
  }
486
+ console.log('[veoveo/embed] fetching:', embedUrl);
487
  fetchRaw(embedUrl, {
 
488
  'referer': 'https://veoveo.ru/',
489
  'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
490
+ 'sec-fetch-dest': 'document',
491
+ 'sec-fetch-mode': 'navigate',
492
+ 'sec-fetch-site': 'cross-site',
493
  }).then(text => {
494
+ if (text.includes('id="cf-challenge"') || text.includes('cf-browser-verification')) {
495
+ console.log('[veoveo/embed] Cloudflare challenge detected');
496
+ // Could potentially fallback to puppeteer here if needed
497
+ }
498
  res.writeHead(200, {
499
  'Access-Control-Allow-Origin': '*',
500
  'Content-Type': 'text/html; charset=utf-8'
 
510
  if (pathname === '/veoveo/balancer') {
511
  const contentId = query.id;
512
  if (!contentId) { jsonResp(res, { ok: false, error: 'no id' }, 400); return; }
513
+ console.log('[veoveo/balancer] contentId:', contentId);
514
  fetchRaw('https://api.rstprgapipt.com/balancer-api/proxy/playlists/catalog-api/episodes?content-id=' + contentId, {
515
  'referer': 'https://veoveo.ru/',
516
+ 'accept': 'application/json, text/plain, */*',
517
+ 'sec-fetch-dest': 'empty',
518
+ 'sec-fetch-mode': 'cors',
519
+ 'sec-fetch-site': 'cross-site',
520
  }).then(text => {
521
  res.writeHead(200, {
522
  'Access-Control-Allow-Origin': '*',