recycle already loaded modules when possible
This commit is contained in:
@@ -5,10 +5,11 @@ require(classPath + "Prototypes.js");
|
|||||||
const { WTVShared, clientShowAlert } = require(classPath + "WTVShared.js");
|
const { WTVShared, clientShowAlert } = require(classPath + "WTVShared.js");
|
||||||
const wtvshared = new WTVShared(); // creates minisrv_config
|
const wtvshared = new WTVShared(); // creates minisrv_config
|
||||||
|
|
||||||
const fs = require('fs');
|
const fs = wtvshared.fs;
|
||||||
|
const zlib = wtvshared.zlib;
|
||||||
|
const process = wtvshared.process;
|
||||||
const util = require('util');
|
const util = require('util');
|
||||||
const nunjucks = require('nunjucks');
|
const nunjucks = require('nunjucks');
|
||||||
const zlib = require('zlib');
|
|
||||||
const {serialize, unserialize} = require('php-serialize');
|
const {serialize, unserialize} = require('php-serialize');
|
||||||
const {spawn} = require('child_process');
|
const {spawn} = require('child_process');
|
||||||
const http = require('follow-redirects').http;
|
const http = require('follow-redirects').http;
|
||||||
@@ -18,7 +19,6 @@ const net = require('net');
|
|||||||
const crypto = require('crypto')
|
const crypto = require('crypto')
|
||||||
const CryptoJS = require('crypto-js');
|
const CryptoJS = require('crypto-js');
|
||||||
const sharp = require('sharp')
|
const sharp = require('sharp')
|
||||||
const process = require('process');
|
|
||||||
const WTVSec = require(classPath + "/WTVSec.js");
|
const WTVSec = require(classPath + "/WTVSec.js");
|
||||||
const WTVSSL = require(classPath + "/WTVSSL.js");
|
const WTVSSL = require(classPath + "/WTVSSL.js");
|
||||||
const LZPF = require(classPath + "/LZPF.js");
|
const LZPF = require(classPath + "/LZPF.js");
|
||||||
@@ -2287,7 +2287,7 @@ Object.keys(minisrv_config.services).forEach(function (k) {
|
|||||||
let extraVar = eval(minisrv_config.services[k].handler_extra_vars[i]);
|
let extraVar = eval(minisrv_config.services[k].handler_extra_vars[i]);
|
||||||
args.push(extraVar);
|
args.push(extraVar);
|
||||||
}
|
}
|
||||||
const constructorArgs = [minisrv_config, k, wtvshared, sendToClient, ...args];
|
const constructorArgs = [minisrv_config, k, wtvshared, sendToClient, net, ...args];
|
||||||
handlerModules[minisrv_config.services[k].handler_module.toLowerCase()] = new handlerModules[minisrv_config.services[k].handler_module + "_main"](...constructorArgs);
|
handlerModules[minisrv_config.services[k].handler_module.toLowerCase()] = new handlerModules[minisrv_config.services[k].handler_module + "_main"](...constructorArgs);
|
||||||
}
|
}
|
||||||
loadedModule = true;
|
loadedModule = true;
|
||||||
|
|||||||
@@ -11,10 +11,7 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const net = require('net');
|
|
||||||
const dgram = require('dgram');
|
const dgram = require('dgram');
|
||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
const MMS_MAGIC = 0xB00BFACE;
|
const MMS_MAGIC = 0xB00BFACE;
|
||||||
const MMS_PROTOCOL = 0x20534D4D; // "MMS " little-endian
|
const MMS_PROTOCOL = 0x20534D4D; // "MMS " little-endian
|
||||||
@@ -71,9 +68,9 @@ class WTVMMS {
|
|||||||
udpServer = null;
|
udpServer = null;
|
||||||
udpServerReady = false;
|
udpServerReady = false;
|
||||||
wtvshared = null;
|
wtvshared = null;
|
||||||
sessions = new Map();
|
sessions = new Map();
|
||||||
|
|
||||||
constructor(minisrv_config, service_name, wtvshared) {
|
constructor(minisrv_config, service_name, wtvshared, sendToClient, net) {
|
||||||
this.minisrv_config = minisrv_config;
|
this.minisrv_config = minisrv_config;
|
||||||
this.service_name = service_name;
|
this.service_name = service_name;
|
||||||
this.service_config = minisrv_config.services[service_name] || {};
|
this.service_config = minisrv_config.services[service_name] || {};
|
||||||
@@ -147,7 +144,7 @@ class WTVMMS {
|
|||||||
const base = this.wtvshared.getAbsolutePath(serviceVaultDir, vault);
|
const base = this.wtvshared.getAbsolutePath(serviceVaultDir, vault);
|
||||||
for (const variant of variants) {
|
for (const variant of variants) {
|
||||||
const candidate = this.wtvshared.makeSafePath(base, variant);
|
const candidate = this.wtvshared.makeSafePath(base, variant);
|
||||||
if (candidate && fs.existsSync(candidate) && fs.lstatSync(candidate).isFile()) {
|
if (candidate && this.wtvshared.fs.existsSync(candidate) && this.wtvshared.fs.lstatSync(candidate).isFile()) {
|
||||||
this.debugLog('media resolved', variant, '->', candidate);
|
this.debugLog('media resolved', variant, '->', candidate);
|
||||||
return candidate;
|
return candidate;
|
||||||
}
|
}
|
||||||
@@ -158,7 +155,7 @@ class WTVMMS {
|
|||||||
|
|
||||||
_mediaVariants(media) {
|
_mediaVariants(media) {
|
||||||
const p = media.replace(/\\/g, '/').replace(/^\/+/, '');
|
const p = media.replace(/\\/g, '/').replace(/^\/+/, '');
|
||||||
const ext = path.posix.extname(p).toLowerCase();
|
const ext = this.wtvshared.path.posix.extname(p).toLowerCase();
|
||||||
const stem = ext ? p.slice(0, -ext.length) : p;
|
const stem = ext ? p.slice(0, -ext.length) : p;
|
||||||
const list = [p];
|
const list = [p];
|
||||||
// Accept both .wma and .asf for the same stem
|
// Accept both .wma and .asf for the same stem
|
||||||
@@ -247,14 +244,14 @@ class WTVMMS {
|
|||||||
|
|
||||||
socket.on('close', () => {
|
socket.on('close', () => {
|
||||||
this._stopStream(session);
|
this._stopStream(session);
|
||||||
if (session.asfFd !== null) { try { fs.closeSync(session.asfFd); } catch(_){} session.asfFd = null; }
|
if (session.asfFd !== null) { try { this.wtvshared.fs.closeSync(session.asfFd); } catch(_){} session.asfFd = null; }
|
||||||
this.sessions.delete(socket);
|
this.sessions.delete(socket);
|
||||||
this.debugLog('client disconnected', session.id, 'tx=' + session.bytesTx);
|
this.debugLog('client disconnected', session.id, 'tx=' + session.bytesTx);
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('error', (err) => {
|
socket.on('error', (err) => {
|
||||||
this._stopStream(session);
|
this._stopStream(session);
|
||||||
if (session.asfFd !== null) { try { fs.closeSync(session.asfFd); } catch(_){} session.asfFd = null; }
|
if (session.asfFd !== null) { try { this.wtvshared.fs.closeSync(session.asfFd); } catch(_){} session.asfFd = null; }
|
||||||
this.sessions.delete(socket);
|
this.sessions.delete(socket);
|
||||||
this.debugLog('socket error', session.id, err.message);
|
this.debugLog('socket error', session.id, err.message);
|
||||||
});
|
});
|
||||||
@@ -619,15 +616,15 @@ class WTVMMS {
|
|||||||
if (!session.mediaPath) return;
|
if (!session.mediaPath) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const stat = fs.statSync(session.mediaPath);
|
const stat = this.wtvshared.fs.statSync(session.mediaPath);
|
||||||
session.asfFileSize = stat.size;
|
session.asfFileSize = stat.size;
|
||||||
|
|
||||||
// Read first 64 KB to find ASF header objects
|
// Read first 64 KB to find ASF header objects
|
||||||
const readLen = Math.min(65536, stat.size);
|
const readLen = Math.min(65536, stat.size);
|
||||||
const buf = Buffer.alloc(readLen);
|
const buf = Buffer.alloc(readLen);
|
||||||
const fd = fs.openSync(session.mediaPath, 'r');
|
const fd = this.wtvshared.fs.openSync(session.mediaPath, 'r');
|
||||||
fs.readSync(fd, buf, 0, readLen, 0);
|
this.wtvshared.fs.readSync(fd, buf, 0, readLen, 0);
|
||||||
fs.closeSync(fd);
|
this.wtvshared.fs.closeSync(fd);
|
||||||
|
|
||||||
// ASF Header Object GUID: {75B22630-668E-11CF-A6D9-00AA0062CE6C}
|
// ASF Header Object GUID: {75B22630-668E-11CF-A6D9-00AA0062CE6C}
|
||||||
const ASF_HEADER_GUID = Buffer.from([
|
const ASF_HEADER_GUID = Buffer.from([
|
||||||
@@ -725,9 +722,9 @@ class WTVMMS {
|
|||||||
try {
|
try {
|
||||||
const headerLength = Math.min(session.asfFileSize, session.asfDataOffset + 50);
|
const headerLength = Math.min(session.asfFileSize, session.asfDataOffset + 50);
|
||||||
const buf = Buffer.alloc(headerLength);
|
const buf = Buffer.alloc(headerLength);
|
||||||
const fd = fs.openSync(session.mediaPath, 'r');
|
const fd = this.wtvshared.fs.openSync(session.mediaPath, 'r');
|
||||||
fs.readSync(fd, buf, 0, headerLength, 0);
|
this.wtvshared.fs.readSync(fd, buf, 0, headerLength, 0);
|
||||||
fs.closeSync(fd);
|
this.wtvshared.fs.closeSync(fd);
|
||||||
return buf;
|
return buf;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('[WTVMMS] ASF header read error', e.message);
|
console.error('[WTVMMS] ASF header read error', e.message);
|
||||||
@@ -801,7 +798,7 @@ class WTVMMS {
|
|||||||
'burstMultiplier=' + session.burstMultiplier);
|
'burstMultiplier=' + session.burstMultiplier);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
session.asfFd = fs.openSync(session.mediaPath, 'r');
|
session.asfFd = this.wtvshared.fs.openSync(session.mediaPath, 'r');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('[WTVMMS] failed to open media for streaming', e.message);
|
console.error('[WTVMMS] failed to open media for streaming', e.message);
|
||||||
session.streaming = false;
|
session.streaming = false;
|
||||||
@@ -845,7 +842,7 @@ class WTVMMS {
|
|||||||
session.drainHandler = null;
|
session.drainHandler = null;
|
||||||
session.waitingForDrain = false;
|
session.waitingForDrain = false;
|
||||||
if (session.asfFd !== null) {
|
if (session.asfFd !== null) {
|
||||||
try { fs.closeSync(session.asfFd); } catch(_){}
|
try { this.wtvshared.fs.closeSync(session.asfFd); } catch(_){}
|
||||||
session.asfFd = null;
|
session.asfFd = null;
|
||||||
}
|
}
|
||||||
session.packetQueue = [];
|
session.packetQueue = [];
|
||||||
@@ -970,7 +967,7 @@ class WTVMMS {
|
|||||||
|
|
||||||
let bytesRead = 0;
|
let bytesRead = 0;
|
||||||
try {
|
try {
|
||||||
bytesRead = fs.readSync(session.asfFd, buf, 0, pktSize, session._readPos);
|
bytesRead = this.wtvshared.fs.readSync(session.asfFd, buf, 0, pktSize, session._readPos);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.debugLog('read error', session.id, e.message);
|
this.debugLog('read error', session.id, e.message);
|
||||||
this._endStream(socket, session);
|
this._endStream(socket, session);
|
||||||
|
|||||||
@@ -15,8 +15,6 @@
|
|||||||
// The client validates this challenge by calculating the server challenge and its own client challenge to produce a final hash, which it sends back to the server.
|
// The client validates this challenge by calculating the server challenge and its own client challenge to produce a final hash, which it sends back to the server.
|
||||||
// If the hash matches, the client is authenticated and the server starts sending UDP packets.
|
// If the hash matches, the client is authenticated and the server starts sending UDP packets.
|
||||||
|
|
||||||
const net = require('net');
|
|
||||||
const crypto = require('crypto');
|
|
||||||
const dgram = require('dgram');
|
const dgram = require('dgram');
|
||||||
|
|
||||||
class WTVPNM {
|
class WTVPNM {
|
||||||
@@ -27,7 +25,7 @@ class WTVPNM {
|
|||||||
wtvshared = null;
|
wtvshared = null;
|
||||||
sessions = new Map();
|
sessions = new Map();
|
||||||
|
|
||||||
constructor(...[minisrv_config, service_name, wtvshared, sendToClient]) {
|
constructor(...[minisrv_config, service_name, wtvshared, sendToClient, net, crypto]) {
|
||||||
this.minisrv_config = minisrv_config;
|
this.minisrv_config = minisrv_config;
|
||||||
this.service_name = service_name;
|
this.service_name = service_name;
|
||||||
this.service_config = minisrv_config.services[service_name] || {};
|
this.service_config = minisrv_config.services[service_name] || {};
|
||||||
|
|||||||
@@ -466,7 +466,8 @@
|
|||||||
"allow_indexing": true,
|
"allow_indexing": true,
|
||||||
"debug": false,
|
"debug": false,
|
||||||
"handler_module": "WTVPNM",
|
"handler_module": "WTVPNM",
|
||||||
"handler_handles_port": true
|
"handler_handles_port": true,
|
||||||
|
"handler_extra_vars": ["crypto"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"favorites": {
|
"favorites": {
|
||||||
|
|||||||
Reference in New Issue
Block a user