mirror of https://github.com/FongMi/CatVodOpen.git
parent
50054f5c86
commit
d82d120277
@ -0,0 +1,11 @@ |
|||||||
|
## Standalone windows & macos sniffer server base on electron. |
||||||
|
|
||||||
|
`npm install` |
||||||
|
|
||||||
|
`npm run start` |
||||||
|
|
||||||
|
`curl http://127.0.0.1:8887/?url=https://v.qq.com/x/page/i3038urj2mt.html` |
||||||
|
|
||||||
|
`curl http://127.0.0.1:8887/?url=http://www.mgtv.com/v/1/290346/f/3664551.html` |
||||||
|
|
||||||
|
`curl http://127.0.0.1:8887/?url=https://555dy.cc/vodplay/414521-1-1.html` |
||||||
@ -0,0 +1,43 @@ |
|||||||
|
<html> |
||||||
|
<script src="./jquery.min.js"></script> |
||||||
|
|
||||||
|
<body> |
||||||
|
<input type="text" id="port" value="8887" /> |
||||||
|
<button id="start" onclick="start()">Start</button> |
||||||
|
<button id="stop" onclick="stop()">Stop</button> |
||||||
|
</body> |
||||||
|
<script> |
||||||
|
msg_center.on((event, msg) => { |
||||||
|
console.log(msg); |
||||||
|
switch (msg.code) { |
||||||
|
case 100: |
||||||
|
$('#port')[0].value = msg.cfg.port; |
||||||
|
break; |
||||||
|
case 200: |
||||||
|
$('#start').hide(); |
||||||
|
$('#stop').show(); |
||||||
|
break; |
||||||
|
case 201: |
||||||
|
$('#start').show(); |
||||||
|
$('#stop').hide(); |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
function start() { |
||||||
|
const port = $('#port')[0].value; |
||||||
|
msg_center.send({ code: 200, cfg: { port: port } }); |
||||||
|
} |
||||||
|
|
||||||
|
function stop() { |
||||||
|
msg_center.send({ code: 201 }); |
||||||
|
} |
||||||
|
|
||||||
|
$('#start').show(); |
||||||
|
$('#stop').hide(); |
||||||
|
msg_center.send({ code: 100 }); |
||||||
|
</script> |
||||||
|
|
||||||
|
</html> |
||||||
@ -0,0 +1,8 @@ |
|||||||
|
const { contextBridge, ipcRenderer } = require('electron'); |
||||||
|
|
||||||
|
contextBridge.exposeInMainWorld('msg_center', { |
||||||
|
send: (...args) => ipcRenderer.send('msg', ...args), |
||||||
|
on: (fn) => { |
||||||
|
ipcRenderer.on('msg', (event, ...args) => fn(event, ...args)); |
||||||
|
}, |
||||||
|
}); |
||||||
@ -0,0 +1,182 @@ |
|||||||
|
const os = require('os'); |
||||||
|
const { app, session, BrowserWindow, ipcMain } = require('electron'); |
||||||
|
const pie = require('puppeteer-in-electron'); |
||||||
|
const puppeteer = require('puppeteer-core'); |
||||||
|
const http = require('http'); |
||||||
|
const Store = require('electron-store'); |
||||||
|
const store = new Store(); |
||||||
|
|
||||||
|
const urlRegex = 'http((?!http).){12,}?\\.(m3u8|mp4|flv|avi|mkv|rm|wmv|mpg|m4a|mp3)\\?.*|http((?!http).){12,}\\.(m3u8|mp4|flv|avi|mkv|rm|wmv|mpg|m4a|mp3)|http((?!http).)*?video/tos*'; |
||||||
|
|
||||||
|
async function trySniffer(url) { |
||||||
|
const promise = new Promise(async (resolve, reject) => { |
||||||
|
try { |
||||||
|
let timeout = setTimeout(() => { |
||||||
|
timeout = null; |
||||||
|
resolve({ code: 500 }); |
||||||
|
page.close(); |
||||||
|
}, 15000); |
||||||
|
const browser = await pie.connect(app, puppeteer); |
||||||
|
const window = new BrowserWindow({ |
||||||
|
show: false, |
||||||
|
}); |
||||||
|
// window.webContents.openDevTools();
|
||||||
|
const page = await pie.getPage(browser, window); |
||||||
|
await page.setRequestInterception(true); |
||||||
|
page.on('request', (req) => { |
||||||
|
if (!timeout) req.abort().catch((err) => console.error(err)); |
||||||
|
var reqUrl = req.url(); |
||||||
|
if (reqUrl.match(urlRegex)) { |
||||||
|
if (reqUrl.indexOf('url=http') < 0 && reqUrl.indexOf('v=http') < 0 && reqUrl.indexOf('.css') < 0 && reqUrl.indexOf('.html') < 0) { |
||||||
|
console.log(req.headers()); |
||||||
|
console.log(reqUrl); |
||||||
|
const headers = req.headers(); |
||||||
|
const header = {}; |
||||||
|
if (headers['referer']) header['referer'] = headers['referer']; |
||||||
|
if (headers['user-agent']) header['user-agent'] = headers['user-agent']; |
||||||
|
resolve({ code: 200, url: reqUrl, header: header }); |
||||||
|
req.abort().catch((err) => console.error(err)); |
||||||
|
clearTimeout(timeout); |
||||||
|
timeout = null; |
||||||
|
page.close(); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
if (req.isInterceptResolutionHandled()) return; |
||||||
|
if (req.resourceType() == 'image') req.abort().catch((err) => console.error(err)); |
||||||
|
else req.continue().catch((err) => console.error(err)); |
||||||
|
}); |
||||||
|
await page.setUserAgent('Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1'); |
||||||
|
await page.goto(url).catch((err) => {}); |
||||||
|
} catch (e) { |
||||||
|
console.error(e); |
||||||
|
resolve({ code: 500 }); |
||||||
|
} |
||||||
|
}); |
||||||
|
return promise; |
||||||
|
} |
||||||
|
|
||||||
|
pie.initialize(app); |
||||||
|
|
||||||
|
let httpServer = null; |
||||||
|
const httpServerSockets = new Set(); |
||||||
|
|
||||||
|
const createMain = async () => { |
||||||
|
// await session.defaultSession.clearCache();
|
||||||
|
const mainWindow = new BrowserWindow({ |
||||||
|
show: false, |
||||||
|
width: 480, |
||||||
|
resizable: false, |
||||||
|
height: 300, |
||||||
|
webPreferences: { |
||||||
|
preload: __dirname + '/config.js', |
||||||
|
}, |
||||||
|
}); |
||||||
|
mainWindow.removeMenu(); |
||||||
|
|
||||||
|
const defaultPort = 8889; |
||||||
|
|
||||||
|
function startServer() { |
||||||
|
if (httpServer) { |
||||||
|
return; |
||||||
|
} |
||||||
|
httpServerSockets.clear(); |
||||||
|
const requestListener = async function (req, res) { |
||||||
|
if (!req.url.startsWith('/?url=')) { |
||||||
|
res.writeHead(500); |
||||||
|
res.end('Url must /?url=http*****'); |
||||||
|
return; |
||||||
|
} |
||||||
|
const sniffUrl = req.url.substring(6).trim(); |
||||||
|
const result = await trySniffer(sniffUrl); |
||||||
|
res.writeHead(200); |
||||||
|
res.end(JSON.stringify(result)); |
||||||
|
}; |
||||||
|
httpServer = http.createServer(requestListener); |
||||||
|
const port = store.get('port', defaultPort); |
||||||
|
store.set('port', port); |
||||||
|
httpServer.on('error', (e) => { |
||||||
|
httpServer = null; |
||||||
|
mainWindow.webContents.send('msg', { |
||||||
|
code: 201, |
||||||
|
}); |
||||||
|
}); |
||||||
|
httpServer.on('connection', (socket) => { |
||||||
|
httpServerSockets.add(socket); |
||||||
|
httpServer.once('close', () => { |
||||||
|
httpServerSockets.delete(socket); |
||||||
|
}); |
||||||
|
}); |
||||||
|
httpServer.listen(port, '0.0.0.0', () => { |
||||||
|
console.log(`Server is running on`); |
||||||
|
console.log(`\thttp://127.0.0.1:${port}`); |
||||||
|
const interfaces = os.networkInterfaces(); |
||||||
|
for (let intf in interfaces) { |
||||||
|
for (let i in interfaces[intf]) { |
||||||
|
let address = interfaces[intf][i]; |
||||||
|
if (address.family === 'IPv4' && !address.internal) { |
||||||
|
console.log(`\thttp://${address.address}:${port}`); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
mainWindow.webContents.send('msg', { |
||||||
|
code: 200, |
||||||
|
}); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
function stopServer() { |
||||||
|
if (httpServer) { |
||||||
|
for (const socket of httpServerSockets) { |
||||||
|
socket.destroy(); |
||||||
|
httpServerSockets.delete(socket); |
||||||
|
} |
||||||
|
httpServer.close(); |
||||||
|
httpServerSockets.clear(); |
||||||
|
httpServer = null; |
||||||
|
} |
||||||
|
mainWindow.webContents.send('msg', { |
||||||
|
code: 201, |
||||||
|
}); |
||||||
|
} |
||||||
|
// mainWindow.webContents.openDevTools();
|
||||||
|
ipcMain.on('msg', async (event, msg) => { |
||||||
|
switch (msg.code) { |
||||||
|
case 100: { |
||||||
|
const port = store.get('port', defaultPort); |
||||||
|
mainWindow.webContents.send('msg', { |
||||||
|
code: 100, |
||||||
|
cfg: { |
||||||
|
port: port, |
||||||
|
}, |
||||||
|
}); |
||||||
|
startServer(); |
||||||
|
break; |
||||||
|
} |
||||||
|
case 200: { |
||||||
|
const port = msg.cfg.port; |
||||||
|
store.set('port', port); |
||||||
|
startServer(); |
||||||
|
break; |
||||||
|
} |
||||||
|
case 201: |
||||||
|
stopServer(); |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
console.log(msg); |
||||||
|
}); |
||||||
|
await mainWindow.loadFile(__dirname + '/config.html'); |
||||||
|
mainWindow.show(); |
||||||
|
}; |
||||||
|
|
||||||
|
app.whenReady().then(() => { |
||||||
|
createMain(); |
||||||
|
}); |
||||||
|
|
||||||
|
app.on('window-all-closed', () => { |
||||||
|
if (process.platform !== 'darwin') { |
||||||
|
app.quit(); |
||||||
|
} |
||||||
|
}); |
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,24 @@ |
|||||||
|
{ |
||||||
|
"name": "sniffer", |
||||||
|
"version": "1.0.0", |
||||||
|
"description": "CatVodeOpen sniffer", |
||||||
|
"main": "index.js", |
||||||
|
"scripts": { |
||||||
|
"start": "electron index.js" |
||||||
|
}, |
||||||
|
"author": "Simon", |
||||||
|
"license": "ISC", |
||||||
|
"devDependencies": {}, |
||||||
|
"build": { |
||||||
|
"win": { |
||||||
|
"target": "dir", |
||||||
|
"icon": "./app_icon.ico" |
||||||
|
} |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"electron": "^21.2.2", |
||||||
|
"puppeteer-core": "^19.2.2", |
||||||
|
"puppeteer-in-electron": "^3.0.5", |
||||||
|
"electron-store": "^8.1.0" |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue