2021-01-02 13:10:00 -05:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
function App() {
|
|
|
|
this._on_output = null;
|
|
|
|
this._send_queue = [];
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
App.prototype.readOutput = function(callback) {
|
|
|
|
this._on_output = callback;
|
|
|
|
}
|
|
|
|
|
|
|
|
App.prototype.makeFunction = function(api) {
|
|
|
|
let self = this;
|
|
|
|
let result = function() {
|
|
|
|
let message = {action: api[0]};
|
|
|
|
for (let i = 1; i < api.length; i++) {
|
|
|
|
message[api[i]] = arguments[i - 1];
|
|
|
|
}
|
|
|
|
self.send(message);
|
|
|
|
};
|
|
|
|
Object.defineProperty(result, 'name', {value: api[0], writable: false});
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
App.prototype.send = function(message) {
|
|
|
|
if (message) {
|
|
|
|
this._send_queue.push(message);
|
|
|
|
}
|
|
|
|
if (this._on_output) {
|
|
|
|
this._send_queue.forEach(message => this._on_output(message));
|
|
|
|
this._send_queue = [];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function socket(request, response, client) {
|
|
|
|
var process;
|
|
|
|
var options = {};
|
|
|
|
var credentials = auth.query(request.headers);
|
|
|
|
|
2022-01-20 19:49:03 -05:00
|
|
|
response.onClose = async function() {
|
|
|
|
if (process && process.task) {
|
|
|
|
process.task.kill();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
response.onError = async function(error) {
|
|
|
|
if (process && process.task) {
|
|
|
|
process.task.kill();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-02 13:10:00 -05:00
|
|
|
response.onMessage = async function(event) {
|
|
|
|
if (event.opCode == 0x1 || event.opCode == 0x2) {
|
|
|
|
var message;
|
|
|
|
try {
|
|
|
|
message = JSON.parse(event.data);
|
|
|
|
} catch (error) {
|
|
|
|
print("ERROR", error, event.data, event.data.length, event.opCode);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (message.action == "hello") {
|
|
|
|
var packageOwner;
|
|
|
|
var packageName;
|
|
|
|
var blobId;
|
|
|
|
var match;
|
2022-01-30 09:51:09 -05:00
|
|
|
var parentApp;
|
2021-01-09 18:06:33 -05:00
|
|
|
if (match = /^\/([&%][^\.]{44}(?:\.\w+)?)(\/?.*)/.exec(message.path)) {
|
2021-01-02 13:10:00 -05:00
|
|
|
blobId = match[1];
|
|
|
|
} else if (match = /^\/\~([^\/]+)\/([^\/]+)\/$/.exec(message.path)) {
|
|
|
|
var user = match[1];
|
|
|
|
var path = match[2];
|
|
|
|
blobId = await new Database(user).get('path:' + path);
|
|
|
|
if (!blobId) {
|
|
|
|
response.send(JSON.stringify({action: "error", error: message.path + ' not found'}), 0x1);
|
2022-01-17 21:50:46 -05:00
|
|
|
return;
|
2021-01-02 13:10:00 -05:00
|
|
|
}
|
2022-01-30 09:51:09 -05:00
|
|
|
if (user != 'core') {
|
|
|
|
var coreId = await new Database('core').get('path:' + path);
|
|
|
|
parentApp = {
|
|
|
|
path: '/~core/' + path + '/',
|
|
|
|
id: coreId,
|
|
|
|
};
|
|
|
|
}
|
2021-01-02 13:10:00 -05:00
|
|
|
}
|
2022-01-30 09:51:09 -05:00
|
|
|
response.send(JSON.stringify({
|
|
|
|
action: "session",
|
|
|
|
credentials: credentials,
|
|
|
|
parentApp: parentApp,
|
|
|
|
id: blobId,
|
|
|
|
}), 0x1);
|
2021-01-02 13:10:00 -05:00
|
|
|
|
|
|
|
options.api = message.api || [];
|
|
|
|
options.credentials = credentials;
|
|
|
|
var sessionId = makeSessionId();
|
|
|
|
if (blobId) {
|
|
|
|
process = await getSessionProcessBlob(blobId, sessionId, options);
|
|
|
|
}
|
|
|
|
if (process) {
|
|
|
|
process.app.readOutput(function(message) {
|
|
|
|
response.send(JSON.stringify(message), 0x1);
|
|
|
|
});
|
|
|
|
process.app.send();
|
|
|
|
}
|
|
|
|
|
|
|
|
var ping = function() {
|
|
|
|
var now = Date.now();
|
|
|
|
var again = true;
|
|
|
|
if (now - process.lastActive < process.timeout) {
|
|
|
|
// Active.
|
|
|
|
} else if (process.lastPing > process.lastActive) {
|
|
|
|
// We lost them.
|
|
|
|
if (process.task) {
|
|
|
|
process.task.kill();
|
|
|
|
}
|
|
|
|
again = false;
|
|
|
|
} else {
|
|
|
|
// Idle. Ping them.
|
|
|
|
response.send("", 0x9);
|
|
|
|
process.lastPing = now;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (again) {
|
|
|
|
setTimeout(ping, process.timeout);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (process && process.timeout > 0) {
|
|
|
|
setTimeout(ping, process.timeout);
|
|
|
|
}
|
2022-02-26 16:17:15 -05:00
|
|
|
} else if (message.action == 'enableStats') {
|
2022-03-07 16:06:20 -05:00
|
|
|
if (process) {
|
|
|
|
process.stats = message.enabled;
|
|
|
|
if (!gStatsTimer) {
|
|
|
|
sendStats();
|
|
|
|
gStatsTimer = true;
|
|
|
|
}
|
2022-02-26 16:17:15 -05:00
|
|
|
}
|
2021-01-02 13:10:00 -05:00
|
|
|
} else {
|
|
|
|
if (process && process.eventHandlers['message']) {
|
|
|
|
await invoke(process.eventHandlers['message'], [message]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (event.opCode == 0x8) {
|
|
|
|
// Close.
|
2022-01-20 19:49:03 -05:00
|
|
|
if (process && process.task) {
|
2021-01-02 13:10:00 -05:00
|
|
|
process.task.kill();
|
|
|
|
}
|
|
|
|
response.send(event.data, 0x8);
|
|
|
|
} else if (event.opCode == 0xa) {
|
|
|
|
// PONG
|
|
|
|
}
|
|
|
|
|
|
|
|
if (process) {
|
|
|
|
process.lastActive = Date.now();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
exports.socket = socket;
|