mirror of
https://github.com/imputnet/cobalt.git
synced 2025-07-18 03:08:30 +00:00
Merge branch 'wukko:current' into current
This commit is contained in:
commit
ca34525fac
@ -131,14 +131,14 @@ export function runAPI(express, app, gitCommit, gitBranch, __dirname) {
|
|||||||
const checkBaseLength = q.t.length === 21 && q.e.length === 13;
|
const checkBaseLength = q.t.length === 21 && q.e.length === 13;
|
||||||
const checkSafeLength = q.h.length === 43 && q.s.length === 43 && q.i.length === 22;
|
const checkSafeLength = q.h.length === 43 && q.s.length === 43 && q.i.length === 22;
|
||||||
if (checkQueries && checkBaseLength && checkSafeLength) {
|
if (checkQueries && checkBaseLength && checkSafeLength) {
|
||||||
let streamInfo = verifyStream(q.t, q.h, q.e, q.s, q.i);
|
|
||||||
if (streamInfo.error) {
|
|
||||||
return res.status(streamInfo.status).json(apiJSON(0, { t: streamInfo.error }).body);
|
|
||||||
}
|
|
||||||
if (q.p) {
|
if (q.p) {
|
||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
status: "continue"
|
status: "continue"
|
||||||
});
|
})
|
||||||
|
}
|
||||||
|
let streamInfo = verifyStream(q.t, q.h, q.e, q.s, q.i);
|
||||||
|
if (streamInfo.error) {
|
||||||
|
return res.status(streamInfo.status).json(apiJSON(0, { t: streamInfo.error }).body);
|
||||||
}
|
}
|
||||||
return stream(res, streamInfo);
|
return stream(res, streamInfo);
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ import { decryptStream, encryptStream, generateHmac } from "../sub/crypto.js";
|
|||||||
import { streamLifespan } from "../config.js";
|
import { streamLifespan } from "../config.js";
|
||||||
import { strict as assert } from "assert";
|
import { strict as assert } from "assert";
|
||||||
|
|
||||||
|
const M3U_SERVICES = ['dailymotion', 'vimeo', 'rutube'];
|
||||||
|
|
||||||
const streamNoAccess = {
|
const streamNoAccess = {
|
||||||
error: "i couldn't verify if you have access to this stream. go back and try again!",
|
error: "i couldn't verify if you have access to this stream. go back and try again!",
|
||||||
status: 401
|
status: 401
|
||||||
@ -73,24 +75,28 @@ export function getInternalStream(id) {
|
|||||||
return internalStreamCache[id];
|
return internalStreamCache[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createInternalStream(obj = {}) {
|
export function createInternalStream(url, obj = {}) {
|
||||||
assert(typeof obj.url === 'string');
|
assert(typeof url === 'string');
|
||||||
|
|
||||||
const streamID = nanoid();
|
const streamID = nanoid();
|
||||||
internalStreamCache[streamID] = {
|
internalStreamCache[streamID] = {
|
||||||
url: obj.url,
|
url,
|
||||||
service: obj.service,
|
service: obj.service,
|
||||||
controller: new AbortController()
|
controller: new AbortController()
|
||||||
};
|
};
|
||||||
|
|
||||||
let streamLink = new URL('/api/istream', `http://127.0.0.1:${process.env.API_PORT}`);
|
let streamLink = new URL('/api/istream', `http://127.0.0.1:${process.env.API_PORT || 9000}`);
|
||||||
streamLink.searchParams.set('t', streamID);
|
streamLink.searchParams.set('t', streamID);
|
||||||
return streamLink.toString();
|
return streamLink.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function destroyInternalStream(url) {
|
export function destroyInternalStream(url) {
|
||||||
const id = new URL(url).searchParams.get('t');
|
url = new URL(url);
|
||||||
assert(id);
|
if (url.hostname !== '127.0.0.1') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const id = url.searchParams.get('t');
|
||||||
|
|
||||||
if (internalStreamCache[id]) {
|
if (internalStreamCache[id]) {
|
||||||
internalStreamCache[id].controller.abort();
|
internalStreamCache[id].controller.abort();
|
||||||
@ -98,6 +104,28 @@ export function destroyInternalStream(url) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function wrapStream(streamInfo) {
|
||||||
|
/* m3u8 links are currently not supported
|
||||||
|
* for internal streams, skip them */
|
||||||
|
if (M3U_SERVICES.includes(streamInfo.service)) {
|
||||||
|
return streamInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = streamInfo.urls;
|
||||||
|
|
||||||
|
if (typeof url === 'string') {
|
||||||
|
streamInfo.urls = createInternalStream(url, streamInfo);
|
||||||
|
} else if (Array.isArray(url)) {
|
||||||
|
for (const idx in streamInfo.urls) {
|
||||||
|
streamInfo.urls[idx] = createInternalStream(
|
||||||
|
streamInfo.urls[idx], streamInfo
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else throw 'invalid urls';
|
||||||
|
|
||||||
|
return streamInfo;
|
||||||
|
}
|
||||||
|
|
||||||
export function verifyStream(id, hmac, exp, secret, iv) {
|
export function verifyStream(id, hmac, exp, secret, iv) {
|
||||||
try {
|
try {
|
||||||
const ghmac = generateHmac(`${id},${exp},${iv},${secret}`, hmacSalt);
|
const ghmac = generateHmac(`${id},${exp},${iv},${secret}`, hmacSalt);
|
||||||
@ -113,25 +141,7 @@ export function verifyStream(id, hmac, exp, secret, iv) {
|
|||||||
if (Number(exp) <= new Date().getTime())
|
if (Number(exp) <= new Date().getTime())
|
||||||
return streamNoExist;
|
return streamNoExist;
|
||||||
|
|
||||||
if (!streamInfo.originalUrls) {
|
return wrapStream(streamInfo);
|
||||||
streamInfo.originalUrls = streamInfo.urls;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof streamInfo.originalUrls === 'string') {
|
|
||||||
streamInfo.urls = createInternalStream({
|
|
||||||
url: streamInfo.originalUrls,
|
|
||||||
...streamInfo
|
|
||||||
});
|
|
||||||
} else if (Array.isArray(streamInfo.originalUrls)) {
|
|
||||||
for (const idx in streamInfo.originalUrls) {
|
|
||||||
streamInfo.originalUrls[idx] = createInternalStream({
|
|
||||||
url: streamInfo.originalUrls[idx],
|
|
||||||
...streamInfo
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else throw 'invalid urls';
|
|
||||||
|
|
||||||
return streamInfo;
|
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
return {
|
return {
|
||||||
|
Loading…
Reference in New Issue
Block a user