mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-06 00:13:33 +00:00
Many improvements.
This commit is contained in:
122
Debug/PE.js
Normal file
122
Debug/PE.js
Normal file
@@ -0,0 +1,122 @@
|
||||
// JavaScript source code
|
||||
|
||||
var fs = require('fs');
|
||||
//var buffer = fs.readFileSync('test.bin');
|
||||
//var tls = require('tls');
|
||||
|
||||
//var pem = tls.loadpkcs7b(buffer);
|
||||
//console.log(pem.toString());
|
||||
|
||||
|
||||
|
||||
|
||||
var fd = fs.openSync(process.execPath.replace('MeshConsole', 'MC2'), 'rb+');
|
||||
var bytesRead;
|
||||
var dosHeader = new Buffer(64);
|
||||
var ntHeader = new Buffer(24);
|
||||
var optHeader;
|
||||
|
||||
console.log(process.execPath.replace('MeshConsole', 'MC2'));
|
||||
|
||||
bytesRead = fs.readSync(fd, dosHeader, 0, 64, 0);
|
||||
if (dosHeader.readUInt16LE(0).toString(16).toUpperCase() != '5A4D')
|
||||
{
|
||||
console.log('unrecognized binary format');
|
||||
}
|
||||
|
||||
bytesRead = fs.readSync(fd, ntHeader, 0, ntHeader.length, dosHeader.readUInt32LE(60));
|
||||
|
||||
if (ntHeader.slice(0, 4).toString('hex') != '50450000')
|
||||
{
|
||||
console.log('not PE format');
|
||||
}
|
||||
|
||||
switch (ntHeader.readUInt16LE(4).toString(16))
|
||||
{
|
||||
case '14c':
|
||||
console.log('x86 binary');
|
||||
break;
|
||||
case '8664':
|
||||
console.log('x64 binary');
|
||||
break;
|
||||
default:
|
||||
console.log('unknown binary type');
|
||||
break;
|
||||
}
|
||||
|
||||
console.log('Optional Size = ' + ntHeader.readUInt16LE(20) + 'bytes');
|
||||
optHeader = new Buffer(ntHeader.readUInt16LE(20));
|
||||
bytesRead = fs.readSync(fd, optHeader, 0, optHeader.length, dosHeader.readUInt32LE(60) + 24);
|
||||
var numRVA = undefined;
|
||||
var CertificateTableAddress = undefined;
|
||||
var CertificateTableSize = undefined;
|
||||
|
||||
switch (optHeader.readUInt16LE(0).toString(16).toUpperCase())
|
||||
{
|
||||
case '10B':
|
||||
console.log('Found IMAGE_NT_OPTIONAL_HDR32_MAGIC');
|
||||
numRVA = optHeader.readUInt32LE(92);
|
||||
CertificateTableAddress = optHeader.readUInt32LE(128);
|
||||
CertificateTableSize = optHeader.readUInt32LE(132);
|
||||
break;
|
||||
case '20B':
|
||||
console.log('Found IMAGE_NT_OPTIONAL_HDR64_MAGIC');
|
||||
numRVA = optHeader.readUInt32LE(108);
|
||||
CertificateTableAddress = optHeader.readUInt32LE(144);
|
||||
CertificateTableSize = optHeader.readUInt32LE(148);
|
||||
break;
|
||||
default:
|
||||
console.log('Unknown Value found for Optional Magic: ' + ntHeader.readUInt16LE(24).toString(16).toUpperCase());
|
||||
break;
|
||||
}
|
||||
|
||||
console.log('Number of RVA Entries: ' + numRVA.toString());
|
||||
console.log('Certificate Table Address: ' + CertificateTableAddress.toString(16).toUpperCase());
|
||||
console.log('Certificate Table Size: ' + CertificateTableSize.toString());
|
||||
|
||||
var hdr = new Buffer(8);
|
||||
fs.readSync(fd, hdr, 0, hdr.length, CertificateTableAddress);
|
||||
console.log('dwLength = ' + hdr.readUInt32LE(0).toString());
|
||||
|
||||
console.log('Updating Table Entries: ');
|
||||
optHeader.writeUInt32LE(6848, 132);
|
||||
hdr.writeUInt32LE(6848, 0);
|
||||
|
||||
console.log('written', fs.writeSync(fd, optHeader, 0, optHeader.length, dosHeader.readUInt32LE(60) + 24));
|
||||
console.log('written', fs.writeSync(fd, hdr, 0, hdr.length, CertificateTableAddress));
|
||||
|
||||
console.log('Done!');
|
||||
|
||||
|
||||
fs.closeSync(fd);
|
||||
|
||||
//switch (hdr.readUInt16LE(6).toString(16).toUpperCase())
|
||||
//{
|
||||
// case '1':
|
||||
// console.log('Cert Type = X509');
|
||||
// break;
|
||||
// case '2':
|
||||
// console.log('Cert Type = PKCS#7')
|
||||
// break;
|
||||
// case '3':
|
||||
// console.log('Cert Type = RESERVED')
|
||||
// break;
|
||||
// case '4':
|
||||
// console.log('Cert Type = TERMINAL_SERVER')
|
||||
// break;
|
||||
//}
|
||||
|
||||
//var cert = new Buffer(hdr.readUInt32LE(0) - 8);
|
||||
//fs.readSync(fd, cert, 0, cert.length, CertificateTableAddress + hdr.length);
|
||||
|
||||
//console.log('Cert Length: ' + cert.length);
|
||||
//console.log(cert.toString());
|
||||
|
||||
//console.log(1);
|
||||
//var ws = fs.createWriteStream("test.txt", { flags: "wb" });
|
||||
//ws.write(cert);
|
||||
//console.log(2);
|
||||
//ws.end();
|
||||
//console.log(3);
|
||||
|
||||
|
||||
50
Debug/PostBuild.js
Normal file
50
Debug/PostBuild.js
Normal file
@@ -0,0 +1,50 @@
|
||||
// JavaScript source code
|
||||
|
||||
console.log('Running Post Build Step....');
|
||||
|
||||
var fs = require('fs');
|
||||
var hash = require('SHA384Stream').create();
|
||||
|
||||
var stream1;
|
||||
var stream2;
|
||||
var pending;
|
||||
|
||||
hash.on('hashString', function (h)
|
||||
{
|
||||
if (process.platform == 'win32') {
|
||||
pending = 2;
|
||||
var newFileName = process.execPath.substring(0, process.execPath.length - 4) + "_" + h.substring(0, 16) + ".exe";
|
||||
var pdbFileName = process.execPath.substring(0, process.execPath.length - 4) + '.pdb';
|
||||
var newPdbFileName = process.execPath.substring(0, process.execPath.length - 4) + "_" + h.substring(0, 16) + ".pdb";
|
||||
|
||||
console.log(process.execPath + ' => ' + newFileName);
|
||||
console.log(pdbFileName + ' => ' + newPdbFileName);
|
||||
|
||||
stream1 = fs.createReadStream(process.execPath, { flags: "rb" });
|
||||
stream1.output = fs.createWriteStream(newFileName, { flags: "wb+" });
|
||||
stream1.output.on('finish', OnFinish);
|
||||
stream1.pipe(stream1.output);
|
||||
|
||||
stream2 = fs.createReadStream(pdbFileName, { flags: "rb" });
|
||||
stream2.output = fs.createWriteStream(newPdbFileName, { flags: "wb+" });
|
||||
stream2.output.on('finish', OnFinish);
|
||||
stream2.pipe(stream2.output);
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log(process.platform + ' is not supported');
|
||||
process.exit();
|
||||
}
|
||||
});
|
||||
|
||||
function OnFinish()
|
||||
{
|
||||
if (--pending == 0)
|
||||
{
|
||||
console.log('Finished!');
|
||||
process.exit();
|
||||
}
|
||||
}
|
||||
|
||||
var exeStream = fs.createReadStream(process.execPath, { flags: "rb" });
|
||||
exeStream.pipe(hash);
|
||||
@@ -17,7 +17,7 @@
|
||||
function start()
|
||||
{
|
||||
debug("Connecting signaling channel...");
|
||||
wsocket = new WebSocket("ws://127.0.0.1:8585/control");
|
||||
wsocket = new WebSocket("ws://192.168.5.128:8585/control");
|
||||
wsocket.binaryType = "arraybuffer";
|
||||
wsocket.onopen = function (evt)
|
||||
{
|
||||
@@ -33,7 +33,7 @@
|
||||
debug("Received WebRTC Offer...");
|
||||
|
||||
var ax = null;
|
||||
if (typeof mozRTCSessionDescription !== 'undefined') { ax = new mozRTCSessionDescription({ type: "answer", sdp: cmd.data }) } else { ax = new RTCSessionDescription({ type: "answer", sdp: cmd.data }) }
|
||||
if (typeof mozRTCSessionDescription !== 'undefined') { ax = new mozRTCSessionDescription({ type: "offer", sdp: cmd.data }) } else { ax = new RTCSessionDescription({ type: "offer", sdp: cmd.data }) }
|
||||
connection.setRemoteDescription(ax, onSetRemoteDescriptionDone, onError);
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
function onSetRemoteDescriptionDone()
|
||||
{
|
||||
//connection.createAnswer(onAnswerDone, onError);
|
||||
connection.createAnswer(onAnswerDone, onError);
|
||||
}
|
||||
function onAnswerDone(answer)
|
||||
{
|
||||
@@ -61,13 +61,7 @@
|
||||
|
||||
connection.ondatachannel = onDataChannel
|
||||
connection.onicecandidate = onIceCandidate;
|
||||
|
||||
datachannel = connection.createDataChannel("browserDataChannel", {});
|
||||
datachannel.onmessage = function (event) { debug("Remote: " + event.data); };
|
||||
datachannel.onopen = function () { debug("browserDataChannel Connected."); };
|
||||
datachannel.onclose = function (event) { debug("DataChannel was closed by remote"); }
|
||||
|
||||
connection.createOffer(onOfferDone, onError, { mandatory: { OfferToReceiveAudio: false, OfferToReceiveVideo: false } });
|
||||
connection.oniceconnectionstatechange = function () { if (connection != null) { if ((connection.iceConnectionState == 'disconnected') || (connection.iceConnectionState == 'failed')) { debug("WTF Happened?"); } } }
|
||||
}
|
||||
function onOfferDone(offer)
|
||||
{
|
||||
@@ -83,15 +77,15 @@
|
||||
datachannel.binaryType = "arraybuffer";
|
||||
datachannel.onmessage = function (msg)
|
||||
{
|
||||
try
|
||||
{
|
||||
datachannel.send(msg.data.byteLength.toString());
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
debug(e.toString());
|
||||
debug(msg.data.toString());
|
||||
}
|
||||
//try
|
||||
//{
|
||||
// datachannel.send(msg.data.byteLength.toString() + 'bytes of ' + msg.data[0].toString());
|
||||
//}
|
||||
//catch(e)
|
||||
//{
|
||||
// debug(e.toString());
|
||||
// //debug(msg.data.toString());
|
||||
//}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
console.enableWebLog(9595);
|
||||
var mesh = null;
|
||||
var kvmStream = null;
|
||||
var Readable = require('stream').Readable;
|
||||
var RS = new Readable({
|
||||
read: function (options)
|
||||
{
|
||||
var min = 62000;
|
||||
var max = 65535;
|
||||
var size = Math.floor(Math.random() * (max - min)) + min;
|
||||
var retVal = Buffer.alloc(size).fill(this.val++);
|
||||
retVal.writeUInt32BE(size, 0);
|
||||
if (this.val == 10) { this.val = 0; }
|
||||
return (retVal);
|
||||
}
|
||||
});
|
||||
RS.val = 0;
|
||||
|
||||
var http = require('http');
|
||||
var rtc = require('ILibWebRTC');
|
||||
@@ -6,12 +23,30 @@ var signalingChannel;
|
||||
var dc;
|
||||
|
||||
var webServer = http.createServer(OnLocalWebRequest);
|
||||
var processMgr = require('ILibProcessPipe');
|
||||
|
||||
var childprocess = require('child_process');
|
||||
var p;
|
||||
|
||||
webServer.on('upgrade', OnUpgrade);
|
||||
webServer.listen(8585);
|
||||
//p = processMgr.CreateProcess("c:\\windows\\system32\\cmd.exe", "/c", "start", "http://localhost:8585/start.html");
|
||||
|
||||
if (process.platform == 'win32') {
|
||||
p = childprocess.execFile("c:\\windows\\system32\\cmd.exe", ["/c", "start", "http://localhost:8585/start.html"]);
|
||||
}
|
||||
else {
|
||||
console.log('Manually point your browser to http://localhost:8585/start.html');
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
mesh = require('MeshAgent');
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
function OnUpgrade(imsg, sck, head)
|
||||
{
|
||||
@@ -20,20 +55,102 @@ function OnUpgrade(imsg, sck, head)
|
||||
signalingChannel.on('data', OnSignalData);
|
||||
|
||||
peerConnection = rtc.createConnection();
|
||||
peerConnection.on('disconnected', function () { console.log('SCTP was disconnected'); });
|
||||
peerConnection.on('connected', OnWebRTC_Connected);
|
||||
peerConnection.on('dataChannel', OnWebRTC_DataChannel);
|
||||
|
||||
//console.log("Generating WebRTC Offer...");
|
||||
//signalingChannel.write({ cmd: "offer", data: peerConnection.generateOffer() });
|
||||
try
|
||||
{
|
||||
// peerConnection.on('_hold', function (val) { console.log('Holding Count: ' + val);});
|
||||
peerConnection.on('_congestionWindowSizeChange', function (val) { console.log('Congestion Window: ' + val); });
|
||||
// peerConnection.on('_receiverCredits', function (val) { console.log('Receiver Credits: ' + val); });
|
||||
peerConnection.on('_t3tx', function (val) { console.log('T3TX: ' + val); });
|
||||
//peerConnection.on('_fastRecovery', function (val) { console.log('Fast Recovery: ' + val);});
|
||||
//peerConnection.on('_rttCalculated', function (val) { console.log('Calculated RTT Value = ' + val); });
|
||||
peerConnection.on('_lastSackTime', function (val) { console.log('Last SACK Time = ' + val); });
|
||||
peerConnection.on('_retransmit', function (val) { console.log('Retransmit: ' + (new Uint32Array([val]))[0]); });
|
||||
//peerConnection.on('_retransmitPacket', function (val) { DebugPacket(val); console.log('RetransmitPacket: ' + val.toString('hex')); });
|
||||
//peerConnection.on('_lastSentTime', function (val) { console.log('Last Sent Time = ' + val); });
|
||||
peerConnection.on('_sackReceived', function (val) { console.log('SACK: ' + (new Uint32Array([val]))[0]); });
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
}
|
||||
|
||||
console.log("Generating WebRTC Offer...");
|
||||
signalingChannel.write({ cmd: "offer", data: peerConnection.generateOffer() });
|
||||
}
|
||||
|
||||
|
||||
function FOURBYTEBOUNDARY(a)
|
||||
{
|
||||
return ((a) + ((4 - ((a) % 4)) % 4));
|
||||
}
|
||||
function crc32c(crc, bytes)
|
||||
{
|
||||
var POLY = 0x82f63b78;
|
||||
var n;
|
||||
|
||||
crc ^= 0xffffffff;
|
||||
for (n = 0; n < bytes.length; n++) {
|
||||
crc ^= bytes[n];
|
||||
crc = crc & 1 ? (crc >>> 1) ^ POLY : crc >>> 1;
|
||||
crc = crc & 1 ? (crc >>> 1) ^ POLY : crc >>> 1;
|
||||
crc = crc & 1 ? (crc >>> 1) ^ POLY : crc >>> 1;
|
||||
crc = crc & 1 ? (crc >>> 1) ^ POLY : crc >>> 1;
|
||||
crc = crc & 1 ? (crc >>> 1) ^ POLY : crc >>> 1;
|
||||
crc = crc & 1 ? (crc >>> 1) ^ POLY : crc >>> 1;
|
||||
crc = crc & 1 ? (crc >>> 1) ^ POLY : crc >>> 1;
|
||||
crc = crc & 1 ? (crc >>> 1) ^ POLY : crc >>> 1;
|
||||
}
|
||||
return crc ^ 0xffffffff;
|
||||
}
|
||||
|
||||
function DebugPacket(val)
|
||||
{
|
||||
console.log('BufferLen: ' + val.length);
|
||||
console.log('CRC32C: ' + val.readInt32LE(8))
|
||||
val.writeUInt32BE(0, 8);
|
||||
console.log('CRC32C/Calc: ' + crc32c(0, val));
|
||||
console.log('VTAG: ' + val.readUInt32LE(4));
|
||||
var ptr = 12;
|
||||
|
||||
while (ptr + 4 <= val.length)
|
||||
{
|
||||
var hdr = val.slice(ptr);
|
||||
|
||||
var chunkType = hdr[0];
|
||||
var chunkFlags = hdr[1];
|
||||
var chunkSize = hdr.readUInt16BE(2);
|
||||
|
||||
switch (chunkType) {
|
||||
case 0:
|
||||
console.log('DATA Chunk');
|
||||
console.log('...chunkFlags: ' + chunkFlags);
|
||||
console.log('...chunkLength: ' + chunkSize);
|
||||
console.log('...TSN: ' + hdr.readUInt32BE(4));
|
||||
console.log('...StreamID: ' + hdr.readUInt16BE(8));
|
||||
console.log('...Seq: ' + hdr.readUInt16BE(10));
|
||||
console.log('...ProtocolID: ' + hdr.readUInt32BE(12));
|
||||
break;
|
||||
default:
|
||||
console.log('UNKNOWN Chunk');
|
||||
console.log('...chunkFlags: ' + chunkFlags);
|
||||
console.log('...chunkLength: ' + chunkSize);
|
||||
break;
|
||||
}
|
||||
|
||||
ptr += FOURBYTEBOUNDARY(chunkSize);
|
||||
}
|
||||
}
|
||||
function OnSignalData(chunk)
|
||||
{
|
||||
var j = JSON.parse(chunk);
|
||||
if (j.cmd == 'offer')
|
||||
{
|
||||
console.log("Received Offer");
|
||||
signalingChannel.write({ cmd: "offer", data: peerConnection.setOffer(j.data) });
|
||||
//signalingChannel.write({ cmd: "offer", data: peerConnection.setOffer(j.data) });
|
||||
peerConnection.setOffer(j.data);
|
||||
}
|
||||
}
|
||||
function OnLocalWebRequest(request, response)
|
||||
@@ -66,24 +183,30 @@ function OnLocalWebRequest(request, response)
|
||||
function OnWebRTC_Connected()
|
||||
{
|
||||
console.log("WebRTC Session Established");
|
||||
//this.dc = this.createDataChannel("testChannel", OnTestChannel);
|
||||
//if(mesh != null)
|
||||
//{
|
||||
// // Let create a data channel
|
||||
// this.dc = this.createDataChannel("remoteDesktop", OnKVMChannel)
|
||||
// this.tempTimeout = setTimeout(function (dc) { console.log("sending: 'test'"); dc.write("test"); }, 10000, this.dc);
|
||||
//}
|
||||
|
||||
this.jsdc = this.createDataChannel("testChannel", OnTestChannel);
|
||||
}
|
||||
function OnTestChannel()
|
||||
{
|
||||
console.log("Successfully established Data Channel");
|
||||
console.log("Successfully established JavaScript Data Channel");
|
||||
|
||||
if (mesh == null) {
|
||||
RS.pipe(this);
|
||||
}
|
||||
else {
|
||||
kvmStream = mesh.getRemoteDesktopStream();
|
||||
kvmStream.pipe(this);
|
||||
}
|
||||
}
|
||||
function OnKVMChannel()
|
||||
{
|
||||
console.log("Successfully established Data Channel to test Data throughput");
|
||||
dc = this;
|
||||
dc.kvm = mesh.getRemoteDesktopStream();
|
||||
dc.on('data', function (buffer) { console.log("Peer Received: " + buffer.toString() + " bytes"); });
|
||||
dc.on('data', function (buffer)
|
||||
{
|
||||
console.log("Peer Received: " + buffer.toString() + " bytes");
|
||||
});
|
||||
dc.on('end', function () { this.kvm.end(); console.log("Closing KVM Session"); });
|
||||
dc.kvm.pipe(dc);
|
||||
}
|
||||
@@ -91,8 +214,21 @@ function OnWebRTC_DataChannel(dataChannel)
|
||||
{
|
||||
console.log("Data Channel (" + dataChannel.name + ") was created");
|
||||
dc = dataChannel;
|
||||
dc.on('data', function (buffer) { console.log("Received: " + buffer.length + " bytes"); dc.write(buffer.length.toString()); });
|
||||
dc.on('data', function (buffer)
|
||||
{
|
||||
//console.log("Received: " + buffer);
|
||||
});
|
||||
dc.on('end', function () { console.log("Data Channel: " + this.name + " was closed"); });
|
||||
|
||||
//if (mesh == null)
|
||||
//{
|
||||
// RS.pipe(dc);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// kvmStream = mesh.getRemoteDesktopStream();
|
||||
// kvmStream.pipe(dc);
|
||||
//}
|
||||
}
|
||||
function OnTunnelData(buffer)
|
||||
{
|
||||
|
||||
@@ -2,10 +2,11 @@ var http = require('http');
|
||||
var https = require('https');
|
||||
var WS;
|
||||
console.log("Starting HTTP (Rewrite) Test");
|
||||
console.displayStreamPipeMessages = 1;
|
||||
console.displayFinalizerMessages = 1;
|
||||
|
||||
var cert = https.generateCertificate('test');
|
||||
|
||||
var server = https.createServer();
|
||||
var cert = require('tls').generateCertificate('test');
|
||||
var server = https.createServer({ pfx: cert, passphrase: 'test' });
|
||||
|
||||
server.on('request', function (imsg, rsp)
|
||||
{
|
||||
@@ -16,27 +17,28 @@ server.on('upgrade', function (imsg, sck, head)
|
||||
{
|
||||
console.log('Server On Upgrade');
|
||||
WS = sck.upgradeWebSocket();
|
||||
WS.on('pong', function () { console.log('Server received PONG'); WS.write('this is test'); WS.write(Buffer.from("This is a good day")); WS.end();});
|
||||
WS.on('pong', function () { console.log('Server received PONG'); WS.write('this is test'); WS.write(Buffer.from("This is a good day.. Bye!")); WS.end();});
|
||||
WS.on('data', function (chunk) { console.log('Server received: ' + chunk); });
|
||||
WS.on('end', function () { console.log('Server WS ended'); WS = null; });
|
||||
WS.ping();
|
||||
});
|
||||
|
||||
|
||||
server.listen({ port: 9095, pfx: cert, passphrase: 'test' });
|
||||
server.listen({ port: 9095 });
|
||||
//var req = http.get("http://127.0.0.1:9095/test.html");
|
||||
//var req = http.get("ws://127.0.0.1:9095/test.html");
|
||||
var req = http.request({ protocol: 'wss:', host: '127.0.0.1', port: 9095, method: 'GET', path: '/test.html', rejectUnauthorized: false})
|
||||
req.end();
|
||||
|
||||
var req2 = http.request({ protocol: 'https:', host: '127.0.0.1', port: 9095, method: 'GET', path: '/test.html', rejectUnauthorized: false })
|
||||
req2.end();
|
||||
//var req2 = http.request({ protocol: 'https:', host: '127.0.0.1', port: 9095, method: 'GET', path: '/test.html', rejectUnauthorized: false })
|
||||
//req2.end();
|
||||
|
||||
req.on('upgrade', function (imsg, sck, head)
|
||||
{
|
||||
console.log('client upgraded to WebSocket');
|
||||
sck.on('ping', function () { console.log('Client received ping'); this.write('Client says hello');});
|
||||
sck.on('data', function (chunk) { console.log('client received: ' + chunk, typeof (chunk)); });
|
||||
sck.on('end', function () { console.log('Client side closed'); });
|
||||
sck.on('end', function () { console.log('Client side closed'); console.logReferenceCount(req); req = null; _debugGC(); });
|
||||
});
|
||||
req.on('response', function (imsg)
|
||||
{
|
||||
@@ -47,10 +49,10 @@ req.on('response', function (imsg)
|
||||
})
|
||||
req.on('error', function (err) { console.log('error received', err); });
|
||||
|
||||
req2.on('response', function (imsg) {
|
||||
console.log('received response', imsg.statusCode, imsg.statusMessage);
|
||||
imsg.on('end', function () {
|
||||
console.log('Done reading IncomingMessageStream');
|
||||
});
|
||||
})
|
||||
req2.on('error', function (err) { console.log('error received', err); });
|
||||
//req2.on('response', function (imsg) {
|
||||
// console.log('received response', imsg.statusCode, imsg.statusMessage);
|
||||
// imsg.on('end', function () {
|
||||
// console.log('Done reading IncomingMessageStream');
|
||||
// });
|
||||
//})
|
||||
//req2.on('error', function (err) { console.log('error received', err); });
|
||||
9
makefile
9
makefile
@@ -32,7 +32,7 @@
|
||||
SOURCES = microstack/ILibAsyncServerSocket.c microstack/ILibAsyncSocket.c microstack/ILibAsyncUDPSocket.c microstack/ILibParsers.c microstack/ILibMulticastSocket.c
|
||||
SOURCES += microstack/ILibRemoteLogging.c microstack/ILibWebClient.c microstack/ILibWebRTC.c microstack/ILibWebServer.c microstack/ILibCrypto.c
|
||||
SOURCES += microstack/ILibWrapperWebRTC.c microstack/md5.c microstack/sha1.c microstack/ILibSimpleDataStore.c microstack/ILibProcessPipe.c microstack/ILibIPAddressMonitor.c
|
||||
SOURCES += microscript/duktape.c microscript/ILibAsyncSocket_Duktape.c microscript/ILibDuktape_DuplexStream.c microscript/ILibDuktape_Helpers.c
|
||||
SOURCES += microscript/duktape.c microscript/duk_module_duktape.c microscript/ILibAsyncSocket_Duktape.c microscript/ILibDuktape_DuplexStream.c microscript/ILibDuktape_Helpers.c
|
||||
SOURCES += microscript/ILibDuktape_http.c microscript/ILibDuktape_net.c microscript/ILibDuktape_ReadableStream.c microscript/ILibDuktape_WritableStream.c
|
||||
SOURCES += microscript/ILibDuktapeModSearch.c microscript/ILibParsers_Duktape.c microscript/ILibWebClient_Duktape.c microscript/ILibDuktape_WebRTC.c
|
||||
SOURCES += microscript/ILibWebServer_Duktape.c microscript/ILibDuktape_SimpleDataStore.c microscript/ILibDuktape_GenericMarshal.c
|
||||
@@ -188,6 +188,11 @@ else
|
||||
CFLAGS += -D_NOHECI
|
||||
endif
|
||||
|
||||
ifeq ($(WEBRTCDEBUG),1)
|
||||
# Adds WebRTC Debug Interfaces
|
||||
CFLAGS += -D_WEBRTCDEBUG
|
||||
endif
|
||||
|
||||
ifneq ($(WatchDog),)
|
||||
CWATCHDOG := -DILibChain_WATCHDOG_TIMEOUT=$(WatchDog)
|
||||
endif
|
||||
@@ -264,7 +269,7 @@ $(LIBNAME): $(OBJECTS) $(SOURCES)
|
||||
|
||||
# Compile on Raspberry Pi 2/3 with KVM
|
||||
pi:
|
||||
$(MAKE) EXENAME="meshagent_pi" CFLAGS="-std=gnu99 -g -Wall -D_POSIX -DMICROSTACK_PROXY -D_LINKVM $(CWEBLOG) $(CWATCHDOG) -fno-strict-aliasing $(INCDIRS) -DMESH_AGENTID=25 -D_NOFSWATCHER -D_NOHECI" LDFLAGS="-Lopenssl/libstatic/linux/pi $(LDFLAGS) $(LDEXTRA)"
|
||||
$(MAKE) EXENAME="meshagent_pi" CFLAGS="-std=gnu99 -g -Wall -D_POSIX -DMICROSTACK_PROXY -DMICROSTACK_TLS_DETECT -D_LINKVM $(CWEBLOG) $(CWATCHDOG) -fno-strict-aliasing $(INCDIRS) -DMESH_AGENTID=25 -D_NOFSWATCHER -D_NOHECI" LDFLAGS="-Lopenssl/libstatic/linux/pi $(LDFLAGS) $(LDEXTRA)"
|
||||
strip meshagent_pi
|
||||
|
||||
linux:
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
<ClCompile Include="..\meshcore\KVM\Windows\tile.cpp" />
|
||||
<ClCompile Include="..\meshcore\meshinfo.c" />
|
||||
<ClCompile Include="..\microscript\duktape.c" />
|
||||
<ClCompile Include="..\microscript\duk_module_duktape.c" />
|
||||
<ClCompile Include="..\microscript\ILibDuktapeModSearch.c" />
|
||||
<ClCompile Include="..\microscript\ILibDuktape_ChildProcess.c" />
|
||||
<ClCompile Include="..\microscript\ILibDuktape_Debugger.c" />
|
||||
<ClCompile Include="..\microscript\ILibDuktape_Dgram.c" />
|
||||
<ClCompile Include="..\microscript\ILibDuktape_DuplexStream.c" />
|
||||
<ClCompile Include="..\microscript\ILibDuktape_EncryptionStream.c" />
|
||||
@@ -48,9 +48,6 @@
|
||||
<ClCompile Include="..\microscript\ILibDuktape_SimpleDataStore.c" />
|
||||
<ClCompile Include="..\microscript\ILibDuktape_WebRTC.c" />
|
||||
<ClCompile Include="..\microscript\ILibDuktape_WritableStream.c" />
|
||||
<ClCompile Include="..\microscript\ILibParsers_Duktape.c" />
|
||||
<ClCompile Include="..\microscript\ILibWebClient_Duktape.c" />
|
||||
<ClCompile Include="..\microscript\ILibWebServer_Duktape.c" />
|
||||
<ClCompile Include="..\microstack\ILibAsyncServerSocket.c" />
|
||||
<ClCompile Include="..\microstack\ILibAsyncSocket.c" />
|
||||
<ClCompile Include="..\microstack\ILibAsyncUDPSocket.c" />
|
||||
@@ -76,9 +73,9 @@
|
||||
<ClInclude Include="..\meshcore\meshinfo.h" />
|
||||
<ClInclude Include="..\microscript\duktape.h" />
|
||||
<ClInclude Include="..\microscript\duk_config.h" />
|
||||
<ClInclude Include="..\microscript\duk_module_duktape.h" />
|
||||
<ClInclude Include="..\microscript\ILibDuktapeModSearch.h" />
|
||||
<ClInclude Include="..\microscript\ILibDuktape_ChildProcess.h" />
|
||||
<ClInclude Include="..\microscript\ILibDuktape_Debugger.h" />
|
||||
<ClInclude Include="..\microscript\ILibDuktape_Dgram.h" />
|
||||
<ClInclude Include="..\microscript\ILibDuktape_DuplexStream.h" />
|
||||
<ClInclude Include="..\microscript\ILibDuktape_EncryptionStream.h" />
|
||||
@@ -97,9 +94,6 @@
|
||||
<ClInclude Include="..\microscript\ILibDuktape_SimpleDataStore.h" />
|
||||
<ClInclude Include="..\microscript\ILibDuktape_WebRTC.h" />
|
||||
<ClInclude Include="..\microscript\ILibDuktape_WritableStream.h" />
|
||||
<ClInclude Include="..\microscript\ILibParsers_Duktape.h" />
|
||||
<ClInclude Include="..\microscript\ILibWebClient_Duktape.h" />
|
||||
<ClInclude Include="..\microscript\ILibWebServer_Duktape.h" />
|
||||
<ClInclude Include="..\microstack\ILibAsyncServerSocket.h" />
|
||||
<ClInclude Include="..\microstack\ILibAsyncSocket.h" />
|
||||
<ClInclude Include="..\microstack\ILibAsyncUDPSocket.h" />
|
||||
@@ -189,7 +183,7 @@
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>MESH_AGENTID=1;NOLMSCOMMANDER;_DEBUG;MICROSTACK_PROXY;_LINKVM;DUK_OPT_DEBUGGER_SUPPORT;DUK_OPT_INTERRUPT_COUNTER;WIN32;WINSOCK2;_WINSOCK_DEPRECATED_NO_WARNINGS;_MSC_PLATFORM_TOOLSET_$(PlatformToolset);MICROSTACK_TLS_DETECT;MICROSTACK_NO_STDAFX;_REMOTELOGGING;_REMOTELOGGINGSERVER;ILibChain_WATCHDOG_TIMEOUT=600000;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>MESH_AGENTID=1;NOLMSCOMMANDER;_DEBUG;MICROSTACK_PROXY;_LINKVM;WIN32;WINSOCK2;_WINSOCK_DEPRECATED_NO_WARNINGS;_MSC_PLATFORM_TOOLSET_$(PlatformToolset);MICROSTACK_TLS_DETECT;MICROSTACK_NO_STDAFX;_REMOTELOGGING;_REMOTELOGGINGSERVER;ILibChain_WATCHDOG_TIMEOUT=600000;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\openssl\include;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<ExceptionHandling>Async</ExceptionHandling>
|
||||
@@ -214,6 +208,9 @@
|
||||
<AdditionalOptions> /ignore:4099 %(AdditionalOptions)</AdditionalOptions>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>"$(OutputPath)$(TargetFileName)" ..\modules\PostBuild.js</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
@@ -244,6 +241,9 @@
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<AdditionalOptions> /ignore:4099 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>"$(OutputPath)$(TargetFileName)" ..\modules\PostBuild.js</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
||||
@@ -21,9 +21,6 @@
|
||||
<ClInclude Include="..\microscript\duktape.h">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\microscript\ILibDuktape_Debugger.h">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\microscript\ILibDuktape_DuplexStream.h">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClInclude>
|
||||
@@ -51,15 +48,6 @@
|
||||
<ClInclude Include="..\microscript\ILibDuktapeModSearch.h">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\microscript\ILibParsers_Duktape.h">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\microscript\ILibWebClient_Duktape.h">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\microscript\ILibWebServer_Duktape.h">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\microstack\ILibAsyncServerSocket.h">
|
||||
<Filter>Microstack</Filter>
|
||||
</ClInclude>
|
||||
@@ -154,14 +142,14 @@
|
||||
<ClInclude Include="..\microscript\ILibDuktape_HECI.h">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\microscript\duk_module_duktape.h">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\microscript\duktape.c">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\microscript\ILibDuktape_Debugger.c">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\microscript\ILibDuktape_DuplexStream.c">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClCompile>
|
||||
@@ -189,15 +177,6 @@
|
||||
<ClCompile Include="..\microscript\ILibDuktapeModSearch.c">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\microscript\ILibParsers_Duktape.c">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\microscript\ILibWebClient_Duktape.c">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\microscript\ILibWebServer_Duktape.c">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\microstack\ILibAsyncServerSocket.c">
|
||||
<Filter>Microstack</Filter>
|
||||
</ClCompile>
|
||||
@@ -295,6 +274,9 @@
|
||||
<ClCompile Include="..\microscript\ILibDuktape_HttpStream.c">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\microscript\duk_module_duktape.c">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="MeshConsole.rc" />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -30,6 +30,7 @@ limitations under the License.
|
||||
#endif
|
||||
|
||||
#include "microscript/ILibDuktape_ScriptContainer.h"
|
||||
#include "microstack/ILibCrypto.h"
|
||||
|
||||
MeshAgentHostContainer *agentHost = NULL;
|
||||
|
||||
|
||||
@@ -224,7 +224,7 @@ void getAvailableDisplays(unsigned short **array, int *len) {
|
||||
if (dir != NULL) {
|
||||
*len = scandir("/tmp/", &ent, lockfileCheckFn, alphasort);
|
||||
|
||||
if ((*array = (unsigned short *)malloc(*len)) == NULL) ILIBCRITICALEXIT(254);
|
||||
if ((*array = (unsigned short *)malloc((*len)*sizeof(unsigned short))) == NULL) ILIBCRITICALEXIT(254);
|
||||
|
||||
for (i = 0; i < *len; i++) {
|
||||
int dispNo = 0;
|
||||
|
||||
@@ -390,7 +390,7 @@ int getScreenBuffer(char **desktop, long long *desktopsize, XImage *image)
|
||||
if (*desktopsize != size) {
|
||||
if (*desktop != NULL) { free(*desktop); }
|
||||
*desktopsize = size;
|
||||
if ((*desktop = (char *) malloc (*desktopsize)) == NULL) ILIBCRITICALEXIT(254);
|
||||
if ((*desktop = (char *) malloc (*desktopsize + 4)) == NULL) ILIBCRITICALEXIT(254);
|
||||
}
|
||||
|
||||
if (bpp == 16) {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
Copyright 2006 - 2015 Intel Corporation
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
Copyright 2006 - 2015 Intel Corporation
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
Copyright 2006 - 2015 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -111,6 +111,7 @@ int kvm_relay_restart(int paused, void *pipeMgr, char *exePath, ILibKVM_WriteHan
|
||||
HANDLE hStdOut = INVALID_HANDLE_VALUE;
|
||||
HANDLE hStdIn = INVALID_HANDLE_VALUE;
|
||||
int ThreadRunning = 0;
|
||||
int kvmConsoleMode = 0;
|
||||
|
||||
ILibRemoteLogging gKVMRemoteLogging = NULL;
|
||||
#ifdef _WINSERVICE
|
||||
@@ -379,7 +380,7 @@ void CheckDesktopSwitch(int checkres, ILibKVM_WriteHandler writeHandler, void *r
|
||||
|
||||
if (SCREEN_X != x || SCREEN_Y != y || SCREEN_WIDTH != w || SCREEN_HEIGHT != h || SCALING_FACTOR != SCALING_FACTOR_NEW)
|
||||
{
|
||||
printf("RESOLUTION CHANGED! (supposedly)\n");
|
||||
//printf("RESOLUTION CHANGED! (supposedly)\n");
|
||||
SCREEN_X = x;
|
||||
SCREEN_Y = y;
|
||||
SCREEN_WIDTH = w;
|
||||
@@ -460,12 +461,13 @@ int kvm_server_inputdata(char* block, int blocklen, ILibKVM_WriteHandler writeHa
|
||||
{
|
||||
unsigned short type, size;
|
||||
|
||||
// Decode the block header
|
||||
if (blocklen < 4) return 0;
|
||||
|
||||
ILibRemoteLogging_printf(gKVMRemoteLogging, ILibRemoteLogging_Modules_Agent_KVM, ILibRemoteLogging_Flags_VerbosityLevel_2, "KVM [SLAVE]: Handle Input [Len = %d]", blocklen);
|
||||
// KVMDEBUG("kvm_server_inputdata", blocklen);
|
||||
CheckDesktopSwitch(0, writeHandler, reserved);
|
||||
|
||||
// Decode the block header
|
||||
if (blocklen < 4) return 0;
|
||||
type = ntohs(((unsigned short*)(block))[0]);
|
||||
size = ntohs(((unsigned short*)(block))[1]);
|
||||
|
||||
@@ -649,22 +651,25 @@ typedef struct kvm_data_handler
|
||||
// This method consumes as many input commands as it can.
|
||||
int kvm_relay_feeddata(char* buf, int len, ILibKVM_WriteHandler writeHandler, void *reserved)
|
||||
{
|
||||
#ifdef _WINSERVICE
|
||||
if (len >= 2 && ntohs(((unsigned short*)buf)[0]) == MNG_CTRLALTDEL)
|
||||
if (gChildProcess != NULL)
|
||||
{
|
||||
HANDLE ht = CreateThread(NULL, 0, kvm_ctrlaltdel, 0, 0, 0);
|
||||
if (ht != NULL) CloseHandle(ht);
|
||||
if (len >= 2 && ntohs(((unsigned short*)buf)[0]) == MNG_CTRLALTDEL)
|
||||
{
|
||||
HANDLE ht = CreateThread(NULL, 0, kvm_ctrlaltdel, 0, 0, 0);
|
||||
if (ht != NULL) CloseHandle(ht);
|
||||
}
|
||||
ILibProcessPipe_Process_WriteStdIn(gChildProcess, buf, len, ILibTransport_MemoryOwnership_USER);
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(gILibChain), ILibRemoteLogging_Modules_Microstack_Generic, ILibRemoteLogging_Flags_VerbosityLevel_2, "KVM [Master]: Write Input [Type = %u]", ntohs(((unsigned short*)buf)[0]));
|
||||
return len;
|
||||
}
|
||||
else
|
||||
{
|
||||
int len2 = 0;
|
||||
int ptr = 0;
|
||||
//while ((len2 = kvm_server_inputdata(buf + ptr, len - ptr, kvm_relay_feeddata_ex, (void*[]) {writeHandler, reserved})) != 0) { ptr += len2; }
|
||||
while ((len2 = kvm_server_inputdata(buf + ptr, len - ptr, writeHandler, reserved)) != 0) { ptr += len2; }
|
||||
return ptr;
|
||||
}
|
||||
ILibProcessPipe_Process_WriteStdIn(gChildProcess, buf, len, ILibTransport_MemoryOwnership_USER);
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(gILibChain), ILibRemoteLogging_Modules_Microstack_Generic, ILibRemoteLogging_Flags_VerbosityLevel_2, "KVM [Master]: Write Input [Type = %u]", ntohs(((unsigned short*)buf)[0]));
|
||||
return len;
|
||||
#else
|
||||
int len2 = 0;
|
||||
int ptr = 0;
|
||||
//while ((len2 = kvm_server_inputdata(buf + ptr, len - ptr, kvm_relay_feeddata_ex, (void*[]) {writeHandler, reserved})) != 0) { ptr += len2; }
|
||||
while ((len2 = kvm_server_inputdata(buf + ptr, len - ptr, writeHandler, reserved)) != 0) { ptr += len2; }
|
||||
return ptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Set the KVM pause state
|
||||
@@ -781,9 +786,12 @@ DWORD WINAPI kvm_server_mainloop(LPVOID parm)
|
||||
void *reserved = ((void**)parm)[1];
|
||||
|
||||
#ifdef _WINSERVICE
|
||||
gKVMRemoteLogging = ILibRemoteLogging_Create(NULL);
|
||||
ILibRemoteLogging_SetRawForward(gKVMRemoteLogging, sizeof(KVMDebugLog), kvm_slave_OnRawForwardLog);
|
||||
ILibRemoteLogging_printf(gKVMRemoteLogging, ILibRemoteLogging_Modules_Agent_KVM, ILibRemoteLogging_Flags_VerbosityLevel_1, "KVM [SLAVE]: Child Processing Running...");
|
||||
if (!kvmConsoleMode)
|
||||
{
|
||||
gKVMRemoteLogging = ILibRemoteLogging_Create(NULL);
|
||||
ILibRemoteLogging_SetRawForward(gKVMRemoteLogging, sizeof(KVMDebugLog), kvm_slave_OnRawForwardLog);
|
||||
ILibRemoteLogging_printf(gKVMRemoteLogging, ILibRemoteLogging_Modules_Agent_KVM, ILibRemoteLogging_Flags_VerbosityLevel_1, "KVM [SLAVE]: Child Processing Running...");
|
||||
}
|
||||
#endif
|
||||
|
||||
// This basic lock will prevent 2 thread from running at the same time. Gives time for the first one to fully exit.
|
||||
@@ -798,27 +806,39 @@ DWORD WINAPI kvm_server_mainloop(LPVOID parm)
|
||||
KVMDEBUG("kvm_server_mainloop / start1", (int)GetCurrentThreadId());
|
||||
|
||||
#ifdef _WINSERVICE
|
||||
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
hStdIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||
if (!kvmConsoleMode)
|
||||
{
|
||||
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
hStdIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||
}
|
||||
#endif
|
||||
|
||||
KVMDEBUG("kvm_server_mainloop / start2", (int)GetCurrentThreadId());
|
||||
|
||||
if (!initialize_gdiplus())
|
||||
{
|
||||
if (!initialize_gdiplus())
|
||||
{
|
||||
#ifdef _WINSERVICE
|
||||
ILibRemoteLogging_printf(gKVMRemoteLogging, ILibRemoteLogging_Modules_Agent_KVM, ILibRemoteLogging_Flags_VerbosityLevel_1, "KVM [SLAVE]: initialize_gdiplus() failed");
|
||||
if (!kvmConsoleMode)
|
||||
{
|
||||
ILibRemoteLogging_printf(gKVMRemoteLogging, ILibRemoteLogging_Modules_Agent_KVM, ILibRemoteLogging_Flags_VerbosityLevel_1, "KVM [SLAVE]: initialize_gdiplus() failed");
|
||||
}
|
||||
#endif
|
||||
KVMDEBUG("kvm_server_mainloop / initialize_gdiplus failed", (int)GetCurrentThreadId()); return 0;
|
||||
KVMDEBUG("kvm_server_mainloop / initialize_gdiplus failed", (int)GetCurrentThreadId()); return 0;
|
||||
}
|
||||
#ifdef _WINSERVICE
|
||||
ILibRemoteLogging_printf(gKVMRemoteLogging, ILibRemoteLogging_Modules_Agent_KVM, ILibRemoteLogging_Flags_VerbosityLevel_1, "KVM [SLAVE]: initialize_gdiplus() SUCCESS");
|
||||
if (!kvmConsoleMode)
|
||||
{
|
||||
ILibRemoteLogging_printf(gKVMRemoteLogging, ILibRemoteLogging_Modules_Agent_KVM, ILibRemoteLogging_Flags_VerbosityLevel_1, "KVM [SLAVE]: initialize_gdiplus() SUCCESS");
|
||||
}
|
||||
#endif
|
||||
kvm_server_SetResolution(writeHandler, reserved);
|
||||
|
||||
#ifdef _WINSERVICE
|
||||
g_shutdown = 0;
|
||||
kvmthread = CreateThread(NULL, 0, kvm_mainloopinput, parm, 0, 0);
|
||||
if (!kvmConsoleMode)
|
||||
{
|
||||
g_shutdown = 0;
|
||||
kvmthread = CreateThread(NULL, 0, kvm_mainloopinput, parm, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set all CRCs to 0xFF
|
||||
@@ -864,7 +884,10 @@ DWORD WINAPI kvm_server_mainloop(LPVOID parm)
|
||||
if (get_desktop_buffer(&desktop, &desktopsize) == 1)
|
||||
{
|
||||
#ifdef _WINSERVICE
|
||||
ILibRemoteLogging_printf(gKVMRemoteLogging, ILibRemoteLogging_Modules_Agent_KVM, ILibRemoteLogging_Flags_VerbosityLevel_1, "KVM [SLAVE]: get_desktop_buffer() failed");
|
||||
if (!kvmConsoleMode)
|
||||
{
|
||||
ILibRemoteLogging_printf(gKVMRemoteLogging, ILibRemoteLogging_Modules_Agent_KVM, ILibRemoteLogging_Flags_VerbosityLevel_1, "KVM [SLAVE]: get_desktop_buffer() failed");
|
||||
}
|
||||
#endif
|
||||
KVMDEBUG("get_desktop_buffer() failed, shutting down", (int)GetCurrentThreadId());
|
||||
g_shutdown = 1;
|
||||
@@ -979,32 +1002,22 @@ void kvm_relay_ExitHandler(ILibProcessPipe_Process sender, int exitCode, void* u
|
||||
|
||||
void kvm_relay_StdOutHandler(ILibProcessPipe_Process sender, char *buffer, int bufferLen, int* bytesConsumed, void* user)
|
||||
{
|
||||
int ptr = 0;
|
||||
unsigned short size = 0;
|
||||
unsigned short cmd = 0;
|
||||
UNREFERENCED_PARAMETER(sender);
|
||||
ILibKVM_WriteHandler writeHandler = (ILibKVM_WriteHandler)((void**)user)[0];
|
||||
void *reserved = ((void**)user)[1];
|
||||
|
||||
while (bufferLen - ptr > 4)
|
||||
if (bufferLen > 4)
|
||||
{
|
||||
//type = ntohs(((unsigned short*)(pchRequest + ptr))[0]);
|
||||
size = ntohs(((unsigned short*)(buffer + ptr))[1]);
|
||||
cmd = ntohs(((unsigned short*)(buffer + ptr))[0]);
|
||||
if ((ptr + size > bufferLen) || size == 0) break;
|
||||
ptr += size;
|
||||
}
|
||||
|
||||
if (ptr > 0)
|
||||
{
|
||||
//ILibRemoteLogging_printf(ILibChainGetLogger(gILibChain), ILibRemoteLogging_Modules_Agent_KVM, ILibRemoteLogging_Flags_VerbosityLevel_2, "KVM Data: CMD: %d, Size = %d", cmd, size);
|
||||
writeHandler(buffer, ptr, reserved); // stream object will take care of flow control
|
||||
*bytesConsumed = ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
*bytesConsumed = 0;
|
||||
size = ntohs(((unsigned short*)(buffer))[1]);
|
||||
if (size <= bufferLen)
|
||||
{
|
||||
*bytesConsumed = size;
|
||||
writeHandler(buffer, size, reserved);
|
||||
return;
|
||||
}
|
||||
}
|
||||
*bytesConsumed = 0;
|
||||
}
|
||||
void kvm_relay_StdErrHandler(ILibProcessPipe_Process sender, char *buffer, int bufferLen, int* bytesConsumed, void* user)
|
||||
{
|
||||
@@ -1055,24 +1068,31 @@ int kvm_relay_restart(int paused, void *pipeMgr, char *exePath, ILibKVM_WriteHan
|
||||
// Setup the KVM session. Return 1 if ok, 0 if it could not be setup.
|
||||
int kvm_relay_setup(char *exePath, void *processPipeMgr, ILibKVM_WriteHandler writeHandler, void *reserved)
|
||||
{
|
||||
if (processPipeMgr != NULL)
|
||||
{
|
||||
#ifdef _WINSERVICE
|
||||
// if (kvmthread != NULL || g_slavekvm != 0) { KVMDEBUG("kvm_relay_setup() session already exists", 0); return 0; }
|
||||
if (ThreadRunning == 1 && g_shutdown == 0) { KVMDEBUG("kvm_relay_setup() session already exists", 0); return 0; }
|
||||
g_restartcount = 0;
|
||||
gProcessSpawnType = ILibProcessPipe_SpawnTypes_USER;
|
||||
KVMDEBUG("kvm_relay_setup() session starting", 0);
|
||||
return kvm_relay_restart(1, processPipeMgr, exePath, writeHandler, reserved);
|
||||
if (ThreadRunning == 1 && g_shutdown == 0) { KVMDEBUG("kvm_relay_setup() session already exists", 0); return 0; }
|
||||
g_restartcount = 0;
|
||||
gProcessSpawnType = ILibProcessPipe_SpawnTypes_USER;
|
||||
KVMDEBUG("kvm_relay_setup() session starting", 0);
|
||||
return kvm_relay_restart(1, processPipeMgr, exePath, writeHandler, reserved);
|
||||
#else
|
||||
// if (kvmthread != NULL && g_shutdown == 0) return 0;
|
||||
void **parms = (void**)ILibMemory_Allocate((2 * sizeof(void*)) + sizeof(int), 0, NULL, NULL);
|
||||
parms[0] = writeHandler;
|
||||
parms[1] = reserved;
|
||||
((int*)(&parms[2]))[0] = 1;
|
||||
|
||||
if (ThreadRunning == 1 && g_shutdown == 0) { KVMDEBUG("kvm_relay_setup() session already exists", 0); free(parms); return 0; }
|
||||
kvmthread = CreateThread(NULL, 0, kvm_server_mainloop, (void*)parms, 0, 0);
|
||||
return 1;
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// if (kvmthread != NULL && g_shutdown == 0) return 0;
|
||||
void **parms = (void**)ILibMemory_Allocate((2 * sizeof(void*)) + sizeof(int), 0, NULL, NULL);
|
||||
parms[0] = writeHandler;
|
||||
parms[1] = reserved;
|
||||
((int*)(&parms[2]))[0] = 1;
|
||||
kvmConsoleMode = 1;
|
||||
|
||||
if (ThreadRunning == 1 && g_shutdown == 0) { KVMDEBUG("kvm_relay_setup() session already exists", 0); free(parms); return 0; }
|
||||
kvmthread = CreateThread(NULL, 0, kvm_server_mainloop, (void*)parms, 0, 0);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Force a KVM reset & refresh
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
Copyright 2006 - 2015 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
Copyright 2006 - 2015 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
Copyright 2006 - 2015 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -68,12 +68,12 @@ limitations under the License.
|
||||
#define MESH_MCASTv4_GROUP "239.255.255.235"
|
||||
#define MESH_MCASTv6_GROUP "FF02:0:0:0:0:0:0:FE"
|
||||
|
||||
char exeMeshPolicyGuid[] = { 0xB9, 0x96, 0x01, 0x58, 0x80, 0x54, 0x4A, 0x19, 0xB7, 0xF7, 0xE9, 0xBE, 0x44, 0x91, 0x4C, 0x19 };
|
||||
#define MESH_SCRIPTCONTAINER_ID "\xFF_ScriptContainer_ID"
|
||||
#define MESH_AGENT_SINGLETON "\xFF_MeshAgentObject_Singleton"
|
||||
#define SEQ_TABLE_KEY "\xFF_seqTable"
|
||||
#define CONTAINER_PTR "\xFF_ptr"
|
||||
#define MESH_AGENT_PTR "\xFFMeshAgentPtr"
|
||||
#define MESH_AGENT_DUKPTRS "\xFFptrs"
|
||||
#define CTX_PTR "\xFF_Heap"
|
||||
#define CONTEXT_GUID_PTR "_CONTEXT_GUID_PTR"
|
||||
#define REMOTE_DESKTOP_STREAM "\xFF_RemoteDesktopStream"
|
||||
@@ -521,85 +521,28 @@ void IPAddressMonitor(void *data)
|
||||
Begin Mesh Agent Duktape Abstraction
|
||||
--------------------------------*/
|
||||
|
||||
MeshAgentDuktapePtrs* ILibDuktape_MeshAgent_GetMeshAgentPtrs(duk_context *ctx)
|
||||
{
|
||||
MeshAgentDuktapePtrs *ptrs = NULL;
|
||||
MeshAgentHostContainer *agent = NULL;
|
||||
|
||||
duk_push_this(ctx); // [MeshAgent]
|
||||
if (duk_has_prop_string(ctx, -1, MESH_AGENT_DUKPTRS))
|
||||
{
|
||||
// We already created a binding earlier
|
||||
duk_get_prop_string(ctx, -1, MESH_AGENT_DUKPTRS); // [MeshAgent][ptrs]
|
||||
ptrs = (MeshAgentDuktapePtrs*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_pop(ctx); // [MeshAgent]
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a new binding
|
||||
duk_push_fixed_buffer(ctx, sizeof(MeshAgentDuktapePtrs)); // [MeshAgent][buffer]
|
||||
ptrs = (MeshAgentDuktapePtrs*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_put_prop_string(ctx, -2, MESH_AGENT_DUKPTRS); // [MeshAgent]
|
||||
|
||||
memset(ptrs, 0, sizeof(MeshAgentDuktapePtrs));
|
||||
ptrs->ctx = ctx;
|
||||
ptrs->MeshAgentObject = duk_get_heapptr(ctx, -1);
|
||||
|
||||
duk_get_prop_string(ctx, -1, MESH_AGENT_PTR); // [MeshAgent][Host]
|
||||
agent = (MeshAgentHostContainer*)duk_get_pointer(ctx, -1);
|
||||
duk_pop(ctx); // [MeshAgent]
|
||||
ptrs->Next = agent->DuktapeMeshBindings;
|
||||
agent->DuktapeMeshBindings = ptrs;
|
||||
}
|
||||
duk_pop(ctx); // ...
|
||||
return ptrs;
|
||||
}
|
||||
duk_ret_t ILibDuktape_MeshAgent_AddCommandHandler(duk_context *ctx)
|
||||
{
|
||||
MeshAgentDuktapePtrs *ptrs;
|
||||
void *OnCommand = duk_require_heapptr(ctx, 0);
|
||||
|
||||
ptrs = ILibDuktape_MeshAgent_GetMeshAgentPtrs(ctx);
|
||||
ptrs->OnCommand = OnCommand;
|
||||
duk_push_this(ctx); // [agent]
|
||||
duk_get_prop_string(ctx, -1, "on"); // [agent][on]
|
||||
duk_swap_top(ctx, -2); // [on][this]
|
||||
duk_push_string(ctx, "Command"); // [on][this][Command]
|
||||
duk_dup(ctx, 0); // [on][this][Command][listener]
|
||||
duk_call_method(ctx, 2);
|
||||
return 0;
|
||||
}
|
||||
duk_ret_t ILibDuktape_MeshAgent_AddConnectHandler(duk_context *ctx)
|
||||
{
|
||||
MeshAgentDuktapePtrs *ptrs;
|
||||
void *OnConnect = duk_require_heapptr(ctx, 0);
|
||||
|
||||
ptrs = ILibDuktape_MeshAgent_GetMeshAgentPtrs(ctx);
|
||||
ptrs->OnConnect = OnConnect;
|
||||
duk_push_this(ctx); // [agent]
|
||||
duk_get_prop_string(ctx, -1, "on"); // [agent][on]
|
||||
duk_swap_top(ctx, -2); // [on][this]
|
||||
duk_push_string(ctx, "Connected"); // [on][this][connected]
|
||||
duk_dup(ctx, 0); // [on][this][connected][listener]
|
||||
duk_call_method(ctx, 2);
|
||||
return 0;
|
||||
}
|
||||
duk_ret_t ILibDuktape_MeshAgent_Finalizer(duk_context *ctx)
|
||||
{
|
||||
MeshAgentDuktapePtrs *ptrs = NULL, *binding = NULL;
|
||||
MeshAgentHostContainer *agent = NULL;
|
||||
|
||||
duk_dup(ctx, 0); // [MeshAgent]
|
||||
duk_get_prop_string(ctx, -1, MESH_AGENT_PTR); // [MeshAgent][MeshAgentPtr]
|
||||
agent = (MeshAgentHostContainer*)duk_get_pointer(ctx, -1);
|
||||
|
||||
if (duk_has_prop_string(ctx, -2, MESH_AGENT_DUKPTRS))
|
||||
{
|
||||
duk_get_prop_string(ctx, -2, MESH_AGENT_DUKPTRS); // [MeshAgent][MeshAgentPtr][ptrs]
|
||||
ptrs = (MeshAgentDuktapePtrs*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
|
||||
if (agent->DuktapeMeshBindings == ptrs)
|
||||
{
|
||||
agent->DuktapeMeshBindings = ptrs->Next;
|
||||
}
|
||||
else
|
||||
{
|
||||
binding = agent->DuktapeMeshBindings;
|
||||
while (binding->Next != NULL)
|
||||
{
|
||||
if (binding->Next == ptrs) { binding->Next = ptrs->Next; break; }
|
||||
binding = binding->Next;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -735,7 +678,6 @@ void ILibDuktape_MeshAgent_RemoteDesktop_EndSink(ILibDuktape_DuplexStream *strea
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->MeshAgentObject); // [MeshAgent]
|
||||
duk_del_prop_string(ptrs->ctx, -1, REMOTE_DESKTOP_STREAM);
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
|
||||
memset(ptrs, 0, sizeof(RemoteDesktop_Ptrs));
|
||||
}
|
||||
kvm_cleanup();
|
||||
@@ -745,7 +687,7 @@ void ILibDuktape_MeshAgent_RemoteDesktop_PauseSink(ILibDuktape_DuplexStream *sen
|
||||
{
|
||||
//printf("KVM/PAUSE\n");
|
||||
#ifdef _POSIX
|
||||
ILibProcessPipe_Pipe_Pause(((RemoteDesktop_Ptrs*)user)->kvmPipe);
|
||||
if (((RemoteDesktop_Ptrs*)user)->kvmPipe != NULL) { ILibProcessPipe_Pipe_Pause(((RemoteDesktop_Ptrs*)user)->kvmPipe); }
|
||||
#else
|
||||
kvm_pause(1);
|
||||
#endif
|
||||
@@ -755,7 +697,7 @@ void ILibDuktape_MeshAgent_RemoteDesktop_ResumeSink(ILibDuktape_DuplexStream *se
|
||||
//printf("KVM/RESUME\n");
|
||||
|
||||
#ifdef _POSIX
|
||||
ILibProcessPipe_Pipe_Resume(((RemoteDesktop_Ptrs*)user)->kvmPipe);
|
||||
if (((RemoteDesktop_Ptrs*)user)->kvmPipe != NULL) { ILibProcessPipe_Pipe_Resume(((RemoteDesktop_Ptrs*)user)->kvmPipe); }
|
||||
#else
|
||||
kvm_pause(0);
|
||||
#endif
|
||||
@@ -838,7 +780,11 @@ duk_ret_t ILibDuktape_MeshAgent_getRemoteDesktop(duk_context *ctx)
|
||||
|
||||
// Setup Remote Desktop
|
||||
#ifdef WIN32
|
||||
kvm_relay_setup(agent->exePath, agent->pipeManager, ILibDuktape_MeshAgent_RemoteDesktop_KVM_WriteSink, ptrs);
|
||||
#ifdef _WINSERVICE
|
||||
kvm_relay_setup(agent->exePath, agent->runningAsConsole ? NULL : agent->pipeManager, ILibDuktape_MeshAgent_RemoteDesktop_KVM_WriteSink, ptrs);
|
||||
#else
|
||||
kvm_relay_setup(agent->exePath, NULL, ILibDuktape_MeshAgent_RemoteDesktop_KVM_WriteSink, ptrs);
|
||||
#endif
|
||||
#else
|
||||
ptrs->kvmPipe = kvm_relay_setup(agent->pipeManager, ILibDuktape_MeshAgent_RemoteDesktop_KVM_WriteSink, ptrs);
|
||||
#endif
|
||||
@@ -933,18 +879,55 @@ duk_ret_t ILibDuktape_MeshAgent_isControlChannelConnected(duk_context *ctx)
|
||||
duk_ret_t ILibDuktape_MeshAgent_eval(duk_context *ctx)
|
||||
{
|
||||
duk_size_t evalStrLen;
|
||||
char *evalStr = duk_get_lstring(ctx, 0, &evalStrLen);
|
||||
char *evalStr = (char*)duk_get_lstring(ctx, 0, &evalStrLen);
|
||||
|
||||
printf("eval(): %s\n", evalStr);
|
||||
duk_eval_string(ctx, evalStr);
|
||||
return(1);
|
||||
}
|
||||
duk_context* ScriptEngine_Stop(MeshAgentHostContainer *agent, char *contextGUID);
|
||||
|
||||
void ILibDuktape_MeshAgent_dumpCoreModuleEx(void *chain, void *user)
|
||||
{
|
||||
MeshAgentHostContainer* agentHost = (MeshAgentHostContainer*)user;
|
||||
char *CoreModule;
|
||||
|
||||
ScriptEngine_Stop((MeshAgentHostContainer*)user, MeshAgent_JavaCore_ContextGuid);
|
||||
printf("CoreModule was manually dumped, restarting!\n");
|
||||
|
||||
int CoreModuleLen = ILibSimpleDataStore_Get(agentHost->masterDb, "CoreModule", NULL, 0);
|
||||
if (CoreModuleLen > 0)
|
||||
{
|
||||
// There is a core module, launch it now.
|
||||
CoreModule = (char*)ILibMemory_Allocate(CoreModuleLen, 0, NULL, NULL);
|
||||
ILibSimpleDataStore_Get(agentHost->masterDb, "CoreModule", CoreModule, CoreModuleLen);
|
||||
|
||||
if (ILibDuktape_ScriptContainer_CompileJavaScript(agentHost->meshCoreCtx, CoreModule + 4, CoreModuleLen - 4) != 0 ||
|
||||
ILibDuktape_ScriptContainer_ExecuteByteCode(agentHost->meshCoreCtx) != 0)
|
||||
{
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(agentHost->chain), ILibRemoteLogging_Modules_Microstack_Generic | ILibRemoteLogging_Modules_ConsolePrint,
|
||||
ILibRemoteLogging_Flags_VerbosityLevel_1, "Error Executing MeshCore: %s", duk_safe_to_string(agentHost->meshCoreCtx, -1));
|
||||
duk_pop(agentHost->meshCoreCtx);
|
||||
}
|
||||
free(CoreModule);
|
||||
}
|
||||
agentHost->localScript = 1;
|
||||
}
|
||||
duk_ret_t ILibDuktape_MeshAgent_dumpCoreModule(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx); // [agent]
|
||||
duk_get_prop_string(ctx, -1, MESH_AGENT_PTR); // [agent][ptr]
|
||||
MeshAgentHostContainer *agent = (MeshAgentHostContainer*)duk_get_pointer(ctx, -1);
|
||||
|
||||
agent->localScript = 0;
|
||||
ILibChain_RunOnMicrostackThreadEx(agent->chain, ILibDuktape_MeshAgent_dumpCoreModuleEx, agent);
|
||||
return(0);
|
||||
}
|
||||
void ILibDuktape_MeshAgent_PUSH(duk_context *ctx, void *chain)
|
||||
{
|
||||
MeshAgentHostContainer *agent;
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
|
||||
|
||||
duk_push_heap_stash(ctx); // [stash]
|
||||
if (duk_has_prop_string(ctx, -1, MESH_AGENT_SINGLETON))
|
||||
{
|
||||
@@ -959,6 +942,7 @@ void ILibDuktape_MeshAgent_PUSH(duk_context *ctx, void *chain)
|
||||
|
||||
duk_pop_2(ctx); // ...
|
||||
duk_push_object(ctx); // [MeshAgent]
|
||||
ILibDuktape_WriteID(ctx, "MeshAgent");
|
||||
duk_push_pointer(ctx, agent); // [MeshAgent][ptr]
|
||||
duk_put_prop_string(ctx, -2, MESH_AGENT_PTR); // [MeshAgent]
|
||||
|
||||
@@ -979,18 +963,10 @@ void ILibDuktape_MeshAgent_PUSH(duk_context *ctx, void *chain)
|
||||
duk_push_pointer(ctx, &agent->selfcert);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_MeshAgent_Cert_NonLeaf);
|
||||
#endif
|
||||
duk_push_fixed_buffer(ctx, sizeof(MeshAgentDuktapePtrs)); // [MeshAgent][buffer]
|
||||
MeshAgentDuktapePtrs *ptrs = (MeshAgentDuktapePtrs*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_put_prop_string(ctx, -2, MESH_AGENT_DUKPTRS); // [MeshAgent]
|
||||
|
||||
memset(ptrs, 0, sizeof(MeshAgentDuktapePtrs));
|
||||
ptrs->ctx = ctx;
|
||||
ptrs->MeshAgentObject = duk_get_heapptr(ctx, -1);
|
||||
ptrs->Next = agent->DuktapeMeshBindings;
|
||||
agent->DuktapeMeshBindings = ptrs;
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEvent(emitter, "Ready", &(ptrs->OnReady));
|
||||
ILibDuktape_EventEmitter_CreateEvent(emitter, "Connected", &(ptrs->OnConnect));
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "Ready");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "Connected");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "Command");
|
||||
|
||||
ILibDuktape_CreateEventWithGetter(ctx, "isControlChannelConnected", ILibDuktape_MeshAgent_isControlChannelConnected);
|
||||
ILibDuktape_EventEmitter_AddHook(emitter, "Ready", ILibDuktape_MeshAgent_Ready);
|
||||
@@ -1002,6 +978,7 @@ void ILibDuktape_MeshAgent_PUSH(duk_context *ctx, void *chain)
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "SendCommand", ILibDuktape_MeshAgent_SendCommand, 1);
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_MeshAgent_Finalizer);
|
||||
ILibDuktape_CreateReadonlyProperty_int(ctx, "activeMicroLMS", (agent->microLMS != NULL ? 1 : 0));
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "restartCore", ILibDuktape_MeshAgent_dumpCoreModule, 0);
|
||||
#ifdef _LINKVM
|
||||
ILibDuktape_CreateReadonlyProperty_int(ctx, "hasKVM", 1);
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "kvmConnected");
|
||||
@@ -1264,7 +1241,7 @@ duk_context* ScriptEngine_Stop(MeshAgentHostContainer *agent, char *contextGUID)
|
||||
ILibDuktape_MeshAgent_Init(newCtx, agent->chain, agent);
|
||||
|
||||
ILibDuktape_SetNativeUncaughtExceptionHandler(newCtx, settings->nExeptionHandler, settings->nExceptionUserObject);
|
||||
|
||||
if (g_displayFinalizerMessages) { printf("\n\n==> Stopping JavaScript Engine\n"); }
|
||||
duk_destroy_heap(oldCtx);
|
||||
agent->meshCoreCtx = newCtx;
|
||||
if (agent->proxyServer != NULL)
|
||||
@@ -1314,10 +1291,131 @@ void MeshServer_OnSendOK(ILibWebClient_StateObject sender, void *user1, void *us
|
||||
// TODO: Inform JavaScript core module that we are in underflow situation
|
||||
}
|
||||
|
||||
|
||||
int GenerateSHA384FileHash(char *filePath, char *fileHash)
|
||||
{
|
||||
FILE *tmpFile = NULL;
|
||||
unsigned int endIndex = 0;
|
||||
unsigned int bytesLeft = 0;
|
||||
size_t bytesRead;
|
||||
unsigned int checkSumIndex = 0;
|
||||
unsigned int tableIndex = 0;
|
||||
|
||||
#ifdef WIN32
|
||||
int retVal = 1;
|
||||
fopen_s(&tmpFile, filePath, "rb");
|
||||
#else
|
||||
tmpFile = fopen(filePath, "rb");
|
||||
#endif
|
||||
if (tmpFile == NULL) { return(1); }
|
||||
|
||||
#ifdef WIN32
|
||||
// We need to check if this is a signed binary
|
||||
// Read the PE Headers, to determine where to look for the Embedded JS
|
||||
char *optHeader = NULL;
|
||||
unsigned int NTHeaderIndex = 0;
|
||||
fseek(tmpFile, 0, SEEK_SET);
|
||||
ignore_result(fread(ILibScratchPad, 1, 2, tmpFile));
|
||||
if (ntohs(((unsigned int*)ILibScratchPad)[0]) == 19802) // 5A4D
|
||||
{
|
||||
fseek(tmpFile, 60, SEEK_SET);
|
||||
ignore_result(fread((void*)&NTHeaderIndex, 1, 4, tmpFile));
|
||||
fseek(tmpFile, NTHeaderIndex, SEEK_SET); // NT HEADER
|
||||
checkSumIndex = NTHeaderIndex + 24 + 64;
|
||||
|
||||
ignore_result(fread(ILibScratchPad, 1, 24, tmpFile));
|
||||
if (((unsigned int*)ILibScratchPad)[0] == 17744)
|
||||
{
|
||||
// PE Image
|
||||
optHeader = ILibMemory_AllocateA(((unsigned short*)ILibScratchPad)[10]);
|
||||
ignore_result(fread(optHeader, 1, ILibMemory_AllocateA_Size(optHeader), tmpFile));
|
||||
switch (((unsigned short*)optHeader)[0])
|
||||
{
|
||||
case 0x10B:
|
||||
if (((unsigned int*)(optHeader + 128))[0] != 0)
|
||||
{
|
||||
endIndex = ((unsigned int*)(optHeader + 128))[0];
|
||||
}
|
||||
tableIndex = NTHeaderIndex + 24 + 128;
|
||||
retVal = 0;
|
||||
break;
|
||||
case 0x20B:
|
||||
if (((unsigned int*)(optHeader + 144))[0] != 0)
|
||||
{
|
||||
endIndex = ((unsigned int*)(optHeader + 144))[0];
|
||||
}
|
||||
tableIndex = NTHeaderIndex + 24 + 144;
|
||||
retVal = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (retVal != 0)
|
||||
{
|
||||
fclose(tmpFile);
|
||||
return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (endIndex == 0)
|
||||
{
|
||||
// We just need to check for Embedded MSH file
|
||||
int mshLen = 0;
|
||||
fseek(tmpFile, -16, SEEK_END);
|
||||
ignore_result(fread(ILibScratchPad, 1, 16, tmpFile));
|
||||
if (memcmp(ILibScratchPad, exeMeshPolicyGuid, 16) == 0)
|
||||
{
|
||||
fseek(tmpFile, -20, SEEK_CUR);
|
||||
ignore_result(fread((void*)&mshLen, 1, 4, tmpFile));
|
||||
mshLen = ntohl(mshLen);
|
||||
endIndex = (unsigned int)ftell(tmpFile) - 4 - mshLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
endIndex = (unsigned int)ftell(tmpFile);
|
||||
}
|
||||
}
|
||||
|
||||
SHA512_CTX ctx;
|
||||
SHA384_Init(&ctx);
|
||||
bytesLeft = endIndex;
|
||||
fseek(tmpFile, 0, SEEK_SET);
|
||||
if (checkSumIndex != 0)
|
||||
{
|
||||
bytesRead = fread(ILibScratchPad, 1, checkSumIndex + 4, tmpFile);
|
||||
((unsigned int*)(ILibScratchPad + checkSumIndex))[0] = 0;
|
||||
SHA384_Update(&ctx, ILibScratchPad, bytesRead);
|
||||
if (endIndex > 0) { bytesLeft -= (unsigned int)bytesRead; }
|
||||
|
||||
bytesRead = fread(ILibScratchPad, 1, tableIndex + 8 - (checkSumIndex + 4), tmpFile);
|
||||
((unsigned int*)(ILibScratchPad + bytesRead - 8))[0] = 0;
|
||||
((unsigned int*)(ILibScratchPad + bytesRead - 8))[1] = 0;
|
||||
SHA384_Update(&ctx, ILibScratchPad, bytesRead);
|
||||
if (endIndex > 0) { bytesLeft -= (unsigned int)bytesRead; }
|
||||
}
|
||||
|
||||
while ((bytesRead = fread(ILibScratchPad, 1, endIndex == 0 ? sizeof(ILibScratchPad) : (bytesLeft > sizeof(ILibScratchPad) ? sizeof(ILibScratchPad) : bytesLeft), tmpFile)) > 0)
|
||||
{
|
||||
SHA384_Update(&ctx, ILibScratchPad, bytesRead);
|
||||
if (endIndex > 0)
|
||||
{
|
||||
bytesLeft -= (unsigned int)bytesRead;
|
||||
if (bytesLeft == 0) { break; }
|
||||
}
|
||||
}
|
||||
SHA384_Final((unsigned char*)fileHash, &ctx);
|
||||
fclose(tmpFile);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Called when the connection of the mesh server is fully authenticated
|
||||
void MeshServer_ServerAuthenticated(ILibWebClient_StateObject WebStateObject, MeshAgentHostContainer *agent) {
|
||||
int len = 0;
|
||||
MeshAgentDuktapePtrs *meshBindings;
|
||||
|
||||
// Send the mesh agent tag to the server
|
||||
// We send the tag information independently of the meshcore because we could use this to select what meshcore to use on the server.
|
||||
@@ -1327,20 +1425,15 @@ void MeshServer_ServerAuthenticated(ILibWebClient_StateObject WebStateObject, Me
|
||||
|
||||
// Inform JavaScript core module of the connection
|
||||
// TODO: Verify with Bryan that only the core module will get this. No other modules should.
|
||||
if (agent->serverAuthState == 3) {
|
||||
meshBindings = agent->DuktapeMeshBindings;
|
||||
while (meshBindings != NULL)
|
||||
{
|
||||
if (meshBindings->OnConnect != NULL)
|
||||
{
|
||||
duk_push_heapptr(meshBindings->ctx, meshBindings->OnConnect);
|
||||
duk_push_heapptr(meshBindings->ctx, meshBindings->MeshAgentObject);
|
||||
duk_push_int(meshBindings->ctx, 1); // Argument 1 here indicates connection
|
||||
if (duk_pcall_method(meshBindings->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(meshBindings->ctx); }
|
||||
duk_pop(meshBindings->ctx);
|
||||
}
|
||||
meshBindings = meshBindings->Next;
|
||||
}
|
||||
if (agent->serverAuthState == 3)
|
||||
{
|
||||
ILibDuktape_MeshAgent_PUSH(agent->meshCoreCtx, agent->chain); // [agent]
|
||||
duk_get_prop_string(agent->meshCoreCtx, -1, "emit"); // [agent][emit]
|
||||
duk_swap_top(agent->meshCoreCtx, -2); // [emit][this]
|
||||
duk_push_string(agent->meshCoreCtx, "Connected"); // [emit][this][Connected]
|
||||
duk_push_int(agent->meshCoreCtx, 1); // [emit][this][Connected][1]
|
||||
if (duk_pcall_method(agent->meshCoreCtx, 2) != 0) { ILibDuktape_Process_UncaughtException(agent->meshCoreCtx); }
|
||||
duk_pop(agent->meshCoreCtx); // ...
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1349,7 +1442,6 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
|
||||
{
|
||||
unsigned short command = ntohs(((unsigned short*)cmd)[0]);
|
||||
unsigned short requestid;
|
||||
MeshAgentDuktapePtrs *meshBindings;
|
||||
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
// If we are not authenticated with the mesh server, we only support auth commands.
|
||||
@@ -1501,49 +1593,41 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
|
||||
// TODO: Verify with Bryan that only the core module will get this. No other modules should.
|
||||
if (cmd[0] == '{' || command >= 1000)
|
||||
{
|
||||
int processed = 0;
|
||||
int popCount = 0;
|
||||
// if (cmd[0] == '{') { cmd[cmdLen] = 0; printf("%s\r\n", cmd); } // DEBUG: Print JSON command
|
||||
meshBindings = agent->DuktapeMeshBindings;
|
||||
while (processed == 0 && meshBindings != NULL)
|
||||
{
|
||||
if (meshBindings->OnCommand != NULL)
|
||||
{
|
||||
duk_push_heapptr(meshBindings->ctx, meshBindings->OnCommand); // [func]
|
||||
duk_push_heapptr(meshBindings->ctx, meshBindings->MeshAgentObject); // [func][this]
|
||||
if (cmd[0] == '{')
|
||||
{
|
||||
// JSON
|
||||
duk_push_global_object(meshBindings->ctx); // [g]
|
||||
duk_get_prop_string(meshBindings->ctx, -1, "JSON"); // [g][JSON]
|
||||
duk_get_prop_string(meshBindings->ctx, -1, "parse"); // [g][JSON][func]
|
||||
duk_swap_top(meshBindings->ctx, -3); // [func][JSON][g]
|
||||
duk_pop_2(meshBindings->ctx); // [func]
|
||||
duk_push_lstring(meshBindings->ctx, cmd, cmdLen); // [func][str]
|
||||
if (duk_pcall(meshBindings->ctx, 1) != 0)
|
||||
{
|
||||
duk_pop(meshBindings->ctx);
|
||||
duk_push_lstring(meshBindings->ctx, cmd, cmdLen);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// BINARY
|
||||
duk_push_external_buffer(meshBindings->ctx); // [func][this][buffer]
|
||||
duk_config_buffer(meshBindings->ctx, -1, cmd, cmdLen);
|
||||
}
|
||||
|
||||
if (duk_pcall_method(meshBindings->ctx, 1) == 0) // [retVal]
|
||||
{
|
||||
if (duk_is_number(meshBindings->ctx, -1)) { processed = duk_get_int(meshBindings->ctx, -1); } // Get the return value
|
||||
}
|
||||
else
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(meshBindings->ctx);
|
||||
}
|
||||
duk_pop(meshBindings->ctx); // ...
|
||||
ILibDuktape_MeshAgent_PUSH(agent->meshCoreCtx, agent->chain); // [agent]
|
||||
duk_get_prop_string(agent->meshCoreCtx, -1, "emit"); // [agent][emit]
|
||||
duk_swap_top(agent->meshCoreCtx, -2); // [emit][this]
|
||||
duk_push_string(agent->meshCoreCtx, "Command"); // [emit][this][Command]
|
||||
if (cmd[0] == '{')
|
||||
{
|
||||
// JSON
|
||||
duk_push_global_object(agent->meshCoreCtx); // [emit][this][Command][g]
|
||||
duk_get_prop_string(agent->meshCoreCtx, -1, "JSON"); // [emit][this][Command][g][JSON]
|
||||
duk_get_prop_string(agent->meshCoreCtx, -1, "parse"); // [emit][this][Command][g][JSON][func]
|
||||
duk_swap_top(agent->meshCoreCtx, -3); // [emit][this][Command][func][JSON][g]
|
||||
duk_pop_2(agent->meshCoreCtx); // [emit][this][Command][func]
|
||||
duk_push_lstring(agent->meshCoreCtx, cmd, cmdLen); // [emit][this][Command][func][str]
|
||||
if (duk_pcall(agent->meshCoreCtx, 1) != 0) // [emit][this][Command][JSON]
|
||||
{
|
||||
duk_pop(agent->meshCoreCtx); // [emit][this][Command]
|
||||
duk_push_lstring(agent->meshCoreCtx, cmd, cmdLen); // [emit][this][Command][str]
|
||||
}
|
||||
meshBindings = meshBindings->Next;
|
||||
popCount = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// BINARY
|
||||
duk_push_external_buffer(agent->meshCoreCtx); // [emit][this][Command][extBuffer]
|
||||
duk_insert(agent->meshCoreCtx, -4); // [extBuffer][emit][this][Command]
|
||||
duk_config_buffer(agent->meshCoreCtx, -4, cmd, cmdLen);
|
||||
duk_push_buffer_object(agent->meshCoreCtx, -4, 0, cmdLen, DUK_BUFOBJ_NODEJS_BUFFER);// [extBuffer][emit][this][Command][buffer]
|
||||
popCount = 2;
|
||||
}
|
||||
|
||||
if (duk_pcall_method(agent->meshCoreCtx, 2) != 0) { ILibDuktape_Process_UncaughtException(agent->meshCoreCtx); }
|
||||
duk_pop_n(agent->meshCoreCtx, popCount); // ...
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1685,16 +1769,19 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
|
||||
{
|
||||
// Indicates the end of the agent update transfer
|
||||
// Check the SHA384 hash of the received file against the file we got.
|
||||
if ((util_sha384file(updateFilePath, updateFileHash) == 0) && (memcmp(updateFileHash, cm->coreModuleHash, sizeof(cm->coreModuleHash)) == 0))
|
||||
if ((GenerateSHA384FileHash(updateFilePath, updateFileHash) == 0) && (memcmp(updateFileHash, cm->coreModuleHash, sizeof(cm->coreModuleHash)) == 0))
|
||||
{
|
||||
printf("UPDATE: End OK\r\n");
|
||||
// Check the file signature & version number
|
||||
//if (signcheck_verifysign(updateFilePath, 1))
|
||||
{
|
||||
// Everything looks good, lets perform the update
|
||||
agent->performSelfUpdate = 1;
|
||||
ILibStopChain(agent->chain);
|
||||
}
|
||||
//printf("UPDATE: End OK\r\n");
|
||||
#ifdef WIN32
|
||||
agent->performSelfUpdate = 1;
|
||||
#else
|
||||
// Set performSelfUpdate to the startupType, on Linux is this important: 1 = systemd, 2 = upstart, 3 = sysv-init
|
||||
int len = ILibSimpleDataStore_Get(agent->masterDb, "StartupType", ILibScratchPad, sizeof(ILibScratchPad));
|
||||
if (len > 0) { agent->performSelfUpdate = atoi(ILibScratchPad); }
|
||||
if (agent->performSelfUpdate == 0) { agent->performSelfUpdate = 999; } // Never allow this value to be zero.
|
||||
#endif
|
||||
// Everything looks good, lets perform the update
|
||||
ILibStopChain(agent->chain);
|
||||
} else {
|
||||
// Hash check failed, delete the file and do nothing. On next server reconnect, we will try again.
|
||||
util_deletefile(updateFilePath);
|
||||
@@ -1816,18 +1903,15 @@ void MeshServer_OnResponse(ILibWebClient_StateObject WebStateObject, int Interru
|
||||
if (agent->serverAuthState == 3)
|
||||
#endif
|
||||
{
|
||||
MeshAgentDuktapePtrs *meshBindings = agent->DuktapeMeshBindings;
|
||||
while (meshBindings != NULL)
|
||||
if (agent->meshCoreCtx != NULL)
|
||||
{
|
||||
if (meshBindings->OnConnect != NULL)
|
||||
{
|
||||
duk_push_heapptr(meshBindings->ctx, meshBindings->OnConnect);
|
||||
duk_push_heapptr(meshBindings->ctx, meshBindings->MeshAgentObject);
|
||||
duk_push_int(meshBindings->ctx, 0); // 0 here as second parameter indicates disconnection
|
||||
if (duk_pcall_method(meshBindings->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(meshBindings->ctx); }
|
||||
duk_pop(meshBindings->ctx);
|
||||
}
|
||||
meshBindings = meshBindings->Next;
|
||||
ILibDuktape_MeshAgent_PUSH(agent->meshCoreCtx, agent->chain); // [agent]
|
||||
duk_get_prop_string(agent->meshCoreCtx, -1, "emit"); // [agent][emit]
|
||||
duk_swap_top(agent->meshCoreCtx, -2); // [emit][this]
|
||||
duk_push_string(agent->meshCoreCtx, "Connected"); // [emit][this][Connected]
|
||||
duk_push_int(agent->meshCoreCtx, 0); // [emit][this][Connected][0] (0 means disconnected)
|
||||
if (duk_pcall_method(agent->meshCoreCtx, 2) != 0) { ILibDuktape_Process_UncaughtException(agent->meshCoreCtx); }
|
||||
duk_pop(agent->meshCoreCtx);
|
||||
}
|
||||
}
|
||||
agent->controlChannel = NULL; // Set the agent MeshCentral server control channel
|
||||
@@ -2094,7 +2178,50 @@ int ValidateMeshServer(ILibWebClient_RequestToken sender, int preverify_ok, STAC
|
||||
}
|
||||
#endif
|
||||
|
||||
void importSettings(MeshAgentHostContainer *agent, char* fileName)
|
||||
|
||||
void checkForEmbeddedMSH(MeshAgentHostContainer *agent)
|
||||
{
|
||||
FILE *tmpFile = NULL;
|
||||
int mshLen;
|
||||
|
||||
#ifdef WIN32
|
||||
fopen_s(&tmpFile, agent->exePath, "rb");
|
||||
#else
|
||||
tmpFile = fopen(agent->exePath, "rb");
|
||||
#endif
|
||||
if (tmpFile == NULL) { return; }
|
||||
|
||||
fseek(tmpFile, -16, SEEK_END);
|
||||
ignore_result(fread(ILibScratchPad, 1, 16, tmpFile));
|
||||
if (memcmp(ILibScratchPad, exeMeshPolicyGuid, 16) == 0)
|
||||
{
|
||||
// Found Embedded MSH File
|
||||
fseek(tmpFile, -20, SEEK_CUR);
|
||||
if (fread((void*)&mshLen, 1, 4, tmpFile) == 4)
|
||||
{
|
||||
mshLen = ntohl(mshLen);
|
||||
fseek(tmpFile, -4 - mshLen, SEEK_CUR);
|
||||
char *eMSH = ILibMemory_AllocateA(mshLen);
|
||||
if (fread(eMSH, 1, mshLen, tmpFile) == mshLen)
|
||||
{
|
||||
FILE *msh = NULL;
|
||||
#ifdef WIN32
|
||||
fopen_s(&msh, MeshAgent_MakeAbsolutePath(agent->exePath, ".msh"), "wb");
|
||||
#else
|
||||
msh = fopen(MeshAgent_MakeAbsolutePath(agent->exePath, ".msh"), "wb");
|
||||
#endif
|
||||
if (msh != NULL)
|
||||
{
|
||||
fwrite(eMSH, 1, mshLen, msh);
|
||||
fclose(msh);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
fclose(tmpFile);
|
||||
}
|
||||
int importSettings(MeshAgentHostContainer *agent, char* fileName)
|
||||
{
|
||||
int eq;
|
||||
char* importFile;
|
||||
@@ -2103,7 +2230,7 @@ void importSettings(MeshAgentHostContainer *agent, char* fileName)
|
||||
parser_result_field *f;
|
||||
|
||||
importFileLen = ILibReadFileFromDiskEx(&importFile, fileName);
|
||||
if (importFileLen == 0) { return; }
|
||||
if (importFileLen == 0) { return(0); }
|
||||
//printf("Importing settings file: %s\n", fileName);
|
||||
|
||||
pr = ILibParseString(importFile, 0, importFileLen, "\n", 1);
|
||||
@@ -2152,6 +2279,8 @@ void importSettings(MeshAgentHostContainer *agent, char* fileName)
|
||||
}
|
||||
ILibDestructParserResults(pr);
|
||||
free(importFile);
|
||||
|
||||
return(importFileLen);
|
||||
}
|
||||
|
||||
void agentDumpKeysSink(ILibSimpleDataStore sender, char* Key, int KeyLen, void *user)
|
||||
@@ -2207,7 +2336,12 @@ void MeshAgent_Slave(MeshAgentHostContainer *agentHost)
|
||||
void MeshAgent_ChainEnd(void *chain, void *user)
|
||||
{
|
||||
MeshAgentHostContainer *agent = (MeshAgentHostContainer*)user;
|
||||
if (agent->meshCoreCtx != NULL) { duk_destroy_heap(agent->meshCoreCtx); }
|
||||
if (agent->meshCoreCtx != NULL)
|
||||
{
|
||||
if (g_displayFinalizerMessages) { printf("\n\n==> Stopping JavaScript Engine\n"); }
|
||||
duk_destroy_heap(agent->meshCoreCtx);
|
||||
}
|
||||
agent->meshCoreCtx = NULL;
|
||||
}
|
||||
|
||||
void MeshAgent_RunScriptOnly_Finalizer(duk_context *ctx, void *user)
|
||||
@@ -2338,14 +2472,26 @@ int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **
|
||||
|
||||
// Read the .proxy file if present and push it into the database
|
||||
{
|
||||
char* str = NULL;
|
||||
int len = (int)util_readfile(MeshAgent_MakeAbsolutePath(agentHost->exePath, ".proxy"), &str, 1024);
|
||||
if (str != NULL) { ILibSimpleDataStore_PutEx(agentHost->masterDb, "WebProxy", 8, str, len); free(str); } else { ILibSimpleDataStore_DeleteEx(agentHost->masterDb, "WebProxy", 8); }
|
||||
char tmp[255];
|
||||
if (ILibSimpleDataStore_GetEx(agentHost->masterDb, "ignoreProxyFile", 15, tmp, sizeof(tmp)) == 0)
|
||||
{
|
||||
char* str = NULL;
|
||||
int len = (int)util_readfile(MeshAgent_MakeAbsolutePath(agentHost->exePath, ".proxy"), &str, 1024);
|
||||
if (str != NULL) { ILibSimpleDataStore_PutEx(agentHost->masterDb, "WebProxy", 8, str, len); free(str); }
|
||||
else { ILibSimpleDataStore_DeleteEx(agentHost->masterDb, "WebProxy", 8); }
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if we need to import a settings file
|
||||
importSettings(agentHost, MeshAgent_MakeAbsolutePath(agentHost->exePath, ".mshx"));
|
||||
importSettings(agentHost, MeshAgent_MakeAbsolutePath(agentHost->exePath, ".msh"));
|
||||
if (importSettings(agentHost, MeshAgent_MakeAbsolutePath(agentHost->exePath, ".mshx")) == 0)
|
||||
{
|
||||
if (importSettings(agentHost, MeshAgent_MakeAbsolutePath(agentHost->exePath, ".msh")) == 0)
|
||||
{
|
||||
// Let's check to see if an .msh was embedded into our binary
|
||||
checkForEmbeddedMSH(agentHost);
|
||||
importSettings(agentHost, MeshAgent_MakeAbsolutePath(agentHost->exePath, ".msh"));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
// If running as a Windows service, set basic values to the registry, this allows other applications to know what the mesh agent is doing.
|
||||
@@ -2495,18 +2641,15 @@ int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **
|
||||
// Check if there is a CoreModule in the db
|
||||
char *CoreModule;
|
||||
int CoreModuleLen = agentHost->localScript == 0 ? ILibSimpleDataStore_Get(agentHost->masterDb, "CoreModule", NULL, 0) : 0;
|
||||
MeshAgentDuktapePtrs* ptrs = agentHost->DuktapeMeshBindings;
|
||||
|
||||
while (ptrs != NULL)
|
||||
|
||||
if (agentHost->meshCoreCtx != NULL)
|
||||
{
|
||||
if (ptrs->OnReady != NULL)
|
||||
{
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->OnReady); // [func]
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->MeshAgentObject); // [func][this]
|
||||
if (duk_pcall_method(ptrs->ctx, 0) != 0) {ILibDuktape_Process_UncaughtException(ptrs->ctx); } // [retVal]
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
}
|
||||
ptrs = ptrs->Next;
|
||||
ILibDuktape_MeshAgent_PUSH(agentHost->meshCoreCtx, agentHost->chain); // [agent]
|
||||
duk_get_prop_string(agentHost->meshCoreCtx, -1, "emit"); // [agent][emit]
|
||||
duk_swap_top(agentHost->meshCoreCtx, -2); // [emit][this]
|
||||
duk_push_string(agentHost->meshCoreCtx, "Ready"); // [emit][this][Ready]
|
||||
if (duk_pcall_method(agentHost->meshCoreCtx, 1) != 0) { ILibDuktape_Process_UncaughtException(agentHost->meshCoreCtx); }
|
||||
duk_pop(agentHost->meshCoreCtx); // ...
|
||||
}
|
||||
|
||||
if (agentHost->localScript == 0)
|
||||
@@ -2532,6 +2675,7 @@ int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **
|
||||
}
|
||||
|
||||
free(CoreModule);
|
||||
if (ILibSimpleDataStore_Get(agentHost->masterDb, "noUpdateCoreModule", NULL, 0) != 0) { agentHost->localScript = 1; printf("** CoreModule: Update Disabled**\n"); }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2757,7 +2901,7 @@ int MeshAgent_Start(MeshAgentHostContainer *agentHost, int paramLen, char **para
|
||||
#endif
|
||||
|
||||
// Perform a self SHA384 Hash
|
||||
util_sha384file(agentHost->exePath, agentHost->agentHash);
|
||||
GenerateSHA384FileHash(agentHost->exePath, agentHost->agentHash);
|
||||
|
||||
#ifdef _REMOTELOGGINGSERVER
|
||||
{
|
||||
@@ -2812,8 +2956,8 @@ int MeshAgent_Start(MeshAgentHostContainer *agentHost, int paramLen, char **para
|
||||
ILibStartChain(agentHost->chain);
|
||||
agentHost->chain = NULL; // Mesh agent has exited, set the chain to NULL
|
||||
|
||||
// Check if we need to perform self-update
|
||||
if (agentHost->performSelfUpdate == 1)
|
||||
// Check if we need to perform self-update (performSelfUpdate should indicate startup type on Liunx: 1 = systemd, 2 = upstart, 3 = sysv-init)
|
||||
if (agentHost->performSelfUpdate != 0)
|
||||
{
|
||||
int i, ptr = 0;
|
||||
#ifdef WIN32
|
||||
@@ -2860,7 +3004,19 @@ int MeshAgent_Start(MeshAgentHostContainer *agentHost, int paramLen, char **para
|
||||
}
|
||||
#else
|
||||
// Linux version
|
||||
{
|
||||
if (agentHost->performSelfUpdate == 1) {
|
||||
// Systemd is in use, move the update using "mv" and restart the systemd service
|
||||
struct stat results;
|
||||
stat(agentHost->exePath, &results); // This the mode of the current executable
|
||||
chmod(updateFilePath, results.st_mode); // Set the new executable to the same mode as the current one.
|
||||
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "mv \"%s\" \"%s\"", updateFilePath, agentHost->exePath); // Move the update over our own executable
|
||||
if (system(ILibScratchPad)) {}
|
||||
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "systemctl restart meshagent"); // Restart the service
|
||||
if (system(ILibScratchPad)) {}
|
||||
} else {
|
||||
// Generic update process, call our own update with arguments.
|
||||
struct stat results;
|
||||
stat(agentHost->exePath, &results); // This the mode of the current executable
|
||||
chmod(updateFilePath, results.st_mode); // Set the new executable to the same mode as the current one.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -118,16 +118,6 @@ typedef struct MeshAgent_Commands_SCRIPT_ExecuteString
|
||||
}MeshAgent_Commands_SCRIPT_ExecuteString;
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef struct MeshAgentDuktapePtrs
|
||||
{
|
||||
struct MeshAgentDuktapePtrs *Next;
|
||||
duk_context *ctx;
|
||||
void *MeshAgentObject;
|
||||
void *OnCommand;
|
||||
void *OnConnect;
|
||||
void *OnReady;
|
||||
}MeshAgentDuktapePtrs;
|
||||
|
||||
typedef enum MeshAgentHost_BatteryInfo
|
||||
{
|
||||
MeshAgentHost_BatteryInfo_HIGH = 1,
|
||||
@@ -148,7 +138,6 @@ typedef struct MeshAgentHostContainer
|
||||
duk_context *meshCoreCtx;
|
||||
char *meshCoreCtx_embeddedScript;
|
||||
int meshCoreCtx_embeddedScriptLen;
|
||||
MeshAgentDuktapePtrs *DuktapeMeshBindings;
|
||||
ILibProcessPipe_Manager *pipeManager;
|
||||
|
||||
char* exePath;
|
||||
@@ -192,6 +181,9 @@ typedef struct MeshAgentHostContainer
|
||||
#ifndef WIN32
|
||||
int dbRetryCount;
|
||||
#endif
|
||||
#if defined(_WINSERVICE)
|
||||
int runningAsConsole;
|
||||
#endif
|
||||
}MeshAgentHostContainer;
|
||||
|
||||
MeshAgentHostContainer* MeshAgent_Create();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -95,10 +95,10 @@
|
||||
<PostBuildEventUseInBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<PostBuildEventUseInBuild>false</PostBuildEventUseInBuild>
|
||||
<PostBuildEventUseInBuild>true</PostBuildEventUseInBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<PostBuildEventUseInBuild>false</PostBuildEventUseInBuild>
|
||||
<PostBuildEventUseInBuild>true</PostBuildEventUseInBuild>
|
||||
<TargetName>$(ProjectName)64</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
@@ -198,7 +198,8 @@
|
||||
<AdditionalOptions> /ignore:4099 %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>signtool.exe sign /sha1 fd5940d8fd585545614fea6da455f25d224b00c9 /d "MeshService" /du "http://opentools.homeip.net" /t http://timestamp.comodoca.com/authenticode "$(TargetPath)"</Command>
|
||||
<Command>REM signtool.exe sign /sha1 fd5940d8fd585545614fea6da455f25d224b00c9 /d "MeshService" /du "http://opentools.homeip.net" /t http://timestamp.comodoca.com/authenticode "$(TargetPath)"
|
||||
"$(OutputPath)$(TargetFileName)" ..\modules\PostBuild.js</Command>
|
||||
</PostBuildEvent>
|
||||
<Manifest>
|
||||
<AdditionalManifestFiles>$(ProjectDir)dpiaware.manifest %(AdditionalManifestFiles)</AdditionalManifestFiles>
|
||||
@@ -233,7 +234,8 @@
|
||||
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>signtool.exe sign /sha1 fd5940d8fd585545614fea6da455f25d224b00c9 /d "MeshService" /du "http://opentools.homeip.net" /t http://timestamp.comodoca.com/authenticode "$(TargetPath)"</Command>
|
||||
<Command>REM signtool.exe sign /sha1 fd5940d8fd585545614fea6da455f25d224b00c9 /d "MeshService" /du "http://opentools.homeip.net" /t http://timestamp.comodoca.com/authenticode "$(TargetPath)"
|
||||
"$(OutputPath)$(TargetFileName)" ..\modules\PostBuild.js</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
@@ -253,9 +255,9 @@
|
||||
<ClCompile Include="..\meshcore\meshinfo.c" />
|
||||
<ClCompile Include="..\meshcore\signcheck.c" />
|
||||
<ClCompile Include="..\microscript\duktape.c" />
|
||||
<ClCompile Include="..\microscript\duk_module_duktape.c" />
|
||||
<ClCompile Include="..\microscript\ILibDuktapeModSearch.c" />
|
||||
<ClCompile Include="..\microscript\ILibDuktape_ChildProcess.c" />
|
||||
<ClCompile Include="..\microscript\ILibDuktape_Debugger.c" />
|
||||
<ClCompile Include="..\microscript\ILibDuktape_Dgram.c" />
|
||||
<ClCompile Include="..\microscript\ILibDuktape_DuplexStream.c" />
|
||||
<ClCompile Include="..\microscript\ILibDuktape_EncryptionStream.c" />
|
||||
@@ -276,9 +278,6 @@
|
||||
<ClCompile Include="..\microscript\ILibDuktape_SimpleDataStore.c" />
|
||||
<ClCompile Include="..\microscript\ILibDuktape_WebRTC.c" />
|
||||
<ClCompile Include="..\microscript\ILibDuktape_WritableStream.c" />
|
||||
<ClCompile Include="..\microscript\ILibParsers_Duktape.c" />
|
||||
<ClCompile Include="..\microscript\ILibWebClient_Duktape.c" />
|
||||
<ClCompile Include="..\microscript\ILibWebServer_Duktape.c" />
|
||||
<ClCompile Include="..\microstack\ILibAsyncServerSocket.c" />
|
||||
<ClCompile Include="..\microstack\ILibAsyncSocket.c" />
|
||||
<ClCompile Include="..\microstack\ILibAsyncUDPSocket.c" />
|
||||
@@ -306,9 +305,9 @@
|
||||
<ClInclude Include="..\meshcore\signcheck.h" />
|
||||
<ClInclude Include="..\microscript\duktape.h" />
|
||||
<ClInclude Include="..\microscript\duk_config.h" />
|
||||
<ClInclude Include="..\microscript\duk_module_duktape.h" />
|
||||
<ClInclude Include="..\microscript\ILibDuktapeModSearch.h" />
|
||||
<ClInclude Include="..\microscript\ILibDuktape_ChildProcess.h" />
|
||||
<ClInclude Include="..\microscript\ILibDuktape_Debugger.h" />
|
||||
<ClInclude Include="..\microscript\ILibDuktape_Dgram.h" />
|
||||
<ClInclude Include="..\microscript\ILibDuktape_DuplexStream.h" />
|
||||
<ClInclude Include="..\microscript\ILibDuktape_EncryptionStream.h" />
|
||||
@@ -327,9 +326,6 @@
|
||||
<ClInclude Include="..\microscript\ILibDuktape_SimpleDataStore.h" />
|
||||
<ClInclude Include="..\microscript\ILibDuktape_WebRTC.h" />
|
||||
<ClInclude Include="..\microscript\ILibDuktape_WritableStream.h" />
|
||||
<ClInclude Include="..\microscript\ILibParsers_Duktape.h" />
|
||||
<ClInclude Include="..\microscript\ILibWebClient_Duktape.h" />
|
||||
<ClInclude Include="..\microscript\ILibWebServer_Duktape.h" />
|
||||
<ClInclude Include="..\microstack\ILibAsyncServerSocket.h" />
|
||||
<ClInclude Include="..\microstack\ILibAsyncSocket.h" />
|
||||
<ClInclude Include="..\microstack\ILibAsyncUDPSocket.h" />
|
||||
|
||||
@@ -34,9 +34,6 @@
|
||||
<ClCompile Include="..\microscript\duktape.c">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\microscript\ILibDuktape_Debugger.c">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\microscript\ILibDuktape_DuplexStream.c">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClCompile>
|
||||
@@ -64,15 +61,6 @@
|
||||
<ClCompile Include="..\microscript\ILibDuktapeModSearch.c">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\microscript\ILibParsers_Duktape.c">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\microscript\ILibWebClient_Duktape.c">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\microscript\ILibWebServer_Duktape.c">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\microstack\ILibAsyncServerSocket.c">
|
||||
<Filter>Microstack</Filter>
|
||||
</ClCompile>
|
||||
@@ -172,6 +160,9 @@
|
||||
<ClCompile Include="..\microscript\ILibDuktape_HttpStream.c">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\microscript\duk_module_duktape.c">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\microscript\duk_config.h">
|
||||
@@ -180,9 +171,6 @@
|
||||
<ClInclude Include="..\microscript\duktape.h">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\microscript\ILibDuktape_Debugger.h">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\microscript\ILibDuktape_DuplexStream.h">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClInclude>
|
||||
@@ -210,15 +198,6 @@
|
||||
<ClInclude Include="..\microscript\ILibDuktapeModSearch.h">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\microscript\ILibParsers_Duktape.h">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\microscript\ILibWebClient_Duktape.h">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\microscript\ILibWebServer_Duktape.h">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\microstack\ILibAsyncServerSocket.h">
|
||||
<Filter>Microstack</Filter>
|
||||
</ClInclude>
|
||||
@@ -316,5 +295,8 @@
|
||||
<ClInclude Include="..\microscript\ILibDuktape_HECI.h">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\microscript\duk_module_duktape.h">
|
||||
<Filter>Microscript</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -226,11 +226,11 @@ BOOL InstallService()
|
||||
|
||||
// Update the faliure action
|
||||
failactions[0].Type = SC_ACTION_RESTART;
|
||||
failactions[0].Delay = 120000; // Wait 2 minutes before faliure restart (milliseconds)
|
||||
failactions[0].Delay = 60000; // Wait 1 minutes before faliure restart (milliseconds)
|
||||
failactions[1].Type = SC_ACTION_RESTART;
|
||||
failactions[1].Delay = 120000; // Wait 2 minutes before faliure restart (milliseconds)
|
||||
failactions[2].Type = SC_ACTION_NONE;
|
||||
failactions[2].Delay = 120000;
|
||||
failactions[1].Delay = 60000; // Wait 1 minutes before faliure restart (milliseconds)
|
||||
failactions[2].Type = SC_ACTION_RESTART;
|
||||
failactions[2].Delay = 60000;
|
||||
memset(&fa, 0, sizeof(SERVICE_FAILURE_ACTIONS));
|
||||
fa.dwResetPeriod = 86400; // After 1 days, reset the faliure counters (seconds)
|
||||
fa.cActions = 3;
|
||||
@@ -501,6 +501,14 @@ void fullinstall(int uninstallonly, char* proxy, int proxylen, char* tag, int ta
|
||||
setup2[setup2len] = 0;
|
||||
remove(setup2);
|
||||
|
||||
// Remove "[Executable].mshx" file
|
||||
if ((setup2len = (int)strnlen_s(targetexe, _MAX_PATH + 40)) < 4 || setup2len > 259) return;
|
||||
memcpy_s(setup2, sizeof(setup2), targetexe, setup2len);
|
||||
memcpy_s(setup2 + (setup2len - 3), sizeof(setup2) - setup2len - 3, "mshx", 5);
|
||||
setup2[setup2len + 1] = 0;
|
||||
remove(setup2);
|
||||
|
||||
|
||||
// Remove "[Executable].proxy" file
|
||||
if ((setup2len = (int)strnlen_s(targetexe, _MAX_PATH + 40)) < 4 || setup2len > 257) return;
|
||||
memcpy_s(setup2, sizeof(setup2), targetexe, setup2len);
|
||||
@@ -778,6 +786,7 @@ int main(int argc, char* argv[])
|
||||
agent = MeshAgent_Create();
|
||||
agent->meshCoreCtx_embeddedScript = integratedJavaScript;
|
||||
agent->meshCoreCtx_embeddedScriptLen = integragedJavaScriptLen;
|
||||
if (integratedJavaScript != NULL || (argc > 1 && strcasecmp(argv[1], "run") == 0)) { agent->runningAsConsole = 1; }
|
||||
MeshAgent_Start(agent, argc, argv);
|
||||
retCode = agent->exitCode;
|
||||
MeshAgent_Destroy(agent);
|
||||
@@ -1100,7 +1109,7 @@ int main(int argc, char* argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* getMshSettings(char* fileName, char** meshname, char** meshid, char** serverid, char** serverurl)
|
||||
char* getMshSettings(char* fileName, char* selfexe, char** meshname, char** meshid, char** serverid, char** serverurl)
|
||||
{
|
||||
char* importFile;
|
||||
int eq, importFileLen;
|
||||
@@ -1109,18 +1118,43 @@ char* getMshSettings(char* fileName, char** meshname, char** meshid, char** serv
|
||||
|
||||
*meshname = *meshid = *serverid = *serverurl = NULL;
|
||||
importFileLen = ILibReadFileFromDiskEx(&importFile, fileName);
|
||||
if (importFile == NULL) return NULL;
|
||||
if (importFile == NULL) {
|
||||
// Could not find the .msh file, see if there is one inside our own executable.
|
||||
FILE *tmpFile = NULL;
|
||||
char exeMeshPolicyGuid[] = { 0xB9, 0x96, 0x01, 0x58, 0x80, 0x54, 0x4A, 0x19, 0xB7, 0xF7, 0xE9, 0xBE, 0x44, 0x91, 0x4C, 0x19 };
|
||||
char tmpHash[16];
|
||||
|
||||
fopen_s(&tmpFile, selfexe, "rb");
|
||||
if (tmpFile == NULL) { return NULL; } // Could not open our own executable
|
||||
|
||||
fseek(tmpFile, -16, SEEK_END);
|
||||
ignore_result(fread(tmpHash, 1, 16, tmpFile)); // Read the GUID
|
||||
if (memcmp(tmpHash, exeMeshPolicyGuid, 16) == 0) { // If this is the Mesh policy file guid, we found a MSH file
|
||||
// Found embedded MSH File
|
||||
fseek(tmpFile, -20, SEEK_CUR);
|
||||
if (fread((void*)&importFileLen, 1, 4, tmpFile) == 4) { // Read the length of the MSH file
|
||||
importFileLen = ntohl(importFileLen);
|
||||
if ((importFileLen >= 20000) || (importFileLen < 1)) { fclose(tmpFile); return NULL; }
|
||||
fseek(tmpFile, -4 - importFileLen, SEEK_CUR);
|
||||
if ((importFile = malloc(importFileLen + 1)) == NULL) { fclose(tmpFile); return NULL; }
|
||||
if (fread(importFile, 1, importFileLen, tmpFile) != importFileLen) { fclose(tmpFile); free(importFile); return NULL; }
|
||||
importFile[importFileLen] = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
fclose(tmpFile);
|
||||
return NULL;
|
||||
}
|
||||
fclose(tmpFile);
|
||||
}
|
||||
|
||||
pr = ILibParseString(importFile, 0, importFileLen, "\n", 1);
|
||||
f = pr->FirstResult;
|
||||
while (f != NULL)
|
||||
{
|
||||
while (f != NULL) {
|
||||
f->datalength = ILibTrimString(&(f->data), f->datalength);
|
||||
if (f->data[0] != 35) // Checking to see if this line is commented out
|
||||
{
|
||||
if (f->data[0] != 35) { // Checking to see if this line is commented out
|
||||
eq = ILibString_IndexOf(f->data, f->datalength, "=", 1);
|
||||
if (eq > 0)
|
||||
{
|
||||
if (eq > 0) {
|
||||
char *key, *val;
|
||||
int keyLen, valLen;
|
||||
|
||||
@@ -1145,6 +1179,7 @@ char* getMshSettings(char* fileName, char** meshname, char** meshid, char** serv
|
||||
return importFile;
|
||||
}
|
||||
|
||||
|
||||
#ifndef _MINCORE
|
||||
|
||||
// Message handler for dialog box.
|
||||
@@ -1229,11 +1264,11 @@ INT_PTR CALLBACK DialogHandler(HWND hDlg, UINT message, WPARAM wParam, LPARAM lP
|
||||
}
|
||||
}
|
||||
|
||||
if ((mshfile = getMshSettings(fileName, &meshname, &meshid, &serverid, &serverurl)) != NULL)
|
||||
if ((mshfile = getMshSettings(fileName, selfexe, &meshname, &meshid, &serverid, &serverurl)) != NULL)
|
||||
{
|
||||
// Set text in the dialog box
|
||||
if (strlen(meshid) > 50) { meshid += 2; meshid[42] = 0; }
|
||||
if (strlen(serverid) > 50) { serverid[42] = 0; }
|
||||
if (strnlen_s(meshid, 255) > 50) { meshid += 2; meshid[42] = 0; }
|
||||
if (strnlen_s(serverid, 255) > 50) { serverid[42] = 0; }
|
||||
SetWindowTextA(GetDlgItem(hDlg, IDC_POLICYTEXT), (meshid != NULL) ? meshname : "(None)");
|
||||
SetWindowTextA(GetDlgItem( hDlg, IDC_HASHTEXT), (meshid != NULL) ? meshid : "(None)");
|
||||
SetWindowTextA(GetDlgItem(hDlg, IDC_SERVERLOCATION), (serverurl != NULL) ? serverurl : "(None)");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -22,7 +22,7 @@ limitations under the License.
|
||||
#include "ILibDuktapeModSearch.h"
|
||||
#include "microstack/ILibParsers.h"
|
||||
#include "microscript/ILibDuktape_Helpers.h"
|
||||
|
||||
#include "microscript/duk_module_duktape.h"
|
||||
|
||||
#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(_MINCORE)
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
@@ -204,6 +204,8 @@ void ILibDuktape_ModSearch_Destroy(duk_context *ctx, void *user)
|
||||
}
|
||||
void ILibDuktape_ModSearch_Init(duk_context * ctx, void * chain, ILibSimpleDataStore mDB)
|
||||
{
|
||||
duk_module_duktape_init(ctx);
|
||||
|
||||
duk_push_heap_stash(ctx); // [stash]
|
||||
duk_push_pointer(ctx, chain); // [stash][chain]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Context_Chain); // [stash]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ILibDuktape_ChildProcess.h"
|
||||
|
||||
#include "ILibDuktapeModSearch.h"
|
||||
@@ -100,6 +116,7 @@ duk_ret_t ILibDuktape_ChildProcess_Kill(duk_context *ctx)
|
||||
ILibDuktape_ChildProcess_SubProcess* ILibDuktape_ChildProcess_SpawnedProcess_PUSH(duk_context *ctx, ILibProcessPipe_Process mProcess, void *callback)
|
||||
{
|
||||
duk_push_object(ctx); // [ChildProcess]
|
||||
ILibDuktape_WriteID(ctx, "childProcess.subProcess");
|
||||
duk_push_pointer(ctx, mProcess); // [ChildProcess][ptr]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_ChildProcess_Process); // [ChildProcess]
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_ChildProcess_SubProcess)); // [ChildProcess][buffer]
|
||||
@@ -121,21 +138,21 @@ ILibDuktape_ChildProcess_SubProcess* ILibDuktape_ChildProcess_SpawnedProcess_PUS
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "kill", ILibDuktape_ChildProcess_Kill, 0);
|
||||
|
||||
duk_push_object(ctx);
|
||||
ILibDuktape_WriteID(ctx, "childProcess.stdout");
|
||||
ILibDuktape_WriteID(ctx, "childProcess.subProcess.stdout");
|
||||
duk_dup(ctx, -2);
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "parent");
|
||||
retVal->stdOut = ILibDuktape_ReadableStream_Init(ctx, ILibDuktape_ChildProcess_SubProcess_StdOut_OnPause, ILibDuktape_ChildProcess_SubProcess_StdOut_OnResume, retVal);
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "stdout");
|
||||
|
||||
duk_push_object(ctx);
|
||||
ILibDuktape_WriteID(ctx, "childProcess.stderr");
|
||||
ILibDuktape_WriteID(ctx, "childProcess.subProcess.stderr");
|
||||
duk_dup(ctx, -2);
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "parent");
|
||||
retVal->stdErr = ILibDuktape_ReadableStream_Init(ctx, ILibDuktape_ChildProcess_SubProcess_StdErr_OnPause, ILibDuktape_ChildProcess_SubProcess_StdErr_OnResume, retVal);
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "stderr");
|
||||
|
||||
duk_push_object(ctx);
|
||||
ILibDuktape_WriteID(ctx, "childProcess.stdin");
|
||||
ILibDuktape_WriteID(ctx, "childProcess.subProcess.stdin");
|
||||
duk_dup(ctx, -2);
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "parent");
|
||||
retVal->stdIn = ILibDuktape_WritableStream_Init(ctx, ILibDuktape_ChildProcess_SubProcess_StdIn_WriteHandler, ILibDuktape_ChildProcess_SubProcess_StdIn_EndHandler, retVal);
|
||||
@@ -231,6 +248,7 @@ duk_ret_t ILibDuktape_ChildProcess_execFile(duk_context *ctx)
|
||||
void ILibDuktape_ChildProcess_PUSH(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx);
|
||||
ILibDuktape_WriteID(ctx, "childProcess");
|
||||
duk_push_pointer(ctx, (void*)ILibProcessPipe_Manager_Create(chain));
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_ChildProcess_Manager);
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_ChildProcess_Manager_Finalizer);
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __ILIBDUKTAPE_CHILDPROCESS__
|
||||
#define __ILIBDUKTAPE_CHILDPROCESS__
|
||||
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(_MINCORE)
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#include <crtdbg.h>
|
||||
@@ -38,7 +54,6 @@ typedef struct ILibDuktape_DGRAM_DATA
|
||||
void *socketObject;
|
||||
void *dgramObject;
|
||||
void *chain;
|
||||
void *OnClose, *OnError, *OnListening, *OnMessage, *OnSendOK;
|
||||
ILibAsyncUDPSocket_SocketModule *mSocket;
|
||||
}ILibDuktape_DGRAM_DATA;
|
||||
typedef enum ILibDuktape_DGRAM_Config
|
||||
@@ -68,34 +83,39 @@ void ILibDuktape_Dgram_Socket_OnData(ILibAsyncUDPSocket_SocketModule socketModul
|
||||
ILibDuktape_DGRAM_DATA* ptrs = (ILibDuktape_DGRAM_DATA*)user;
|
||||
|
||||
|
||||
if (ptrs != NULL && ptrs->ctx != NULL && ptrs->OnMessage != NULL)
|
||||
if (ptrs != NULL && ptrs->ctx != NULL)
|
||||
{
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->OnMessage); // [func]
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->socketObject); // [func][this]
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->socketObject); // [this]
|
||||
duk_get_prop_string(ptrs->ctx, -1, "emit"); // [this][emit]
|
||||
duk_swap_top(ptrs->ctx, -2); // [emit][this]
|
||||
duk_push_string(ptrs->ctx, "message"); // [emit][this][message]
|
||||
duk_push_external_buffer(ptrs->ctx);
|
||||
duk_config_buffer(ptrs->ctx, -1, buffer, (duk_size_t)bufferLength); // [func][this][buffer]
|
||||
duk_push_object(ptrs->ctx); // [func][this][buffer][rinfo]
|
||||
duk_push_string(ptrs->ctx, remoteInterface->sin6_family == AF_INET ? "IPv4" : "IPv6"); // [func][this][buffer][rinfo][family]
|
||||
duk_put_prop_string(ptrs->ctx, -2, "family"); // [func][this][buffer][rinfo]
|
||||
duk_push_string(ptrs->ctx, ILibRemoteLogging_ConvertAddress((struct sockaddr*)remoteInterface)); // [func][this][buffer][rinfo][address]
|
||||
duk_put_prop_string(ptrs->ctx, -2, "address"); // [func][this][buffer][rinfo]
|
||||
duk_push_int(ptrs->ctx, (int)ntohs(remoteInterface->sin6_port)); // [func][this][buffer][rinfo][port]
|
||||
duk_put_prop_string(ptrs->ctx, -2, "port"); // [func][this][buffer][rinfo]
|
||||
duk_config_buffer(ptrs->ctx, -1, buffer, (duk_size_t)bufferLength); // [emit][this][message][buffer]
|
||||
duk_push_object(ptrs->ctx); // [emit][this][message][buffer][rinfo]
|
||||
duk_push_string(ptrs->ctx, remoteInterface->sin6_family == AF_INET ? "IPv4" : "IPv6"); // [emit][this][message][buffer][rinfo][family]
|
||||
duk_put_prop_string(ptrs->ctx, -2, "family"); // [emit][this][message][buffer][rinfo]
|
||||
duk_push_string(ptrs->ctx, ILibRemoteLogging_ConvertAddress((struct sockaddr*)remoteInterface)); // [emit][this][message][buffer][rinfo][address]
|
||||
duk_put_prop_string(ptrs->ctx, -2, "address"); // [emit][this][message][buffer][rinfo]
|
||||
duk_push_int(ptrs->ctx, (int)ntohs(remoteInterface->sin6_port)); // [emit][this][message][buffer][rinfo][port]
|
||||
duk_put_prop_string(ptrs->ctx, -2, "port"); // [emit][this][message][buffer][rinfo]
|
||||
duk_push_int(ptrs->ctx, bufferLength);
|
||||
duk_put_prop_string(ptrs->ctx, -2, "size");
|
||||
|
||||
if (duk_pcall_method(ptrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "dgram.message() dispatch error"); }
|
||||
if (duk_pcall_method(ptrs->ctx, 3) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "dgram.message() dispatch error"); }
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
}
|
||||
}
|
||||
void ILibDuktape_Dgram_Socket_OnSendOK(ILibAsyncUDPSocket_SocketModule socketModule, void *user1, void *user2)
|
||||
{
|
||||
ILibDuktape_DGRAM_DATA* ptrs = (ILibDuktape_DGRAM_DATA*)user1;
|
||||
if (ptrs != NULL && ptrs->ctx != NULL && ptrs->OnSendOK != NULL)
|
||||
if (ptrs != NULL && ptrs->ctx != NULL)
|
||||
{
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->OnSendOK); // [func]
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->socketObject); // [func][this]
|
||||
if (duk_pcall_method(ptrs->ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "net.dgram.socket.onSendOk"); }
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->socketObject); // [this]
|
||||
duk_get_prop_string(ptrs->ctx, -1, "emit"); // [this][emit]
|
||||
duk_swap_top(ptrs->ctx, -2); // [emit][this]
|
||||
duk_push_string(ptrs->ctx, "flushed"); // [emit][this][flushed]
|
||||
if (duk_pcall_method(ptrs->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "net.dgram.socket.onSendOk"); }
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,13 +221,14 @@ duk_ret_t ILibDuktape_DGram_Socket_bind(duk_context *ctx)
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ptrs->OnListening != NULL)
|
||||
{
|
||||
duk_push_heapptr(ctx, ptrs->OnListening); // [func]
|
||||
duk_push_heapptr(ctx, ptrs->socketObject); // [func][this]
|
||||
if (duk_pcall_method(ctx, 0) != 0) { ILibDuktape_Process_UncaughtException(ctx); }
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
|
||||
duk_push_heapptr(ctx, ptrs->socketObject); // [this]
|
||||
duk_get_prop_string(ctx, -1, "emit"); // [this][emit]
|
||||
duk_swap_top(ctx, -2); // [emit][this]
|
||||
duk_push_string(ctx, "listening"); // [emit][this][listening]
|
||||
if (duk_pcall_method(ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(ctx); }
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -352,12 +373,14 @@ duk_ret_t ILibDuktape_DGram_send(duk_context *ctx)
|
||||
if (duk_pcall_method(ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "net.dgram.send.callback(): Error "); }
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
else if(ptrs->OnError != NULL)
|
||||
else
|
||||
{
|
||||
duk_push_heapptr(ctx, ptrs->OnError); // [func]
|
||||
duk_push_heapptr(ctx, ptrs->socketObject); // [func][this]
|
||||
duk_push_heapptr(ctx, ptrs->socketObject); // [this]
|
||||
duk_get_prop_string(ctx, -1, "emit"); // [this][emit]
|
||||
duk_swap_top(ctx, -2); // [emit][this]
|
||||
duk_push_string(ctx, "error"); // [emit][this][error]
|
||||
duk_push_error_object(ctx, DUK_ERR_TYPE_ERROR, "net.dgram.send(): Attempted to send on a closed socket");
|
||||
if (duk_pcall_method(ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "net.dgram.onError(): Error "); }
|
||||
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "net.dgram.onError(): Error "); }
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
break;
|
||||
@@ -433,11 +456,11 @@ duk_ret_t ILibDuktape_DGram_createSocket(duk_context *ctx)
|
||||
ptrs->dgramObject = dgram;
|
||||
ptrs->emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "close", &(ptrs->OnClose));
|
||||
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "error", &(ptrs->OnError));
|
||||
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "listening", &(ptrs->OnListening));
|
||||
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "message", &(ptrs->OnMessage));
|
||||
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "flushed", &(ptrs->OnSendOK));
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "close");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "error");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "listening");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "message");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "flushed");
|
||||
|
||||
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "config", config, "bind", ILibDuktape_DGram_Socket_bind, DUK_VARARGS);
|
||||
|
||||
@@ -459,6 +482,7 @@ duk_ret_t ILibDuktape_DGram_createSocket(duk_context *ctx)
|
||||
void ILibDuktape_DGram_PUSH(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx); // [dgram]
|
||||
ILibDuktape_WriteID(ctx, "dgram");
|
||||
duk_push_pointer(ctx, chain); // [dgram][chain]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_DGRAM_CHAIN); // [dgram]
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "createSocket", ILibDuktape_DGram_createSocket, DUK_VARARGS);
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ___ILibDuktape_Dgram___
|
||||
#define ___ILibDuktape_Dgram___
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "duktape.h"
|
||||
#include "ILibDuktape_Helpers.h"
|
||||
#include "ILibParsers_Duktape.h"
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __ILibDuktape_EncryptionStream__
|
||||
#define __ILibDuktape_EncryptionStream__
|
||||
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __ILibDuktape_EVENT_EMITTER__
|
||||
#define __ILibDuktape_EVENT_EMITTER__
|
||||
|
||||
@@ -22,17 +38,18 @@ ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_GetEmitter_fromThis(duk_conte
|
||||
ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_GetEmitter_fromObject(duk_context *ctx, void *objHeapptr);
|
||||
|
||||
void ILibDuktape_EventEmitter_Init(duk_context *ctx);
|
||||
void ILibDuktape_EventEmitter_RemoveAll(ILibDuktape_EventEmitter *emitter); // Removes all event handlers/dispatchers
|
||||
int ILibDuktape_EventEmitter_GetEventCount(ILibDuktape_EventEmitter *emitter);
|
||||
void ILibDuktape_EventEmitter_RemoveAllListeners(ILibDuktape_EventEmitter *emitter, char *eventName); // Invokes JavaScript method EventEmitter.removeAllListeners()
|
||||
void ILibDuktape_EventEmitter_CreateEvent(ILibDuktape_EventEmitter *emitter, char *eventName, void **hptr); // Create Event with hybrid dispatcher
|
||||
void ILibDuktape_EventEmitter_CreateEventEx(ILibDuktape_EventEmitter *emitter, char *eventName); // Create Event with virtual dispatcher
|
||||
void ILibDuktape_EventEmitter_RemoveEventHeapptr(ILibDuktape_EventEmitter *emitter, char *eventName, void **heapptr); // Remove native callback pointer
|
||||
int ILibDuktape_EventEmitter_AddEventHeapptr(ILibDuktape_EventEmitter *emitter, char *eventName, void **heapptr); // Add Callback after the fact
|
||||
int ILibDuktape_EventEmitter_AddSink(ILibDuktape_EventEmitter *emitter, char *eventName, ILibDuktape_EventEmitter_Handler handler); // Add Native Event Handler
|
||||
int ILibDuktape_EventEmitter_AddOnce(ILibDuktape_EventEmitter *emitter, char *eventName, void *heapptr); // Add native event handler 'once'
|
||||
int ILibDuktape_EventEmitter_AddOnceEx(ILibDuktape_EventEmitter *emitter, char *eventName, duk_c_function func, duk_idx_t funcArgs);
|
||||
int ILibDuktape_EventEmitter_AddOnceEx3(duk_context *ctx, duk_idx_t idx, char *eventName, duk_c_function func);
|
||||
int ILibDuktape_EventEmitter_PrependOnce(duk_context *ctx, duk_idx_t i, char *eventName, duk_c_function func);
|
||||
int ILibDuktape_EventEmitter_HasListeners(ILibDuktape_EventEmitter *emitter, char *eventName);
|
||||
#define ILibDuktape_EventEmitter_HasListenersEx(ctx, idx, eventName) ILibDuktape_EventEmitter_HasListeners(ILibDuktape_EventEmitter_GetEmitter(ctx, idx), eventName)
|
||||
|
||||
#define ILibDuktape_EventEmitter_AddOnceEx2(ctx, idx, eventName, func, argCount) ILibDuktape_EventEmitter_AddOnceEx3(ctx, idx, eventName, func)
|
||||
#define ILibDuktape_EventEmitter_SetupEmit(ctx, heapptr, eventName) duk_push_heapptr((ctx), heapptr);duk_get_prop_string((ctx), -1, "emit");duk_swap_top((ctx), -2);duk_push_string((ctx), eventName)
|
||||
|
||||
int ILibDuktape_EventEmitter_AddOn(ILibDuktape_EventEmitter *emitter, char *eventName, void *heapptr); // Add native event handler
|
||||
int ILibDuktape_EventEmitter_AddOnEx(duk_context *ctx, duk_idx_t idx, char *eventName, duk_c_function func);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ILibDuktape_HECI.h"
|
||||
#include "ILibDuktapeModSearch.h"
|
||||
#include "ILibDuktape_Helpers.h"
|
||||
@@ -220,7 +236,7 @@ duk_ret_t ILibDuktape_HECI_SessionFinalizer(duk_context *ctx)
|
||||
|
||||
void ILibDuktape_HECI_Session_EmitErrorEvent(void *chain, void *session)
|
||||
{
|
||||
if (ILibIsRunningOnChainThread(chain) == 0) { ILibChain_RunOnMicrostackThreadEx(chain, ILibDuktape_HECI_Session_EmitErrorEvent, session); }
|
||||
if (ILibIsRunningOnChainThread(chain) == 0) { ILibChain_RunOnMicrostackThreadEx(chain, ILibDuktape_HECI_Session_EmitErrorEvent, session); return; }
|
||||
ILibDuktape_HECI_Session *s = (ILibDuktape_HECI_Session*)session;
|
||||
duk_context *ctx = s->stream->readableStream->ctx;
|
||||
|
||||
@@ -234,7 +250,7 @@ void ILibDuktape_HECI_Session_EmitErrorEvent(void *chain, void *session)
|
||||
}
|
||||
void ILibDuktape_HECI_Session_EmitStreamReady(void *chain, void *session)
|
||||
{
|
||||
if (ILibIsRunningOnChainThread(chain) == 0) { ILibChain_RunOnMicrostackThreadEx(chain, ILibDuktape_HECI_Session_EmitStreamReady, session); }
|
||||
if (ILibIsRunningOnChainThread(chain) == 0) { ILibChain_RunOnMicrostackThreadEx(chain, ILibDuktape_HECI_Session_EmitStreamReady, session); return; }
|
||||
ILibDuktape_DuplexStream_Ready(((ILibDuktape_HECI_Session*)session)->stream);
|
||||
}
|
||||
|
||||
@@ -278,7 +294,7 @@ ILibTransport_DoneState ILibDuktape_HECI_Session_WriteHandler_Process(ILibDuktap
|
||||
DWORD bytesWritten;
|
||||
BOOL result = TRUE;
|
||||
#else
|
||||
size_t bytesWritten;
|
||||
ssize_t bytesWritten;
|
||||
#endif
|
||||
|
||||
while (ILibQueue_GetCount(session->PendingWrites) > 0)
|
||||
@@ -662,6 +678,7 @@ duk_ret_t ILibDuktape_HECI_Session_connect(duk_context *ctx)
|
||||
duk_ret_t ILibDuktape_HECI_create(duk_context *ctx)
|
||||
{
|
||||
duk_push_object(ctx); // [Session]
|
||||
ILibDuktape_WriteID(ctx, "heci.session");
|
||||
ILibDuktape_HECI_Push(ctx, NULL); // [Session][HECI]
|
||||
duk_dup(ctx, -2); // [Session][HECI][Session]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_HECI_Parent); // [Session][HECI]
|
||||
@@ -939,7 +956,7 @@ void ILibDuktape_HECI_PostSelect(void* object, int slct, fd_set *readset, fd_set
|
||||
}
|
||||
if (FD_ISSET(h->descriptor, writeset))
|
||||
{
|
||||
printf("Writeset\n");
|
||||
ILibDuktape_HECI_Session_WriteHandler_Process(h->session);
|
||||
}
|
||||
}
|
||||
void ILibDuktape_HECI_Destroy(void *object)
|
||||
@@ -957,6 +974,7 @@ void ILibDuktape_HECI_Destroy(void *object)
|
||||
void ILibDuktape_HECI_Push(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx); // [HECI]
|
||||
ILibDuktape_WriteID(ctx, "heci");
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_HECI_Finalizer);
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __DUKTAPEHECI__
|
||||
#define __DUKTAPEHECI__
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -39,6 +39,14 @@ struct sockaddr_in6 duktape_internalAddress;
|
||||
#define ILibDuktape_Memory_AllocTable "\xFF_MemoryAllocTable"
|
||||
#define ILibDuktape_ObjectStashKey "\xFF_ObjectStashKey"
|
||||
|
||||
int ILibDuktape_GetReferenceCount(duk_context *ctx, duk_idx_t i)
|
||||
{
|
||||
int retVal = -1;
|
||||
duk_inspect_value(ctx, i);
|
||||
retVal = Duktape_GetIntPropertyValue(ctx, -1, "refc", -1);
|
||||
duk_pop(ctx);
|
||||
return(retVal-1);
|
||||
}
|
||||
void ILibDuktape_Push_ObjectStash(duk_context *ctx)
|
||||
{
|
||||
if (duk_has_prop_string(ctx, -1, ILibDuktape_ObjectStashKey))
|
||||
@@ -299,7 +307,7 @@ void ILibDuktape_CreateEventWithSetterEx(duk_context *ctx, char *propName, duk_c
|
||||
duk_push_string(ctx, propName); // [obj][prop]
|
||||
duk_push_c_function(ctx, setterMethod, 1); // [obj][prop][setFunc]
|
||||
duk_push_string(ctx, propName); // [obj][prop][setFunc][name]
|
||||
duk_put_prop_string(ctx, -2, "name"); // [obj][prop][setFunc]
|
||||
duk_put_prop_string(ctx, -2, "propName"); // [obj][prop][setFunc]
|
||||
duk_def_prop(ctx, -3, DUK_DEFPROP_FORCE | DUK_DEFPROP_HAVE_SETTER); // [obj]
|
||||
}
|
||||
void ILibDuktape_CreateEventWithSetter(duk_context *ctx, char *propName, char *propNamePtr, void **hptr)
|
||||
@@ -333,6 +341,7 @@ void ILibDuktape_Helper_AddHeapFinalizer(duk_context *ctx, ILibDuktape_HelperEve
|
||||
|
||||
duk_push_heap_stash(ctx); // [g]
|
||||
duk_push_object(ctx); // [g][obj]
|
||||
ILibDuktape_WriteID(ctx, "Mesh.ScriptContainer.heapFinalizer");
|
||||
duk_push_pointer(ctx, user); // [g][obj][user]
|
||||
duk_put_prop_string(ctx, -2, "user"); // [g][obj]
|
||||
duk_push_pointer(ctx, handler); // [g][obj][handler]
|
||||
@@ -362,19 +371,6 @@ int ILibDuktape_Process_GetExitCode(duk_context *ctx)
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
ILibDuktape_EventEmitter *ILibDuktape_Process_GetEventEmitter(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_EventEmitter *retVal = NULL;
|
||||
duk_push_global_object(ctx); // [g]
|
||||
if (duk_has_prop_string(ctx, -1, "process"))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, "process"); // [g][process]
|
||||
retVal = ILibDuktape_EventEmitter_GetEmitter_fromCurrent(ctx);
|
||||
duk_pop(ctx); // [g]
|
||||
}
|
||||
duk_pop(ctx); // ...
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void *ILibDuktape_GetProcessObject(duk_context *ctx)
|
||||
{
|
||||
@@ -420,7 +416,7 @@ void ILibDuktape_Process_UncaughtExceptionEx(duk_context *ctx, char *format, ...
|
||||
void *j = ILibDuktape_GetProcessObject(ctx);
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
|
||||
if (strcmp(errmsg, "Process.exit() forced script termination") == 0) { return; }
|
||||
if (ILibString_IndexOf(errmsg, (int)errmsgLen, "Process.exit() forced script termination", 40) >= 0) { return; }
|
||||
|
||||
duk_push_heapptr(ctx, j); // [process]
|
||||
emitter = ILibDuktape_EventEmitter_GetEmitter_fromCurrent(ctx);
|
||||
@@ -454,7 +450,7 @@ void ILibDuktape_Process_UncaughtExceptionEx(duk_context *ctx, char *format, ...
|
||||
duk_get_prop_string(emitter->ctx, -1, "emit"); // [process][emit]
|
||||
duk_swap_top(emitter->ctx, -2); // [emit][this]
|
||||
duk_push_string(emitter->ctx, "uncaughtException"); // [emit][this][eventName]
|
||||
duk_push_error_object(emitter->ctx, DUK_ERR_UNCAUGHT_ERROR, "%s", dest);
|
||||
duk_push_error_object(emitter->ctx, DUK_ERR_ERROR, "%s", dest);
|
||||
duk_pcall_method(emitter->ctx, 2);
|
||||
duk_pop(emitter->ctx); // ...
|
||||
}
|
||||
@@ -533,18 +529,11 @@ duk_ret_t ILibDuktape_IndependentFinalizer_Dispatch(duk_context *ctx)
|
||||
handler(ctx, duk_get_heapptr(ctx, -1));
|
||||
return 0;
|
||||
}
|
||||
void ILibDuktape_CreateIndependentFinalizer(duk_context *ctx, ILibDuktape_IndependentFinalizerHandler handler)
|
||||
{
|
||||
char tmp[255];
|
||||
|
||||
duk_push_object(ctx); // [obj]
|
||||
duk_push_pointer(ctx, handler); // [obj][ptr]
|
||||
duk_put_prop_string(ctx, -2, "ptr"); // [obj]
|
||||
duk_dup(ctx, -2); // [obj][parent]
|
||||
duk_put_prop_string(ctx, -2, "parent"); // [obj]
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_IndependentFinalizer_Dispatch);
|
||||
sprintf_s(tmp, sizeof(tmp), "\xFF_%s", Duktape_GetStashKey(duk_get_heapptr(ctx, -1)));
|
||||
duk_put_prop_string(ctx, -2, tmp);
|
||||
void ILibDuktape_CreateFinalizer(duk_context *ctx, duk_c_function func)
|
||||
{
|
||||
ILibDuktape_EventEmitter_Create(ctx);
|
||||
ILibDuktape_EventEmitter_PrependOnce(ctx, -1, "~", func);
|
||||
}
|
||||
duk_ret_t ILibDuktape_CreateProperty_InstanceMethod_Sink(duk_context *ctx)
|
||||
{
|
||||
@@ -630,10 +619,14 @@ int ILibDuktape_IsPointerValid(void *chain, void *ptr)
|
||||
{
|
||||
return(ILibHashtable_Get(ILibChain_GetBaseHashtable(chain), ptr, NULL, 0) == NULL ? 0 : 1);
|
||||
}
|
||||
void ILibDuktape_PointerValidation_Finalizer(duk_context *ctx, void *obj)
|
||||
duk_ret_t ILibDuktape_PointerValidation_Finalizer(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx);
|
||||
void *chain = Duktape_GetChain(ctx);
|
||||
void *obj = duk_get_heapptr(ctx, -1);
|
||||
ILibDuktape_InValidatePointer(chain, obj);
|
||||
duk_pop(ctx);
|
||||
return(0);
|
||||
}
|
||||
void ILibDuktape_PointerValidation_Init(duk_context *ctx)
|
||||
{
|
||||
@@ -642,7 +635,7 @@ void ILibDuktape_PointerValidation_Init(duk_context *ctx)
|
||||
{
|
||||
// Not set up yet, so set it up
|
||||
ILibDuktape_ValidatePointer(chain, duk_get_heapptr(ctx, -1));
|
||||
ILibDuktape_CreateIndependentFinalizer(ctx, ILibDuktape_PointerValidation_Finalizer);
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_PointerValidation_Finalizer);
|
||||
}
|
||||
}
|
||||
duk_ret_t ILibDuktape_Immediate_Sink(duk_context *ctx)
|
||||
@@ -664,14 +657,17 @@ duk_ret_t ILibDuktape_Immediate_Sink(duk_context *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
duk_push_heap_stash(ctx); // [immediate][array][stash]
|
||||
duk_del_prop_string(ctx, -1, Duktape_GetStashKey(duk_get_heapptr(ctx, -3)));
|
||||
|
||||
if (userCallback != NULL) { userCallback(ctx, args, argsLen); }
|
||||
|
||||
duk_push_heap_stash(ctx); // [stash]
|
||||
duk_push_this(ctx); // [stash][immediate]
|
||||
duk_del_prop_string(ctx, -2, Duktape_GetStashKey(duk_get_heapptr(ctx, -1)));
|
||||
return(0);
|
||||
}
|
||||
void ILibDuktape_Immediate(duk_context *ctx, void ** args, int argsLen, ILibDuktape_ImmediateHandler callback)
|
||||
void* ILibDuktape_Immediate(duk_context *ctx, void ** args, int argsLen, ILibDuktape_ImmediateHandler callback)
|
||||
{
|
||||
void *retval = NULL;
|
||||
int i = 0;
|
||||
duk_push_global_object(ctx); // [g]
|
||||
duk_get_prop_string(ctx, -1, "setImmediate"); // [g][setImmediate]
|
||||
@@ -690,13 +686,15 @@ void ILibDuktape_Immediate(duk_context *ctx, void ** args, int argsLen, ILibDukt
|
||||
++i;
|
||||
}
|
||||
|
||||
if (duk_pcall_method(ctx, 3) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "ILibDuktape_Immediate => immediate(): "); duk_pop(ctx); return; }
|
||||
if (duk_pcall_method(ctx, 3) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "ILibDuktape_Immediate => immediate(): "); duk_pop(ctx); return(NULL); }
|
||||
|
||||
// [immediate]
|
||||
|
||||
retval = duk_get_heapptr(ctx, -1); // [immediate]
|
||||
duk_push_heap_stash(ctx); // [immediate][stash]
|
||||
duk_swap_top(ctx, -2); // [stash][immediate]
|
||||
duk_put_prop_string(ctx, -2, Duktape_GetStashKey(duk_get_heapptr(ctx, -1)));// [stash]
|
||||
duk_put_prop_string(ctx, -2, Duktape_GetStashKey(retval)); // [stash]
|
||||
duk_pop(ctx); // ...
|
||||
return(retval);
|
||||
}
|
||||
void ILibDuktape_CreateInstanceMethodWithProperties(duk_context *ctx, char *funcName, duk_c_function funcImpl, duk_idx_t numArgs, unsigned int propertyCount, ...)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -61,7 +61,6 @@ void ILibDuktape_Process_UncaughtExceptionEx(duk_context *ctx, char *format, ...
|
||||
|
||||
duk_ret_t ILibDuktape_Error(duk_context *ctx, char *format, ...);
|
||||
typedef void(*ILibDuktape_IndependentFinalizerHandler)(duk_context *ctx, void *object);
|
||||
void ILibDuktape_CreateIndependentFinalizer(duk_context *ctx, ILibDuktape_IndependentFinalizerHandler handler);
|
||||
int ILibDuktape_Process_GetExitCode(duk_context *ctx);
|
||||
|
||||
void ILibDuktape_CreateEventWithGetter(duk_context *ctx, char *propName, duk_c_function getterMethod);
|
||||
@@ -86,7 +85,7 @@ void ILibDuktape_CreateProperty_InstanceMethod(duk_context *ctx, char *methodNam
|
||||
void ILibDuktape_CreateProperty_InstanceMethodEx(duk_context *ctx, char *methodName, void *funcHeapPtr);
|
||||
void ILibDuktape_CreateReadonlyProperty(duk_context *ctx, char *propName);
|
||||
#define ILibDuktape_CreateReadonlyProperty_int(ctx, propName, propValue) duk_push_int(ctx, propValue);ILibDuktape_CreateReadonlyProperty(ctx, propName)
|
||||
#define ILibDuktape_CreateFinalizer(context, funcImpl) duk_push_c_function(context, funcImpl, 1); duk_set_finalizer(context, -2);
|
||||
void ILibDuktape_CreateFinalizer(duk_context *ctx, duk_c_function func);
|
||||
|
||||
void *ILibDuktape_Memory_Alloc(duk_context *ctx, duk_size_t size);
|
||||
void *ILibDuktape_Memory_AllocEx(duk_context *ctx, duk_idx_t index, duk_size_t size);
|
||||
@@ -102,7 +101,8 @@ int ILibDuktape_IsPointerValid(void *chain, void *ptr);
|
||||
#define ILibDuktape_InValidateHeapPointer(ctx, objIdx) ILibDuktape_InValidatePointer(Duktape_GetChain(ctx), duk_get_heapptr(ctx, objIdx))
|
||||
|
||||
typedef void(*ILibDuktape_ImmediateHandler)(duk_context *ctx, void ** args, int argsLen);
|
||||
void ILibDuktape_Immediate(duk_context *ctx, void ** args, int argsLen, ILibDuktape_ImmediateHandler callback);
|
||||
void* ILibDuktape_Immediate(duk_context *ctx, void ** args, int argsLen, ILibDuktape_ImmediateHandler callback);
|
||||
int ILibDuktape_GetReferenceCount(duk_context *ctx, duk_idx_t i);
|
||||
|
||||
#define ILibDuktape_WriteID(ctx, id) duk_push_string(ctx, id);duk_put_prop_string(ctx, -2, ILibDuktape_OBJID)
|
||||
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
@@ -29,7 +45,7 @@ extern void ILibWebClient_ResetWCDO(struct ILibWebClientDataObject *wcdo);
|
||||
#define ILibDuktape_CR2Agent "\xFF_CR2Agent"
|
||||
#define ILibDuktape_CR2HTTPStream "\xFF_CR2HTTPStream"
|
||||
#define ILibDuktape_CR2TLSStream "\xFF_CR2TLSStream"
|
||||
#define ILibDuktape_CR2WS "\xFF_ClientRequest2WS"
|
||||
#define ILibDuktape_CR2Transform "\xFF_CR2Transform"
|
||||
#define ILibDuktape_FUNC "\xFF_FUNC"
|
||||
#define IILibDuktape_HTTP_HoldingQueue "\xFF_HoldingQueue"
|
||||
#define ILibDuktape_Http_Server_FixedBuffer "\xFF_Http_Server_FixedBuffer"
|
||||
@@ -41,7 +57,9 @@ extern void ILibWebClient_ResetWCDO(struct ILibWebClientDataObject *wcdo);
|
||||
#define ILibDuktape_HTTP2PipedWritable "\xFF_HTTP2PipedWritable"
|
||||
#define ILibDuktape_HTTPStream2Data "\xFF_HTTPStream2Data"
|
||||
#define ILibDuktape_HTTPStream2HTTP "\xFF_HTTPStream2HTTP"
|
||||
#define ILibDuktape_HTTPStream2Socket "\xFF_HTTPStream2Socket"
|
||||
#define ILibDuktape_IMSG2HttpStream "\xFF_IMSG2HttpStream"
|
||||
#define ILibDuktape_IMSG2Ptr "\xFF_IMSG2Ptr"
|
||||
#define ILibDuktape_IMSG2SR "\xFF_IMSG2ServerResponse"
|
||||
#define ILibDuktape_NS2HttpServer "\xFF_Http_NetServer2HttpServer"
|
||||
#define ILibDuktape_Options2ClientRequest "\xFF_Options2ClientRequest"
|
||||
@@ -52,16 +70,17 @@ extern void ILibWebClient_ResetWCDO(struct ILibWebClientDataObject *wcdo);
|
||||
#define ILibDuktape_Socket2CR "\xFF_Socket2CR"
|
||||
#define ILibDuktape_Socket2HttpServer "\xFF_Socket2HttpServer"
|
||||
#define ILibDuktape_Socket2HttpStream "\xFF_Socket2HttpStream"
|
||||
#define ILibDuktape_Socket2DiedListener "\xFF_Socket2DiedListener"
|
||||
#define ILibDuktape_Socket2TLS "\xFF_Socket2TLS"
|
||||
#define ILibDuktape_SR2HttpStream "\xFF_ServerResponse2HttpStream"
|
||||
#define ILibDuktape_SR2ImplicitHeaders "\xFF_ServerResponse2ImplicitHeaders"
|
||||
#define ILibDuktape_SR2State "\xFF_ServerResponse2State"
|
||||
#define ILibDuktape_SRUSER "\xFF_SRUSER"
|
||||
#define ILibDuktape_SR2WS "\xFF_Http_ServerResponse2WS"
|
||||
#define ILibDuktape_TLS2CR "\xFF_TLS2CR"
|
||||
#define ILibDuktape_WebSocket_Client ((void*)0x01)
|
||||
#define ILibDuktape_WebSocket_Server ((void*)0x02)
|
||||
#define ILibDuktape_WebSocket_StatePtr "\xFF_WebSocketState"
|
||||
#define ILibDuktape_WSENC2WS "\xFF_WSENC2WS"
|
||||
#define ILibDuktape_WS2CR "\xFF_WS2ClientRequest"
|
||||
#define ILibDuktape_WSDEC2WS "\xFF_WSDEC2WS"
|
||||
|
||||
@@ -73,6 +92,8 @@ typedef struct ILibDuktape_Http_ClientRequest_WriteData
|
||||
int noMoreWrites;
|
||||
int headersFinished;
|
||||
int contentLengthSpecified;
|
||||
int needRetry;
|
||||
int retryCounter;
|
||||
size_t bufferWriteLen;
|
||||
size_t bufferLen;
|
||||
}ILibDuktape_Http_ClientRequest_WriteData;
|
||||
@@ -90,6 +111,7 @@ typedef struct ILibDuktape_HttpStream_Data
|
||||
void *WCDO;
|
||||
void *chain;
|
||||
int ConnectMethod;
|
||||
int endPropagated;
|
||||
}ILibDuktape_HttpStream_Data;
|
||||
|
||||
typedef struct ILibDuktape_HttpStream_ServerResponse_State
|
||||
@@ -129,6 +151,9 @@ typedef struct ILibDuktape_WebSocket_State
|
||||
void *ObjectPtr; // Used to emit Ping/Pong events
|
||||
duk_context *ctx; // Used to emit Ping/Pong events
|
||||
|
||||
int noResume;
|
||||
int closed;
|
||||
|
||||
ILibDuktape_DuplexStream *encodedStream;
|
||||
ILibDuktape_DuplexStream *decodedStream;
|
||||
}ILibDuktape_WebSocket_State;
|
||||
@@ -337,10 +362,10 @@ void ILibDuktape_HttpStream_http_ConvertOptionToSend(duk_context *ctx, void *Obj
|
||||
while (duk_next(ctx, -1, 1))
|
||||
{
|
||||
tmp = (char*)duk_get_lstring(ctx, -2, &len);
|
||||
if (buffer != NULL) { memcpy_s(buffer + bufferLen, ILibMemory_AllocateA_Size(buffer) - bufferLen, tmp, len); (buffer + bufferLen)[len] = ':'; }
|
||||
if (buffer != NULL) { memcpy_s(buffer + bufferLen, ILibMemory_AllocateA_Size(buffer) - bufferLen, tmp, len); (buffer + bufferLen)[len] = ':'; (buffer + bufferLen)[len + 1] = ' '; }
|
||||
if (len == 6 && strncasecmp(tmp, "expect", 6) == 0) { expectSpecified = 1; }
|
||||
if (len == 14 && strncasecmp(tmp, "content-length", 14) == 0) { data->contentLengthSpecified = 1; }
|
||||
bufferLen += (len + 1); // ('key:')
|
||||
bufferLen += (len + 2); // ('key: ')
|
||||
tmp = (char*)duk_get_lstring(ctx, -1, &len);
|
||||
if (buffer != NULL) { memcpy_s(buffer + bufferLen, ILibMemory_AllocateA_Size(buffer) - bufferLen, tmp, len); (buffer + bufferLen)[len] = '\r'; (buffer + bufferLen)[len + 1] = '\n'; }
|
||||
bufferLen += (len + 2); // ('value\r\n')
|
||||
@@ -382,41 +407,21 @@ void ILibDuktape_HttpStream_http_ConvertOptionToSend(duk_context *ctx, void *Obj
|
||||
|
||||
duk_pop_n(ctx, 4); // ...
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_http_OnTLSConnect(duk_context *ctx)
|
||||
|
||||
duk_ret_t ILibDuktape_HttpStream_http_WebSocket_closed(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx); // [TLS]
|
||||
|
||||
// ClientRequest Options => DecryptedTransform
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_TLS2CR); // [TLS][ClientRequest]
|
||||
duk_get_prop_string(ctx, -2, "clear"); // [TLS][ClientRequest][DecryptedTransform]
|
||||
duk_get_prop_string(ctx, -2, ILibDuktape_CR2Options); // [TLS][ClientRequest][DecryptedTransform][Options]
|
||||
|
||||
ILibDuktape_HttpStream_http_ConvertOptionToSend(ctx, duk_get_heapptr(ctx, -2), duk_get_heapptr(ctx, -1));
|
||||
|
||||
// ClientRequest => DecryptedTransform
|
||||
duk_pop(ctx); // [TLS][ClientRequest][DecryptedTransform]
|
||||
duk_get_prop_string(ctx, -2, "pipe"); // [TLS][ClientRequest][DecryptedTransform][pipe]
|
||||
duk_dup(ctx, -3); // [TLS][ClientRequest][DecryptedTransform][pipe][this]
|
||||
duk_dup(ctx, -3); // [TLS][ClientRequest][DecryptedTransform][pipe][this][DecryptedTransform]
|
||||
duk_push_object(ctx); // [TLS][ClientRequest][DecryptedTransform][pipe][this][DecryptedTransform][options]
|
||||
duk_push_false(ctx); duk_put_prop_string(ctx, -2, "end");
|
||||
if (duk_pcall_method(ctx, 2) != 0) { return(ILibDuktape_Error(ctx, "http.onTlsConnect() => Error calling pipe on Transform Stream: %s", duk_safe_to_string(ctx, -1))); }
|
||||
duk_pop_2(ctx); // [TLS][ClientRequest]
|
||||
|
||||
// TLS EncryptedTransform => HTTP Stream
|
||||
duk_get_prop_string(ctx, -2, "encrypted"); // [TLS][ClientRequest][EncryptedTransform]
|
||||
duk_get_prop_string(ctx, -1, "pipe"); // [TLS][ClientRequest][EncryptedTransform][pipe]
|
||||
duk_swap_top(ctx, -2); // [TLS][ClientRequest][pipe][this]
|
||||
duk_get_prop_string(ctx, -3, ILibDuktape_CR2HTTPStream);// [TLS][ClientRequest][pipe][this][http]
|
||||
if (duk_pcall_method(ctx, 1) != 0) { return(ILibDuktape_Error(ctx, "http.onTlsConnect() => Error calling pipe: %s", duk_safe_to_string(ctx, -1))); }
|
||||
duk_pop(ctx); // [TLS][ClientRequest]
|
||||
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_CR2HTTPStream);// [TLS][ClientRequest][http]
|
||||
duk_get_prop_string(ctx, -1, "pipe"); // [TLS][ClientRequest][http][pipe]
|
||||
duk_swap_top(ctx, -2); // [TLS][ClientRequest][pipe][this]
|
||||
duk_get_prop_string(ctx, -4, "clear"); // [TLS][ClientRequest][http][this][decryptedTransform]
|
||||
if (duk_pcall_method(ctx, 1) != 0) { return(ILibDuktape_Error(ctx, "http.onTlsConnect() => Error calling pipe: %s", duk_safe_to_string(ctx, -1))); }
|
||||
|
||||
duk_push_this(ctx); // [socket]
|
||||
if (duk_has_prop_string(ctx, -1, ILibDuktape_Socket2CR))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_Socket2CR); // [socket][CR]
|
||||
duk_push_undefined(ctx); // [socket][CR][undefined]
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "socket"); // [socket][CR]
|
||||
duk_pop(ctx); // [socket]
|
||||
duk_del_prop_string(ctx, -1, ILibDuktape_Socket2CR);
|
||||
}
|
||||
duk_get_prop_string(ctx, -1, "unpipe"); // [socket][unpipe]
|
||||
duk_swap_top(ctx, -2); // [unpipe][this]
|
||||
duk_call_method(ctx, 0);
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_http_onUpgrade(duk_context *ctx)
|
||||
@@ -436,11 +441,27 @@ duk_ret_t ILibDuktape_HttpStream_http_onUpgrade(duk_context *ctx)
|
||||
// We were upgraded to WebSocket, so we need to create a WebSocket Stream, detach the HTTPStream, and emit the event
|
||||
// Upstream Readable => X => HttpStream
|
||||
duk_push_this(ctx); // [HTTPStream]
|
||||
if (duk_has_prop_string(ctx, -1, ILibDuktape_HTTP2CR))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_HTTP2CR); // [HTTPStream][CR]
|
||||
duk_del_prop_string(ctx, -1, ILibDuktape_CR2HTTPStream);
|
||||
duk_pop(ctx); // [HTTPStream]
|
||||
}
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_HTTP2PipedReadable); // [HTTPStream][readable]
|
||||
if (duk_has_prop_string(ctx, -1, ILibDuktape_Socket2HttpStream))
|
||||
{
|
||||
duk_del_prop_string(ctx, -1, ILibDuktape_Socket2HttpStream);
|
||||
}
|
||||
duk_get_prop_string(ctx, -1, "unpipe"); // [HTTPStream][readable][unpipe]
|
||||
duk_dup(ctx, -2); // [HTTPStream][readable][unpipe][this]
|
||||
duk_call_method(ctx, 0); // [HTTPStream][readable][...]
|
||||
duk_pop(ctx); // [HTTPStream][readable]
|
||||
|
||||
duk_get_prop_string(ctx, -1, "prependOnceListener"); // [HTTPStream][readable][prepend]
|
||||
duk_dup(ctx, -2); // [HTTPStream][readable][prepend][this]
|
||||
duk_push_string(ctx, "close"); // [HTTPStream][readable][prepend][this]['close']
|
||||
duk_push_c_function(ctx, ILibDuktape_HttpStream_http_WebSocket_closed, DUK_VARARGS);
|
||||
duk_call_method(ctx, 2); duk_pop(ctx); // [HTTPStream][readable]
|
||||
|
||||
duk_push_external_buffer(ctx); // [HTTPStream][readable][ext]
|
||||
duk_config_buffer(ctx, -1, decodedKey, decodedKeyLen);
|
||||
@@ -453,8 +474,8 @@ duk_ret_t ILibDuktape_HttpStream_http_onUpgrade(duk_context *ctx)
|
||||
duk_remove(ctx, -2); // [HTTPStream][readable][websocket]
|
||||
|
||||
duk_get_prop_string(ctx, -3, ILibDuktape_HTTP2CR); // [HTTPStream][readable][websocket][clientRequest]
|
||||
duk_dup(ctx, -2); // [HTTPStream][readable][websocket][clientRequest][websocket]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_CR2WS); // [HTTPStream][readable][websocket][clientRequest]
|
||||
//duk_dup(ctx, -2); // [HTTPStream][readable][websocket][clientRequest][websocket]
|
||||
//duk_put_prop_string(ctx, -2, ILibDuktape_CR2WS); // [HTTPStream][readable][websocket][clientRequest]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_WS2CR); // [HTTPStream][readable][websocket]
|
||||
|
||||
// Upstream Readable => WebSocket Encoded
|
||||
@@ -475,9 +496,10 @@ duk_ret_t ILibDuktape_HttpStream_http_onUpgrade(duk_context *ctx)
|
||||
duk_call_method(ctx, 1); // [HTTPStream][websocket][...]
|
||||
duk_pop(ctx); // [HTTPStream][websocket]
|
||||
}
|
||||
|
||||
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_WS2CR); // [HTTPStream][websocket][clientRequest]
|
||||
duk_get_prop_string(ctx, -1, "emit"); // [HTTPStream][websocket][clientRequest][emit]
|
||||
|
||||
duk_swap_top(ctx, -2); // [HTTPStream][websocket][emit][this]
|
||||
duk_push_string(ctx, "upgrade"); // [HTTPStream][websocket][emit][this][upgrade]
|
||||
duk_dup(ctx, 0); // [HTTPStream][websocket][emit][this][upgrade][imsg]
|
||||
@@ -486,7 +508,7 @@ duk_ret_t ILibDuktape_HttpStream_http_onUpgrade(duk_context *ctx)
|
||||
duk_remove(ctx, -2); // [HTTPStream][websocket][emit][this][upgrade][imsg][WS_DEC]
|
||||
duk_push_null(ctx); // [HTTPStream][websocket][emit][this][upgrade][imsg][WS_DEC][null]
|
||||
duk_call_method(ctx, 4); duk_pop(ctx); // [HTTPStream][websocket]
|
||||
|
||||
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_http_endResponseSink(duk_context *ctx)
|
||||
@@ -494,21 +516,34 @@ duk_ret_t ILibDuktape_HttpStream_http_endResponseSink(duk_context *ctx)
|
||||
duk_push_this(ctx); // [imsg]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_IMSG2HttpStream); // [imsg][httpstream]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_HTTP2CR); // [imsg][httpstream][CR]
|
||||
|
||||
duk_del_prop_string(ctx, -3, ILibDuktape_IMSG2HttpStream);
|
||||
duk_del_prop_string(ctx, -2, ILibDuktape_HTTP2CR);
|
||||
duk_del_prop_string(ctx, -1, ILibDuktape_CR2HTTPStream);
|
||||
|
||||
duk_get_prop_string(ctx, -1, "unpipe"); // [imsg][httpstream][CR][unpipe]
|
||||
duk_dup(ctx, -2); // [imsg][httpstream][CR][unpipe][this]
|
||||
duk_call_method(ctx, 0); duk_pop(ctx); // [imsg][httpstream][CR]
|
||||
|
||||
duk_get_prop_string(ctx, -1, "socket"); // [imsg][httpstream][CR][socket]
|
||||
duk_insert(ctx, -4); // [socket][imsg][httpstream][CR]
|
||||
duk_push_undefined(ctx); // [socket][imsg][httpstream][CR][undefined]
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "socket"); // [socket][imsg][httpstream][CR]
|
||||
if (Duktape_GetBooleanProperty(ctx, -2, "connectionCloseSpecified", 0) != 0)
|
||||
{
|
||||
// We cant persist this connection, so close the socket.
|
||||
// Agent is already listening for the 'close' event, so it'll cleanup automatically
|
||||
duk_get_prop_string(ctx, -1, "socket"); // [imsg][httpstream][CR][socket]
|
||||
duk_get_prop_string(ctx, -1, "end"); // [imsg][httpstream][CR][socket][end]
|
||||
duk_swap_top(ctx, -2); // [imsg][httpstream][CR][end][this]
|
||||
duk_dup(ctx, -4); // [socket][imsg][httpstream][CR][socket]
|
||||
duk_get_prop_string(ctx, -1, "end"); // [socket][imsg][httpstream][CR][socket][end]
|
||||
duk_swap_top(ctx, -2); // [socket][imsg][httpstream][CR][end][this]
|
||||
duk_call_method(ctx, 0);
|
||||
return(0);
|
||||
}
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_CR2Agent); // [imsg][httpstream][CR][Agent]
|
||||
duk_get_prop_string(ctx, -1, "keepSocketAlive"); // [imsg][httpstream][CR][Agent][keepSocketAlive]
|
||||
duk_swap_top(ctx, -2); // [imsg][httpstream][CR][keepSocketAlive][this]
|
||||
duk_get_prop_string(ctx, -3, "socket"); // [imsg][httpstream][CR][keepSocketAlive][this][socket]
|
||||
duk_call_method(ctx, 1); duk_pop(ctx); // [imsg][httpstream][CR]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_CR2Agent); // [socket][imsg][httpstream][CR][Agent]
|
||||
duk_get_prop_string(ctx, -1, "keepSocketAlive"); // [socket][imsg][httpstream][CR][Agent][keepSocketAlive]
|
||||
duk_swap_top(ctx, -2); // [socket][imsg][httpstream][CR][keepSocketAlive][this]
|
||||
duk_dup(ctx, -6); // [socket][imsg][httpstream][CR][keepSocketAlive][this][socket]
|
||||
duk_call_method(ctx, 1); duk_pop(ctx); // [socket][imsg][httpstream][CR]
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_http_responseSink(duk_context *ctx)
|
||||
@@ -517,8 +552,92 @@ duk_ret_t ILibDuktape_HttpStream_http_responseSink(duk_context *ctx)
|
||||
duk_dup(ctx, 0); // [httpstream][imsg]
|
||||
duk_swap_top(ctx, -2); // [imsg][httpstream]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_IMSG2HttpStream); // [imsg]
|
||||
|
||||
ILibDuktape_EventEmitter_AddOnceEx3(ctx, 0, "end", ILibDuktape_HttpStream_http_endResponseSink);
|
||||
duk_pop(ctx);
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_http_SocketDiedPrematurely(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx); // [socket]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_Socket2CR); // [socket][clientRequest]
|
||||
ILibDuktape_Transform *tf = (ILibDuktape_Transform*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_CR2Transform);
|
||||
if (tf->target->resumeImmediate != NULL)
|
||||
{
|
||||
duk_push_global_object(ctx); // [g]
|
||||
duk_get_prop_string(ctx, -1, "clearImmediate"); // [g][clearImmediate]
|
||||
duk_swap_top(ctx, -2); // [clearImmediate][this]
|
||||
duk_push_heapptr(ctx, tf->target->resumeImmediate); // [clearImmediate][this][immedate]
|
||||
duk_call_method(ctx, 1); duk_pop(ctx); // ...
|
||||
tf->target->resumeImmediate = NULL;
|
||||
}
|
||||
|
||||
duk_get_prop_string(ctx, -1, "unpipe"); // [socket][clientRequest][unpipe]
|
||||
duk_dup(ctx, -2); // [socket][clientRequest][unpipe][this]
|
||||
duk_call_method(ctx, 0); duk_pop(ctx); // [socket][clientRequest]
|
||||
|
||||
ILibDuktape_ReadableStream_DestroyPausedData(tf->target);
|
||||
|
||||
|
||||
// Need to specify some stuff, so the request body will go out again
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_CR_RequestBuffer); // [socket][clientRequest][buffer]
|
||||
ILibDuktape_Http_ClientRequest_WriteData *wdata = (ILibDuktape_Http_ClientRequest_WriteData*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
++wdata->retryCounter;
|
||||
wdata->needRetry = 1;
|
||||
wdata->bufferWriteLen = wdata->bufferLen;
|
||||
wdata->headersFinished = 0;
|
||||
duk_pop(ctx); // [socket][clientRequest]
|
||||
|
||||
if (wdata->retryCounter < 3)
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_CR2Agent); // [socket][clientRequest][agent]
|
||||
duk_get_prop_string(ctx, -1, "requests"); // [socket][clientReqeust][agent][requests]
|
||||
duk_get_prop_string(ctx, -4, ILibDuktape_Socket2AgentKey); // [socket][clientRequest][agent][requests][key]
|
||||
duk_get_prop(ctx, -2); // [socket][clientRequest][agent][requests][array]
|
||||
if (!duk_is_undefined(ctx, -1))
|
||||
{
|
||||
// We need to prepend the clientRequest into the request Queue
|
||||
duk_get_prop_string(ctx, -1, "unshift"); // [socket][clientRequest][agent][requests][array][unshift]
|
||||
duk_swap_top(ctx, -2); // [socket][clientRequest][agent][requests][unshift][this]
|
||||
duk_dup(ctx, -5); // [socket][clientRequest][agent][requests][unshift][this][clientRequest]
|
||||
duk_call_method(ctx, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ILibDuktape_EventEmitter_SetupEmit(ctx, duk_get_heapptr(ctx, -1), "error"); // [emit][this][error]
|
||||
duk_push_error_object(ctx, DUK_ERR_ERROR, "Too many failed attempts"); // [emit][this][error][err]
|
||||
duk_call_method(ctx, 2);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_http_SocketResponseReceived(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx); // [httpStream]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_HTTPStream2Socket); // [httpStream][socket]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_Socket2CR); // [httpStream][socket][CR]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_CR2Options); // [httpStream][socket][CR][Options]
|
||||
duk_del_prop_string(ctx, -1, ILibDuktape_Options2ClientRequest);
|
||||
|
||||
duk_pop_2(ctx); // [httpStream][socket]
|
||||
duk_del_prop_string(ctx, -1, ILibDuktape_Socket2CR);
|
||||
|
||||
duk_get_prop_string(ctx, -1, "removeListener"); // [httpStream][socket][removeListener]
|
||||
duk_swap_top(ctx, -2); // [httpStream][removeListener][this]
|
||||
duk_push_string(ctx, "close"); // [httpStream][removeListener][this][close]
|
||||
duk_get_prop_string(ctx, -2, ILibDuktape_Socket2DiedListener); // [httpStream][removeListener][this][close][listener]
|
||||
duk_call_method(ctx, 2);
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_http_OnSocketClosed(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx); // [socket]
|
||||
if (duk_has_prop_string(ctx, -1, ILibDuktape_Socket2HttpStream))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_Socket2HttpStream); // [socket][stream]
|
||||
duk_pop(ctx); // [socket]
|
||||
duk_del_prop_string(ctx, -1, ILibDuktape_Socket2HttpStream);
|
||||
}
|
||||
duk_pop(ctx); // ...
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
|
||||
@@ -526,17 +645,54 @@ duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
|
||||
void *httpStream;
|
||||
|
||||
duk_dup(ctx, 0); // [socket]
|
||||
duk_push_c_function(ctx, ILibDuktape_HttpStream_http_SocketDiedPrematurely, DUK_VARARGS);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Socket2DiedListener); // [socket]
|
||||
|
||||
duk_push_this(ctx); // [socket][clientRequest]
|
||||
|
||||
// Register ourselves for the close event, becuase we'll need to put ourselves back in the Queue if the socket dies before we are done
|
||||
duk_get_prop_string(ctx, -2, "prependOnceListener"); // [socket][clientRequest][prependOnce]
|
||||
duk_dup(ctx, -3); // [socket][clientRequest][prependOnce][this]
|
||||
duk_push_string(ctx, "close"); // [socket][clientRequest][prependOnce][this][close]
|
||||
duk_get_prop_string(ctx, -5, ILibDuktape_Socket2DiedListener); // [socket][clientRequest][prependOnce][this][close][listener]
|
||||
duk_call_method(ctx, 2); duk_pop(ctx); // [socket][clientRequest]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Socket2CR); // [socket]
|
||||
duk_push_this(ctx); // [socket][clientRequest]
|
||||
|
||||
if (duk_has_prop_string(ctx, -2, ILibDuktape_Socket2HttpStream))
|
||||
{
|
||||
// HTTP and/or TLS was already setup previously
|
||||
duk_get_prop_string(ctx, -2, ILibDuktape_Socket2HttpStream); // [socket][clientRequest][HTTPStream]
|
||||
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -1, "write", ILibDuktape_HttpStream_http_SocketResponseReceived);
|
||||
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_HTTPStream2Data); // [socket][clientRequest][HTTPStream][data]
|
||||
ILibDuktape_HttpStream_Data *data = (ILibDuktape_HttpStream_Data*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
ILibWebClient_ResetWCDO(data->WCDO);
|
||||
if (data->bodyStream != NULL) { ILibDuktape_readableStream_WriteEnd(data->bodyStream); data->bodyStream = NULL; }
|
||||
duk_pop(ctx); // [socket][clientRequest][HTTPStream]
|
||||
|
||||
// We need to change the events to propagate to the new clientRequest instead of the old one
|
||||
duk_get_prop_string(ctx, -1, "removeAllListeners"); // [socket][clientRequest][HTTPStream][remove]
|
||||
duk_dup(ctx, -2); // [socket][clientRequest][HTTPStream][remove][this]
|
||||
duk_push_string(ctx, "response"); // [socket][clientRequest][HTTPStream][remove][this][response]
|
||||
duk_call_method(ctx, 1); duk_pop(ctx); // [socket][clientRequest][HTTPStream]
|
||||
duk_get_prop_string(ctx, -1, "removeAllListeners"); // [socket][clientRequest][HTTPStream][remove]
|
||||
duk_dup(ctx, -2); // [socket][clientRequest][HTTPStream][remove][this]
|
||||
duk_push_string(ctx, "continue"); // [socket][clientRequest][HTTPStream][remove][this][continue]
|
||||
duk_call_method(ctx, 1); duk_pop(ctx); // [socket][clientRequest][HTTPStream]
|
||||
duk_get_prop_string(ctx, -1, "removeAllListeners"); // [socket][clientRequest][HTTPStream][remove]
|
||||
duk_dup(ctx, -2); // [socket][clientRequest][HTTPStream][remove][this]
|
||||
duk_push_string(ctx, "upgrade"); // [socket][clientRequest][HTTPStream][remove][this][upgrade]
|
||||
duk_call_method(ctx, 1); duk_pop(ctx); // [socket][clientRequest][HTTPStream]
|
||||
duk_push_this(ctx); // [socket][clientRequest][HTTPStream][clientRequest]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_HTTP2CR); // [socket][clientRequest][HTTPStream]
|
||||
|
||||
ILibDuktape_EventEmitter_ForwardEvent(ctx, -1, "response", -2, "response");
|
||||
ILibDuktape_EventEmitter_ForwardEvent(ctx, -1, "continue", -2, "continue");
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "upgrade", ILibDuktape_HttpStream_http_onUpgrade);
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "response", ILibDuktape_HttpStream_http_responseSink);
|
||||
|
||||
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_HTTP2PipedWritable); // [socket][clientRequest][HTTPStream][destination]
|
||||
duk_get_prop_string(ctx, -3, ILibDuktape_CR2Options); // [socket][clientRequest][HTTPStream][destination][Options]
|
||||
ILibDuktape_HttpStream_http_ConvertOptionToSend(ctx, duk_get_heapptr(ctx, -2), duk_get_heapptr(ctx, -1));
|
||||
@@ -573,13 +729,14 @@ duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
|
||||
ILibDuktape_EventEmitter_ForwardEvent(ctx, -1, "continue", -2, "continue");
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "upgrade", ILibDuktape_HttpStream_http_onUpgrade);
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "response", ILibDuktape_HttpStream_http_responseSink);
|
||||
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -1, "write", ILibDuktape_HttpStream_http_SocketResponseReceived);
|
||||
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -3, "close", ILibDuktape_HttpStream_http_OnSocketClosed); // We need to detach HttpStream when socket closes
|
||||
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_CR2HTTPStream); // [socket][clientRequest]
|
||||
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_CR2Options); // [socket][clientRequest][options]
|
||||
ILibDuktape_HttpStream_http_ConvertOptionToSend(ctx, duk_get_heapptr(ctx, -3), duk_get_heapptr(ctx, -1));
|
||||
duk_pop(ctx); // [socket][clientRequest]
|
||||
|
||||
|
||||
// ClientRequest => Socket
|
||||
duk_get_prop_string(ctx, -1, "pipe"); // [socket][clientRequest][pipe]
|
||||
duk_swap_top(ctx, -2); // [socket][pipe][this]
|
||||
@@ -589,6 +746,12 @@ duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
|
||||
if (duk_pcall_method(ctx, 2) != 0) { return(ILibDuktape_Error(ctx, "http.onConnect(): Error Piping with socket ")); }
|
||||
duk_pop(ctx); // [socket]
|
||||
|
||||
// Save this value, so we can unregister 'close' from socket later
|
||||
duk_push_heapptr(ctx, httpStream); // [socket][httpStream]
|
||||
duk_dup(ctx, -2); // [socket][httpStream][socket]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2Socket); // [socket][httpStream]
|
||||
duk_pop(ctx); // [socket]
|
||||
|
||||
// Socket => HttpStream
|
||||
duk_get_prop_string(ctx, -1, "pipe"); // [socket][pipe]
|
||||
duk_dup(ctx, -2); // [socket][pipe][this]
|
||||
@@ -601,8 +764,8 @@ duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
|
||||
duk_get_prop_string(ctx, -1, "pipe"); // [socket][http][pipe]
|
||||
duk_swap_top(ctx, -2); // [socket][pipe][this]
|
||||
duk_dup(ctx, -3); // [socket][pipe][this][socket]
|
||||
if (duk_pcall_method(ctx, 1) != 0) { return(ILibDuktape_Error(ctx, "http.onConnect(): Error calling pipe ")); }
|
||||
|
||||
if (duk_pcall_method(ctx, 1) != 0) { return(ILibDuktape_Error(ctx, "http.onConnect(): Error calling pipe ")); }
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_http_OnConnectError(duk_context *ctx)
|
||||
@@ -708,37 +871,7 @@ duk_ret_t ILibDuktape_HttpStream_http_OnConnect(duk_context *ctx)
|
||||
{
|
||||
duk_ret_t retVal = 0;
|
||||
duk_push_this(ctx); // [socket]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_SOCKET2OPTIONS); // [socket][options]
|
||||
|
||||
|
||||
//if (duk_has_prop_string(ctx, -1, "proxy"))
|
||||
//{
|
||||
// duk_get_prop_string(ctx, -1, "proxy"); // [socket][options][proxy]
|
||||
// duk_size_t remoteHostLen;
|
||||
// char *remoteHost = (char*)Duktape_GetStringPropertyValueEx(ctx, -1, "remoteHost", NULL, &remoteHostLen);
|
||||
// int remotePort = Duktape_GetIntPropertyValue(ctx, -1, "remotePort", 0);
|
||||
|
||||
// if (remoteHost != NULL && remotePort != 0)
|
||||
// {
|
||||
// duk_pop_2(ctx); // [socket]
|
||||
// ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "data", ILibDuktape_HttpStream_http_proxyData);
|
||||
|
||||
// duk_get_prop_string(ctx, -1, "write"); // [socket][write]
|
||||
// duk_swap_top(ctx, -2); // [write][this]
|
||||
|
||||
// char *tmp = (char*)ILibMemory_AllocateA((2 * remoteHostLen) + 72);
|
||||
// sprintf_s(tmp, ILibMemory_AllocateA_Size(tmp), "CONNECT %s:%u HTTP/1.1\r\nProxy-Connection: keep-alive\r\nHost: %s\r\n\r\n", remoteHost, remotePort, remoteHost);
|
||||
// duk_push_string(ctx, tmp); // [write][this][chunk]
|
||||
// duk_call_method(ctx, 1);
|
||||
// return(0);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// duk_pop(ctx); // [socket][options]
|
||||
// }
|
||||
//}
|
||||
|
||||
duk_pop(ctx); // [socket]
|
||||
if (duk_has_prop_string(ctx, -1, ILibDuktape_Socket2CR))
|
||||
{
|
||||
// Socket was created with passed in createConnection
|
||||
@@ -781,7 +914,7 @@ void ILibDuktape_HttpStream_http_request_transformPiped(struct ILibDuktape_Trans
|
||||
ILibDuktape_readableStream_WriteData(sender->target, tmp, tmpLen);
|
||||
if (data->bufferWriteLen > 0) { ILibDuktape_readableStream_WriteData(sender->target, data->buffer, (int)data->bufferWriteLen); }
|
||||
}
|
||||
else if(data->bufferWriteLen > 0)
|
||||
else if(data->needRetry != 0)
|
||||
{
|
||||
if (data->headersFinished)
|
||||
{
|
||||
@@ -790,15 +923,27 @@ void ILibDuktape_HttpStream_http_request_transformPiped(struct ILibDuktape_Trans
|
||||
else
|
||||
{
|
||||
data->headersFinished = 1;
|
||||
tmpLen = sprintf_s(tmp, sizeof(tmp), "Transfer-Encoding: chunked\r\n\r\n%X\r\n", (unsigned int)data->bufferWriteLen);
|
||||
if (data->contentLengthSpecified)
|
||||
{
|
||||
tmpLen = sprintf_s(tmp, sizeof(tmp), "Content-Length: %d\r\n\r\n", (int)data->bufferWriteLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmpLen = sprintf_s(tmp, sizeof(tmp), "Transfer-Encoding: chunked\r\n\r\n%X\r\n", (unsigned int)data->bufferWriteLen);
|
||||
}
|
||||
}
|
||||
|
||||
ILibDuktape_readableStream_WriteData(sender->target, tmp, tmpLen);
|
||||
ILibDuktape_readableStream_WriteData(sender->target, data->buffer, (int)data->bufferWriteLen);
|
||||
ILibDuktape_readableStream_WriteData(sender->target, "\r\n", 2);
|
||||
free(data->buffer);
|
||||
data->buffer = NULL;
|
||||
if (data->bufferWriteLen > 0)
|
||||
{
|
||||
ILibDuktape_readableStream_WriteData(sender->target, data->buffer, (int)data->bufferWriteLen);
|
||||
if (!data->contentLengthSpecified) { ILibDuktape_readableStream_WriteData(sender->target, "\r\n", 2); }
|
||||
|
||||
free(data->buffer);
|
||||
data->buffer = NULL;
|
||||
}
|
||||
data->bufferLen = data->bufferWriteLen = 0;
|
||||
data->needRetry = 0;
|
||||
}
|
||||
}
|
||||
void ILibDuktape_HttpStream_http_request_transform(struct ILibDuktape_Transform *sender, int Reserved, int flush, char *buffer, int bufferLen, void *user)
|
||||
@@ -820,6 +965,13 @@ void ILibDuktape_HttpStream_http_request_transform(struct ILibDuktape_Transform
|
||||
{
|
||||
ILibDuktape_readableStream_WriteData(sender->target, buffer, bufferLen);
|
||||
}
|
||||
data->contentLengthSpecified = 1;
|
||||
if (bufferLen > 0)
|
||||
{
|
||||
data->buffer = (char*)ILibMemory_Allocate(bufferLen, 0, NULL, NULL);
|
||||
data->bufferLen = bufferLen;
|
||||
memcpy_s(data->buffer, bufferLen, buffer, bufferLen);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -844,11 +996,12 @@ void ILibDuktape_HttpStream_http_request_transform(struct ILibDuktape_Transform
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_HttpStream_http_request(duk_context *ctx)
|
||||
{
|
||||
char *proto;
|
||||
duk_size_t protoLen;
|
||||
|
||||
int isTLS = 0;
|
||||
int nargs = duk_get_top(ctx);
|
||||
if (duk_is_string(ctx, 0))
|
||||
{
|
||||
@@ -881,7 +1034,8 @@ duk_ret_t ILibDuktape_HttpStream_http_request(duk_context *ctx)
|
||||
duk_put_prop_string(ctx, -2, "agent"); // [options][protocol][options]
|
||||
duk_pop(ctx); // [options][protocol]
|
||||
}
|
||||
|
||||
if ((protoLen == 4 && strncasecmp(proto, "wss:", 4) == 0) || (protoLen == 6 && strncasecmp(proto, "https:", 6) == 0)) { isTLS = 1; }
|
||||
|
||||
duk_pop(ctx); // [options]
|
||||
if (!duk_has_prop_string(ctx, -1, "headers"))
|
||||
{
|
||||
@@ -912,15 +1066,16 @@ duk_ret_t ILibDuktape_HttpStream_http_request(duk_context *ctx)
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_CR2HTTP); // [clientRequest]
|
||||
|
||||
duk_push_false(ctx);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_CR_EndCalled); // [clientRequest]
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_Http_ClientRequest_WriteData));
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_CR_EndCalled); // [clientRequest]
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_Http_ClientRequest_WriteData)); // [clientRequest][buffer]
|
||||
ILibDuktape_Http_ClientRequest_WriteData *wdata = (ILibDuktape_Http_ClientRequest_WriteData*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_CR_RequestBuffer);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_CR_RequestBuffer); // [clientRequest]
|
||||
memset(wdata, 0, sizeof(ILibDuktape_Http_ClientRequest_WriteData));
|
||||
|
||||
ILibDuktape_Transform_Init(ctx, ILibDuktape_HttpStream_http_request_transform, ILibDuktape_HttpStream_http_request_transformPiped, wdata);
|
||||
duk_push_pointer(ctx, ILibDuktape_Transform_Init(ctx, ILibDuktape_HttpStream_http_request_transform, ILibDuktape_HttpStream_http_request_transformPiped, wdata));
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_CR2Transform); // [clientRequest]
|
||||
|
||||
ILibDuktape_WriteID(ctx, "https.clientRequest");
|
||||
ILibDuktape_WriteID(ctx, isTLS ? "https.clientRequest" : "http.clientRequest");
|
||||
ILibDuktape_EventEmitter *emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "abort");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "connect");
|
||||
@@ -930,8 +1085,18 @@ duk_ret_t ILibDuktape_HttpStream_http_request(duk_context *ctx)
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "timeout");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "upgrade");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "error");
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "socket", ILibDuktape_HttpStream_http_OnSocketReady);
|
||||
|
||||
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -1, "socket", ILibDuktape_HttpStream_http_OnSocketReady);
|
||||
|
||||
|
||||
if (nargs > 1 && duk_is_function(ctx, 1))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, "once"); // [clientRequest][once]
|
||||
duk_dup(ctx, -2); // [clientRequest][once][this]
|
||||
duk_push_string(ctx, "response"); // [clientRequest][once][this][response]
|
||||
duk_dup(ctx, 1); // [clientRequest][once][this][response][handler]
|
||||
duk_call_method(ctx, 2); duk_pop(ctx); // [clientRequest]
|
||||
}
|
||||
|
||||
duk_dup(ctx, 0); // [clientRequest][options]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_CR2Options); // [clientReqeust]
|
||||
@@ -1185,7 +1350,6 @@ duk_ret_t ILibDuktape_HttpStream_http_server_upgradeWebsocket(duk_context *ctx)
|
||||
duk_get_prop_string(ctx, -1, "webSocketStream"); // [http][constructor]
|
||||
duk_push_lstring(ctx, keyResult, keyResultLen); // [http][constructor][key]
|
||||
duk_new(ctx, 1); // [http][wss]
|
||||
|
||||
|
||||
duk_push_this(ctx); // [http][wss][socket]
|
||||
duk_get_prop_string(ctx, -1, "pipe"); // [http][wss][socket][pipe]
|
||||
@@ -1311,7 +1475,8 @@ duk_ret_t ILibDuktape_HttpStream_http_server_onConnection(duk_context *ctx)
|
||||
//ILibDuktape_EventEmitter_ForwardEvent(ctx, -2, "close", -1, "close");
|
||||
ILibDuktape_EventEmitter_ForwardEvent(ctx, -2, "connect", -1, "connect");
|
||||
ILibDuktape_EventEmitter_ForwardEvent(ctx, -2, "request", -1, "request");
|
||||
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -2, "upgrade", ILibDuktape_HttpStream_http_server_onUpgrade);
|
||||
if (ILibDuktape_EventEmitter_HasListenersEx(ctx, -1, "upgrade") > 0) { ILibDuktape_EventEmitter_AddOnceEx3(ctx, -2, "upgrade", ILibDuktape_HttpStream_http_server_onUpgrade); }
|
||||
|
||||
duk_pop(ctx); // [NS][socket][pipe][this][httpStream]
|
||||
duk_call_method(ctx, 1); duk_pop_2(ctx); // [NS]
|
||||
|
||||
@@ -1396,6 +1561,7 @@ duk_ret_t ILibDuktape_HttpStream_http_server_address(duk_context *ctx)
|
||||
duk_call_method(ctx, 0); // [httpServer][result]
|
||||
return(1);
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_HttpStream_http_createServer(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_Http_Server *server;
|
||||
@@ -1430,7 +1596,7 @@ duk_ret_t ILibDuktape_HttpStream_http_createServer(duk_context *ctx)
|
||||
|
||||
if (nargs > 0 && duk_is_function(ctx, 0))
|
||||
{
|
||||
ILibDuktape_EventEmitter_AddOn(emitter, "request", duk_require_heapptr(ctx, 1));
|
||||
ILibDuktape_EventEmitter_AddOn(emitter, "request", duk_require_heapptr(ctx, 0));
|
||||
}
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "close", ILibDuktape_HttpStream_http_server_close, DUK_VARARGS);
|
||||
@@ -1451,18 +1617,17 @@ duk_ret_t ILibDuktape_HttpStream_http_createServer(duk_context *ctx)
|
||||
duk_get_prop_string(ctx, -1, "createServer"); // [server][nettls][createServer]
|
||||
duk_swap_top(ctx, -2); // [server][createServer][this]
|
||||
|
||||
if (nargs > 0 && duk_is_object(ctx, 0))
|
||||
if (nargs > 0 && duk_is_object(ctx, 0) && !duk_is_function(ctx, 0))
|
||||
{
|
||||
// Options was specified
|
||||
duk_dup(ctx, 0); // [server][createServer][this][options]
|
||||
}
|
||||
duk_push_c_function(ctx, ILibDuktape_HttpStream_http_server_onConnection, DUK_VARARGS);
|
||||
|
||||
duk_call_method(ctx, (nargs > 0 && duk_is_object(ctx, 0)) ? 2 : 1); // [server][netServer]
|
||||
duk_call_method(ctx, (nargs > 0 && duk_is_object(ctx, 0) && !duk_is_function(ctx, 0)) ? 2 : 1); // [server][netServer]
|
||||
duk_dup(ctx, -2); // [server][netServer][server]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_NS2HttpServer); // [server][netServer]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Http_Server2NetServer); // [server]
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
@@ -1547,6 +1712,13 @@ ILibTransport_DoneState ILibDuktape_HttpStream_WriteSink(ILibDuktape_DuplexStrea
|
||||
return(ILibTransport_DoneState_INCOMPLETE);
|
||||
}
|
||||
|
||||
duk_push_heapptr(DS->readableStream->ctx, DS->ParentObject); // [httpStream]
|
||||
duk_get_prop_string(DS->readableStream->ctx, -1, "emit"); // [httpStream][emit]
|
||||
duk_swap_top(DS->readableStream->ctx, -2); // [emit][this]
|
||||
duk_push_string(DS->readableStream->ctx, "write"); // [emit][this][write]
|
||||
if (duk_pcall_method(DS->readableStream->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(DS->readableStream->ctx, "httpStream.write(): Error dispatching 'write' event "); }
|
||||
duk_pop(DS->readableStream->ctx); // ...
|
||||
|
||||
// We're already on Chain Thread, so we can just directly write
|
||||
int beginPointer = 0;
|
||||
int PAUSE = 0;
|
||||
@@ -1571,7 +1743,7 @@ ILibTransport_DoneState ILibDuktape_HttpStream_WriteSink(ILibDuktape_DuplexStrea
|
||||
duk_swap_top(stream->ctx, -2); // [extBuffer][unshift][this]
|
||||
duk_push_buffer_object(stream->ctx, -3, 0, (int)bufferLen - beginPointer, DUK_BUFOBJ_NODEJS_BUFFER);// [extBuffer][unshift][this][buffer]
|
||||
if (duk_pcall_method(stream->ctx, 1) != 0) { MustBuffer = 1; }
|
||||
duk_pop(stream->ctx); // ...
|
||||
duk_pop_2(stream->ctx); // ...
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1631,9 +1803,10 @@ void ILibDuktape_HttpStream_EndSink(ILibDuktape_DuplexStream *stream, void *user
|
||||
{
|
||||
ILibDuktape_HttpStream_Data *data = (ILibDuktape_HttpStream_Data*)user;
|
||||
|
||||
if (data->bodyStream != NULL)
|
||||
if (data->bodyStream != NULL && data->endPropagated == 0)
|
||||
{
|
||||
ILibDuktape_readableStream_WriteEnd(data->bodyStream);
|
||||
data->endPropagated = 1;
|
||||
}
|
||||
}
|
||||
void ILibDuktape_HttpStream_ServerResponse_WriteImplicitHeaders(void *chain, void *user)
|
||||
@@ -1786,9 +1959,9 @@ ILibTransport_DoneState ILibDuktape_HttpStream_ServerResponse_WriteSink(struct I
|
||||
tmp->writeStream = state->writeStream;
|
||||
tmp->endBytes = stream->endBytes;
|
||||
tmp->chunk = state->chunkSupported;
|
||||
if (bufferLen > 0) { memcpy_s(tmp->buffer, bufferLen, buffer, bufferLen); }
|
||||
if (bufferLen > 0) { memcpy_s(tmp->buffer, bufferLen, buffer, bufferLen); tmp->bufferLen = bufferLen; }
|
||||
|
||||
ILibDuktape_HttpStream_ServerResponse_WriteImplicitHeaders(NULL, &tmp);
|
||||
ILibDuktape_HttpStream_ServerResponse_WriteImplicitHeaders(NULL, tmp);
|
||||
return(ILibTransport_DoneState_COMPLETE);
|
||||
}
|
||||
else
|
||||
@@ -2216,9 +2389,21 @@ void ILibDuktape_HttpStream_ServerResponse_PUSH(duk_context *ctx, void* writeStr
|
||||
{
|
||||
ILibDuktape_HttpStream_ServerResponse_State *state;
|
||||
|
||||
duk_push_object(ctx); // [resp]
|
||||
duk_push_heapptr(ctx, httpStream); // [resp][httpStream]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_SR2HttpStream); // [resp]
|
||||
duk_push_object(ctx); // [resp]
|
||||
duk_push_heapptr(ctx, httpStream); // [resp][httpStream]
|
||||
duk_dup(ctx, -1); // [resp][httpStream][dup]
|
||||
duk_put_prop_string(ctx, -3, ILibDuktape_SR2HttpStream); // [resp][httpStream]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_HTTPStream2HTTP); // [resp][httpStream][http]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_OBJID); // [resp][httpStream][http][id]
|
||||
duk_remove(ctx, -2); // [resp][httpStream][id]
|
||||
duk_get_prop_string(ctx, -1, "concat"); // [resp][httpStream][id][concat]
|
||||
duk_swap_top(ctx, -2); // [resp][httpStream][concat][this]
|
||||
duk_push_string(ctx, ".serverResponse"); // [resp][httpStream][concat][this][serverResponse]
|
||||
if (duk_pcall_method(ctx, 1) != 0) { duk_pop(ctx); duk_push_string(ctx, "http[s].serverResponse"); } // [resp][httpStream][http/s.serverResponse]
|
||||
duk_remove(ctx, -2); // [resp][http/s.serverResponse]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_OBJID); // [resp]
|
||||
|
||||
|
||||
ILibDuktape_PointerValidation_Init(ctx);
|
||||
ILibDuktape_WriteID(ctx, "http.serverResponse");
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_HttpStream_ServerResponse_State)); // [resp][state]
|
||||
@@ -2408,11 +2593,27 @@ duk_ret_t ILibDuktape_HttpStream_IncomingMessage_Digest_ValidatePassword(duk_con
|
||||
duk_push_int(ctx, retVal);
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_IncomingMessage_finalizer(duk_context *ctx)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
void ILibDuktape_HttpStream_IncomingMessage_PUSH(duk_context *ctx, ILibHTTPPacket *header, void *httpstream)
|
||||
{
|
||||
duk_push_object(ctx); // [message]
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_HttpStream_IncomingMessage_finalizer);
|
||||
duk_push_heapptr(ctx, httpstream); // [message][httpStream]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_IMSG2HttpStream); // [message]
|
||||
duk_dup(ctx, -1); // [message][httpStream][dup]
|
||||
duk_put_prop_string(ctx, -3, ILibDuktape_IMSG2HttpStream); // [message][httpStream]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_HTTPStream2HTTP); // [message][httpStream][http]
|
||||
duk_remove(ctx, -2); // [message][http]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_OBJID); // [message][http][id]
|
||||
duk_get_prop_string(ctx, -1, "concat"); // [message][http][id][concat]
|
||||
duk_swap_top(ctx, -2); // [message][http][concat][this]
|
||||
duk_push_string(ctx, ".IncomingMessage"); // [message][http][concat][this][.IncomingMessage]
|
||||
if (duk_pcall_method(ctx, 1) != 0) { duk_pop(ctx); duk_push_string(ctx, "http[s].IncomingMessage"); }
|
||||
duk_remove(ctx, -2); // [message][http/s.IncomingMessage]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_OBJID); // [message]
|
||||
|
||||
duk_push_object(ctx); // [message][headers]
|
||||
packetheader_field_node *node = header->FirstField;
|
||||
while (node != NULL)
|
||||
@@ -2479,7 +2680,26 @@ void ILibDuktape_HttpStream_DispatchEnd(void *chain, void *user)
|
||||
}
|
||||
free(user);
|
||||
}
|
||||
void ILibDuktape_HttpStream_ForceDisconnect(duk_context *ctx, void ** args, int argsLen)
|
||||
{
|
||||
duk_push_heapptr(ctx, args[0]);
|
||||
duk_get_prop_string(ctx, -1, "end");
|
||||
duk_swap_top(ctx, -2);
|
||||
if (duk_pcall_method(ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "httpStream.OnUpgrade(): "); }
|
||||
duk_pop(ctx);
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_HttpStream_OnReceive_bodyStreamFinalized(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_HttpStream_Data *data = (ILibDuktape_HttpStream_Data*)Duktape_GetPointerProperty(ctx, 0, ILibDuktape_IMSG2Ptr);
|
||||
if (data != NULL)
|
||||
{
|
||||
if (data->endPropagated == 0) { ILibDuktape_readableStream_WriteEnd(data->bodyStream); }
|
||||
data->endPropagated = 1;
|
||||
data->bodyStream = NULL;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject, int InterruptFlag, struct packetheader *header, char *bodyBuffer, int *beginPointer, int endPointer, ILibWebClient_ReceiveStatus recvStatus, void *user1, void *user2, int *PAUSE)
|
||||
{
|
||||
ILibDuktape_HttpStream_Data *data = (ILibDuktape_HttpStream_Data*)user1;
|
||||
@@ -2525,7 +2745,22 @@ void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject,
|
||||
ILibDuktape_HttpStream_IncomingMessage_PUSH(ctx, header, data->DS->ParentObject); // [emit][this][upgrade][imsg]
|
||||
ILibDuktape_HttpStream_ServerResponse_PUSH(ctx, data->DS->writableStream->pipedReadable, header, data->DS->ParentObject); // [emit][this][request][imsg][rsp]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_IMSG2SR);
|
||||
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.httpStream.onReceive->upgrade(): "); }
|
||||
if (duk_pcall_method(ctx, 2) != 0)
|
||||
{ ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.httpStream.onReceive->upgrade(): "); }
|
||||
else
|
||||
{
|
||||
if (!duk_get_boolean(ctx, -1))
|
||||
{
|
||||
// No upgrade listener... Close connection
|
||||
printf("\n\nNo Upgrade Listener\n");
|
||||
void *imm = ILibDuktape_Immediate(ctx, (void*[]) { data->DS->writableStream->pipedReadable }, 1, ILibDuktape_HttpStream_ForceDisconnect);
|
||||
duk_push_heapptr(ctx, imm);
|
||||
duk_push_heapptr(ctx, data->DS->writableStream->pipedReadable);
|
||||
duk_put_prop_string(ctx, -2, "r");
|
||||
duk_pop_2(ctx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
else
|
||||
@@ -2604,15 +2839,27 @@ void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject,
|
||||
case 101:
|
||||
duk_push_string(ctx, "upgrade"); // [emit][this][upgrade]
|
||||
ILibDuktape_HttpStream_IncomingMessage_PUSH(ctx, header, data->DS->ParentObject); // [emit][this][upgrade][imsg]
|
||||
duk_del_prop_string(ctx, -1, ILibDuktape_IMSG2HttpStream);
|
||||
duk_insert(ctx, -4); // [imsg][emit][this][upgrade]
|
||||
duk_dup(ctx, -4); // [imsg][emit][this][upgrade][imsg]
|
||||
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.httpStream.onReceive->upgrade(): "); }
|
||||
duk_pop(ctx);
|
||||
duk_pop(ctx);
|
||||
break;
|
||||
default:
|
||||
duk_push_string(ctx, "response"); // [emit][this][response]
|
||||
ILibDuktape_HttpStream_IncomingMessage_PUSH(ctx, header, data->DS->ParentObject); // [emit][this][response][imsg]
|
||||
data->bodyStream = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_HttpStream_IncomingMessage_PauseSink, ILibDuktape_HttpStream_IncomingMessage_ResumeSink, ILibDuktape_HttpStream_IncomingMessage_UnshiftBytes, data);
|
||||
duk_push_pointer(ctx, data);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_IMSG2Ptr);
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "~", ILibDuktape_HttpStream_OnReceive_bodyStreamFinalized);
|
||||
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.httpStream.onReceive->response(): "); }
|
||||
duk_pop(ctx);
|
||||
|
||||
if (bodyBuffer != NULL && endPointer > 0)
|
||||
{
|
||||
ILibDuktape_readableStream_WriteData(data->bodyStream, bodyBuffer + *beginPointer, endPointer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2620,6 +2867,7 @@ void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject,
|
||||
if (data->bodyStream != NULL && recvStatus == ILibWebClient_ReceiveStatus_Complete)
|
||||
{
|
||||
ILibDuktape_readableStream_WriteEnd(data->bodyStream);
|
||||
data->endPropagated = 1;
|
||||
}
|
||||
if (recvStatus == ILibWebClient_ReceiveStatus_Complete)
|
||||
{
|
||||
@@ -2651,7 +2899,6 @@ duk_ret_t ILibDuktape_HttpStream_Finalizer(duk_context *ctx)
|
||||
ILibDuktape_InValidateHeapPointer(ctx, 0);
|
||||
|
||||
ILibWebClient_DestroyWebClientDataObject(data->WCDO);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -2702,6 +2949,7 @@ duk_ret_t ILibduktape_HttpStream_create(duk_context *ctx)
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "clientError");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "request");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "connect");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "write");
|
||||
|
||||
data->DS = ILibDuktape_DuplexStream_InitEx(ctx, ILibDuktape_HttpStream_WriteSink, ILibDuktape_HttpStream_EndSink,
|
||||
NULL, NULL, NULL, data);
|
||||
@@ -2772,7 +3020,7 @@ void ILibDuktape_RemoveObjFromTable(duk_context *ctx, duk_idx_t tableIdx, char *
|
||||
duk_ret_t ILibDuktape_HttpStream_Agent_socketEndSink(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx); // [socket]
|
||||
printf("socket has closed: %p\n", duk_get_heapptr(ctx, -1));
|
||||
//printf("socket has closed: %p\n", duk_get_heapptr(ctx, -1));
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_Socket2Agent); // [socket][agent]
|
||||
duk_get_prop_string(ctx, -2, ILibDuktape_Socket2AgentKey); // [socket][agent][key]
|
||||
char *key = Duktape_GetBuffer(ctx, -1, NULL);
|
||||
@@ -2806,10 +3054,10 @@ duk_ret_t ILibDuktape_HttpStream_Agent_socketEndSink(duk_context *ctx)
|
||||
duk_get_prop_string(ctx, -1, "createConnection"); // [socket][agent][agent][createConnection]
|
||||
duk_swap_top(ctx, -2); // [socket][agent][createConnection][this]
|
||||
duk_get_prop_string(ctx, -4, "\xFF_NET_SOCKET2OPTIONS"); // [socket][agent][createConnection][this][options]
|
||||
duk_call_method(ctx, 1); // [socket][agent][newsocket]
|
||||
duk_push_c_function(ctx, ILibDuktape_HttpStream_http_OnConnect, DUK_VARARGS); // We need to register here, because TLS/NonTLS have different event names
|
||||
duk_call_method(ctx, 2); // [socket][agent][newsocket]
|
||||
duk_swap_top(ctx, -2); // [socket][newsocket][agent]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Socket2Agent); // [socket][newsocket]
|
||||
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -1, "connect", ILibDuktape_HttpStream_http_OnConnect);
|
||||
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -1, "error", ILibDuktape_HttpStream_http_OnConnectError);
|
||||
}
|
||||
}
|
||||
@@ -2882,6 +3130,7 @@ duk_ret_t ILibDuktape_HttpStream_Agent_keepSocketAlive(duk_context *ctx)
|
||||
duk_dup(ctx, -4); // [key][Agent][requests][request][reuseSocket][this][socket][request]
|
||||
duk_call_method(ctx, 2); // [key][Agent][requests][request][retVal]
|
||||
retVal = 1;
|
||||
duk_pop(ctx); // [key][Agent][requests][request]
|
||||
}
|
||||
}
|
||||
if (retVal == 0)
|
||||
@@ -2917,6 +3166,11 @@ duk_ret_t ILibDuktape_HttpStream_Agent_keepSocketAlive(duk_context *ctx)
|
||||
}
|
||||
void ILibDuktape_HttpStream_Agent_reuseSocketEx(duk_context *ctx, void ** args, int argsLen)
|
||||
{
|
||||
duk_push_this(ctx); // [immediate]
|
||||
duk_del_prop_string(ctx, -1, "CR");
|
||||
duk_del_prop_string(ctx, -2, "Socket");
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
duk_push_heapptr(ctx, args[1]); // [clientRequest]
|
||||
duk_push_heapptr(ctx, args[0]); // [clientRequest][socket]
|
||||
|
||||
@@ -2926,6 +3180,7 @@ void ILibDuktape_HttpStream_Agent_reuseSocketEx(duk_context *ctx, void ** args,
|
||||
duk_call_method(ctx, 1); duk_pop(ctx); // [clientRequest][socket]
|
||||
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "socket"); // [clientRequest]
|
||||
|
||||
duk_get_prop_string(ctx, -1, "emit"); // [clientRequest][emit]
|
||||
duk_swap_top(ctx, -2); // [emit][this]
|
||||
duk_push_string(ctx, "socket"); // [emit][this][name]
|
||||
@@ -2936,7 +3191,13 @@ void ILibDuktape_HttpStream_Agent_reuseSocketEx(duk_context *ctx, void ** args,
|
||||
duk_ret_t ILibDuktape_HttpStream_Agent_reuseSocket(duk_context *ctx)
|
||||
{
|
||||
// Yield to the next loop, before we emit a 'socket' event, because emitting this event before anyone has the clientRequest object is pointless
|
||||
ILibDuktape_Immediate(ctx, (void*[]) { duk_get_heapptr(ctx, 0), duk_get_heapptr(ctx, 1) }, 2, ILibDuktape_HttpStream_Agent_reuseSocketEx);
|
||||
void *imm = ILibDuktape_Immediate(ctx, (void*[]) { duk_get_heapptr(ctx, 0), duk_get_heapptr(ctx, 1) }, 2, ILibDuktape_HttpStream_Agent_reuseSocketEx);
|
||||
duk_push_heapptr(ctx, imm); // [immediate]
|
||||
duk_dup(ctx, 1); // [immediate][ClientRequest]
|
||||
duk_put_prop_string(ctx, -2, "CR"); // [immediate]
|
||||
duk_dup(ctx, 0); // [immediate][Socket]
|
||||
duk_put_prop_string(ctx, -2, "Socket"); // [immediate]
|
||||
duk_pop(ctx);
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_Agent_createConnection_eventSink(duk_context *ctx)
|
||||
@@ -3144,8 +3405,15 @@ ILibTransport_DoneState ILibDuktape_httpStream_webSocket_WriteWebSocketPacket(IL
|
||||
if (ILibIsRunningOnChainThread(state->chain) != 0)
|
||||
{
|
||||
// We're on the Duktape Thread, so we can just call write multiple times, cuz we won't interleave with JavaScript
|
||||
ILibDuktape_DuplexStream_WriteData(state->encodedStream, header, headerLen);
|
||||
retVal = ILibDuktape_DuplexStream_WriteData(state->encodedStream, buffer, bufferLen) == 0 ? ILibTransport_DoneState_COMPLETE : ILibTransport_DoneState_INCOMPLETE;
|
||||
if (bufferLen > 0)
|
||||
{
|
||||
ILibDuktape_DuplexStream_WriteData(state->encodedStream, header, headerLen);
|
||||
retVal = ILibDuktape_DuplexStream_WriteData(state->encodedStream, buffer, bufferLen) == 0 ? ILibTransport_DoneState_COMPLETE : ILibTransport_DoneState_INCOMPLETE;
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = ILibDuktape_DuplexStream_WriteData(state->encodedStream, header, headerLen) == 0 ? ILibTransport_DoneState_COMPLETE : ILibTransport_DoneState_INCOMPLETE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3314,6 +3582,7 @@ ILibTransport_DoneState ILibDuktape_httpStream_webSocket_EncodedWriteSink(ILibDu
|
||||
switch (OPCODE)
|
||||
{
|
||||
case WEBSOCKET_OPCODE_CLOSE:
|
||||
state->closed = 1;
|
||||
ILibDuktape_DuplexStream_WriteEnd(state->decodedStream);
|
||||
if (ILibIsRunningOnChainThread(state->chain) != 0 && state->encodedStream->writableStream->pipedReadable != NULL)
|
||||
{
|
||||
@@ -3363,7 +3632,7 @@ ILibTransport_DoneState ILibDuktape_httpStream_webSocket_EncodedWriteSink(ILibDu
|
||||
void ILibDuktape_httpStream_webSocket_EncodedEndSink(ILibDuktape_DuplexStream *stream, void *user)
|
||||
{
|
||||
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)user;
|
||||
ILibDuktape_DuplexStream_WriteEnd(state->decodedStream);
|
||||
if (!state->closed) { ILibDuktape_DuplexStream_WriteEnd(state->decodedStream); }
|
||||
}
|
||||
void ILibDuktape_httpStream_webSocket_EncodedPauseSink_Chain(void *chain, void *user)
|
||||
{
|
||||
@@ -3453,6 +3722,14 @@ void ILibDuktape_httpStream_webSocket_DecodedPauseSink_Chain(void *chain, void *
|
||||
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)user;
|
||||
duk_context *ctx = state->encodedStream->writableStream->ctx;
|
||||
|
||||
if (state->encodedStream->writableStream->pipedReadable == NULL)
|
||||
{
|
||||
// We're not piped yet, so just set a flag, and we'll make sure we don't resume
|
||||
state->noResume = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
duk_push_heapptr(ctx, state->encodedStream->writableStream->pipedReadable); // [readable]
|
||||
duk_get_prop_string(ctx, -1, "pause"); // [readable][pause]
|
||||
duk_swap_top(ctx, -2); // [pause][this]
|
||||
@@ -3485,6 +3762,12 @@ void ILibDuktape_httpStream_webSocket_DecodedResumeSink_Chain(void *chain, void
|
||||
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)user;
|
||||
duk_context *ctx = state->encodedStream->writableStream->ctx;
|
||||
|
||||
if (state->encodedStream->writableStream->pipedReadable == NULL)
|
||||
{
|
||||
state->noResume = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
duk_push_heapptr(ctx, state->encodedStream->writableStream->pipedReadable); // [readable]
|
||||
duk_get_prop_string(ctx, -1, "resume"); // [readable][resume]
|
||||
duk_swap_top(ctx, -2); // [resume][this]
|
||||
@@ -3521,6 +3804,17 @@ duk_ret_t ILibDuktape_httpStream_webSocketStream_finalizer(duk_context *ctx)
|
||||
{
|
||||
void *chain = Duktape_GetChain(ctx);
|
||||
duk_get_prop_string(ctx, 0, ILibDuktape_WebSocket_StatePtr);
|
||||
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
|
||||
if (state->encodedStream->writableStream->pipedReadable != NULL)
|
||||
{
|
||||
duk_push_heapptr(ctx, state->encodedStream->writableStream->pipedReadable); // [readable]
|
||||
duk_get_prop_string(ctx, -1, "unpipe"); // [readable][unpipe]
|
||||
duk_swap_top(ctx, -2); // [unpipe][this]
|
||||
duk_push_heapptr(ctx, state->encodedStream->writableStream->obj); // [unpipe][this][ws]
|
||||
duk_call_method(ctx, 1); duk_pop(ctx); // ...
|
||||
}
|
||||
|
||||
ILibDuktape_InValidatePointer(chain, Duktape_GetBuffer(ctx, -1, NULL));
|
||||
return(0);
|
||||
}
|
||||
@@ -3544,6 +3838,24 @@ duk_ret_t ILibDuktape_httpStream_webSocketStream_sendPong(duk_context *ctx)
|
||||
ILibDuktape_httpStream_webSocket_WriteWebSocketPacket(state, WEBSOCKET_OPCODE_PONG, NULL, 0, ILibWebClient_WebSocket_FragmentFlag_Complete);
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_httpStream_webSocketStream_encodedPiped(duk_context *ctx)
|
||||
{
|
||||
// Someone Piped to the Encoded Stream
|
||||
duk_push_this(ctx); // [ENC]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_WSENC2WS); // [ENC][WS]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_WebSocket_StatePtr); // [ENC][WS][state]
|
||||
|
||||
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
if (state->noResume)
|
||||
{
|
||||
state->noResume = 0;
|
||||
duk_push_heapptr(state->ctx, state->encodedStream->writableStream->pipedReadable); // [Readable]
|
||||
duk_get_prop_string(state->ctx, -1, "pause"); // [Readable][pause]
|
||||
duk_swap_top(ctx, -2); // [pause][this]
|
||||
duk_call_method(ctx, 0);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_httpStream_webSocketStream_new(duk_context *ctx)
|
||||
{
|
||||
@@ -3562,6 +3874,10 @@ duk_ret_t ILibDuktape_httpStream_webSocketStream_new(duk_context *ctx)
|
||||
duk_push_object(ctx); // [WebSocket][Encoded]
|
||||
ILibDuktape_WriteID(ctx, "http.WebSocketStream.encoded");
|
||||
state->encodedStream = ILibDuktape_DuplexStream_InitEx(ctx, ILibDuktape_httpStream_webSocket_EncodedWriteSink, ILibDuktape_httpStream_webSocket_EncodedEndSink, ILibDuktape_httpStream_webSocket_EncodedPauseSink, ILibDuktape_httpStream_webSocket_EncodedResumeSink, ILibDuktape_httpStream_webSocket_EncodedUnshiftSink, state);
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "pipe", ILibDuktape_httpStream_webSocketStream_encodedPiped);
|
||||
duk_dup(ctx, -2); // [WebSocket][Encoded][WebSocket]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_WSENC2WS); // [WebSocket][Encoded]
|
||||
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "encoded"); // [WebSocket]
|
||||
duk_push_object(ctx); // [WebSocket][Decoded]
|
||||
ILibDuktape_WriteID(ctx, "http.WebSocketStream.decoded");
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "duktape.h"
|
||||
#include "ILibDuktapeModSearch.h"
|
||||
#include "ILibDuktape_Helpers.h"
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "duktape.h"
|
||||
#include "ILibDuktapeModSearch.h"
|
||||
@@ -15,9 +30,6 @@ typedef struct ILibDuktape_NetworkMonitor
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
ILibIPAddressMonitor addressMonitor;
|
||||
ILibHashtable *addressTable;
|
||||
void *OnChange;
|
||||
void *OnAdded;
|
||||
void *OnRemoved;
|
||||
}ILibDuktape_NetworkMonitor;
|
||||
|
||||
|
||||
@@ -63,45 +75,31 @@ ILibHashtable ILibDuktape_NetworkMonitor_CreateTable(duk_context *ctx)
|
||||
void ILibDuktape_NetworkMonitor_EventSink_OnEnumerateCurrent(ILibHashtable sender, void *Key1, char* Key2, int Key2Len, void *Data, void *user)
|
||||
{
|
||||
duk_context *ctx = (duk_context*)((void**)user)[0];
|
||||
void *OnEvent = ((void**)user)[1];
|
||||
char *eventName = (char*)((void**)user)[1];
|
||||
void *Self = ((void**)user)[2];
|
||||
ILibHashtable other = (ILibHashtable)((void**)user)[3];
|
||||
|
||||
if (ILibHashtable_Get(other, NULL, Key2, Key2Len) == NULL)
|
||||
{
|
||||
if (OnEvent != NULL)
|
||||
{
|
||||
duk_push_heapptr(ctx, OnEvent); // [func]
|
||||
duk_push_heapptr(ctx, Self); // [func][this]
|
||||
duk_push_lstring(ctx, Key2, (duk_size_t)Key2Len); // [func][this][address]
|
||||
if (duk_pcall_method(ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "NetworkMonitor.OnAdd/Remove(): "); }
|
||||
duk_pop(ctx);
|
||||
}
|
||||
ILibDuktape_EventEmitter_SetupEmit(ctx, Self, eventName); // [emit][this][eventName]
|
||||
duk_push_lstring(ctx, Key2, (duk_size_t)Key2Len); // [emit][this][eventName][address]
|
||||
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "NetworkMonitor.OnAdd/Remove(): "); }
|
||||
duk_pop(ctx);
|
||||
}
|
||||
}
|
||||
void ILibDuktape_NetworkMonitor_EventSink(ILibIPAddressMonitor sender, void *user)
|
||||
{
|
||||
ILibDuktape_NetworkMonitor *nm = (ILibDuktape_NetworkMonitor*)user;
|
||||
if (nm->OnChange != NULL)
|
||||
{
|
||||
duk_push_heapptr(nm->ctx, nm->OnChange); // [func]
|
||||
duk_push_heapptr(nm->ctx, nm->emitter->object); // [func][this]
|
||||
if (duk_pcall_method(nm->ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(nm->ctx, "NetworkMonitor.change(): "); }
|
||||
duk_pop(nm->ctx); // ...
|
||||
}
|
||||
|
||||
ILibDuktape_EventEmitter_SetupEmit(nm->ctx, nm->emitter->object, "change"); // [emit][this][change]
|
||||
if (duk_pcall_method(nm->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(nm->ctx, "NetworkMonitor.change(): "); }
|
||||
duk_pop(nm->ctx); // ...
|
||||
|
||||
|
||||
ILibHashtable current = ILibDuktape_NetworkMonitor_CreateTable(nm->ctx);
|
||||
ILibHashtable_Enumerate(current, ILibDuktape_NetworkMonitor_EventSink_OnEnumerateCurrent, (void*[]){ nm->ctx, "add", nm->emitter->object, nm->addressTable });
|
||||
ILibHashtable_Enumerate(nm->addressTable, ILibDuktape_NetworkMonitor_EventSink_OnEnumerateCurrent, (void*[]) { nm->ctx, "remove", nm->emitter->object, current });
|
||||
|
||||
if (nm->OnAdded != NULL)
|
||||
{
|
||||
void *data[] = { nm->ctx, nm->OnAdded, nm->emitter->object, nm->addressTable };
|
||||
ILibHashtable_Enumerate(current, ILibDuktape_NetworkMonitor_EventSink_OnEnumerateCurrent, data);
|
||||
}
|
||||
if(nm->OnRemoved != NULL)
|
||||
{
|
||||
void *data[] = { nm->ctx, nm->OnRemoved, nm->emitter->object, current };
|
||||
ILibHashtable_Enumerate(nm->addressTable, ILibDuktape_NetworkMonitor_EventSink_OnEnumerateCurrent, data);
|
||||
}
|
||||
|
||||
ILibHashtable_Destroy(nm->addressTable);
|
||||
nm->addressTable = current;
|
||||
@@ -130,9 +128,9 @@ void ILibDuktape_NetworkMonitor_PUSH(duk_context *ctx, void *chain)
|
||||
nm->emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
nm->addressMonitor = ILibIPAddressMonitor_Create(chain, ILibDuktape_NetworkMonitor_EventSink, nm);
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEvent(nm->emitter, "change", &(nm->OnChange));
|
||||
ILibDuktape_EventEmitter_CreateEvent(nm->emitter, "add", &(nm->OnAdded));
|
||||
ILibDuktape_EventEmitter_CreateEvent(nm->emitter, "remove", &(nm->OnRemoved));
|
||||
ILibDuktape_EventEmitter_CreateEventEx(nm->emitter, "change");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(nm->emitter, "add");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(nm->emitter, "remove");
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_NetworkMonitor_Finalizer);
|
||||
|
||||
//
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __ILIBDUKTAPE_NETWORKMONITOR__
|
||||
#define __ILIBDUKTAPE_NETWORKMONITOR__
|
||||
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "duktape.h"
|
||||
#include "ILibDuktape_Helpers.h"
|
||||
#include "ILibDuktapeModSearch.h"
|
||||
@@ -9,7 +25,10 @@
|
||||
|
||||
#define ILibDuktape_Timer_Ptrs "\xFF_DuktapeTimer_PTRS"
|
||||
#define ILibDuktape_Queue_Ptr "\xFF_Queue"
|
||||
|
||||
#define ILibDuktape_Stream_Buffer "\xFF_BUFFER"
|
||||
#define ILibDuktape_Stream_ReadablePtr "\xFF_ReadablePtr"
|
||||
int g_displayStreamPipeMessages = 0;
|
||||
int g_displayFinalizerMessages = 0;
|
||||
|
||||
duk_ret_t ILibDuktape_Pollyfills_Buffer_slice(duk_context *ctx)
|
||||
{
|
||||
@@ -157,23 +176,23 @@ duk_ret_t ILibDuktape_Polyfills_Buffer_alloc(duk_context *ctx)
|
||||
}
|
||||
void ILibDuktape_Polyfills_Buffer(duk_context *ctx)
|
||||
{
|
||||
// Polyfill 'Buffer.slice'
|
||||
duk_get_prop_string(ctx, -1, "Duktape"); // [g][Duktape]
|
||||
duk_get_prop_string(ctx, -1, "Buffer"); // [g][Duktape][Buffer]
|
||||
duk_get_prop_string(ctx, -1, "prototype"); // [g][Duktape][Buffer][prototype]
|
||||
duk_push_c_function(ctx, ILibDuktape_Pollyfills_Buffer_slice, DUK_VARARGS); // [g][Duktape][Buffer][prototype][func]
|
||||
duk_put_prop_string(ctx, -2, "slice"); // [g][Duktape][Buffer][prototype]
|
||||
duk_push_c_function(ctx, ILibDuktape_Polyfills_Buffer_readInt32BE, DUK_VARARGS);// [g][Duktape][Buffer][prototype][func]
|
||||
duk_put_prop_string(ctx, -2, "readInt32BE"); // [g][Duktape][Buffer][prototype]
|
||||
duk_pop_3(ctx); // [g]
|
||||
//// Polyfill 'Buffer.slice'
|
||||
//duk_get_prop_string(ctx, -1, "Duktape"); // [g][Duktape]
|
||||
//duk_get_prop_string(ctx, -1, "Buffer"); // [g][Duktape][Buffer]
|
||||
//duk_get_prop_string(ctx, -1, "prototype"); // [g][Duktape][Buffer][prototype]
|
||||
//duk_push_c_function(ctx, ILibDuktape_Pollyfills_Buffer_slice, DUK_VARARGS); // [g][Duktape][Buffer][prototype][func]
|
||||
//duk_put_prop_string(ctx, -2, "slice"); // [g][Duktape][Buffer][prototype]
|
||||
//duk_push_c_function(ctx, ILibDuktape_Polyfills_Buffer_readInt32BE, DUK_VARARGS);// [g][Duktape][Buffer][prototype][func]
|
||||
//duk_put_prop_string(ctx, -2, "readInt32BE"); // [g][Duktape][Buffer][prototype]
|
||||
//duk_pop_3(ctx); // [g]
|
||||
|
||||
// Polyfill 'Buffer.toString()
|
||||
duk_get_prop_string(ctx, -1, "Duktape"); // [g][Duktape]
|
||||
duk_get_prop_string(ctx, -1, "Buffer"); // [g][Duktape][Buffer]
|
||||
duk_get_prop_string(ctx, -1, "prototype"); // [g][Duktape][Buffer][prototype]
|
||||
duk_push_c_function(ctx, ILibDuktape_Polyfills_Buffer_toString, DUK_VARARGS); // [g][Duktape][Buffer][prototype][func]
|
||||
duk_put_prop_string(ctx, -2, "toString"); // [g][Duktape][Buffer][prototype]
|
||||
duk_pop_3(ctx); // [g]
|
||||
//// Polyfill 'Buffer.toString()
|
||||
//duk_get_prop_string(ctx, -1, "Duktape"); // [g][Duktape]
|
||||
//duk_get_prop_string(ctx, -1, "Buffer"); // [g][Duktape][Buffer]
|
||||
//duk_get_prop_string(ctx, -1, "prototype"); // [g][Duktape][Buffer][prototype]
|
||||
//duk_push_c_function(ctx, ILibDuktape_Polyfills_Buffer_toString, DUK_VARARGS); // [g][Duktape][Buffer][prototype][func]
|
||||
//duk_put_prop_string(ctx, -2, "toString"); // [g][Duktape][Buffer][prototype]
|
||||
//duk_pop_3(ctx); // [g]
|
||||
|
||||
// Polyfill Buffer.from()
|
||||
duk_get_prop_string(ctx, -1, "Buffer"); // [g][Buffer]
|
||||
@@ -313,6 +332,31 @@ duk_ret_t ILibDuktape_Polyfills_Console_enableWebLog(duk_context *ctx)
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Polyfills_Console_displayStreamPipe_getter(duk_context *ctx)
|
||||
{
|
||||
duk_push_int(ctx, g_displayStreamPipeMessages);
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Polyfills_Console_displayStreamPipe_setter(duk_context *ctx)
|
||||
{
|
||||
g_displayStreamPipeMessages = duk_require_int(ctx, 0);
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Polyfills_Console_displayFinalizer_getter(duk_context *ctx)
|
||||
{
|
||||
duk_push_int(ctx, g_displayFinalizerMessages);
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Polyfills_Console_displayFinalizer_setter(duk_context *ctx)
|
||||
{
|
||||
g_displayFinalizerMessages = duk_require_int(ctx, 0);
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Polyfills_Console_logRefCount(duk_context *ctx)
|
||||
{
|
||||
printf("Reference Count => %s[%p]:%d\n", Duktape_GetStringPropertyValue(ctx, 0, ILibDuktape_OBJID, "UNKNOWN"), duk_require_heapptr(ctx, 0), ILibDuktape_GetReferenceCount(ctx, 0) - 1);
|
||||
return(0);
|
||||
}
|
||||
void ILibDuktape_Polyfills_Console(duk_context *ctx)
|
||||
{
|
||||
// Polyfill console.log()
|
||||
@@ -326,11 +370,12 @@ void ILibDuktape_Polyfills_Console(duk_context *ctx)
|
||||
duk_dup(ctx, -1); // [g][console][console]
|
||||
duk_put_prop_string(ctx, -3, "console"); // [g][console]
|
||||
}
|
||||
duk_push_c_function(ctx, ILibDuktape_Polyfills_Console_log, DUK_VARARGS); // [g][console][log]
|
||||
duk_put_prop_string(ctx, -2, "log"); // [g][console]
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "log", ILibDuktape_Polyfills_Console_log, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "enableWebLog", ILibDuktape_Polyfills_Console_enableWebLog, 1);
|
||||
|
||||
ILibDuktape_CreateEventWithGetterAndSetterEx(ctx, "displayStreamPipeMessages", ILibDuktape_Polyfills_Console_displayStreamPipe_getter, ILibDuktape_Polyfills_Console_displayStreamPipe_setter);
|
||||
ILibDuktape_CreateEventWithGetterAndSetterEx(ctx, "displayFinalizerMessages", ILibDuktape_Polyfills_Console_displayFinalizer_getter, ILibDuktape_Polyfills_Console_displayFinalizer_setter);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "logReferenceCount", ILibDuktape_Polyfills_Console_logRefCount, 1);
|
||||
duk_pop(ctx); // [g]
|
||||
}
|
||||
duk_ret_t ILibDuktape_ntohl(duk_context *ctx)
|
||||
@@ -404,6 +449,14 @@ duk_ret_t ILibDuktape_Polyfills_timer_finalizer(duk_context *ctx)
|
||||
// Make sure we remove any timers just in case, so we don't leak resources
|
||||
ILibDuktape_Timer *ptrs;
|
||||
duk_get_prop_string(ctx, 0, ILibDuktape_Timer_Ptrs);
|
||||
if (duk_has_prop_string(ctx, 0, "\xFF_callback"))
|
||||
{
|
||||
duk_del_prop_string(ctx, 0, "\xFF_callback");
|
||||
}
|
||||
if (duk_has_prop_string(ctx, 0, "\xFF_argArray"))
|
||||
{
|
||||
duk_del_prop_string(ctx, 0, "\xFF_argArray");
|
||||
}
|
||||
ptrs = (ILibDuktape_Timer*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
|
||||
ILibLifeTime_Remove(ILibGetBaseTimer(Duktape_GetChain(ctx)), ptrs);
|
||||
@@ -415,24 +468,29 @@ void ILibDuktape_Polyfills_timer_elapsed(void *obj)
|
||||
int argCount, i;
|
||||
duk_context *ctx = ptrs->ctx;
|
||||
|
||||
duk_push_heapptr(ctx, ptrs->callback); // [func]
|
||||
duk_push_heapptr(ctx, ptrs->object); // [func][this]
|
||||
duk_push_heapptr(ctx, ptrs->args); // [func][this][argArray]
|
||||
|
||||
if (ptrs->timerType == ILibDuktape_Timer_Type_INTERVAL)
|
||||
{
|
||||
ILibLifeTime_AddEx(ILibGetBaseTimer(Duktape_GetChain(ptrs->ctx)), ptrs, ptrs->timeout, ILibDuktape_Polyfills_timer_elapsed, NULL);
|
||||
ILibLifeTime_AddEx(ILibGetBaseTimer(Duktape_GetChain(ctx)), ptrs, ptrs->timeout, ILibDuktape_Polyfills_timer_elapsed, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_del_prop_string(ctx, -2, "\xFF_callback");
|
||||
duk_del_prop_string(ctx, -2, "\xFF_argArray");
|
||||
}
|
||||
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->callback); // [func]
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->object); // [func][this]
|
||||
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->args); // [func][this][argArray]
|
||||
argCount = (int)duk_get_length(ptrs->ctx, -1);
|
||||
argCount = (int)duk_get_length(ctx, -1);
|
||||
for (i = 0; i < argCount; ++i)
|
||||
{
|
||||
duk_get_prop_index(ptrs->ctx, -1, i); // [func][this][argArray][arg]
|
||||
duk_swap_top(ptrs->ctx, -2); // [func][this][arg][argArray]
|
||||
duk_get_prop_index(ctx, -1, i); // [func][this][argArray][arg]
|
||||
duk_swap_top(ctx, -2); // [func][this][arg][argArray]
|
||||
}
|
||||
duk_pop(ptrs->ctx); // [func][this][...arg...]
|
||||
if (duk_pcall_method(ptrs->ctx, argCount) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "timers.onElapsed() callback handler"); }
|
||||
duk_pop(ctx); // ...
|
||||
duk_pop(ctx); // [func][this][...arg...]
|
||||
if (duk_pcall_method(ctx, argCount) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "timers.onElapsed() callback handler"); }
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
duk_ret_t ILibDuktape_Polyfills_timer_set(duk_context *ctx)
|
||||
{
|
||||
@@ -447,6 +505,18 @@ duk_ret_t ILibDuktape_Polyfills_timer_set(duk_context *ctx)
|
||||
timerType = (ILibDuktape_Timer_Type)duk_get_int(ctx, -1);
|
||||
|
||||
duk_push_object(ctx); //[retVal]
|
||||
switch (timerType)
|
||||
{
|
||||
case ILibDuktape_Timer_Type_IMMEDIATE:
|
||||
ILibDuktape_WriteID(ctx, "Timers.immediate");
|
||||
break;
|
||||
case ILibDuktape_Timer_Type_INTERVAL:
|
||||
ILibDuktape_WriteID(ctx, "Timers.interval");
|
||||
break;
|
||||
case ILibDuktape_Timer_Type_TIMEOUT:
|
||||
ILibDuktape_WriteID(ctx, "Timers.timeout");
|
||||
break;
|
||||
}
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_Polyfills_timer_finalizer);
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_Timer)); //[retVal][ptrs]
|
||||
ptrs = (ILibDuktape_Timer*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
@@ -463,13 +533,13 @@ duk_ret_t ILibDuktape_Polyfills_timer_set(duk_context *ctx)
|
||||
for (argx = ILibDuktape_Timer_Type_IMMEDIATE == timerType ? 1 : 2; argx < nargs; ++argx)
|
||||
{
|
||||
duk_dup(ctx, argx); //[retVal][argArray][arg]
|
||||
duk_put_prop_index(ctx, -2, argx - (ILibDuktape_Timer_Type_IMMEDIATE == timerType ? 1 : 2)); //[retVal][argArray]
|
||||
duk_put_prop_index(ctx, -2, argx - (ILibDuktape_Timer_Type_IMMEDIATE == timerType ? 1 : 2));//[retVal][argArray]
|
||||
}
|
||||
ptrs->args = duk_get_heapptr(ctx, -1);
|
||||
ptrs->args = duk_get_heapptr(ctx, -1); //[retVal]
|
||||
duk_put_prop_string(ctx, -2, "\xFF_argArray");
|
||||
|
||||
duk_dup(ctx, 0); //[retVal][callback]
|
||||
duk_put_prop_string(ctx, -2, "\xFF_callback"); //[retVal]
|
||||
duk_dup(ctx, 0); //[retVal][callback]
|
||||
duk_put_prop_string(ctx, -2, "\xFF_callback"); //[retVal]
|
||||
|
||||
ILibLifeTime_AddEx(ILibGetBaseTimer(chain), ptrs, ptrs->timeout, ILibDuktape_Polyfills_timer_elapsed, NULL);
|
||||
return 1;
|
||||
@@ -758,11 +828,179 @@ void ILibDuktape_DynamicBuffer_Push(duk_context *ctx, void *chain)
|
||||
duk_push_c_function(ctx, ILibDuktape_DynamicBuffer_new, DUK_VARARGS);
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_Polyfills_debugCrash(duk_context *ctx)
|
||||
{
|
||||
void *p = NULL;
|
||||
((int*)p)[0] = 55;
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
void ILibDuktape_Stream_PauseSink(struct ILibDuktape_readableStream *sender, void *user)
|
||||
{
|
||||
}
|
||||
void ILibDuktape_Stream_ResumeSink(struct ILibDuktape_readableStream *sender, void *user)
|
||||
{
|
||||
int skip = 0;
|
||||
duk_size_t bufferLen;
|
||||
|
||||
duk_push_heapptr(sender->ctx, sender->object); // [stream]
|
||||
void *func = Duktape_GetHeapptrProperty(sender->ctx, -1, "_read");
|
||||
duk_pop(sender->ctx); // ...
|
||||
|
||||
while (func != NULL && sender->paused == 0)
|
||||
{
|
||||
duk_push_heapptr(sender->ctx, sender->object); // [this]
|
||||
if (!skip && duk_has_prop_string(sender->ctx, -1, ILibDuktape_Stream_Buffer))
|
||||
{
|
||||
duk_get_prop_string(sender->ctx, -1, ILibDuktape_Stream_Buffer); // [this][buffer]
|
||||
if ((bufferLen = duk_get_length(sender->ctx, -1)) > 0)
|
||||
{
|
||||
// Buffer is not empty, so we need to 'PUSH' it
|
||||
duk_get_prop_string(sender->ctx, -2, "push"); // [this][buffer][push]
|
||||
duk_dup(sender->ctx, -3); // [this][buffer][push][this]
|
||||
duk_dup(sender->ctx, -3); // [this][buffer][push][this][buffer]
|
||||
duk_remove(sender->ctx, -4); // [this][push][this][buffer]
|
||||
duk_call_method(sender->ctx, 1); // [this][boolean]
|
||||
sender->paused = !duk_get_boolean(sender->ctx, -1);
|
||||
duk_pop(sender->ctx); // [this]
|
||||
|
||||
if (duk_has_prop_string(sender->ctx, -1, ILibDuktape_Stream_Buffer))
|
||||
{
|
||||
duk_get_prop_string(sender->ctx, -1, ILibDuktape_Stream_Buffer); // [this][buffer]
|
||||
if (duk_get_length(sender->ctx, -1) == bufferLen)
|
||||
{
|
||||
// All the data was unshifted
|
||||
skip = !sender->paused;
|
||||
}
|
||||
duk_pop(sender->ctx); // [this]
|
||||
}
|
||||
duk_pop(sender->ctx); // ...
|
||||
}
|
||||
else
|
||||
{
|
||||
// Buffer is empty
|
||||
duk_pop(sender->ctx); // [this]
|
||||
duk_del_prop_string(sender->ctx, -1, ILibDuktape_Stream_Buffer);
|
||||
duk_pop(sender->ctx); // ...
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We need to 'read' more data
|
||||
duk_push_heapptr(sender->ctx, func); // [this][read]
|
||||
duk_swap_top(sender->ctx, -2); // [read][this]
|
||||
if (duk_pcall_method(sender->ctx, 0) != 0) { ILibDuktape_Process_UncaughtException(sender->ctx); duk_pop(sender->ctx); break; }
|
||||
// // [buffer]
|
||||
duk_push_heapptr(sender->ctx, sender->object); // [buffer][this]
|
||||
duk_swap_top(sender->ctx, -2); // [this][buffer]
|
||||
if (duk_has_prop_string(sender->ctx, -2, ILibDuktape_Stream_Buffer))
|
||||
{
|
||||
duk_push_global_object(sender->ctx); // [this][buffer][g]
|
||||
duk_get_prop_string(sender->ctx, -1, "Buffer"); // [this][buffer][g][Buffer]
|
||||
duk_remove(sender->ctx, -2); // [this][buffer][Buffer]
|
||||
duk_get_prop_string(sender->ctx, -1, "concat"); // [this][buffer][Buffer][concat]
|
||||
duk_swap_top(sender->ctx, -2); // [this][buffer][concat][this]
|
||||
duk_push_array(sender->ctx); // [this][buffer][concat][this][Array]
|
||||
duk_get_prop_string(sender->ctx, -1, "push"); // [this][buffer][concat][this][Array][push]
|
||||
duk_dup(sender->ctx, -2); // [this][buffer][concat][this][Array][push][this]
|
||||
duk_get_prop_string(sender->ctx, -7, ILibDuktape_Stream_Buffer); // [this][buffer][concat][this][Array][push][this][buffer]
|
||||
duk_call_method(sender->ctx, 1); duk_pop(sender->ctx); // [this][buffer][concat][this][Array]
|
||||
duk_get_prop_string(sender->ctx, -1, "push"); // [this][buffer][concat][this][Array][push]
|
||||
duk_dup(sender->ctx, -2); // [this][buffer][concat][this][Array][push][this]
|
||||
duk_dup(sender->ctx, -6); // [this][buffer][concat][this][Array][push][this][buffer]
|
||||
duk_remove(sender->ctx, -7); // [this][concat][this][Array][push][this][buffer]
|
||||
duk_call_method(sender->ctx, 1); duk_pop(sender->ctx); // [this][concat][this][Array]
|
||||
duk_call_method(sender->ctx, 1); // [this][buffer]
|
||||
}
|
||||
duk_put_prop_string(sender->ctx, -2, ILibDuktape_Stream_Buffer); // [this]
|
||||
duk_pop(sender->ctx); // ...
|
||||
skip = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
int ILibDuktape_Stream_UnshiftSink(struct ILibDuktape_readableStream *sender, int unshiftBytes, void *user)
|
||||
{
|
||||
duk_push_fixed_buffer(sender->ctx, unshiftBytes); // [buffer]
|
||||
memcpy_s(Duktape_GetBuffer(sender->ctx, -1, NULL), unshiftBytes, sender->unshiftReserved, unshiftBytes);
|
||||
duk_push_heapptr(sender->ctx, sender->object); // [buffer][stream]
|
||||
duk_push_buffer_object(sender->ctx, -2, 0, unshiftBytes, DUK_BUFOBJ_NODEJS_BUFFER); // [buffer][stream][buffer]
|
||||
duk_put_prop_string(sender->ctx, -2, ILibDuktape_Stream_Buffer); // [buffer][stream]
|
||||
duk_pop_2(sender->ctx); // ...
|
||||
|
||||
return(unshiftBytes);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Stream_Push(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx); // [stream]
|
||||
ILibDuktape_readableStream *RS = (ILibDuktape_readableStream*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Stream_ReadablePtr);
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_Stream_Buffer); // [stream][buffer]
|
||||
duk_del_prop_string(ctx, -2, ILibDuktape_Stream_Buffer); // (Deleting here, because unshift will save it again, if necessary)
|
||||
|
||||
duk_size_t bufferLen;
|
||||
char *buffer = (char*)Duktape_GetBuffer(ctx, -1, &bufferLen);
|
||||
|
||||
duk_push_boolean(ctx, !ILibDuktape_readableStream_WriteDataEx(RS, 0, buffer, (int)bufferLen)); // [stream][buffer][retVal]
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Stream_EndSink(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx); // [stream]
|
||||
ILibDuktape_readableStream *RS = (ILibDuktape_readableStream*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Stream_ReadablePtr);
|
||||
ILibDuktape_readableStream_WriteEnd(RS);
|
||||
return(0);
|
||||
}
|
||||
duk_idx_t ILibDuktape_Stream_newReadable(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_readableStream *RS;
|
||||
duk_push_object(ctx); // [Readable]
|
||||
ILibDuktape_WriteID(ctx, "stream.readable");
|
||||
RS = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_Stream_PauseSink, ILibDuktape_Stream_ResumeSink, ILibDuktape_Stream_UnshiftSink, NULL);
|
||||
RS->paused = 1;
|
||||
|
||||
duk_push_pointer(ctx, RS);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Stream_ReadablePtr);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "push", ILibDuktape_Stream_Push, DUK_VARARGS);
|
||||
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -1, "end", ILibDuktape_Stream_EndSink);
|
||||
|
||||
if (duk_is_object(ctx, 0))
|
||||
{
|
||||
void *h = Duktape_GetHeapptrProperty(ctx, 0, "read");
|
||||
if (h != NULL) { duk_push_heapptr(ctx, h); duk_put_prop_string(ctx, -2, "_read"); }
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
void ILibDuktape_Stream_Init(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx); // [stream
|
||||
ILibDuktape_WriteID(ctx, "stream");
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "Readable", ILibDuktape_Stream_newReadable, DUK_VARARGS);
|
||||
}
|
||||
void ILibDuktape_Polyfills_debugGC2(duk_context *ctx, void ** args, int argsLen)
|
||||
{
|
||||
if (g_displayFinalizerMessages) { printf("=> GC();\n"); }
|
||||
duk_gc(ctx, 0);
|
||||
duk_gc(ctx, 0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Polyfills_debugGC(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_Immediate(ctx, (void*[]) { NULL }, 0, ILibDuktape_Polyfills_debugGC2);
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Polyfills_debug(duk_context *ctx)
|
||||
{
|
||||
#ifdef WIN32
|
||||
if (IsDebuggerPresent()) { __debugbreak(); }
|
||||
#elif defined(_POSIX)
|
||||
raise(SIGTRAP);
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
void ILibDuktape_Polyfills_Init(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "queue", ILibDuktape_Queue_Push);
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "DynamicBuffer", ILibDuktape_DynamicBuffer_Push);
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "stream", ILibDuktape_Stream_Init);
|
||||
|
||||
// Global Polyfills
|
||||
duk_push_global_object(ctx); // [g]
|
||||
@@ -774,6 +1012,9 @@ void ILibDuktape_Polyfills_Init(duk_context *ctx)
|
||||
ILibDuktape_Polyfills_timer(ctx);
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "addModule", ILibDuktape_Polyfills_addModule, 2);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "_debugCrash", ILibDuktape_Polyfills_debugCrash, 0);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "_debugGC", ILibDuktape_Polyfills_debugGC, 0);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "_debug", ILibDuktape_Polyfills_debug, 0);
|
||||
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
|
||||
@@ -1,8 +1,26 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __ILibDuktape_Polyfills__
|
||||
#define __ILibDuktape_Polyfills__
|
||||
|
||||
#include "duktape.h"
|
||||
|
||||
extern int g_displayStreamPipeMessages;
|
||||
extern int g_displayFinalizerMessages;
|
||||
void ILibDuktape_Polyfills_Init(duk_context *ctx);
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -20,6 +20,7 @@ limitations under the License.
|
||||
#include "ILibParsers_Duktape.h"
|
||||
#include "microstack/ILibParsers.h"
|
||||
#include "ILibDuktape_EventEmitter.h"
|
||||
#include "ILibDuktape_Polyfills.h"
|
||||
|
||||
|
||||
#define ILibDuktape_readableStream_WritePipes "\xFF_WritePipes"
|
||||
@@ -105,6 +106,19 @@ typedef struct ILibDuktape_readableStream_bufferedData
|
||||
char buffer[];
|
||||
}ILibDuktape_readableStream_bufferedData;
|
||||
|
||||
void ILibDuktape_ReadableStream_DestroyPausedData(ILibDuktape_readableStream *stream)
|
||||
{
|
||||
ILibDuktape_readableStream_bufferedData *buffered = (ILibDuktape_readableStream_bufferedData*)stream->paused_data;
|
||||
ILibDuktape_readableStream_bufferedData *tmp;
|
||||
|
||||
while (buffered != NULL)
|
||||
{
|
||||
tmp = buffered->Next;
|
||||
free(buffered);
|
||||
buffered = tmp;
|
||||
}
|
||||
stream->paused_data = NULL;
|
||||
}
|
||||
void ILibDuktape_readableStream_WriteData_buffer(ILibDuktape_readableStream *stream, int streamReserved, char *buffer, int bufferLen)
|
||||
{
|
||||
ILibDuktape_readableStream_bufferedData *buffered = (ILibDuktape_readableStream_bufferedData*)ILibMemory_Allocate(bufferLen + sizeof(ILibDuktape_readableStream_bufferedData), 0, NULL, NULL);
|
||||
@@ -137,17 +151,17 @@ void ILibDuktape_readableStream_WriteData_OnData_ChainThread(void *chain, void *
|
||||
duk_push_external_buffer(stream->ctx); // [ext]
|
||||
duk_config_buffer(stream->ctx, -1, data->buffer, data->bufferLen);
|
||||
}
|
||||
duk_push_heapptr(stream->ctx, stream->OnData); // [ext][func]
|
||||
duk_push_heapptr(stream->ctx, stream->object); // [ext][func][this]
|
||||
|
||||
ILibDuktape_EventEmitter_SetupEmit(stream->ctx, stream->object, "data"); // [ext][emit][this][data]
|
||||
if (data->Reserved == 0)
|
||||
{
|
||||
duk_push_buffer_object(stream->ctx, -3, 0, data->bufferLen, DUK_BUFOBJ_NODEJS_BUFFER); // [ext][func][this][buffer]
|
||||
duk_push_buffer_object(stream->ctx, -4, 0, data->bufferLen, DUK_BUFOBJ_NODEJS_BUFFER); // [ext][emit][this][data][buffer]
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_lstring(stream->ctx, data->buffer, data->bufferLen); // [ext][func][this][buffer/string]
|
||||
duk_push_lstring(stream->ctx, data->buffer, data->bufferLen); // [ext][emit][this][data][buffer/string]
|
||||
}
|
||||
if (duk_pcall_method(stream->ctx, 1) != 0) // [...][retVal]
|
||||
if (duk_pcall_method(stream->ctx, 2) != 0) // [...][retVal]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(stream->ctx);
|
||||
}
|
||||
@@ -275,6 +289,7 @@ int ILibDuktape_readableStream_WriteDataEx(ILibDuktape_readableStream *stream, i
|
||||
{
|
||||
ILibDuktape_WritableStream *ws = (ILibDuktape_WritableStream*)w->nativeWritable;
|
||||
ws->Reserved = streamReserved;
|
||||
ws->endBytes = -1;
|
||||
switch (ws->WriteSink(ws, buffer, bufferLen, ws->WriteSink_User))
|
||||
{
|
||||
case ILibTransport_DoneState_INCOMPLETE:
|
||||
@@ -333,7 +348,7 @@ int ILibDuktape_readableStream_WriteDataEx(ILibDuktape_readableStream *stream, i
|
||||
stream->pipeInProgress = 0;
|
||||
sem_post(&(stream->pipeLock));
|
||||
|
||||
if (stream->OnData != NULL)
|
||||
if(ILibDuktape_EventEmitter_HasListeners(stream->emitter, "data"))
|
||||
{
|
||||
if (ILibIsRunningOnChainThread(stream->chain))
|
||||
{
|
||||
@@ -342,17 +357,16 @@ int ILibDuktape_readableStream_WriteDataEx(ILibDuktape_readableStream *stream, i
|
||||
duk_push_external_buffer(stream->ctx); // [extBuffer]
|
||||
duk_config_buffer(stream->ctx, -1, buffer, bufferLen);
|
||||
}
|
||||
duk_push_heapptr(stream->ctx, stream->OnData); // [func]
|
||||
duk_push_heapptr(stream->ctx, stream->object); // [func][this]
|
||||
ILibDuktape_EventEmitter_SetupEmit(stream->ctx, stream->object, "data"); // [extBuffer][emit][this][data]
|
||||
if (streamReserved == 0)
|
||||
{
|
||||
duk_push_buffer_object(stream->ctx, -3, 0, bufferLen, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][func][this][nodeBuffer]
|
||||
duk_push_buffer_object(stream->ctx, -4, 0, bufferLen, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this][data][nodeBuffer]
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_lstring(stream->ctx, buffer, bufferLen); // [func][this][string]
|
||||
duk_push_lstring(stream->ctx, buffer, bufferLen); // [extBuffer][emit][this][data][string]
|
||||
}
|
||||
if (duk_pcall_method(stream->ctx, 1) != 0) // [retVal]
|
||||
if (duk_pcall_method(stream->ctx, 2) != 0) // [retVal]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(stream->ctx);
|
||||
}
|
||||
@@ -377,14 +391,14 @@ int ILibDuktape_readableStream_WriteDataEx(ILibDuktape_readableStream *stream, i
|
||||
ILibChain_RunOnMicrostackThread(stream->chain, ILibDuktape_readableStream_WriteData_OnData_ChainThread, tmp);
|
||||
}
|
||||
}
|
||||
else if (stream->PauseHandler != NULL && stream->OnEnd == NULL)
|
||||
else if (stream->PauseHandler != NULL && ILibDuktape_EventEmitter_HasListeners(stream->emitter, "end") == 0)
|
||||
{
|
||||
// If we get here, it means we are writing data, but nobody is going to be receiving it...
|
||||
// So we need to buffer the data, so when we are resumed later, we can retry
|
||||
needPause = 1;
|
||||
ILibDuktape_readableStream_WriteData_buffer(stream, streamReserved, buffer, bufferLen);
|
||||
}
|
||||
else if (stream->OnEnd != NULL)
|
||||
else if (ILibDuktape_EventEmitter_HasListeners(stream->emitter, "end") != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -429,16 +443,11 @@ int ILibDuktape_readableStream_WriteEnd(ILibDuktape_readableStream *stream)
|
||||
retVal = 0;
|
||||
}
|
||||
}
|
||||
else if (stream->OnEnd != NULL)
|
||||
else if (ILibDuktape_EventEmitter_HasListeners(stream->emitter, "end") != 0)
|
||||
{
|
||||
duk_context *x = stream->ctx;
|
||||
duk_push_heapptr(stream->ctx, stream->OnEnd); // [func]
|
||||
duk_push_heapptr(stream->ctx, stream->object); // [func][this]
|
||||
if (duk_pcall_method(stream->ctx, 0) != 0) // [retVal]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(stream->ctx);
|
||||
}
|
||||
duk_pop(x); // ...
|
||||
ILibDuktape_EventEmitter_SetupEmit(stream->ctx, stream->object, "end"); // [emit][this][end]
|
||||
if (duk_pcall_method(stream->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(stream->ctx); }
|
||||
duk_pop(stream->ctx); // ...
|
||||
retVal = 0;
|
||||
}
|
||||
}
|
||||
@@ -447,16 +456,18 @@ int ILibDuktape_readableStream_WriteEnd(ILibDuktape_readableStream *stream)
|
||||
void ILibDuktape_readableStream_Closed(ILibDuktape_readableStream *stream)
|
||||
{
|
||||
ILibDuktape_readableStream_WriteEnd(stream);
|
||||
if (stream->OnClose != NULL)
|
||||
if(ILibDuktape_EventEmitter_HasListeners(stream->emitter, "close")!=0)
|
||||
{
|
||||
duk_push_heapptr(stream->ctx, stream->OnClose); // [func]
|
||||
duk_push_heapptr(stream->ctx, stream->object); // [func][this]
|
||||
if (duk_pcall_method(stream->ctx, 0) != 0) // [retVal]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(stream->ctx);
|
||||
}
|
||||
duk_pop(stream->ctx); // ...
|
||||
ILibDuktape_EventEmitter_SetupEmit(stream->ctx, stream->object, "close"); // [emit][this][close]
|
||||
if (duk_pcall_method(stream->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(stream->ctx); }
|
||||
duk_pop(stream->ctx); // ...
|
||||
}
|
||||
|
||||
duk_push_heapptr(stream->ctx, stream->object); // [stream]
|
||||
duk_get_prop_string(stream->ctx, -1, "unpipe"); // [stream][unpipe]
|
||||
duk_swap_top(stream->ctx, -2); // [unpipe][this]
|
||||
if (duk_pcall_method(stream->ctx, 0) != 0) { ILibDuktape_Process_UncaughtException(stream->ctx); }
|
||||
duk_pop(stream->ctx); // ...
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_readableStream_pause(duk_context *ctx)
|
||||
@@ -482,7 +493,7 @@ duk_ret_t ILibDuktape_readableStream_pause(duk_context *ctx)
|
||||
int ILibDuktape_readableStream_resume_flush(ILibDuktape_readableStream *rs)
|
||||
{
|
||||
// Sanity check, and make sure there is a listener first, otherwise we're wasting our time
|
||||
if (rs->OnData == NULL && rs->nextWriteable == NULL && rs->OnEnd == NULL)
|
||||
if(ILibDuktape_EventEmitter_HasListeners(rs->emitter, "data")==0 && rs->nextWriteable == NULL && ILibDuktape_EventEmitter_HasListeners(rs->emitter, "end")==0)
|
||||
{
|
||||
return 1; // No listeners....
|
||||
}
|
||||
@@ -528,12 +539,23 @@ duk_ret_t ILibDuktape_readableStream_resume(duk_context *ctx)
|
||||
void ILibDuktape_ReadableStream_pipe_ResumeLater(duk_context *ctx, void **args, int argsLen)
|
||||
{
|
||||
ILibDuktape_readableStream *rs = (ILibDuktape_readableStream*)args[0];
|
||||
rs->resumeImmediate = NULL;
|
||||
if (ILibDuktape_readableStream_resume_flush(rs) == 0 && rs->ResumeHandler != NULL) { rs->paused = 0; rs->ResumeHandler(rs, rs->user); }
|
||||
if (rs->PipeHookHandler != NULL) { rs->PipeHookHandler(rs, args[1], rs->user); }
|
||||
}
|
||||
void ILibDuktape_readableStream_pipe_later(duk_context *ctx, void **args, int argsLen)
|
||||
{
|
||||
duk_push_heapptr(ctx, args[0]); // [readable]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_readableStream_RSPTRS);
|
||||
ILibDuktape_readableStream *rs = (ILibDuktape_readableStream*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_pop(ctx);
|
||||
|
||||
duk_push_heapptr(ctx, rs->pipeImmediate);
|
||||
duk_del_prop_string(ctx, -1, "dest");
|
||||
duk_pop(ctx);
|
||||
rs->pipeImmediate = NULL;
|
||||
|
||||
|
||||
duk_get_prop_string(ctx, -1, "pipe"); // [readable][pipe]
|
||||
duk_swap_top(ctx, -2); // [pipe][this]
|
||||
duk_push_heapptr(ctx, args[1]); // [pipe][this][writable]
|
||||
@@ -557,8 +579,10 @@ duk_ret_t ILibDuktape_readableStream_pipe(duk_context *ctx)
|
||||
{
|
||||
// We must YIELD and try again later, becuase there is an active dispatch going on
|
||||
duk_push_this(ctx);
|
||||
ILibDuktape_Immediate(ctx, (void*[]) { duk_get_heapptr(ctx, -1), duk_get_heapptr(ctx, 0), nargs > 1 ? duk_get_heapptr(ctx, 1) : NULL }, 1 + nargs, ILibDuktape_readableStream_pipe_later);
|
||||
|
||||
rstream->pipeImmediate = ILibDuktape_Immediate(ctx, (void*[]) { duk_get_heapptr(ctx, -1), duk_get_heapptr(ctx, 0), nargs > 1 ? duk_get_heapptr(ctx, 1) : NULL }, 1 + nargs, ILibDuktape_readableStream_pipe_later);
|
||||
duk_push_heapptr(ctx, rstream->pipeImmediate); // [immediate]
|
||||
duk_dup(ctx, 0); // [immediate][ws]
|
||||
duk_put_prop_string(ctx, -2, "dest"); // [immediate]
|
||||
duk_dup(ctx, 0);
|
||||
sem_post(&(rstream->pipeLock));
|
||||
return(1);
|
||||
@@ -615,12 +639,14 @@ duk_ret_t ILibDuktape_readableStream_pipe(duk_context *ctx)
|
||||
duk_push_string(ctx, "pipe"); // [emit][this][pipe]
|
||||
duk_push_this(ctx); // [emit][this][pipe][readable]
|
||||
duk_call_method(ctx, 2); duk_pop(ctx); // ...
|
||||
|
||||
|
||||
if (rstream->paused != 0)
|
||||
{
|
||||
// We are paused, so we should yield and resume... We yield, so in case the user tries to chain multiple pipes, it will chain first
|
||||
ILibDuktape_Immediate(ctx, (void*[]) { rstream, duk_get_heapptr(ctx, 0) }, 1, ILibDuktape_ReadableStream_pipe_ResumeLater);
|
||||
rstream->resumeImmediate = ILibDuktape_Immediate(ctx, (void*[]) { rstream, duk_get_heapptr(ctx, 0) }, 1, ILibDuktape_ReadableStream_pipe_ResumeLater);
|
||||
duk_push_heapptr(ctx, rstream->resumeImmediate); // [immediate]
|
||||
duk_push_this(ctx); // [immediate][this]
|
||||
duk_put_prop_string(ctx, -2, "self"); // [immediate]
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -646,7 +672,12 @@ void ILibDuktape_readableStream_unpipe_later(duk_context *ctx, void ** args, int
|
||||
if (data->pipeInProgress != 0)
|
||||
{
|
||||
// We must yield, and try again, because there's an active dispatch going on
|
||||
ILibDuktape_Immediate(ctx, (void*[]) { args[0], args[1] }, argsLen, ILibDuktape_readableStream_unpipe_later);
|
||||
void *imm = ILibDuktape_Immediate(ctx, (void*[]) { args[0], args[1] }, argsLen, ILibDuktape_readableStream_unpipe_later);
|
||||
duk_push_heapptr(ctx, imm); // [immediate]
|
||||
duk_push_heapptr(ctx, args[0]); // [immediate][this]
|
||||
duk_put_prop_string(ctx, -2, "\xFF_Self"); // [immediate]
|
||||
if (args[1] != NULL) { duk_push_heapptr(ctx, args[1]); duk_put_prop_string(ctx, -2, "\xFF_w"); }
|
||||
duk_pop(ctx); // ...
|
||||
sem_post(&(data->pipeLock));
|
||||
return;
|
||||
}
|
||||
@@ -683,11 +714,11 @@ void ILibDuktape_readableStream_unpipe_later(duk_context *ctx, void ** args, int
|
||||
for (i = 0; i < (int)arrayLen; ++i)
|
||||
{
|
||||
duk_get_prop_index(ctx, -1, i); // [array][ws]
|
||||
ILibDuktape_Push_ObjectStash(ctx); // [array][ws][stash]
|
||||
if (duk_has_prop_string(ctx, -1, Duktape_GetStashKey(args[1])))
|
||||
if(duk_get_heapptr(ctx, -1) == args[1])
|
||||
{
|
||||
if (g_displayFinalizerMessages) { printf("*** UNPIPE/Removing Reference to Writeable: %s (RefCount: %d)\n", Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "UNKNOWN"), ILibDuktape_GetReferenceCount(ctx, -1)); }
|
||||
// Removing the entry from the Array
|
||||
duk_pop_2(ctx); // [array]
|
||||
duk_pop(ctx); // [array]
|
||||
duk_get_prop_string(ctx, -1, "splice"); // [array][splice]
|
||||
duk_swap_top(ctx, -2); // [splice][this]
|
||||
duk_push_int(ctx, i); // [splice][this][i]
|
||||
@@ -707,10 +738,10 @@ void ILibDuktape_readableStream_unpipe_later(duk_context *ctx, void ** args, int
|
||||
else
|
||||
{
|
||||
// 'unpipe' all pipes
|
||||
w = data->nextWriteable;
|
||||
while (w != NULL)
|
||||
{
|
||||
duk_push_heapptr(ctx, w->writableStream); // [ws]
|
||||
if (g_displayFinalizerMessages) { printf("*** UNPIPE/Removing Reference to Writeable: %s (RefCount: %d)\n", Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "UNKNOWN"), ILibDuktape_GetReferenceCount(ctx, -1)); }
|
||||
duk_get_prop_string(ctx, -1, "emit"); // [ws][emit]
|
||||
duk_swap_top(ctx, -2); // [emit][this]
|
||||
duk_push_string(ctx, "unpipe"); // [emit][this][unpipe]
|
||||
@@ -752,7 +783,13 @@ duk_ret_t ILibDuktape_readableStream_unpipe(duk_context *ctx)
|
||||
duk_call_method(ctx, 0); duk_pop(ctx); // [readable]
|
||||
|
||||
// We must yield, and do this on the next event loop, because we can't unpipe if we're called from a pipe'ed call
|
||||
ILibDuktape_Immediate(ctx, (void*[]) { duk_get_heapptr(ctx, -1), nargs == 1 ? duk_get_heapptr(ctx, 0) : NULL }, nargs + 1, ILibDuktape_readableStream_unpipe_later);
|
||||
void *imm = ILibDuktape_Immediate(ctx, (void*[]) { duk_get_heapptr(ctx, -1), nargs == 1 ? duk_get_heapptr(ctx, 0) : NULL }, nargs + 1, ILibDuktape_readableStream_unpipe_later);
|
||||
duk_push_heapptr(ctx, imm); // [immediate]
|
||||
duk_push_this(ctx); // [immediate][this]
|
||||
duk_put_prop_string(ctx, -2, "\xFF_Self"); // [immediate]
|
||||
if (nargs == 1) { duk_dup(ctx, 0); duk_put_prop_string(ctx, -2, "\xFF_w"); }
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
return 0;
|
||||
}
|
||||
duk_ret_t ILibDuktape_readableStream_isPaused(duk_context *ctx)
|
||||
@@ -777,13 +814,23 @@ duk_ret_t ILibDuktape_readableStream_pipe_getter(duk_context *ctx)
|
||||
duk_push_c_function(ctx, ILibDuktape_readableStream_pipe, DUK_VARARGS);
|
||||
return 1;
|
||||
}
|
||||
void ILibDuktape_ReadableStream_PipeLockFinalizer(duk_context *ctx, void *stream)
|
||||
duk_ret_t ILibDuktape_ReadableStream_PipeLockFinalizer(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_readableStream_bufferedData *tmp;
|
||||
ILibDuktape_readableStream *ptrs;
|
||||
duk_push_heapptr(ctx, stream); // [stream]
|
||||
|
||||
duk_push_this(ctx); // [stream]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_readableStream_RSPTRS); // [stream][buffer]
|
||||
ptrs = (ILibDuktape_readableStream*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
if (ptrs->pipeImmediate != NULL)
|
||||
{
|
||||
duk_push_global_object(ctx); // [g]
|
||||
duk_get_prop_string(ctx, -1, "clearImmediate"); // [g][clearImmediate]
|
||||
duk_swap_top(ctx, -2); // [clearImmediate][this]
|
||||
duk_push_heapptr(ctx, ptrs->pipeImmediate); // [clearImmediate][this][immedate]
|
||||
duk_call_method(ctx, 1); duk_pop(ctx); // ...
|
||||
ptrs->pipeImmediate = NULL;
|
||||
}
|
||||
|
||||
while ((tmp = (ILibDuktape_readableStream_bufferedData*)ptrs->paused_data) != NULL)
|
||||
{
|
||||
@@ -794,6 +841,7 @@ void ILibDuktape_ReadableStream_PipeLockFinalizer(duk_context *ctx, void *stream
|
||||
|
||||
sem_destroy(&(ptrs->pipeLock));
|
||||
duk_pop_2(ctx);
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_ReadableStream_unshift(duk_context *ctx)
|
||||
{
|
||||
@@ -809,7 +857,7 @@ duk_ret_t ILibDuktape_ReadableStream_unshift(duk_context *ctx)
|
||||
else
|
||||
{
|
||||
duk_size_t bufferLen;
|
||||
Duktape_GetBuffer(ctx, 0, &bufferLen);
|
||||
rs->unshiftReserved = (char*)Duktape_GetBuffer(ctx, 0, &bufferLen);
|
||||
duk_push_int(ctx, rs->UnshiftHandler(rs, (int)bufferLen, rs->user));
|
||||
return(1);
|
||||
}
|
||||
@@ -831,7 +879,6 @@ ILibDuktape_readableStream* ILibDuktape_ReadableStream_InitEx(duk_context *ctx,
|
||||
retVal->pipeArray = duk_get_heapptr(ctx, -1);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_readableStream_PipeArray); // [obj]
|
||||
|
||||
|
||||
retVal->ctx = ctx;
|
||||
retVal->chain = Duktape_GetChain(ctx);
|
||||
retVal->object = duk_get_heapptr(ctx, -1);
|
||||
@@ -840,12 +887,12 @@ ILibDuktape_readableStream* ILibDuktape_ReadableStream_InitEx(duk_context *ctx,
|
||||
retVal->ResumeHandler = OnResume;
|
||||
retVal->UnshiftHandler = OnUnshift;
|
||||
sem_init(&(retVal->pipeLock), 0, 1);
|
||||
ILibDuktape_CreateIndependentFinalizer(ctx, ILibDuktape_ReadableStream_PipeLockFinalizer);
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_ReadableStream_PipeLockFinalizer);
|
||||
|
||||
emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
ILibDuktape_EventEmitter_CreateEvent(emitter, "end", &(retVal->OnEnd));
|
||||
ILibDuktape_EventEmitter_CreateEvent(emitter, "data", &(retVal->OnData));
|
||||
ILibDuktape_EventEmitter_CreateEvent(emitter, "close", &(retVal->OnClose));
|
||||
retVal->emitter = emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "end");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "data");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "close");
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "pause", ILibDuktape_readableStream_pause, 0);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "resume", ILibDuktape_readableStream_resume, 0);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ limitations under the License.
|
||||
|
||||
#include "duktape.h"
|
||||
#include "microstack/ILibParsers.h"
|
||||
#include "ILibDuktape_EventEmitter.h"
|
||||
|
||||
#define ILibDuktape_readableStream_RSPTRS "\xFF_ReadableStream_PTRS"
|
||||
|
||||
@@ -39,9 +40,6 @@ typedef struct ILibDuktape_readableStream
|
||||
duk_context *ctx;
|
||||
void *chain;
|
||||
void *object;
|
||||
void *OnClose;
|
||||
void *OnData;
|
||||
void *OnEnd;
|
||||
|
||||
void *user;
|
||||
void *pipeArray;
|
||||
@@ -64,6 +62,10 @@ typedef struct ILibDuktape_readableStream
|
||||
ILibDuktape_readableStream_PauseResumeHandler ResumeHandler;
|
||||
ILibDuktape_readableStream_MethodHookHandler PipeHookHandler;
|
||||
ILibDuktape_readableStream_UnShiftHandler UnshiftHandler;
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
char *unshiftReserved;
|
||||
void *resumeImmediate;
|
||||
void *pipeImmediate;
|
||||
}ILibDuktape_readableStream;
|
||||
|
||||
ILibDuktape_readableStream* ILibDuktape_ReadableStream_InitEx(duk_context *ctx, ILibDuktape_readableStream_PauseResumeHandler OnPause, ILibDuktape_readableStream_PauseResumeHandler OnResume, ILibDuktape_readableStream_UnShiftHandler OnUnshift, void *user);
|
||||
@@ -71,6 +73,7 @@ ILibDuktape_readableStream* ILibDuktape_ReadableStream_InitEx(duk_context *ctx,
|
||||
#define ILibDuktape_ReadableStream_Init(ctx, OnPause, OnResume, user) ILibDuktape_ReadableStream_InitEx(ctx, OnPause, OnResume, NULL, user)
|
||||
#define ILibDuktape_readableStream_SetPauseResumeHandlers(stream, PauseFunc, ResumeFunc, userObj) ((ILibDuktape_readableStream*)stream)->PauseHandler = PauseFunc; ((ILibDuktape_readableStream*)stream)->ResumeHandler = ResumeFunc; ((ILibDuktape_readableStream*)stream)->user = userObj;
|
||||
|
||||
void ILibDuktape_ReadableStream_DestroyPausedData(ILibDuktape_readableStream *stream);
|
||||
int ILibDuktape_readableStream_WriteDataEx(ILibDuktape_readableStream *stream, int streamReserved, char* buffer, int bufferLen);
|
||||
int ILibDuktape_readableStream_WriteEnd(ILibDuktape_readableStream *stream);
|
||||
#define ILibDuktape_readableStream_WriteData(stream, buffer, bufferLen) ILibDuktape_readableStream_WriteDataEx(stream, 0, buffer, bufferLen)
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ILibDuktape_SHA256.h"
|
||||
#include "duktape.h"
|
||||
#include "ILibDuktape_Helpers.h"
|
||||
@@ -21,8 +37,6 @@ typedef struct ILibDuktape_SHA256_Data
|
||||
duk_context *ctx;
|
||||
|
||||
void *object;
|
||||
void *OnHash;
|
||||
void *OnHashString;
|
||||
char buffer[33];
|
||||
SHA256_CTX shctx;
|
||||
}ILibDuktape_SHA256_Data;
|
||||
@@ -31,8 +45,6 @@ typedef struct ILibDuktape_SHA512_Data
|
||||
duk_context *ctx;
|
||||
|
||||
void *object;
|
||||
void *OnHash;
|
||||
void *OnHashString;
|
||||
char buffer[65];
|
||||
SHA512_CTX shctx;
|
||||
}ILibDuktape_SHA512_Data;
|
||||
@@ -41,8 +53,6 @@ typedef struct ILibDuktape_MD5_Data
|
||||
duk_context *ctx;
|
||||
|
||||
void *object;
|
||||
void *OnHash;
|
||||
void *OnHashString;
|
||||
char buffer[33];
|
||||
MD5_CTX mctx;
|
||||
}ILibDuktape_MD5_Data;
|
||||
@@ -82,34 +92,21 @@ ILibTransport_DoneState ILibDuktape_SHA384_Write(struct ILibDuktape_WritableStre
|
||||
}
|
||||
void ILibDuktape_SHA256_End(struct ILibDuktape_WritableStream *stream, void *user)
|
||||
{
|
||||
|
||||
ILibDuktape_SHA256_Data *data = (ILibDuktape_SHA256_Data*)user;
|
||||
data->buffer[32] = 0;
|
||||
SHA256_Final((unsigned char*)data->buffer, &(data->shctx));
|
||||
|
||||
if (data->ctx != NULL && data->OnHash != NULL)
|
||||
{
|
||||
duk_push_heapptr(data->ctx, data->OnHash); // [func]
|
||||
duk_push_heapptr(data->ctx, data->object); // [func][this]
|
||||
duk_push_external_buffer(data->ctx); // [func][this][hash]
|
||||
duk_config_buffer(data->ctx, -1, data->buffer, 32);
|
||||
if (duk_pcall_method(data->ctx, 1) != 0) // [retVal]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(data->ctx);
|
||||
}
|
||||
duk_pop(data->ctx); // ...
|
||||
}
|
||||
if (data->ctx != NULL && data->OnHashString != NULL)
|
||||
{
|
||||
duk_push_heapptr(data->ctx, data->OnHashString); // [func]
|
||||
duk_push_heapptr(data->ctx, data->object); // [func][this]
|
||||
duk_push_string(data->ctx, util_tohex(data->buffer, 32, ILibScratchPad)); // [func][this][hashString]
|
||||
if (duk_pcall_method(data->ctx, 1) != 0) // [retVal]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(data->ctx);
|
||||
}
|
||||
duk_pop(data->ctx); // ...
|
||||
}
|
||||
duk_push_external_buffer(data->ctx); // [extBuffer]
|
||||
duk_config_buffer(data->ctx, -1, data->buffer, 32);
|
||||
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hash"); // [extBuffer][emit][this]['hash']
|
||||
duk_push_buffer_object(data->ctx, -4, 0, 32, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this]['hash'][hash]
|
||||
if (duk_pcall_method(data->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
|
||||
duk_pop_2(data->ctx); // ...
|
||||
|
||||
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hashString"); // [emit][this]['hash']
|
||||
duk_push_string(data->ctx, util_tohex(data->buffer, 32, ILibScratchPad)); // [emit][this]['hash'][hashString]
|
||||
if (duk_pcall_method(data->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
|
||||
duk_pop(data->ctx); // ...
|
||||
}
|
||||
void ILibDuktape_SHA384_End(struct ILibDuktape_WritableStream *stream, void *user)
|
||||
{
|
||||
@@ -117,29 +114,17 @@ void ILibDuktape_SHA384_End(struct ILibDuktape_WritableStream *stream, void *use
|
||||
data->buffer[48] = 0;
|
||||
SHA384_Final((unsigned char*)data->buffer, &(data->shctx));
|
||||
|
||||
if (data->ctx != NULL && data->OnHash != NULL)
|
||||
{
|
||||
duk_push_heapptr(data->ctx, data->OnHash); // [func]
|
||||
duk_push_heapptr(data->ctx, data->object); // [func][this]
|
||||
duk_push_external_buffer(data->ctx); // [func][this][hash]
|
||||
duk_config_buffer(data->ctx, -1, data->buffer, 48);
|
||||
if (duk_pcall_method(data->ctx, 1) != 0) // [retVal]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(data->ctx);
|
||||
}
|
||||
duk_pop(data->ctx); // ...
|
||||
}
|
||||
if (data->ctx != NULL && data->OnHashString != NULL)
|
||||
{
|
||||
duk_push_heapptr(data->ctx, data->OnHashString); // [func]
|
||||
duk_push_heapptr(data->ctx, data->object); // [func][this]
|
||||
duk_push_string(data->ctx, util_tohex(data->buffer, 48, ILibScratchPad)); // [func][this][hashString]
|
||||
if (duk_pcall_method(data->ctx, 1) != 0) // [retVal]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(data->ctx);
|
||||
}
|
||||
duk_pop(data->ctx); // ...
|
||||
}
|
||||
duk_push_external_buffer(data->ctx); // [extBuffer]
|
||||
duk_config_buffer(data->ctx, -1, data->buffer, 48);
|
||||
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hash"); // [extBuffer][emit][this]['hash']
|
||||
duk_push_buffer_object(data->ctx, -4, 0, 48, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this]['hash'][hash]
|
||||
if (duk_pcall_method(data->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
|
||||
duk_pop_2(data->ctx); // ...
|
||||
|
||||
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hashString"); // [emit][this]['hashString']
|
||||
duk_push_string(data->ctx, util_tohex(data->buffer, 48, ILibScratchPad)); // [emit][this]['hashString'][hashString]
|
||||
if (duk_pcall_method(data->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
|
||||
duk_pop(data->ctx); // ...
|
||||
}
|
||||
duk_ret_t ILibDuktape_SHA256_SIGNER_Finalizer(duk_context *ctx)
|
||||
{
|
||||
@@ -175,7 +160,7 @@ void ILibDuktape_SHA256_SIGNER_End(struct ILibDuktape_WritableStream *stream, vo
|
||||
duk_swap_top(data->ctx, -2); // [sigBuffer][signer]
|
||||
duk_push_heapptr(data->ctx, data->OnSignature); // [sigBuffer][signer][func]
|
||||
duk_swap_top(data->ctx, -2); // [sigBuffer][func][signer/this]
|
||||
duk_push_buffer_object(data->ctx, -3, 0, len, DUK_BUFOBJ_DUKTAPE_BUFFER); // [sigBuffer][func][signer/this][bufView]
|
||||
duk_push_buffer_object(data->ctx, -3, 0, len, DUK_BUFOBJ_NODEJS_BUFFER); // [sigBuffer][func][signer/this][bufView]
|
||||
if (duk_pcall_method(data->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); } // ...
|
||||
}
|
||||
duk_pop(data->ctx); // ...
|
||||
@@ -363,29 +348,23 @@ void ILibDuktape_MD5_End(struct ILibDuktape_WritableStream *stream, void *user)
|
||||
data->buffer[32] = 0;
|
||||
MD5_Final((unsigned char*)data->buffer, &(data->mctx));
|
||||
|
||||
if (data->ctx != NULL && data->OnHash != NULL)
|
||||
duk_push_external_buffer(data->ctx); // [extBuffer]
|
||||
duk_config_buffer(data->ctx, -1, data->buffer, 32);
|
||||
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hash"); // [extBuffer][emit][this]["hash"]
|
||||
duk_push_buffer_object(data->ctx, -4, 0, 32, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this]["hash"][buffer]
|
||||
if (duk_pcall_method(data->ctx, 2) != 0) // [retVal]
|
||||
{
|
||||
duk_push_heapptr(data->ctx, data->OnHash); // [func]
|
||||
duk_push_heapptr(data->ctx, data->object); // [func][this]
|
||||
duk_push_external_buffer(data->ctx); // [func][this][hash]
|
||||
duk_config_buffer(data->ctx, -1, data->buffer, 32);
|
||||
if (duk_pcall_method(data->ctx, 1) != 0) // [retVal]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(data->ctx);
|
||||
}
|
||||
duk_pop(data->ctx); // ...
|
||||
ILibDuktape_Process_UncaughtException(data->ctx);
|
||||
}
|
||||
if (data->ctx != NULL && data->OnHashString != NULL)
|
||||
duk_pop_2(data->ctx); // ...
|
||||
|
||||
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hashString"); // [emit][this]["hashString"]
|
||||
duk_push_string(data->ctx, util_tohex(data->buffer, 32, ILibScratchPad)); // [emit][this]["hashString"][hashString]
|
||||
if (duk_pcall_method(data->ctx, 2) != 0) // [retVal]
|
||||
{
|
||||
duk_push_heapptr(data->ctx, data->OnHashString); // [func]
|
||||
duk_push_heapptr(data->ctx, data->object); // [func][this]
|
||||
duk_push_string(data->ctx, util_tohex(data->buffer, 32, ILibScratchPad)); // [func][this][hashString]
|
||||
if (duk_pcall_method(data->ctx, 1) != 0) // [retVal]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(data->ctx);
|
||||
}
|
||||
duk_pop(data->ctx); // ...
|
||||
ILibDuktape_Process_UncaughtException(data->ctx);
|
||||
}
|
||||
duk_pop(data->ctx); // ...
|
||||
}
|
||||
duk_ret_t ILibDuktape_MD5_syncHash(duk_context *ctx)
|
||||
{
|
||||
@@ -431,8 +410,8 @@ duk_ret_t ILibDuktape_MD5_Create(duk_context *ctx)
|
||||
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 0, "syncHash", ILibDuktape_MD5_syncHash, 1);
|
||||
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 1, "syncHashString", ILibDuktape_MD5_syncHash, 1);
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEvent(emitter, "hash", &(data->OnHash));
|
||||
ILibDuktape_EventEmitter_CreateEvent(emitter, "hashString", &(data->OnHashString));
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hash");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hashString");
|
||||
|
||||
data->ctx = ctx;
|
||||
data->object = duk_get_heapptr(ctx, -1);
|
||||
@@ -457,8 +436,8 @@ duk_ret_t ILibDuktape_SHA256_Create(duk_context *ctx)
|
||||
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 0, "syncHash", ILibDuktape_SHA256_syncHash, 1);
|
||||
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 1, "syncHashString", ILibDuktape_SHA256_syncHash, 1);
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEvent(emitter, "hash", &(data->OnHash));
|
||||
ILibDuktape_EventEmitter_CreateEvent(emitter, "hashString", &(data->OnHashString));
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hash");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hashString");
|
||||
|
||||
data->ctx = ctx;
|
||||
data->object = duk_get_heapptr(ctx, -1);
|
||||
@@ -474,6 +453,7 @@ duk_ret_t ILibDuktape_SHA384_Create(duk_context *ctx)
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
|
||||
duk_push_object(ctx); // [sha]
|
||||
ILibDuktape_WriteID(ctx, "SHA384Stream");
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_SHA512_Data)); // [sha][buffer]
|
||||
data = (ILibDuktape_SHA512_Data*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_SHA512_PTR); // [sha]
|
||||
@@ -484,8 +464,8 @@ duk_ret_t ILibDuktape_SHA384_Create(duk_context *ctx)
|
||||
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 0, "syncHash", ILibDuktape_SHA384_syncHash, 1);
|
||||
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 1, "syncHashString", ILibDuktape_SHA384_syncHash, 1);
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEvent(emitter, "hash", &(data->OnHash));
|
||||
ILibDuktape_EventEmitter_CreateEvent(emitter, "hashString", &(data->OnHashString));
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hash");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hashString");
|
||||
|
||||
data->ctx = ctx;
|
||||
data->object = duk_get_heapptr(ctx, -1);
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ___DUKTAPE_SHA256___
|
||||
#define ___DUKTAPE_SHA256___
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -14,7 +14,6 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#include <WinSock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
@@ -52,6 +51,7 @@ limitations under the License.
|
||||
#include "ILibDuktape_Polyfills.h"
|
||||
#include "ILibDuktape_SimpleDataStore.h"
|
||||
#include "ILibDuktape_NetworkMonitor.h"
|
||||
#include "ILibDuktape_ReadableStream.h"
|
||||
|
||||
#include "ILibDuktape_SHA256.h"
|
||||
#include "ILibDuktape_EncryptionStream.h"
|
||||
@@ -62,13 +62,16 @@ limitations under the License.
|
||||
extern char **environ;
|
||||
#endif
|
||||
#define SCRIPT_ENGINE_PIPE_BUFFER_SIZE 65535
|
||||
|
||||
char exeJavaScriptGuid[] = "B996015880544A19B7F7E9BE44914C18";
|
||||
#define ILibDuktape_ScriptContainer_MasterPtr "\xFF_ScriptContainer_MasterPtr"
|
||||
#define ILibDuktape_ScriptContainer_SlavePtr "\xFF_ScriptContainer_SlavePtr"
|
||||
#define ILibDuktape_ScriptContainer_ExePath "\xFF_ScriptContainer_ExePath"
|
||||
#define ILibDuktape_ScriptContainer_PipeManager "\xFF_ScriptContainer_PipeManager"
|
||||
#define ILibDuktape_ScriptContainer_PtrTable "\xFF_ScriptContainer_PtrTable"
|
||||
#define ILibDuktape_ScriptContainer_PtrTable_Idx "\xFF_ScriptContainer_PtrTableIdx"
|
||||
|
||||
#define ILibDuktape_ScriptContainer_ProcessIsolated "\xFF_ScriptContainer_ProcessIsolated"
|
||||
#define ILibDuktape_ScriptContainer_PeerThread "\xFF_ScriptContainer_PeerThread"
|
||||
|
||||
#define ILibDuktape_ScriptContainer_Command_Execute_Status "ScriptContainer_Command_Execute_Status"
|
||||
#define ILibDuktape_ScriptContainer_Command_Log "ScriptContainer_Command_Log"
|
||||
@@ -79,6 +82,7 @@ extern char **environ;
|
||||
#define ILibDuktape_ScriptContainer_Settings_ExitUser "\xFF_ScriptContainerSettings_ExitUser"
|
||||
#define ILibDuktape_ScriptContainer_Process_ArgArray "\xFF_argArray"
|
||||
#define ILibDuktape_ScriptContainer_Process_Restart "\xFF_ScriptContainer_Process_Restart"
|
||||
#define ILibDuktape_ScriptContainer_Process_stdin "\xFF_stdin"
|
||||
|
||||
#define ILibDuktape_ScriptContainer_ExitCode "\xFF_ExitCode"
|
||||
#define ILibDuktape_ScriptContainer_Exitting "\xFF_Exiting"
|
||||
@@ -111,6 +115,7 @@ extern char **environ;
|
||||
|
||||
extern void ILibDuktape_MemoryStream_Init(duk_context *ctx);
|
||||
extern void ILibDuktape_NetworkMonitor_Init(duk_context *ctx);
|
||||
char g_AgentCrashID[280];
|
||||
|
||||
typedef enum SCRIPT_ENGINE_COMMAND
|
||||
{
|
||||
@@ -121,6 +126,8 @@ typedef enum SCRIPT_ENGINE_COMMAND
|
||||
SCRIPT_ENGINE_COMMAND_SEND_JSON = 0x10,
|
||||
SCRIPT_ENGINE_COMMAND_QUERY = 0x20,
|
||||
SCRIPT_ENGINE_COMMAND_SET = 0x21,
|
||||
SCRIPT_ENGINE_COMMAND_ERROR = 0x40,
|
||||
SCRIPT_ENGINE_COMMAND_EXIT = 0x80,
|
||||
SCRIPT_ENGINE_COMMAND_LOG = 0xFF
|
||||
}SCRIPT_ENGINE_COMMAND;
|
||||
|
||||
@@ -132,7 +139,8 @@ typedef struct ILibDuktape_ScriptContainer_Master
|
||||
|
||||
ILibProcessPipe_Process child;
|
||||
void *chain;
|
||||
void *OnExit, *OnError, *OnJSON;
|
||||
void *PeerThread, *PeerChain;
|
||||
unsigned int ChildSecurityFlags;
|
||||
}ILibDuktape_ScriptContainer_Master;
|
||||
|
||||
typedef struct ILibDuktape_ScriptContainer_Slave
|
||||
@@ -140,11 +148,21 @@ typedef struct ILibDuktape_ScriptContainer_Slave
|
||||
duk_context *ctx;
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
|
||||
void *OnData;
|
||||
void *chain;
|
||||
int exitCode;
|
||||
int noRespond;
|
||||
}ILibDuktape_ScriptContainer_Slave;
|
||||
|
||||
|
||||
typedef struct ILibDuktape_ScriptContainer_NonIsolated_Command
|
||||
{
|
||||
union { ILibDuktape_ScriptContainer_Master * master; ILibDuktape_ScriptContainer_Slave *slave; }container;
|
||||
char json[];
|
||||
}ILibDuktape_ScriptContainer_NonIsolated_Command;
|
||||
|
||||
void ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsSlave(void *chain, void *user);
|
||||
void ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsMaster(void *chain, void *user);
|
||||
|
||||
#ifdef _REMOTELOGGING
|
||||
void ILibDuktape_ScriptContainer_Slave_LogForwarder(ILibRemoteLogging sender, ILibRemoteLogging_Modules module, ILibRemoteLogging_Flags flags, char *buffer, int bufferLen)
|
||||
{
|
||||
@@ -190,40 +208,134 @@ void ILibDuktape_ScriptContainer_Slave_OnBrokenPipe(ILibProcessPipe_Pipe sender)
|
||||
void ILibDuktape_ScriptContainer_CheckEmbedded(char **argv, char **script, int *scriptLen)
|
||||
{
|
||||
// Check if .JS file is integrated with executable
|
||||
int i;
|
||||
FILE *tmpFile;
|
||||
char *integratedJavaScript = NULL;
|
||||
int integratedJavaScriptLen = 0;
|
||||
#ifdef WIN32
|
||||
if (ILibString_EndsWith(argv[0], -1, ".exe", 4) == 0)
|
||||
{
|
||||
i = sprintf_s(g_AgentCrashID, sizeof(g_AgentCrashID), "%s_", argv[0]);
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "%s.exe", argv[0]);
|
||||
fopen_s(&tmpFile, ILibScratchPad, "rb");
|
||||
}
|
||||
else
|
||||
{
|
||||
i = ILibString_LastIndexOf(argv[0], -1, "\\", 1);
|
||||
if (i > 0)
|
||||
{
|
||||
i = sprintf_s(g_AgentCrashID, sizeof(g_AgentCrashID), "%s", argv[0] + i + 1);
|
||||
g_AgentCrashID[i-4] = '_';
|
||||
i -= 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = sprintf_s(g_AgentCrashID, sizeof(g_AgentCrashID), "%s", argv[0]);
|
||||
g_AgentCrashID[i-4] = '_';
|
||||
i -= 3;
|
||||
}
|
||||
fopen_s(&tmpFile, argv[0], "rb");
|
||||
}
|
||||
#else
|
||||
i = sprintf_s(g_AgentCrashID, sizeof(g_AgentCrashID), "%s_", argv[0]);
|
||||
tmpFile = fopen(argv[0], "rb");
|
||||
#endif
|
||||
|
||||
if (tmpFile != NULL)
|
||||
{
|
||||
fseek(tmpFile, 0, SEEK_END);
|
||||
fseek(tmpFile, ftell(tmpFile) - 4, SEEK_SET);
|
||||
ignore_result(fread(ILibScratchPad, 1, 4, tmpFile));
|
||||
fseek(tmpFile, 0, SEEK_END);
|
||||
if (ftell(tmpFile) == ntohl(((int*)ILibScratchPad)[0]))
|
||||
SHA512_CTX shctx;
|
||||
char hashBuffer[4096];
|
||||
char hashValue[1 + UTIL_SHA384_HASHSIZE];
|
||||
int hashBufferReadLen;
|
||||
|
||||
SHA384_Init(&shctx);
|
||||
while ((hashBufferReadLen = (int)fread(hashBuffer, 1, sizeof(hashBuffer), tmpFile)) > 0)
|
||||
{
|
||||
fseek(tmpFile, ftell(tmpFile) - 8, SEEK_SET);
|
||||
SHA384_Update(&shctx, hashBuffer, hashBufferReadLen);
|
||||
}
|
||||
SHA384_Final((unsigned char*)hashValue, &shctx);
|
||||
util_tohex(hashValue, UTIL_SHA384_HASHSIZE, g_AgentCrashID + i);
|
||||
#ifdef WIN32
|
||||
memcpy_s(g_AgentCrashID + i + 16, 5, ".exe", 5);
|
||||
#else
|
||||
g_AgentCrashID[i + 16] = 0;
|
||||
#endif
|
||||
|
||||
g_ILibCrashID = g_AgentCrashID;
|
||||
|
||||
#ifdef WIN32
|
||||
// Read the PE Headers, to determine where to look for the Embedded JS
|
||||
char *optHeader = NULL;
|
||||
fseek(tmpFile, 0, SEEK_SET);
|
||||
ignore_result(fread(ILibScratchPad, 1, 2, tmpFile));
|
||||
if (ntohs(((unsigned int*)ILibScratchPad)[0]) == 19802) // 5A4D
|
||||
{
|
||||
fseek(tmpFile, 60, SEEK_SET);
|
||||
ignore_result(fread(ILibScratchPad, 1, 4, tmpFile));
|
||||
integratedJavaScriptLen = ntohl(((int*)ILibScratchPad)[0]);
|
||||
integratedJavaScript = ILibMemory_Allocate(1 + integratedJavaScriptLen, 0, NULL, NULL);
|
||||
fseek(tmpFile, 0, SEEK_END);
|
||||
fseek(tmpFile, ftell(tmpFile) - 8 - integratedJavaScriptLen, SEEK_SET);
|
||||
fseek(tmpFile, ((unsigned *)ILibScratchPad)[0], SEEK_SET);
|
||||
ignore_result(fread(ILibScratchPad, 1, 24, tmpFile));
|
||||
if (((unsigned int*)ILibScratchPad)[0] == 17744)
|
||||
{
|
||||
// PE Image
|
||||
optHeader = ILibMemory_AllocateA(((unsigned short*)ILibScratchPad)[10]);
|
||||
ignore_result(fread(optHeader, 1, ILibMemory_AllocateA_Size(optHeader), tmpFile));
|
||||
switch (((unsigned short*)optHeader)[0])
|
||||
{
|
||||
case 0x10B:
|
||||
if (((unsigned int*)(optHeader + 128))[0] != 0)
|
||||
{
|
||||
fseek(tmpFile, ((unsigned int*)(optHeader + 128))[0] - 16, SEEK_SET);
|
||||
}
|
||||
else
|
||||
{
|
||||
fseek(tmpFile, -16, SEEK_END);
|
||||
}
|
||||
break;
|
||||
case 0x20B:
|
||||
if (((unsigned int*)(optHeader + 144))[0] != 0)
|
||||
{
|
||||
fseek(tmpFile, ((unsigned int*)(optHeader + 144))[0] - 16, SEEK_SET);
|
||||
}
|
||||
else
|
||||
{
|
||||
fseek(tmpFile, -16, SEEK_END);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fclose(tmpFile);
|
||||
return;
|
||||
}
|
||||
ignore_result(fread(ILibScratchPad, 1, 16, tmpFile));
|
||||
util_hexToBuf(exeJavaScriptGuid, 32, ILibScratchPad2);
|
||||
if (memcmp(ILibScratchPad, ILibScratchPad2, 16) == 0)
|
||||
{
|
||||
// Found an Embedded JS
|
||||
fseek(tmpFile, -20, SEEK_CUR);
|
||||
ignore_result(fread((void*)&integratedJavaScriptLen, 1, 4, tmpFile));
|
||||
integratedJavaScriptLen = (int)ntohl(integratedJavaScriptLen);
|
||||
fseek(tmpFile, -4 - integratedJavaScriptLen, SEEK_CUR);
|
||||
integratedJavaScript = ILibMemory_Allocate(integratedJavaScriptLen + 1, 0, NULL, NULL);
|
||||
ignore_result(fread(integratedJavaScript, 1, integratedJavaScriptLen, tmpFile));
|
||||
integratedJavaScript[integratedJavaScriptLen] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
fseek(tmpFile, -16, SEEK_END);
|
||||
ignore_result(fread(ILibScratchPad, 1, 16, tmpFile));
|
||||
util_hexToBuf(exeJavaScriptGuid, 32, ILibScratchPad2);
|
||||
if (memcmp(ILibScratchPad, ILibScratchPad2, 16) == 0)
|
||||
{
|
||||
// Found an Embedded JS
|
||||
fseek(tmpFile, -20, SEEK_CUR);
|
||||
ignore_result(fread((void*)&integratedJavaScriptLen, 1, 4, tmpFile));
|
||||
integratedJavaScriptLen = (int)ntohl(integratedJavaScriptLen);
|
||||
fseek(tmpFile, -4 - integratedJavaScriptLen, SEEK_CUR);
|
||||
integratedJavaScript = ILibMemory_Allocate(integratedJavaScriptLen + 1, 0, NULL, NULL);
|
||||
ignore_result(fread(integratedJavaScript, 1, integratedJavaScriptLen, tmpFile));
|
||||
integratedJavaScript[integratedJavaScriptLen] = 0;
|
||||
}
|
||||
#endif
|
||||
fclose(tmpFile);
|
||||
}
|
||||
*script = integratedJavaScript;
|
||||
@@ -353,6 +465,146 @@ duk_ret_t ILibDuktape_ScriptContainer_Process_env(duk_context *ctx)
|
||||
return(1);
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_ScriptContainer_Process_Finalizer(duk_context *ctx)
|
||||
{
|
||||
// We need to dispatch the 'exit' event
|
||||
int exitCode = 0;
|
||||
duk_push_this(ctx); // [process]
|
||||
if (duk_has_prop_string(ctx, -1, "\xFF_ExitCode"))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, "\xFF_ExitCode"); // [process][exitCode]
|
||||
exitCode = duk_get_int(ctx, -1);
|
||||
duk_pop(ctx); // [process]
|
||||
}
|
||||
ILibDuktape_EventEmitter_SetupEmit(ctx, duk_get_heapptr(ctx, -1), "exit"); // [emit][this]['exit']
|
||||
duk_push_int(ctx, exitCode); // [emit][this]['exit'][exitCode]
|
||||
duk_call_method(ctx, 2);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
typedef struct ILibDuktape_Process_StdIn_Data
|
||||
{
|
||||
ILibDuktape_readableStream *rs;
|
||||
#ifdef WIN32
|
||||
HANDLE workerThread;
|
||||
HANDLE resumeEvent;
|
||||
int exit;
|
||||
#endif
|
||||
int wasUnshifted;
|
||||
int endPointer;
|
||||
int bufferSize;
|
||||
char buffer[];
|
||||
}ILibDuktape_Process_StdIn_Data;
|
||||
|
||||
#ifdef WIN32
|
||||
void __stdcall ILibDuktape_Process_stdin_readSink(ULONG_PTR obj)
|
||||
{
|
||||
ILibDuktape_Process_StdIn_Data *data = (ILibDuktape_Process_StdIn_Data*)obj;
|
||||
int endPointer;
|
||||
do
|
||||
{
|
||||
endPointer = data->endPointer;
|
||||
data->wasUnshifted = 0;
|
||||
ILibDuktape_readableStream_WriteData(data->rs, data->buffer, data->endPointer);
|
||||
} while (!data->rs->paused && data->wasUnshifted > 0 && data->wasUnshifted != endPointer);
|
||||
|
||||
data->endPointer = data->wasUnshifted;
|
||||
if (!data->rs->paused) { SetEvent(data->resumeEvent); }
|
||||
}
|
||||
#endif
|
||||
void ILibDuktape_Process_stdin_pauseSink(struct ILibDuktape_readableStream *sender, void *user)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(sender);
|
||||
UNREFERENCED_PARAMETER(user);
|
||||
|
||||
// NO-OP, because stream state flag will be paused, which will cause the processing loop to exit
|
||||
}
|
||||
void ILibDuktape_Process_stdin_resumeSink(struct ILibDuktape_readableStream *sender, void *user)
|
||||
{
|
||||
ILibDuktape_Process_StdIn_Data *data = (ILibDuktape_Process_StdIn_Data*)user;
|
||||
#ifdef WIN32
|
||||
SetEvent(data->resumeEvent);
|
||||
#endif
|
||||
}
|
||||
int ILibDuktape_Process_stdin_unshiftSink(struct ILibDuktape_readableStream *sender, int unshiftBytes, void *user)
|
||||
{
|
||||
ILibDuktape_Process_StdIn_Data *data = (ILibDuktape_Process_StdIn_Data*)user;
|
||||
data->wasUnshifted = unshiftBytes <= data->endPointer ? unshiftBytes : data->endPointer;
|
||||
|
||||
if (unshiftBytes > 0 && unshiftBytes < data->endPointer)
|
||||
{
|
||||
memmove_s(data->buffer, data->bufferSize, data->buffer + (data->endPointer - unshiftBytes), unshiftBytes);
|
||||
data->endPointer = unshiftBytes;
|
||||
}
|
||||
return(data->wasUnshifted);
|
||||
}
|
||||
#ifdef WIN32
|
||||
void ILibDuktape_Process_stdin_WindowsRunLoop(void *arg)
|
||||
{
|
||||
ILibDuktape_Process_StdIn_Data *data = (ILibDuktape_Process_StdIn_Data*)arg;
|
||||
HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
|
||||
DWORD bytesRead, waitResult;
|
||||
|
||||
while (((waitResult = WaitForSingleObjectEx(data->resumeEvent, INFINITE, TRUE)) == WAIT_OBJECT_0 || waitResult == WAIT_IO_COMPLETION) && !data->exit)
|
||||
{
|
||||
if (!ReadFile(h, data->buffer + data->endPointer, data->bufferSize - data->endPointer, &bytesRead, NULL))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
ResetEvent(data->resumeEvent); // Reset, becuase we'll need to pause and context switch to Duktape thread
|
||||
data->endPointer += (int)bytesRead;
|
||||
QueueUserAPC((PAPCFUNC)ILibDuktape_Process_stdin_readSink, ILibChain_GetMicrostackThreadHandle(data->rs->chain), (ULONG_PTR)data);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
duk_ret_t ILibDuktape_Process_stdin_finalizer(duk_context *ctx)
|
||||
{
|
||||
duk_get_prop_string(ctx, 0, ILibDuktape_readableStream_RSPTRS);
|
||||
ILibDuktape_readableStream *rs = (ILibDuktape_readableStream*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
ILibDuktape_Process_StdIn_Data *data = (ILibDuktape_Process_StdIn_Data*)rs->user;
|
||||
|
||||
#ifdef WIN32
|
||||
data->exit = 1;
|
||||
SetEvent(data->resumeEvent);
|
||||
CancelSynchronousIo(data->workerThread);
|
||||
WaitForSingleObject(data->workerThread, 10000);
|
||||
|
||||
CloseHandle(data->resumeEvent);
|
||||
#endif
|
||||
|
||||
free(data);
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Process_stdin_get(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx); // [process]
|
||||
if (duk_has_prop_string(ctx, -1, ILibDuktape_ScriptContainer_Process_stdin))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_ScriptContainer_Process_stdin);
|
||||
return(1);
|
||||
}
|
||||
|
||||
duk_push_object(ctx); // [process][stdin]
|
||||
duk_dup(ctx, -1); // [process][stdin][dup]
|
||||
duk_put_prop_string(ctx, -3, ILibDuktape_ScriptContainer_Process_stdin); // [process][stdin]
|
||||
ILibDuktape_WriteID(ctx, "process.stdin");
|
||||
ILibDuktape_readableStream *rs = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_Process_stdin_pauseSink, ILibDuktape_Process_stdin_resumeSink, ILibDuktape_Process_stdin_unshiftSink, NULL);
|
||||
rs->user = ILibMemory_Allocate(sizeof(ILibDuktape_Process_StdIn_Data) + 4096, 0, NULL, NULL);
|
||||
((ILibDuktape_Process_StdIn_Data*)rs->user)->rs = rs;
|
||||
((ILibDuktape_Process_StdIn_Data*)rs->user)->bufferSize = 4096;
|
||||
|
||||
#ifdef WIN32
|
||||
((ILibDuktape_Process_StdIn_Data*)rs->user)->resumeEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
|
||||
((ILibDuktape_Process_StdIn_Data*)rs->user)->workerThread = ILibSpawnNormalThread(ILibDuktape_Process_stdin_WindowsRunLoop, rs->user);
|
||||
#endif
|
||||
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "~", ILibDuktape_Process_stdin_finalizer);
|
||||
return(1);
|
||||
}
|
||||
void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList)
|
||||
{
|
||||
int i = 0;
|
||||
@@ -360,6 +612,7 @@ void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList)
|
||||
|
||||
duk_push_global_object(ctx); // [g]
|
||||
duk_push_object(ctx); // [g][process]
|
||||
ILibDuktape_WriteID(ctx, "process");
|
||||
ILibDuktape_CreateEventWithGetter(ctx, "env", ILibDuktape_ScriptContainer_Process_env);
|
||||
|
||||
#if defined(WIN32) // [g][process][platform]
|
||||
@@ -416,8 +669,21 @@ void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList)
|
||||
duk_push_int(ctx, 0);
|
||||
ILibDuktape_CreateEventWithGetterAndCustomProperty(ctx, "readOnly", "_argv", ILibDuktape_ScriptContainer_Process_Argv);
|
||||
|
||||
duk_push_heap_stash(ctx); // [g][process][stash]
|
||||
if (!duk_has_prop_string(ctx, -1, ILibDuktape_ScriptContainer_SlavePtr))
|
||||
{
|
||||
duk_pop(ctx); // [g][process]
|
||||
ILibDuktape_CreateEventWithGetter(ctx, "stdin", ILibDuktape_Process_stdin_get);
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_pop(ctx); // [g][process]
|
||||
}
|
||||
|
||||
duk_put_prop_string(ctx, -2, "process"); // [g]
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
ILibDuktape_EventEmitter_AddOnceEx(emitter, "~", ILibDuktape_ScriptContainer_Process_Finalizer, 1);
|
||||
}
|
||||
void ILibDuktape_ScriptContainer_ExecTimeout_Finalizer(duk_context *ctx, void *timeoutKey)
|
||||
{
|
||||
@@ -510,9 +776,9 @@ void ILibDuktape_ScriptContainer_Engine_free(void *udata, void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
void ILibDuktape_ScriptContainer_Engine_fatal(duk_context *ctx, duk_errcode_t code, const char *msg)
|
||||
void ILibDuktape_ScriptContainer_Engine_fatal(void *udata, const char *msg)
|
||||
{
|
||||
ILIBCRITICALEXITMSG(code, msg);
|
||||
ILIBCRITICALEXITMSG(254, msg);
|
||||
}
|
||||
duk_ret_t ILibDuktape_ScriptContainer_OS_arch(duk_context *ctx)
|
||||
{
|
||||
@@ -756,6 +1022,7 @@ duk_ret_t ILibDuktape_ScriptContainer_OS_networkInterfaces(duk_context *ctx)
|
||||
void ILibDuktape_ScriptContainer_OS_Push(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx); // [os]
|
||||
ILibDuktape_WriteID(ctx, "os");
|
||||
|
||||
#ifdef WIN32
|
||||
duk_push_string(ctx, "\r\n");
|
||||
@@ -773,10 +1040,13 @@ void ILibDuktape_ScriptContainer_OS_Init(duk_context *ctx)
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "os", ILibDuktape_ScriptContainer_OS_Push);
|
||||
}
|
||||
extern void ILibDuktape_HttpStream_Init(duk_context *ctx);
|
||||
duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx(SCRIPT_ENGINE_SECURITY_FLAGS securityFlags, unsigned int executionTimeout, void *chain, char **argList, ILibSimpleDataStore *db, char *exePath, ILibProcessPipe_Manager pipeManager, ILibDuktape_HelperEvent exitHandler, void *exitUser)
|
||||
duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngine_minimal()
|
||||
{
|
||||
duk_context *ctx = duk_create_heap(ILibDuktape_ScriptContainer_Engine_malloc, ILibDuktape_ScriptContainer_Engine_realloc, ILibDuktape_ScriptContainer_Engine_free, NULL, ILibDuktape_ScriptContainer_Engine_fatal);
|
||||
//duk_context *ctx = duk_create_heap_default();
|
||||
return(ctx);
|
||||
}
|
||||
duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx3(duk_context *ctx, SCRIPT_ENGINE_SECURITY_FLAGS securityFlags, unsigned int executionTimeout, void *chain, char **argList, ILibSimpleDataStore *db, char *exePath, ILibProcessPipe_Manager pipeManager, ILibDuktape_HelperEvent exitHandler, void *exitUser)
|
||||
{
|
||||
void **timeoutKey = executionTimeout > 0 ? (void**)ILibMemory_Allocate(sizeof(void*), 0, NULL, NULL) : NULL;
|
||||
|
||||
duk_push_heap_stash(ctx); // [s]
|
||||
@@ -897,7 +1167,7 @@ int ILibDuktape_ScriptContainer_CompileJavaScript_FromFile(duk_context *ctx, cha
|
||||
|
||||
if (path == NULL || pathLen == 0)
|
||||
{
|
||||
duk_push_error_object(ctx, DUK_ERR_API_ERROR, "Invalid Path specified");
|
||||
duk_push_error_object(ctx, DUK_ERR_ERROR, "Invalid Path specified");
|
||||
return(1);
|
||||
}
|
||||
else
|
||||
@@ -1153,16 +1423,15 @@ void ILibDuktape_ScriptContainer_Slave_ProcessCommands(ILibDuktape_ScriptContain
|
||||
break;
|
||||
case SCRIPT_ENGINE_COMMAND_SEND_JSON:
|
||||
{
|
||||
if (slave->OnData != NULL)
|
||||
if (ILibDuktape_EventEmitter_HasListeners(slave->emitter, "data")!=0)
|
||||
{
|
||||
char *json = Duktape_GetStringPropertyValue(slave->ctx, -1, "json", NULL);
|
||||
if (json != NULL)
|
||||
{
|
||||
duk_push_heapptr(slave->ctx, slave->OnData); // [func]
|
||||
duk_push_heapptr(slave->ctx, slave->emitter->object); // [func][this]
|
||||
duk_push_string(slave->ctx, json); // [func][this][json]
|
||||
duk_json_decode(slave->ctx, -1); // [func][this][object]
|
||||
if (duk_pcall_method(slave->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(slave->ctx, "ScriptContainer.OnData(): "); }
|
||||
ILibDuktape_EventEmitter_SetupEmit(slave->ctx, slave->emitter->object, "data"); // [emit][this][data]
|
||||
duk_push_string(slave->ctx, json); // [emit][this][data][json]
|
||||
duk_json_decode(slave->ctx, -1); // [emit][this][data][object]
|
||||
if (duk_pcall_method(slave->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(slave->ctx, "ScriptContainer.OnData(): "); }
|
||||
duk_pop(slave->ctx); // ...
|
||||
}
|
||||
}
|
||||
@@ -1313,6 +1582,15 @@ duk_ret_t ILibDuktape_ScriptContainer_Exit(duk_context *ctx)
|
||||
duk_push_this(ctx);
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_ScriptContainer_MasterPtr);
|
||||
master = (ILibDuktape_ScriptContainer_Master*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
if (master->PeerChain != NULL)
|
||||
{
|
||||
char json[] = "{\"command\": \"128\"}";
|
||||
ILibDuktape_ScriptContainer_NonIsolated_Command *cmd = ILibMemory_Allocate(sizeof(json) + sizeof(ILibDuktape_ScriptContainer_NonIsolated_Command), 0, NULL, NULL);
|
||||
cmd->container.slave = ((void**)ILibMemory_GetExtraMemory(master->PeerChain, ILibMemory_CHAIN_CONTAINERSIZE))[1];
|
||||
memcpy_s(cmd->json, sizeof(json), json, sizeof(json));
|
||||
ILibChain_RunOnMicrostackThread(master->PeerChain, ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsSlave, cmd);
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (ILibIsChainBeingDestroyed(Duktape_GetChain(ctx)) == 0)
|
||||
{
|
||||
@@ -1338,6 +1616,27 @@ duk_ret_t ILibDuktape_ScriptContainer_ExecuteString(duk_context *ctx)
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_ScriptContainer_MasterPtr); // [container][buffer]
|
||||
master = (ILibDuktape_ScriptContainer_Master*)Duktape_GetBuffer(ctx, -1, NULL); // [container][buffer]
|
||||
|
||||
|
||||
if (master->PeerChain != NULL)
|
||||
{
|
||||
char json[] = "{\"command\": \"2\", \"base64\": \"\"}";
|
||||
char *payload;
|
||||
duk_size_t payloadLen;
|
||||
payload = (char*)duk_get_lstring(ctx, 0, &payloadLen);
|
||||
int encodedPayloadLen = ILibBase64EncodeLength((int)payloadLen);
|
||||
ILibDuktape_ScriptContainer_NonIsolated_Command *cmd = (ILibDuktape_ScriptContainer_NonIsolated_Command*)ILibMemory_Allocate(sizeof(ILibDuktape_ScriptContainer_NonIsolated_Command) + encodedPayloadLen + sizeof(json), 0, NULL, NULL);
|
||||
|
||||
cmd->container.slave = (ILibDuktape_ScriptContainer_Slave*)((void**)ILibMemory_GetExtraMemory(master->PeerChain, ILibMemory_CHAIN_CONTAINERSIZE))[1];
|
||||
int i = sprintf_s(cmd->json, sizeof(json) + encodedPayloadLen, json);
|
||||
char *output = cmd->json + i -2;
|
||||
i += ILibBase64Encode((unsigned char*)payload, (int)payloadLen, (unsigned char**)&output);
|
||||
sprintf_s(cmd->json + i - 2, 3, "\"}");
|
||||
|
||||
ILibChain_RunOnMicrostackThread(master->PeerChain, ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsSlave, cmd);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
if (ptr != NULL) { seq = ILibDuktape_ScriptContainer_AddVoidPtr(ctx, duk_get_heapptr(ctx, -2), ptr); }
|
||||
|
||||
duk_push_object(ctx); // [container][buffer][obj]
|
||||
@@ -1364,18 +1663,13 @@ duk_ret_t ILibDuktape_ScriptContainer_ExecuteString(duk_context *ctx)
|
||||
void ILibDuktape_ScriptContainer_ExitSink(ILibProcessPipe_Process sender, int exitCode, void* user)
|
||||
{
|
||||
ILibDuktape_ScriptContainer_Master *master = (ILibDuktape_ScriptContainer_Master*)user;
|
||||
|
||||
if (master->OnExit != NULL)
|
||||
ILibDuktape_EventEmitter_SetupEmit(master->ctx, master->emitter->object, "exit"); // [emit][this][exit]
|
||||
duk_push_int(master->ctx, exitCode); // [emit][this][exit][code]
|
||||
if (duk_pcall_method(master->ctx, 2) != 0)
|
||||
{
|
||||
duk_push_heapptr(master->ctx, master->OnExit); // [func]
|
||||
duk_push_heapptr(master->ctx, master->emitter->object); // [func][this]
|
||||
duk_push_int(master->ctx, exitCode); // [func][this][code]
|
||||
if (duk_pcall_method(master->ctx, 1) != 0) // [retVal]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(master->ctx);
|
||||
}
|
||||
duk_pop(master->ctx); // ...
|
||||
ILibDuktape_Process_UncaughtException(master->ctx);
|
||||
}
|
||||
duk_pop(master->ctx);
|
||||
|
||||
master->child = NULL;
|
||||
}
|
||||
@@ -1402,16 +1696,15 @@ void ILibDuktape_ScriptContainer_StdErrSink_MicrostackThread(void *chain, void *
|
||||
{
|
||||
case SCRIPT_ENGINE_COMMAND_SEND_JSON:
|
||||
{
|
||||
if (master->OnJSON != NULL)
|
||||
{
|
||||
if(ILibDuktape_EventEmitter_HasListeners(master->emitter, "data")!=0)
|
||||
{
|
||||
char *json = Duktape_GetStringPropertyValue(master->ctx, -1, "json", NULL);
|
||||
if (json != NULL)
|
||||
{
|
||||
duk_push_heapptr(master->ctx, master->OnJSON);
|
||||
duk_push_heapptr(master->ctx, master->emitter->object);
|
||||
duk_push_string(master->ctx, json);
|
||||
duk_json_decode(master->ctx, -1);
|
||||
if (duk_pcall_method(master->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "ScriptContainer.OnData(): "); }
|
||||
ILibDuktape_EventEmitter_SetupEmit(master->ctx, master->emitter->object, "data"); // [emit][this][data]
|
||||
duk_push_string(master->ctx, json); // [emit][this][data][str]
|
||||
duk_json_decode(master->ctx, -1); // [emit][this][data][json]
|
||||
if (duk_pcall_method(master->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "ScriptContainer.OnData(): "); }
|
||||
duk_pop(master->ctx);
|
||||
}
|
||||
}
|
||||
@@ -1430,14 +1723,10 @@ void ILibDuktape_ScriptContainer_StdErrSink_MicrostackThread(void *chain, void *
|
||||
if ((i = Duktape_GetIntPropertyValue(master->ctx, -1, "sequence", -1)) < 0)
|
||||
{
|
||||
// No callback was specified
|
||||
if (master->OnError != NULL)
|
||||
{
|
||||
duk_push_heapptr(master->ctx, master->OnError); // [func]
|
||||
duk_push_heapptr(master->ctx, master->emitter->object); // [func][this]
|
||||
duk_get_prop_string(master->ctx, -3, "error"); // [func][this][error]
|
||||
if (duk_pcall_method(master->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "ScriptContainer_OnError_Dispatch(): "); }
|
||||
duk_pop(master->ctx); // ...
|
||||
}
|
||||
ILibDuktape_EventEmitter_SetupEmit(master->ctx, master->emitter->object, "error"); // [emit][this][error]
|
||||
duk_get_prop_string(master->ctx, -4, "error"); // [emit][this][error][errorObj]
|
||||
if (duk_pcall_method(master->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "ScriptContainer_OnError_Dispatch(): "); }
|
||||
duk_pop(master->ctx); // ...
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1515,6 +1804,17 @@ duk_ret_t ILibDuktape_ScriptContainer_Finalizer(duk_context *ctx)
|
||||
{
|
||||
ILibProcessPipe_Process_KillEx(master->child);
|
||||
}
|
||||
else if (master->PeerChain != NULL)
|
||||
{
|
||||
char json[] = "{\"command\": \"128\", \"noResponse\": \"1\"}";
|
||||
ILibDuktape_ScriptContainer_NonIsolated_Command *cmd = ILibMemory_Allocate(sizeof(json) + sizeof(ILibDuktape_ScriptContainer_NonIsolated_Command), 0, NULL, NULL);
|
||||
cmd->container.slave = ((void**)ILibMemory_GetExtraMemory(master->PeerChain, ILibMemory_CHAIN_CONTAINERSIZE))[1];
|
||||
memcpy_s(cmd->json, sizeof(json), json, sizeof(json));
|
||||
ILibChain_RunOnMicrostackThread(master->PeerChain, ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsSlave, cmd);
|
||||
#ifdef WIN32
|
||||
WaitForSingleObject(master->PeerThread, INFINITE);
|
||||
#endif
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -1535,10 +1835,23 @@ duk_ret_t ILibDuktape_ScriptContainer_SendToSlave(duk_context *ctx)
|
||||
duk_put_prop_string(ctx, -2, "json"); // [container][master][obj]
|
||||
|
||||
duk_json_encode(ctx, -1); // [container][master][json]
|
||||
len = sprintf_s(ILibScratchPad2 + 4, sizeof(ILibScratchPad2) - 4, "%s", duk_get_string(ctx, -1));
|
||||
((int*)ILibScratchPad2)[0] = len + 4;
|
||||
|
||||
ILibProcessPipe_Process_WriteStdIn(master->child, ILibScratchPad2, len + 4, ILibTransport_MemoryOwnership_USER);
|
||||
if (master->child != NULL)
|
||||
{
|
||||
len = sprintf_s(ILibScratchPad2 + 4, sizeof(ILibScratchPad2) - 4, "%s", duk_get_string(ctx, -1));
|
||||
((int*)ILibScratchPad2)[0] = len + 4;
|
||||
|
||||
ILibProcessPipe_Process_WriteStdIn(master->child, ILibScratchPad2, len + 4, ILibTransport_MemoryOwnership_USER);
|
||||
}
|
||||
else if(master->PeerChain != NULL)
|
||||
{
|
||||
duk_size_t payloadLen;
|
||||
char *payload = (char*)duk_get_lstring(ctx, -1, &payloadLen);
|
||||
ILibDuktape_ScriptContainer_NonIsolated_Command *cmd = ILibMemory_Allocate(sizeof(ILibDuktape_ScriptContainer_NonIsolated_Command) + (int)payloadLen + 1, 0, NULL, NULL);
|
||||
cmd->container.slave = (ILibDuktape_ScriptContainer_Slave*)((void**)ILibMemory_GetExtraMemory(master->PeerChain, ILibMemory_CHAIN_CONTAINERSIZE))[1];
|
||||
memcpy_s(cmd->json, payloadLen + 1, payload, payloadLen + 1);
|
||||
ILibChain_RunOnMicrostackThread(master->PeerChain, ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsSlave, cmd);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_ScriptContainer_Master_AddModule(duk_context *ctx)
|
||||
@@ -1565,6 +1878,181 @@ duk_ret_t ILibDuktape_ScriptContainer_Master_AddModule(duk_context *ctx)
|
||||
ILibProcessPipe_Process_WriteStdIn(master->child, ILibScratchPad2, len+4, ILibTransport_MemoryOwnership_USER);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
void ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsMaster(void *chain, void *user)
|
||||
{
|
||||
ILibDuktape_ScriptContainer_NonIsolated_Command *cmd = (ILibDuktape_ScriptContainer_NonIsolated_Command*)user;
|
||||
ILibDuktape_ScriptContainer_Master *master = cmd->container.master;
|
||||
ILibDuktape_ScriptContainer_Slave *slave = master->PeerChain == NULL ? NULL : (ILibDuktape_ScriptContainer_Slave*)((void**)ILibMemory_GetExtraMemory(master->PeerChain, ILibMemory_CHAIN_CONTAINERSIZE))[1];
|
||||
|
||||
int id;
|
||||
duk_push_string(master->ctx, cmd->json); // [string]
|
||||
duk_json_decode(master->ctx, -1); // [json]
|
||||
free(cmd);
|
||||
|
||||
switch ((id = Duktape_GetIntPropertyValue(master->ctx, -1, "command", -1)))
|
||||
{
|
||||
case 0: // Ready
|
||||
{
|
||||
// Call INIT first
|
||||
char json[] = "{\"command\": \"1\"}";
|
||||
ILibDuktape_ScriptContainer_NonIsolated_Command* initCmd = (ILibDuktape_ScriptContainer_NonIsolated_Command*)ILibMemory_Allocate(sizeof(json) + sizeof(ILibDuktape_ScriptContainer_NonIsolated_Command), 0, NULL, NULL);
|
||||
initCmd->container.slave = slave;
|
||||
memcpy_s(initCmd->json, sizeof(json), json, sizeof(json));
|
||||
ILibChain_RunOnMicrostackThread(master->PeerChain, ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsSlave, initCmd);
|
||||
|
||||
// Emit Ready Event
|
||||
duk_push_heapptr(master->ctx, master->emitter->object); // [json][container]
|
||||
duk_get_prop_string(master->ctx, -1, "emit"); // [json][container][emit]
|
||||
duk_swap_top(master->ctx, -2); // [json][emit][this]
|
||||
duk_push_string(master->ctx, "ready"); // [json][emit][this][ready]
|
||||
if (duk_pcall_method(master->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "Error Dispatching 'ready' event to Master Script Container"); }
|
||||
duk_pop(master->ctx); // [json]
|
||||
}
|
||||
break;
|
||||
case SCRIPT_ENGINE_COMMAND_ERROR:
|
||||
duk_push_heapptr(master->ctx, master->emitter->object); // [json][container]
|
||||
duk_get_prop_string(master->ctx, -1, "emit"); // [json][container][emit]
|
||||
duk_swap_top(master->ctx, -2); // [json][emit][this]
|
||||
duk_push_string(master->ctx, "error"); // [json][emit][this][error]
|
||||
duk_get_prop_string(master->ctx, -4, "message"); // [json][emit][this][error][msg]
|
||||
if (duk_pcall_method(master->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "Error Emitting ScriptContainer Error Message: "); }
|
||||
duk_pop(master->ctx); // [json]
|
||||
break;
|
||||
case SCRIPT_ENGINE_COMMAND_EXIT:
|
||||
duk_push_heapptr(master->ctx, master->emitter->object); // [json][container]
|
||||
duk_get_prop_string(master->ctx, -1, "emit"); // [json][container][emit]
|
||||
duk_swap_top(master->ctx, -2); // [json][emit][this]
|
||||
duk_push_string(master->ctx, "exit"); // [json][emit][this][exit]
|
||||
duk_get_prop_string(master->ctx, -4, "exitCode"); // [json][emit][this][exit][msg]
|
||||
if (duk_pcall_method(master->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "Error Emitting ScriptContainer Exit: "); }
|
||||
duk_pop(master->ctx); // [json]
|
||||
master->PeerChain = NULL;
|
||||
break;
|
||||
default:
|
||||
ILibDuktape_Process_UncaughtExceptionEx(master->ctx, "Unknown Command [%d] Received from Slave Container ", id);
|
||||
break;
|
||||
}
|
||||
|
||||
duk_pop(master->ctx); // ...
|
||||
|
||||
}
|
||||
|
||||
void ILibDuktape_ScriptContainer_NonIsolatedWorker_ExceptionSink(duk_context *ctx, char *msg, void *user)
|
||||
{
|
||||
duk_push_object(ctx); // [obj]
|
||||
duk_push_int(ctx, (int)SCRIPT_ENGINE_COMMAND_ERROR);
|
||||
duk_put_prop_string(ctx, -2, "command");
|
||||
duk_push_string(ctx, msg);
|
||||
duk_put_prop_string(ctx, -2, "message");
|
||||
duk_json_encode(ctx, -1); // [json]
|
||||
|
||||
duk_size_t payloadLen;
|
||||
char *payload = (char*)duk_get_lstring(ctx, -1, &payloadLen);
|
||||
|
||||
ILibDuktape_ScriptContainer_NonIsolated_Command *cmd = (ILibDuktape_ScriptContainer_NonIsolated_Command*)ILibMemory_Allocate((int)(sizeof(ILibDuktape_ScriptContainer_NonIsolated_Command) + payloadLen + 1), 0, NULL, NULL);
|
||||
cmd->container.master = ((void**)ILibMemory_GetExtraMemory(Duktape_GetChain(ctx), ILibMemory_CHAIN_CONTAINERSIZE))[0];
|
||||
memcpy_s(cmd->json, payloadLen + 1, payload, payloadLen + 1);
|
||||
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
ILibChain_RunOnMicrostackThread(cmd->container.master->chain, ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsMaster, cmd);
|
||||
}
|
||||
void ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsSlave(void *chain, void *user)
|
||||
{
|
||||
ILibDuktape_ScriptContainer_NonIsolated_Command *cmd = (ILibDuktape_ScriptContainer_NonIsolated_Command*)user;
|
||||
ILibDuktape_ScriptContainer_Slave *slave = cmd->container.slave;
|
||||
ILibDuktape_ScriptContainer_Master *master = (ILibDuktape_ScriptContainer_Master*)((void**)ILibMemory_GetExtraMemory(slave->chain, ILibMemory_CHAIN_CONTAINERSIZE))[0];
|
||||
|
||||
int id;
|
||||
duk_push_string(slave->ctx, cmd->json); // [string]
|
||||
duk_json_decode(slave->ctx, -1); // [json]
|
||||
free(cmd);
|
||||
|
||||
switch ((id = Duktape_GetIntPropertyValue(slave->ctx, -1, "command", -1)))
|
||||
{
|
||||
case SCRIPT_ENGINE_COMMAND_INIT:
|
||||
ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx3(slave->ctx, (SCRIPT_ENGINE_SECURITY_FLAGS)master->ChildSecurityFlags, 0, slave->chain, NULL, NULL, NULL, NULL, ILibDuktape_ScriptContainer_Slave_HeapDestroyed, slave);
|
||||
ILibDuktape_SetNativeUncaughtExceptionHandler(slave->ctx, ILibDuktape_ScriptContainer_NonIsolatedWorker_ExceptionSink, master);
|
||||
break;
|
||||
case SCRIPT_ENGINE_COMMAND_EXEC:
|
||||
{
|
||||
char *payload;
|
||||
duk_size_t payloadLen;
|
||||
|
||||
payload = (char*)Duktape_GetStringPropertyValueEx(slave->ctx, -1, "base64", NULL, &payloadLen);
|
||||
payloadLen = ILibBase64Decode((unsigned char*)payload, (int)payloadLen, (unsigned char**)&payload);
|
||||
|
||||
if (ILibDuktape_ScriptContainer_CompileJavaScript(slave->ctx, payload, (int)payloadLen) == 0 && ILibDuktape_ScriptContainer_ExecuteByteCode(slave->ctx) == 0)
|
||||
{
|
||||
// SUCCESS
|
||||
duk_pop(slave->ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
// ERROR
|
||||
ILibDuktape_Process_UncaughtExceptionEx(slave->ctx, "ScriptContainer Error: ");
|
||||
duk_pop(slave->ctx);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SCRIPT_ENGINE_COMMAND_SEND_JSON:
|
||||
{
|
||||
if (slave->emitter != NULL)
|
||||
{
|
||||
duk_get_prop_string(slave->ctx, -1, "json"); // [cmd][string]
|
||||
duk_json_decode(slave->ctx, -1); // [cmd][obj]
|
||||
duk_push_heapptr(slave->ctx, slave->emitter->object); // [cmd][obj][container]
|
||||
duk_get_prop_string(slave->ctx, -1, "emit"); // [cmd][obj][container][emit]
|
||||
duk_swap_top(slave->ctx, -2); // [cmd][obj][emit][this]
|
||||
duk_push_string(slave->ctx, "data"); // [cmd][obj][emit][this][data]
|
||||
duk_dup(slave->ctx, -4); // [cmd][obj][emit][this][data][obj]
|
||||
if (duk_pcall_method(slave->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(slave->ctx); }
|
||||
duk_pop_2(slave->ctx); // [cmd]
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SCRIPT_ENGINE_COMMAND_EXIT:
|
||||
slave->noRespond = Duktape_GetIntPropertyValue(slave->ctx, -1, "noResponse", 0);
|
||||
duk_pop(slave->ctx);
|
||||
duk_destroy_heap(slave->ctx);
|
||||
return;
|
||||
}
|
||||
duk_pop(slave->ctx); // ...
|
||||
}
|
||||
|
||||
void ILibDuktape_ScriptContainer_NonIsolatedWorker(void *arg)
|
||||
{
|
||||
ILibDuktape_ScriptContainer_Master *master = (ILibDuktape_ScriptContainer_Master*)arg;
|
||||
ILibDuktape_ScriptContainer_Slave *slave = ILibMemory_AllocateA(sizeof(ILibDuktape_ScriptContainer_Slave));
|
||||
char json[] = "{\"command\": \"0\"}";
|
||||
|
||||
slave->chain = ILibCreateChainEx(2 * sizeof(void*));
|
||||
((void**)ILibMemory_GetExtraMemory(slave->chain, ILibMemory_CHAIN_CONTAINERSIZE))[0] = master;
|
||||
((void**)ILibMemory_GetExtraMemory(slave->chain, ILibMemory_CHAIN_CONTAINERSIZE))[1] = slave;
|
||||
master->PeerChain = slave->chain;
|
||||
slave->ctx = ILibDuktape_ScriptContainer_InitializeJavaScriptEngine_minimal();
|
||||
|
||||
duk_push_heap_stash(slave->ctx);
|
||||
duk_push_pointer(slave->ctx, slave);
|
||||
duk_put_prop_string(slave->ctx, -2, ILibDuktape_ScriptContainer_SlavePtr);
|
||||
duk_pop(slave->ctx);
|
||||
|
||||
ILibDuktape_ScriptContainer_NonIsolated_Command* cmd = (ILibDuktape_ScriptContainer_NonIsolated_Command*)ILibMemory_Allocate(sizeof(json) + sizeof(ILibDuktape_ScriptContainer_NonIsolated_Command), 0, NULL, NULL);
|
||||
cmd->container.master = master;
|
||||
memcpy_s(cmd->json, sizeof(json), json, sizeof(json));
|
||||
ILibChain_RunOnMicrostackThread(master->chain, ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsMaster, cmd);
|
||||
ILibStartChain(slave->chain);
|
||||
|
||||
if (slave->noRespond == 0)
|
||||
{
|
||||
cmd = (ILibDuktape_ScriptContainer_NonIsolated_Command*)ILibMemory_Allocate(64 + sizeof(ILibDuktape_ScriptContainer_NonIsolated_Command), 0, NULL, NULL);
|
||||
cmd->container.master = master;
|
||||
sprintf_s(cmd->json, 64, "{\"command\": \"128\", \"exitCode\": \"%d\"}", slave->exitCode);
|
||||
ILibChain_RunOnMicrostackThread(master->chain, ILibDuktape_ScriptContainer_NonIsolatedWorker_ProcessAsMaster, cmd);
|
||||
}
|
||||
}
|
||||
duk_ret_t ILibDuktape_ScriptContainer_Create(duk_context *ctx)
|
||||
{
|
||||
char *exePath;
|
||||
@@ -1575,6 +2063,12 @@ duk_ret_t ILibDuktape_ScriptContainer_Create(duk_context *ctx)
|
||||
char *buffer;
|
||||
char header[4];
|
||||
ILibProcessPipe_SpawnTypes spawnType = (duk_get_top(ctx) > 2 && duk_is_number(ctx, 2)) ? (ILibProcessPipe_SpawnTypes)duk_require_int(ctx, 2) : ILibProcessPipe_SpawnTypes_DEFAULT;
|
||||
int processIsolation = 1;
|
||||
|
||||
if (duk_get_top(ctx) > 0 && duk_is_object(ctx, 0))
|
||||
{
|
||||
processIsolation = Duktape_GetIntPropertyValue(ctx, 0, "processIsolation", 1);
|
||||
}
|
||||
|
||||
duk_push_heap_stash(ctx);
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_ScriptContainer_ExePath);
|
||||
@@ -1584,6 +2078,7 @@ duk_ret_t ILibDuktape_ScriptContainer_Create(duk_context *ctx)
|
||||
manager = (ILibProcessPipe_Manager)duk_get_pointer(ctx, -1);
|
||||
|
||||
duk_push_object(ctx); // [container]
|
||||
ILibDuktape_WriteID(ctx, "ScriptContainer.master");
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_ScriptContainer_Master)); // [container][buffer]
|
||||
master = (ILibDuktape_ScriptContainer_Master*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_ScriptContainer_MasterPtr); // [container]
|
||||
@@ -1592,9 +2087,9 @@ duk_ret_t ILibDuktape_ScriptContainer_Create(duk_context *ctx)
|
||||
master->ctx = ctx;
|
||||
master->emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
master->chain = Duktape_GetChain(ctx);
|
||||
ILibDuktape_EventEmitter_CreateEvent(master->emitter, "exit", &(master->OnExit));
|
||||
ILibDuktape_EventEmitter_CreateEvent(master->emitter, "error", &(master->OnError));
|
||||
ILibDuktape_EventEmitter_CreateEvent(master->emitter, "data", &(master->OnJSON));
|
||||
ILibDuktape_EventEmitter_CreateEventEx(master->emitter, "exit");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(master->emitter, "error");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(master->emitter, "data");
|
||||
ILibDuktape_CreateProperty_InstanceMethod(ctx, "exit", ILibDuktape_ScriptContainer_Exit, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(master->ctx, "ExecuteScript", ILibDuktape_ScriptContainer_ExecuteScript, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(master->ctx, "ExecuteString", ILibDuktape_ScriptContainer_ExecuteString, DUK_VARARGS);
|
||||
@@ -1602,28 +2097,43 @@ duk_ret_t ILibDuktape_ScriptContainer_Create(duk_context *ctx)
|
||||
ILibDuktape_CreateInstanceMethod(master->ctx, "addModule", ILibDuktape_ScriptContainer_Master_AddModule, 2);
|
||||
ILibDuktape_CreateFinalizer(master->ctx, ILibDuktape_ScriptContainer_Finalizer);
|
||||
|
||||
unsigned int executionTimeout = (unsigned int)duk_require_int(ctx, 0);
|
||||
unsigned int securityFlags = (unsigned int)duk_require_int(ctx, 1) | SCRIPT_ENGINE_NO_MESH_AGENT_ACCESS;
|
||||
if (processIsolation)
|
||||
{
|
||||
// We're going to spawn a child process to run this ScriptContainer
|
||||
unsigned int executionTimeout = (unsigned int)duk_require_int(ctx, 0);
|
||||
master->ChildSecurityFlags = (unsigned int)duk_require_int(ctx, 1) | SCRIPT_ENGINE_NO_MESH_AGENT_ACCESS;
|
||||
|
||||
master->child = ILibProcessPipe_Manager_SpawnProcessEx2(manager, exePath, (char * const*)param, spawnType, 2 * sizeof(void*));
|
||||
if (master->child == NULL) { return(ILibDuktape_Error(ctx, "ScriptContainer.Create(): Error spawning child process, using [%s]", exePath)); }
|
||||
master->child = ILibProcessPipe_Manager_SpawnProcessEx2(manager, exePath, (char * const*)param, spawnType, 2 * sizeof(void*));
|
||||
if (master->child == NULL) { return(ILibDuktape_Error(ctx, "ScriptContainer.Create(): Error spawning child process, using [%s]", exePath)); }
|
||||
|
||||
duk_push_true(ctx);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_ScriptContainer_ProcessIsolated);
|
||||
duk_push_object(ctx); // [container][obj]
|
||||
duk_push_int(ctx, (int)SCRIPT_ENGINE_COMMAND_INIT);
|
||||
duk_put_prop_string(ctx, -2, "command");
|
||||
duk_push_int(ctx, (int)executionTimeout);
|
||||
duk_put_prop_string(ctx, -2, "executionTimeout");
|
||||
duk_push_int(ctx, (int)master->ChildSecurityFlags);
|
||||
duk_put_prop_string(ctx, -2, "securityFlags");
|
||||
duk_json_encode(ctx, -1);
|
||||
buffer = (char*)Duktape_GetBuffer(ctx, -1, &bufferLen);
|
||||
|
||||
duk_push_object(ctx); // [container][obj]
|
||||
duk_push_int(ctx, (int)SCRIPT_ENGINE_COMMAND_INIT);
|
||||
duk_put_prop_string(ctx, -2, "command");
|
||||
duk_push_int(ctx, (int)executionTimeout);
|
||||
duk_put_prop_string(ctx, -2, "executionTimeout");
|
||||
duk_push_int(ctx, (int)securityFlags);
|
||||
duk_put_prop_string(ctx, -2, "securityFlags");
|
||||
duk_json_encode(ctx, -1);
|
||||
buffer = (char*)Duktape_GetBuffer(ctx, -1, &bufferLen);
|
||||
duk_swap_top(ctx, -2); // [json][container]
|
||||
|
||||
duk_swap_top(ctx, -2); // [json][container]
|
||||
|
||||
((int*)header)[0] = (int)bufferLen + 4;
|
||||
ILibProcessPipe_Process_AddHandlers(master->child, SCRIPT_ENGINE_PIPE_BUFFER_SIZE, ILibDuktape_ScriptContainer_ExitSink, ILibDuktape_ScriptContainer_StdOutSink, ILibDuktape_ScriptContainer_StdErrSink, ILibDuktape_ScriptContainer_SendOkSink, master);
|
||||
ILibProcessPipe_Process_WriteStdIn(master->child, header, sizeof(header), ILibTransport_MemoryOwnership_USER);
|
||||
ILibProcessPipe_Process_WriteStdIn(master->child, buffer, (int)bufferLen, ILibTransport_MemoryOwnership_USER);
|
||||
((int*)header)[0] = (int)bufferLen + 4;
|
||||
ILibProcessPipe_Process_AddHandlers(master->child, SCRIPT_ENGINE_PIPE_BUFFER_SIZE, ILibDuktape_ScriptContainer_ExitSink, ILibDuktape_ScriptContainer_StdOutSink, ILibDuktape_ScriptContainer_StdErrSink, ILibDuktape_ScriptContainer_SendOkSink, master);
|
||||
ILibProcessPipe_Process_WriteStdIn(master->child, header, sizeof(header), ILibTransport_MemoryOwnership_USER);
|
||||
ILibProcessPipe_Process_WriteStdIn(master->child, buffer, (int)bufferLen, ILibTransport_MemoryOwnership_USER);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We're going to spawn a thread to host this Script Container
|
||||
duk_push_false(ctx);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_ScriptContainer_ProcessIsolated);
|
||||
ILibDuktape_EventEmitter_CreateEventEx(master->emitter, "ready");
|
||||
master->PeerThread = ILibSpawnNormalThread(ILibDuktape_ScriptContainer_NonIsolatedWorker, master);
|
||||
master->ChildSecurityFlags = Duktape_GetIntPropertyValue(ctx, 0, "permissions", 0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
void ILibDuktape_ScriptContainer_PUSH_MASTER(duk_context *ctx, void *chain)
|
||||
@@ -1653,8 +2163,9 @@ void ILibDuktape_ScriptContainer_PUSH_SLAVE(duk_context *ctx, void *chain)
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
duk_push_object(ctx);
|
||||
ILibDuktape_WriteID(ctx, "ScriptContainer.slave");
|
||||
slave->emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
ILibDuktape_EventEmitter_CreateEvent(slave->emitter, "data", &(slave->OnData));
|
||||
ILibDuktape_EventEmitter_CreateEventEx(slave->emitter, "data");
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "send", ILibDuktape_ScriptContainer_Slave_SendToMaster, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -144,9 +144,10 @@ void ILibDuktape_ScriptContainer_CheckEmbedded(char **argv, char **script, int *
|
||||
void ILibDuktape_ScriptContainer_InitMaster(void *chain, char *exePath, ILibProcessPipe_Manager manager);
|
||||
int ILibDuktape_ScriptContainer_StartSlave(void *chain, ILibProcessPipe_Manager manager);
|
||||
|
||||
|
||||
duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngine_minimal();
|
||||
duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx3(duk_context *ctx, SCRIPT_ENGINE_SECURITY_FLAGS securityFlags, unsigned int executionTimeout, void *chain, char **argList, ILibSimpleDataStore *db, char *exePath, ILibProcessPipe_Manager pipeManager, ILibDuktape_HelperEvent exitHandler, void *exitUser);
|
||||
duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx2(SCRIPT_ENGINE_SETTINGS *settings);
|
||||
duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx(SCRIPT_ENGINE_SECURITY_FLAGS securityFlags, unsigned int executionTimeout, void *chain, char **argList, ILibSimpleDataStore *db, char *exePath, ILibProcessPipe_Manager pipeManager, ILibDuktape_HelperEvent exitHandler, void *exitUser);
|
||||
#define ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx(securityFlags, executionTimeout, chain, argList, db, exePath, pipeManager, exitHandler, exitUser) ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx3(ILibDuktape_ScriptContainer_InitializeJavaScriptEngine_minimal(), (securityFlags), (executionTimeout), (chain), (argList), (db), (exePath), (pipeManager), (exitHandler), (exitUser))
|
||||
#define ILibDuktape_ScriptContainer_InitializeJavaScriptEngine(securityFlags, executionTimeout, chain, pp_argList, db, exitHandler, exitUser) ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx((securityFlags), (executionTimeout), (chain), (pp_argList), (db), NULL, NULL, (exitHandler), (exitUser))
|
||||
|
||||
SCRIPT_ENGINE_SETTINGS *ILibDuktape_ScriptContainer_GetSettings(duk_context *ctx);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -179,6 +179,17 @@ duk_ret_t ILibDuktape_SimpleDataStore_Keys(duk_context *ctx)
|
||||
ILibSimpleDataStore_EnumerateKeys(ds, ILibDuktape_SimpleDataStore_Keys_EnumerationSink, &enumerator);
|
||||
return 1;
|
||||
}
|
||||
duk_ret_t ILibDuktape_SimpleDataStore_Delete(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx); // [DataStore]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_DataStore_PTR); // [DataStore][ptr]
|
||||
ILibSimpleDataStore ds = (ILibSimpleDataStore)duk_get_pointer(ctx, -1);
|
||||
duk_size_t keyLen;
|
||||
char *key = (char*)duk_get_lstring(ctx, 0, &keyLen);
|
||||
|
||||
ILibSimpleDataStore_DeleteEx(ds, key, (int)keyLen);
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_SimpleDataStore_Create(duk_context *ctx)
|
||||
{
|
||||
ILibSimpleDataStore dataStore;
|
||||
@@ -214,6 +225,7 @@ duk_ret_t ILibDuktape_SimpleDataStore_Create(duk_context *ctx)
|
||||
duk_push_pointer(ctx, dataStore); // [DataStore][RetVal][ds]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_DataStore_PTR);// [DataStore][RetVal]
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "Delete", ILibDuktape_SimpleDataStore_Delete, 1);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "Put", ILibDuktape_SimpleDataStore_Put, 2);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "Get", ILibDuktape_SimpleDataStore_Get, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "Compact", ILibDuktape_SimpleDataStore_Compact, 0);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -44,11 +44,7 @@ typedef struct ILibWebRTC_Duktape_Handlers
|
||||
void *ConnectionObject;
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
|
||||
void *OnConnect;
|
||||
void *OnDataChannel;
|
||||
void *OnConnectionSendOK;
|
||||
void *OnCandidate;
|
||||
void *OnDisconnect;
|
||||
}ILibWebRTC_Duktape_Handlers;
|
||||
typedef struct ILibDuktape_WebRTC_DataChannel
|
||||
{
|
||||
@@ -56,7 +52,6 @@ typedef struct ILibDuktape_WebRTC_DataChannel
|
||||
duk_context *ctx;
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
ILibDuktape_DuplexStream *stream;
|
||||
void *OnAck;
|
||||
}ILibDuktape_WebRTC_DataChannel;
|
||||
|
||||
extern void* ILibWrapper_WebRTC_Connection_GetStunModule(ILibWrapper_WebRTC_Connection connection);
|
||||
@@ -170,7 +165,8 @@ void ILibDuktape_WebRTC_DataChannel_OnClose(struct ILibWrapper_WebRTC_DataChanne
|
||||
void ILibDuktape_WebRTC_DataChannel_OnData(struct ILibWrapper_WebRTC_DataChannel* dataChannel, char* data, int dataLen, int dataType)
|
||||
{
|
||||
ILibDuktape_WebRTC_DataChannel *ptrs = (ILibDuktape_WebRTC_DataChannel*)dataChannel->userData;
|
||||
if (ptrs != NULL) { ILibDuktape_DuplexStream_WriteData(ptrs->stream, data, dataLen); }
|
||||
|
||||
if (ptrs != NULL) { ILibDuktape_DuplexStream_WriteDataEx(ptrs->stream, dataType == 51 ? 1 : 0, data, dataLen); }
|
||||
}
|
||||
duk_ret_t ILibDuktape_WebRTC_DataChannel_Finalizer(duk_context *ctx)
|
||||
{
|
||||
@@ -178,12 +174,14 @@ duk_ret_t ILibDuktape_WebRTC_DataChannel_Finalizer(duk_context *ctx)
|
||||
ILibDuktape_WebRTC_DataChannel *ptrs = (ILibDuktape_WebRTC_DataChannel*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
if (ptrs->dataChannel != NULL)
|
||||
{
|
||||
printf("WebRTC Data Channel Finalizer on Connection: %p\n", ptrs->dataChannel->parent);
|
||||
ptrs->dataChannel->userData = NULL;
|
||||
ILibWrapper_WebRTC_DataChannel_Close(ptrs->dataChannel);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ILibDuktape_WebRTC_DataChannel_PUSH(duk_context *ctx, ILibWrapper_WebRTC_DataChannel *dataChannel)
|
||||
{
|
||||
if (dataChannel == NULL) { duk_push_null(ctx); return; }
|
||||
@@ -195,6 +193,7 @@ void ILibDuktape_WebRTC_DataChannel_PUSH(duk_context *ctx, ILibWrapper_WebRTC_Da
|
||||
dataChannel->OnRawData = ILibDuktape_WebRTC_DataChannel_OnData;
|
||||
|
||||
duk_push_object(ctx); // [dataChannel]
|
||||
ILibDuktape_WriteID(ctx, "webRTC.dataChannel");
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_WebRTC_DataChannel)); // [dataChannel][buffer]
|
||||
ptrs = (ILibDuktape_WebRTC_DataChannel*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
dataChannel->userData = ptrs;
|
||||
@@ -209,7 +208,8 @@ void ILibDuktape_WebRTC_DataChannel_PUSH(duk_context *ctx, ILibWrapper_WebRTC_Da
|
||||
duk_push_int(ctx, dataChannel->streamId);
|
||||
duk_put_prop_string(ctx, -2, "id");
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "ack", &(ptrs->OnAck));
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "ack");
|
||||
|
||||
ptrs->stream = ILibDuktape_DuplexStream_Init(ctx, ILibDuktape_WebRTC_DataChannel_Stream_WriteSink, ILibDuktape_WebRTC_DataChannel_Stream_EndSink,
|
||||
ILibDuktape_WebRTC_DataChannel_Stream_PauseSink, ILibDuktape_WebRTC_DataChannel_Stream_ResumeSink, ptrs);
|
||||
}
|
||||
@@ -221,6 +221,8 @@ duk_ret_t ILibDuktape_WebRTC_ConnectionFactory_Finalizer(duk_context *ctx)
|
||||
duk_get_prop_string(ctx, 0, ILibDuktape_WebRTC_ConnectionFactoryPtr);
|
||||
factory = (ILibWrapper_WebRTC_ConnectionFactory)duk_get_pointer(ctx, -1);
|
||||
|
||||
printf("WebRTC Factory Finalizer: %p\n", factory);
|
||||
|
||||
if (factory != NULL && ILibIsChainBeingDestroyed(chain) == 0)
|
||||
{
|
||||
ILibWrapper_WebRTC_ConnectionFactory_RemoveFromChain(factory);
|
||||
@@ -228,48 +230,140 @@ duk_ret_t ILibDuktape_WebRTC_ConnectionFactory_Finalizer(duk_context *ctx)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#ifdef _WEBRTCDEBUG
|
||||
void ILibDuktape_WebRTC_Connection_Debug(void* dtlsSession, char* debugField, int data)
|
||||
{
|
||||
ILibHashtable *t = ILibChain_GetBaseHashtable(((ILibTransport*)dtlsSession)->ChainLink.ParentChain);
|
||||
ILibWebRTC_Duktape_Handlers *ptrs = (ILibWebRTC_Duktape_Handlers*)ILibHashtable_Get(t, dtlsSession, NULL, 0);
|
||||
if (ptrs != NULL)
|
||||
{
|
||||
if (strcmp(debugField, "OnHold") == 0)
|
||||
{
|
||||
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "_hold"); // [emit][this][name]
|
||||
}
|
||||
else if (strcmp(debugField, "OnCongestionWindowSizeChanged") == 0)
|
||||
{
|
||||
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "_congestionWindowSizeChange"); // [emit][this][name]
|
||||
}
|
||||
else if (strcmp(debugField, "OnRTTCalculated") == 0)
|
||||
{
|
||||
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "_rttCalculated"); // [emit][this][name]
|
||||
}
|
||||
else if (strcmp(debugField, "OnFastRecovery") == 0)
|
||||
{
|
||||
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "_fastRecovery"); // [emit][this][name]
|
||||
}
|
||||
else if (strcmp(debugField, "OnLastSackTime") == 0)
|
||||
{
|
||||
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "_lastSackTime"); // [emit][this][name]
|
||||
}
|
||||
else if (strcmp(debugField, "OnLastSentTime") == 0)
|
||||
{
|
||||
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "_lastSentTime"); // [emit][this][name]
|
||||
}
|
||||
else if (strcmp(debugField, "OnReceiverCredits") == 0)
|
||||
{
|
||||
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "_receiverCredits"); // [emit][this][name]
|
||||
}
|
||||
else if (strcmp(debugField, "OnT3RTX") == 0)
|
||||
{
|
||||
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "_t3tx"); // [emit][this][name]
|
||||
}
|
||||
else if (strcmp(debugField, "OnSendRetry") == 0)
|
||||
{
|
||||
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "_retransmit"); // [emit][this][name]
|
||||
}
|
||||
else if (strcmp(debugField, "OnSACKReceived") == 0)
|
||||
{
|
||||
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "_sackReceived"); // [emit][this][name]
|
||||
}
|
||||
else if (strcmp(debugField, "OnRetryPacket") == 0)
|
||||
{
|
||||
duk_push_external_buffer(ptrs->ctx); // [extBuffer]
|
||||
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "_retransmitPacket"); // [extBuffer][emit][this][name]
|
||||
duk_config_buffer(ptrs->ctx, -4, debugField + 14, data);
|
||||
duk_push_buffer_object(ptrs->ctx, -4, 0, data, DUK_BUFOBJ_NODEJS_BUFFER);
|
||||
if (duk_pcall_method(ptrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(ptrs->ctx); }
|
||||
duk_pop_2(ptrs->ctx); // ...
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
duk_push_int(ptrs->ctx, data); // [emit][this][name][val]
|
||||
if (duk_pcall_method(ptrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(ptrs->ctx); }
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
}
|
||||
}
|
||||
#endif
|
||||
void ILibDuktape_WebRTC_OnConnection(ILibWrapper_WebRTC_Connection connection, int connected)
|
||||
{
|
||||
ILibWebRTC_Duktape_Handlers *ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_GetExtraMemory(connection, ILibMemory_WebRTC_Connection_CONTAINERSIZE);
|
||||
if (ptrs->OnConnect != NULL && connected != 0)
|
||||
if (connected == 0)
|
||||
{
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->OnConnect); // [func]
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->ConnectionObject); // [func][this]
|
||||
if (duk_pcall_method(ptrs->ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.connection.onConnect(): "); }
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "disconnected"); // [emit][this][disconnected]
|
||||
duk_del_prop_string(ptrs->ctx, -2, ILibDuktape_WebRTC_ConnectionPtr);
|
||||
}
|
||||
else if (ptrs->OnDisconnect != NULL && connected == 0)
|
||||
else
|
||||
{
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->OnDisconnect); // [func]
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->ConnectionObject); // [func][this]
|
||||
if (duk_pcall_method(ptrs->ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.connection.onConnect(): "); }
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "connected"); // [emit][this][connected]
|
||||
}
|
||||
if (duk_pcall_method(ptrs->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(ptrs->ctx); }
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
#ifdef _WEBRTCDEBUG
|
||||
ILibHashtable *t = ILibChain_GetBaseHashtable(Duktape_GetChain(ptrs->ctx));
|
||||
|
||||
if (connected != 0)
|
||||
{
|
||||
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnHold", ILibDuktape_WebRTC_Connection_Debug);
|
||||
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnCongestionWindowSizeChanged", ILibDuktape_WebRTC_Connection_Debug);
|
||||
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnRTTCalculated", ILibDuktape_WebRTC_Connection_Debug);
|
||||
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnFastRecovery", ILibDuktape_WebRTC_Connection_Debug);
|
||||
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnReceiverCredits", ILibDuktape_WebRTC_Connection_Debug);
|
||||
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnT3RTX", ILibDuktape_WebRTC_Connection_Debug);
|
||||
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnSendRetry", ILibDuktape_WebRTC_Connection_Debug);
|
||||
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnSendFastRetry", ILibDuktape_WebRTC_Connection_Debug);
|
||||
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnRetryPacket", ILibDuktape_WebRTC_Connection_Debug);
|
||||
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnSACKReceived", ILibDuktape_WebRTC_Connection_Debug);
|
||||
ILibHashtable_Put(t, ILibWrapper_WebRTC_Connection2DtlsSession(connection), NULL, 0, ptrs);
|
||||
}
|
||||
else
|
||||
{
|
||||
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnHold", NULL);
|
||||
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnCongestionWindowSizeChanged", NULL);
|
||||
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnRTTCalculated", NULL);
|
||||
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnFastRecovery", NULL);
|
||||
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnReceiverCredits", NULL);
|
||||
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnT3RTX", NULL);
|
||||
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnSendRetry", NULL);
|
||||
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnSendFastRetry", NULL);
|
||||
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnRetryPacket", NULL);
|
||||
ILibSCTP_Debug_SetDebugCallback(ILibWrapper_WebRTC_Connection2DtlsSession(connection), "OnSACKReceived", NULL);
|
||||
ILibHashtable_Remove(t, ILibWrapper_WebRTC_Connection2DtlsSession(connection), NULL, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void ILibDuktape_WebRTC_OnDataChannel(ILibWrapper_WebRTC_Connection connection, ILibWrapper_WebRTC_DataChannel *dataChannel)
|
||||
{
|
||||
ILibWebRTC_Duktape_Handlers *ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_GetExtraMemory(connection, ILibMemory_WebRTC_Connection_CONTAINERSIZE);
|
||||
|
||||
if (ptrs->OnDataChannel != NULL)
|
||||
{
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->OnDataChannel); // [func]
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->ConnectionObject); // [func][this]
|
||||
ILibDuktape_WebRTC_DataChannel_PUSH(ptrs->ctx, dataChannel);// [func][this][dataChannel]
|
||||
if (duk_pcall_method(ptrs->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.connection.onDataChannel(): "); }
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
}
|
||||
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "dataChannel"); // [emit][this][dataChannel]
|
||||
ILibDuktape_WebRTC_DataChannel_PUSH(ptrs->ctx, dataChannel); // [emit][this][dataChannel][dc]
|
||||
if (duk_pcall_method(ptrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.connection.onDataChannel(): "); }
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
}
|
||||
|
||||
void ILibDuktape_WebRTC_offer_onCandidate(ILibWrapper_WebRTC_Connection connection, struct sockaddr_in6* candidate)
|
||||
{
|
||||
ILibWebRTC_Duktape_Handlers *ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_GetExtraMemory(connection, ILibMemory_WebRTC_Connection_CONTAINERSIZE);
|
||||
if (ptrs->OnCandidate != NULL)
|
||||
if (candidate != NULL)
|
||||
{
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->OnCandidate); // [func]
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->ConnectionObject); // [func][this]
|
||||
ILibDuktape_SockAddrToOptions(ptrs->ctx, candidate); // [func][this][options]
|
||||
if (duk_pcall_method(ptrs->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.connection.onCandidate(): "); }
|
||||
ILibWebRTC_Duktape_Handlers *ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_GetExtraMemory(connection, ILibMemory_WebRTC_Connection_CONTAINERSIZE);
|
||||
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "candidate"); // [emit][this][candidate]
|
||||
ILibDuktape_SockAddrToOptions(ptrs->ctx, candidate); // [emit][this][candidate][options]
|
||||
if (duk_pcall_method(ptrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.connection.onCandidate(): "); }
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
}
|
||||
}
|
||||
@@ -307,20 +401,16 @@ duk_ret_t ILibDuktape_WebRTC_setOffer(duk_context *ctx)
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_null(ctx);
|
||||
return(ILibDuktape_Error(ctx, "WebRTC: Error setting offer. Most likely too many outstanding offers"));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
void ILibDuktape_WebRTC_DataChannel_OnAck(struct ILibWrapper_WebRTC_DataChannel* dataChannel)
|
||||
{
|
||||
ILibDuktape_WebRTC_DataChannel *ptrs = (ILibDuktape_WebRTC_DataChannel*)dataChannel->userData;
|
||||
if (ptrs->OnAck != NULL)
|
||||
{
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->OnAck); // [func]
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->emitter->object); // [func][this]
|
||||
if (duk_pcall_method(ptrs->ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.dataChannel.onAck(): "); };
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
}
|
||||
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->emitter->object, "ack"); // [emit][this][ack]
|
||||
if (duk_pcall_method(ptrs->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.dataChannel.onAck(): "); };
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
}
|
||||
duk_ret_t ILibDuktape_WebRTC_createDataChannel(duk_context *ctx)
|
||||
{
|
||||
@@ -378,8 +468,13 @@ duk_ret_t ILibDuktape_WebRTC_Connection_Finalizer(duk_context *ctx)
|
||||
ILibWrapper_WebRTC_Connection connection;
|
||||
duk_get_prop_string(ctx, 0, ILibDuktape_WebRTC_ConnectionPtr);
|
||||
connection = (ILibWrapper_WebRTC_Connection)duk_get_pointer(ctx, -1);
|
||||
printf("WebRTCConnection Finalizer on %p\n", (void*)connection);
|
||||
if (connection == NULL) { return 0; }
|
||||
|
||||
#ifdef _WEBRTCDEBUG
|
||||
ILibHashtable_Remove(ILibChain_GetBaseHashtable(Duktape_GetChain(ctx)), ILibWrapper_WebRTC_Connection2DtlsSession(connection), NULL, 0);
|
||||
#endif
|
||||
|
||||
if (ILibWrapper_WebRTC_Connection_IsConnected(connection) != 0)
|
||||
{
|
||||
ILibWrapper_WebRTC_Connection_CloseAllDataChannels(connection);
|
||||
@@ -398,17 +493,31 @@ duk_ret_t ILibDuktape_WebRTC_CreateConnection(duk_context *ctx)
|
||||
factory = (ILibWrapper_WebRTC_ConnectionFactory)duk_get_pointer(ctx, -1);
|
||||
|
||||
duk_push_object(ctx); // [factory][connection]
|
||||
ILibDuktape_WriteID(ctx, "webRTC.peerConnection");
|
||||
connection = ILibWrapper_WebRTC_ConnectionFactory_CreateConnection2(factory, ILibDuktape_WebRTC_OnConnection, ILibDuktape_WebRTC_OnDataChannel, NULL, sizeof(ILibWebRTC_Duktape_Handlers));
|
||||
ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_GetExtraMemory(connection, ILibMemory_WebRTC_Connection_CONTAINERSIZE);
|
||||
ptrs->ctx = ctx;
|
||||
ptrs->ConnectionObject = duk_get_heapptr(ctx, -1);
|
||||
ptrs->emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "candidate", &(ptrs->OnCandidate));
|
||||
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "dataChannel", &(ptrs->OnDataChannel));
|
||||
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "connected", &(ptrs->OnConnect));
|
||||
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "disconnected", &(ptrs->OnDisconnect));
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "candidate");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "dataChannel");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "connected");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "disconnected");
|
||||
|
||||
#ifdef _WEBRTCDEBUG
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "_hold");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "_lastSackTime");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "_lastSentTime");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "_congestionWindowSizeChange");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "_fastRecovery");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "_rttCalculated");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "_receiverCredits");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "_t3tx");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "_retransmit");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "_retransmitPacket");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "_sackReceived");
|
||||
#endif
|
||||
duk_push_pointer(ctx, connection); // [factory][connection][ptr]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_WebRTC_ConnectionPtr); // [factory][connection]
|
||||
|
||||
@@ -429,6 +538,7 @@ void ILibDuktape_WebRTC_Push(duk_context *ctx, void *chain)
|
||||
ILibWrapper_WebRTC_ConnectionFactory factory;
|
||||
|
||||
duk_push_object(ctx); // [factory]
|
||||
ILibDuktape_WriteID(ctx, "webRTC");
|
||||
factory = ILibWrapper_WebRTC_ConnectionFactory_CreateConnectionFactory(chain, 0);
|
||||
duk_push_pointer(ctx, factory); // [factory][ptr]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_WebRTC_ConnectionFactoryPtr); // [factory]
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ___ILibDuktape_WebRTC___
|
||||
#define ___ILibDuktape_WebRTC___
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ limitations under the License.
|
||||
#include "ILibDuktape_Helpers.h"
|
||||
#include "ILibDuktape_WritableStream.h"
|
||||
#include "ILibDuktape_EventEmitter.h"
|
||||
#include "ILibDuktape_Polyfills.h"
|
||||
|
||||
#ifdef __DOXY__
|
||||
/*!
|
||||
@@ -118,11 +119,13 @@ void ILibDuktape_WritableStream_Ready(ILibDuktape_WritableStream *stream)
|
||||
}
|
||||
duk_pop(stream->ctx); // ...
|
||||
}
|
||||
else if (stream->OnDrain != NULL)
|
||||
else
|
||||
{
|
||||
duk_push_heapptr(stream->ctx, stream->OnDrain); // [func]
|
||||
duk_push_heapptr(stream->ctx, stream->obj); // [func][this]
|
||||
if (duk_pcall_method(stream->ctx, 0) != 0) // [retVal]
|
||||
duk_push_heapptr(stream->ctx, stream->obj); // [this]
|
||||
duk_get_prop_string(stream->ctx, -1, "emit"); // [this][emit]
|
||||
duk_swap_top(stream->ctx, -2); // [emit][this]
|
||||
duk_push_string(stream->ctx, "drain"); // [emit][this][drain]
|
||||
if (duk_pcall_method(stream->ctx, 1) != 0) // [retVal]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(stream->ctx);
|
||||
}
|
||||
@@ -132,20 +135,17 @@ void ILibDuktape_WritableStream_Ready(ILibDuktape_WritableStream *stream)
|
||||
else
|
||||
{
|
||||
// End of Stream
|
||||
if (stream->OnFinish != NULL)
|
||||
{
|
||||
duk_push_heapptr(stream->ctx, stream->OnFinish); // [func]
|
||||
duk_push_heapptr(stream->ctx, stream->obj); // [func][this]
|
||||
if (duk_pcall_method(stream->ctx, 0) != 0) // [retVal]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(stream->ctx);
|
||||
}
|
||||
duk_pop(stream->ctx); // ...
|
||||
}
|
||||
if (stream->EndSink != NULL)
|
||||
{
|
||||
stream->EndSink(stream, stream->WriteSink_User);
|
||||
}
|
||||
|
||||
duk_push_heapptr(stream->ctx, stream->obj); // [stream]
|
||||
duk_get_prop_string(stream->ctx, -1, "emit"); // [stream][emit]
|
||||
duk_swap_top(stream->ctx, -2); // [emit][this]
|
||||
duk_push_string(stream->ctx, "finish"); // [emit][this][finish]
|
||||
if (duk_pcall_method(stream->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(stream->ctx); }
|
||||
duk_pop(stream->ctx); // ...
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,6 +167,7 @@ duk_ret_t ILibDuktape_WritableStream_Write(duk_context *ctx)
|
||||
|
||||
if (stream->WriteSink != NULL)
|
||||
{
|
||||
stream->endBytes = -1;
|
||||
switch (stream->WriteSink(stream, buffer, (int)bufferLen, stream->WriteSink_User))
|
||||
{
|
||||
case ILibTransport_DoneState_COMPLETE:
|
||||
@@ -192,19 +193,18 @@ duk_ret_t ILibDuktape_WritableStream_Write(duk_context *ctx)
|
||||
duk_push_false(ctx);
|
||||
break;
|
||||
default:
|
||||
if (stream->OnError != NULL)
|
||||
duk_push_heapptr(ctx, stream->obj); // [this]
|
||||
duk_get_prop_string(ctx, -1, "emit"); // [this][emit]
|
||||
duk_swap_top(ctx, -2); // [emit][this]
|
||||
duk_push_string(ctx, "error"); // [emit][this][error]
|
||||
duk_push_object(ctx); // [emit][this][error][errorObj]
|
||||
duk_push_string(ctx, "ILibDuktape_WritableStream_Write");
|
||||
duk_put_prop_string(ctx, -2, "stack");
|
||||
duk_push_string(ctx, "ILibDuktape_WriteableStream_Write/Handler returned Error");
|
||||
duk_put_prop_string(ctx, -2, "message");
|
||||
if (duk_pcall_method(ctx, 2) != 0) // [retVal]
|
||||
{
|
||||
duk_push_heapptr(ctx, stream->OnError); // [func]
|
||||
duk_push_heapptr(ctx, stream->obj); // [func][this]
|
||||
duk_push_object(ctx); // [func][this][error]
|
||||
duk_push_string(ctx, "ILibDuktape_WritableStream_Write");
|
||||
duk_put_prop_string(ctx, -2, "stack");
|
||||
duk_push_string(ctx, "ILibDuktape_WriteableStream_Write/Handler returned Error");
|
||||
duk_put_prop_string(ctx, -2, "message");
|
||||
if (duk_pcall_method(ctx, 1) != 0) // [retVal]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(ctx);
|
||||
}
|
||||
ILibDuktape_Process_UncaughtException(ctx);
|
||||
}
|
||||
duk_push_false(ctx);
|
||||
break;
|
||||
@@ -230,10 +230,7 @@ duk_ret_t ILibDuktape_WritableStream_End(duk_context *ctx)
|
||||
{
|
||||
if (nargs > 2 && !duk_is_null_or_undefined(ctx, 2))
|
||||
{
|
||||
stream->OnFinish = duk_require_heapptr(ctx, 2);
|
||||
duk_push_this(ctx); // [stream]
|
||||
duk_dup(ctx, 2); // [stream][flush]
|
||||
duk_put_prop_string(ctx, -2, "_Finish"); // [stream]
|
||||
ILibDuktape_EventEmitter_AddOnce(ILibDuktape_EventEmitter_GetEmitter_fromThis(ctx), "finish", duk_require_heapptr(ctx, 2));
|
||||
}
|
||||
stream->endBytes = (int)bufferLen;
|
||||
if (stream->WriteSink(stream, buffer, (int)bufferLen, stream->WriteSink_User) == ILibTransport_DoneState_INCOMPLETE)
|
||||
@@ -247,16 +244,14 @@ duk_ret_t ILibDuktape_WritableStream_End(duk_context *ctx)
|
||||
if (stream->WaitForEnd == 0)
|
||||
{
|
||||
// Continue with closing stream
|
||||
if (stream->OnFinish != NULL)
|
||||
{
|
||||
duk_push_heapptr(ctx, stream->OnFinish); // [func]
|
||||
duk_push_heapptr(ctx, stream->obj); // [func][this]
|
||||
if (duk_pcall_method(ctx, 0) != 0) // [retVal]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(ctx);
|
||||
}
|
||||
}
|
||||
if (stream->EndSink != NULL) { stream->EndSink(stream, stream->WriteSink_User); }
|
||||
|
||||
duk_push_heapptr(stream->ctx, stream->obj); // [stream]
|
||||
duk_get_prop_string(stream->ctx, -1, "emit"); // [stream][emit]
|
||||
duk_swap_top(stream->ctx, -2); // [emit][this]
|
||||
duk_push_string(stream->ctx, "finish"); // [emit][this][finish]
|
||||
if (duk_pcall_method(stream->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(stream->ctx); }
|
||||
duk_pop(stream->ctx); // ...
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -268,9 +263,20 @@ duk_ret_t ILibDuktape_WritableStream_End_Getter(duk_context *ctx)
|
||||
}
|
||||
duk_ret_t ILibDuktape_WritableStream_UnPipeSink(duk_context *ctx)
|
||||
{
|
||||
duk_dup(ctx, 0);
|
||||
duk_push_this(ctx);
|
||||
//printf("UNPIPE: [%s] => X => [%s]\n", Duktape_GetStringPropertyValue(ctx, -2, ILibDuktape_OBJID, "unknown"), Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "unknown"));
|
||||
ILibDuktape_WritableStream *ws;
|
||||
|
||||
duk_dup(ctx, 0); // [readable]
|
||||
duk_push_this(ctx); // [readable][writable]
|
||||
if (duk_has_prop_string(ctx, -1, ILibDuktape_WritableStream_WSPTRS))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_WritableStream_WSPTRS); // [readable][writable][ptr]
|
||||
ws = (ILibDuktape_WritableStream*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
ws->pipedReadable = NULL;
|
||||
ws->pipedReadable_native = NULL;
|
||||
duk_pop(ctx); // [readable][writable]
|
||||
if (g_displayStreamPipeMessages) { printf("UNPIPE: [%s] => X => [%s:%d]\n", Duktape_GetStringPropertyValue(ctx, -2, ILibDuktape_OBJID, "unknown"), Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "unknown"), ILibDuktape_GetReferenceCount(ctx, -1) - 1); if (g_displayFinalizerMessages) { duk_eval_string(ctx, "_debugGC();"); duk_pop(ctx); } }
|
||||
}
|
||||
duk_pop_2(ctx);
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_WritableStream_PipeSink(duk_context *ctx)
|
||||
@@ -289,8 +295,7 @@ duk_ret_t ILibDuktape_WritableStream_PipeSink(duk_context *ctx)
|
||||
|
||||
duk_dup(ctx, 0);
|
||||
duk_push_this(ctx);
|
||||
//printf("PIPE: [%s] => [%s]\n", Duktape_GetStringPropertyValue(ctx, -2, ILibDuktape_OBJID, "unknown"), Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "unknown"));
|
||||
|
||||
if (g_displayStreamPipeMessages) { printf("PIPE: [%s] => [%s:%d]\n", Duktape_GetStringPropertyValue(ctx, -2, ILibDuktape_OBJID, "unknown"), Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "unknown"), ILibDuktape_GetReferenceCount(ctx, -1)); }
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -315,11 +320,11 @@ ILibDuktape_WritableStream* ILibDuktape_WritableStream_Init(duk_context *ctx, IL
|
||||
emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "pipe");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "unpipe");
|
||||
ILibDuktape_EventEmitter_CreateEvent(emitter, "drain", &(retVal->OnDrain));
|
||||
ILibDuktape_EventEmitter_CreateEvent(emitter, "finish", &(retVal->OnFinish));
|
||||
ILibDuktape_EventEmitter_CreateEvent(emitter, "error", &(retVal->OnError));
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "drain");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "finish");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "error");
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "write", ILibDuktape_WritableStream_Write, DUK_VARARGS);
|
||||
ILibDuktape_CreateProperty_InstanceMethod(ctx, "write", ILibDuktape_WritableStream_Write, DUK_VARARGS);
|
||||
ILibDuktape_CreateEventWithGetter(ctx, "end", ILibDuktape_WritableStream_End_Getter);
|
||||
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "pipe", ILibDuktape_WritableStream_PipeSink);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -33,14 +33,10 @@ typedef struct ILibDuktape_WritableStream
|
||||
int JSCreated;
|
||||
duk_context *ctx;
|
||||
void *obj;
|
||||
void *OnDrain;
|
||||
void *OnWriteFlush;
|
||||
|
||||
ILibDuktape_WriteableStream_WriteFlushNative OnWriteFlushEx;
|
||||
void *OnWriteFlushEx_User;
|
||||
|
||||
void *OnError;
|
||||
void *OnFinish;
|
||||
char WaitForEnd;
|
||||
|
||||
ILibDuktape_WritableStream_WriteHandler WriteSink;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -69,7 +69,6 @@ typedef struct ILibDuktape_fs_writeStreamData
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
void *fsObject;
|
||||
void *WriteStreamObject;
|
||||
void *onClose;
|
||||
FILE *fPtr;
|
||||
int fd;
|
||||
int autoClose;
|
||||
@@ -82,7 +81,6 @@ typedef struct ILibDuktape_fs_readStreamData
|
||||
void *ReadStreamObject;
|
||||
void *fsObject;
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
void *onClose;
|
||||
FILE *fPtr;
|
||||
int fd;
|
||||
int autoClose;
|
||||
@@ -99,7 +97,6 @@ typedef struct ILibDuktape_fs_watcherData
|
||||
duk_context *ctx;
|
||||
void *object;
|
||||
void *parent;
|
||||
void *OnChange;
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
#if defined(WIN32)
|
||||
int recursive;
|
||||
@@ -240,9 +237,7 @@ duk_ret_t ILibDuktape_fs_openSync(duk_context *ctx)
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_string(ctx, "fs.openSync ERROR");
|
||||
duk_throw(ctx);
|
||||
return(DUK_RET_ERROR);
|
||||
return(ILibDuktape_Error(ctx, "fs.openSync(): Error opening '%s'", path));
|
||||
}
|
||||
}
|
||||
duk_ret_t ILibDuktape_fs_readSync(duk_context *ctx)
|
||||
@@ -260,7 +255,7 @@ duk_ret_t ILibDuktape_fs_readSync(duk_context *ctx)
|
||||
{
|
||||
if (duk_is_number(ctx, 4))
|
||||
{
|
||||
fseek(f, duk_require_int(ctx, 4), SEEK_CUR);
|
||||
fseek(f, duk_require_int(ctx, 4), SEEK_SET);
|
||||
}
|
||||
bytesRead = (int)fread(buffer + offset, 1, length, f);
|
||||
duk_push_int(ctx, bytesRead);
|
||||
@@ -285,7 +280,7 @@ duk_ret_t ILibDuktape_fs_writeSync(duk_context *ctx)
|
||||
f = ILibDuktape_fs_getFilePtr(ctx, duk_require_int(ctx, 0));
|
||||
if (f != NULL)
|
||||
{
|
||||
if (nargs > 4) { fseek(f, duk_require_int(ctx, 4), SEEK_CUR); }
|
||||
if (nargs > 4) { fseek(f, duk_require_int(ctx, 4), SEEK_SET); printf("Write: Seeking to %d\n", duk_require_int(ctx, 4)); }
|
||||
bytesWritten = (int)fwrite(buffer, 1, length, f);
|
||||
duk_push_int(ctx, bytesWritten);
|
||||
return 1;
|
||||
@@ -339,17 +334,14 @@ void ILibDuktape_fs_writeStream_endHandler(struct ILibDuktape_WritableStream *st
|
||||
data->fPtr = NULL;
|
||||
}
|
||||
|
||||
if (data->ctx != NULL && data->onClose != NULL)
|
||||
{
|
||||
// Call the 'close' event on the WriteStream
|
||||
duk_push_heapptr(data->ctx, data->onClose); // [func]
|
||||
duk_push_heapptr(data->ctx, data->WriteStreamObject); // [func][this]
|
||||
if (duk_pcall_method(data->ctx, 0) != 0) // [retVal]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(data->ctx);
|
||||
}
|
||||
duk_pop(data->ctx);
|
||||
}
|
||||
|
||||
// Call the 'close' event on the WriteStream
|
||||
duk_push_heapptr(data->ctx, data->WriteStreamObject); // [this]
|
||||
duk_get_prop_string(data->ctx, -1, "emit"); // [this][emit]
|
||||
duk_swap_top(data->ctx, -2); // [emit][this]
|
||||
duk_push_string(data->ctx, "close"); // [emit][this][close]
|
||||
if (duk_pcall_method(data->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
|
||||
duk_pop(data->ctx); // ...
|
||||
}
|
||||
duk_ret_t ILibDuktape_fs_writeStream_finalizer(duk_context *ctx)
|
||||
{
|
||||
@@ -413,6 +405,7 @@ duk_ret_t ILibDuktape_fs_createWriteStream(duk_context *ctx)
|
||||
if (f != NULL)
|
||||
{
|
||||
duk_push_object(ctx); // [writeStream]
|
||||
ILibDuktape_WriteID(ctx, "fs.writeStream");
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_fs_writeStreamData)); // [writeStream][buffer]
|
||||
data = (ILibDuktape_fs_writeStreamData*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
memset(data, 0, sizeof(ILibDuktape_fs_writeStreamData));
|
||||
@@ -428,7 +421,7 @@ duk_ret_t ILibDuktape_fs_createWriteStream(duk_context *ctx)
|
||||
data->emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
data->stream = ILibDuktape_WritableStream_Init(ctx, ILibDuktape_fs_writeStream_writeHandler, ILibDuktape_fs_writeStream_endHandler, data);
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEvent(data->emitter, "close", &(data->onClose));
|
||||
ILibDuktape_EventEmitter_CreateEventEx(data->emitter, "close");
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_fs_writeStream_finalizer);
|
||||
return 1;
|
||||
}
|
||||
@@ -454,14 +447,15 @@ void ILibDuktape_fs_readStream_Resume(struct ILibDuktape_readableStream *sender,
|
||||
sender->paused = 0;
|
||||
|
||||
if (data->bytesRead == -1) { data->bytesRead = 1; }
|
||||
while (sender->paused == 0 && data->bytesRead > 0 && data->bytesLeft < 0)
|
||||
while (sender->paused == 0 && data->bytesRead > 0 && (data->bytesLeft < 0 || data->bytesLeft > 0))
|
||||
{
|
||||
bytesToRead = data->bytesLeft < 0 ? sizeof(data->buffer) : data->bytesLeft;
|
||||
bytesToRead = data->bytesLeft < 0 ? sizeof(data->buffer) : (data->bytesLeft > sizeof(data->buffer) ? sizeof(data->buffer) : data->bytesLeft);
|
||||
data->bytesRead = (int)fread(data->buffer, 1, bytesToRead, data->fPtr);
|
||||
if (data->bytesRead > 0)
|
||||
{
|
||||
if (data->bytesLeft > 0) { data->bytesLeft -= data->bytesRead; }
|
||||
ILibDuktape_readableStream_WriteData(sender, data->buffer, data->bytesRead);
|
||||
if (data->bytesLeft == 0) { data->bytesRead = 0; }
|
||||
}
|
||||
}
|
||||
if (sender->paused == 0 && data->bytesRead == 0)
|
||||
@@ -477,14 +471,13 @@ void ILibDuktape_fs_readStream_Resume(struct ILibDuktape_readableStream *sender,
|
||||
data->fd = 0;
|
||||
data->fPtr = NULL;
|
||||
|
||||
if (data->onClose != NULL && data->ctx != NULL)
|
||||
if (data->ctx != NULL && data->ReadStreamObject != NULL)
|
||||
{
|
||||
duk_push_heapptr(data->ctx, data->onClose); // [func]
|
||||
duk_push_heapptr(data->ctx, data->ReadStreamObject); // [func][this]
|
||||
if (duk_pcall_method(data->ctx, 0) != 0) // [retVal]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(data->ctx);
|
||||
}
|
||||
duk_push_heapptr(data->ctx, data->ReadStreamObject); // [this]
|
||||
duk_get_prop_string(data->ctx, -1, "emit"); // [this][emit]
|
||||
duk_swap_top(data->ctx, -2); // [emit][this]
|
||||
duk_push_string(data->ctx, "close"); // [emit][this][close]
|
||||
if (duk_pcall_method(data->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
|
||||
duk_pop(data->ctx); // ...
|
||||
}
|
||||
}
|
||||
@@ -551,6 +544,7 @@ duk_ret_t ILibDuktape_fs_createReadStream(duk_context *ctx)
|
||||
}
|
||||
|
||||
duk_push_object(ctx); // [readStream]
|
||||
ILibDuktape_WriteID(ctx, "fs.readStream");
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_fs_readStreamData)); // [readStream][buffer]
|
||||
data = (ILibDuktape_fs_readStreamData*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
memset(data, 0, sizeof(ILibDuktape_fs_readStreamData));
|
||||
@@ -564,17 +558,19 @@ duk_ret_t ILibDuktape_fs_createReadStream(duk_context *ctx)
|
||||
data->fPtr = f;
|
||||
data->autoClose = autoClose;
|
||||
data->ReadStreamObject = duk_get_heapptr(ctx, -1);
|
||||
data->bytesLeft = end;
|
||||
data->bytesLeft = end < 0 ? end : (end - start + 1);
|
||||
data->bytesRead = -1;
|
||||
data->stream = ILibDuktape_ReadableStream_Init(ctx, ILibDuktape_fs_readStream_Pause, ILibDuktape_fs_readStream_Resume, data);
|
||||
data->stream->paused = 1;
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEvent(data->emitter, "close", &(data->onClose));
|
||||
//printf("readStream [start: %d, end: %d\n", start, end);
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEventEx(data->emitter, "close");
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_fs_readStream_finalizer);
|
||||
|
||||
if (start != 0)
|
||||
{
|
||||
fseek(f, start, SEEK_CUR);
|
||||
fseek(f, start, SEEK_SET);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -904,24 +900,23 @@ void ILibDuktape_fs_watch_iocompletionEx(void *chain, void *user)
|
||||
n = (n->NextEntryOffset != 0) ? ((FILE_NOTIFY_INFORMATION*)((char*)n + n->NextEntryOffset)) : NULL;
|
||||
}
|
||||
|
||||
if (data->OnChange != NULL)
|
||||
|
||||
duk_push_heapptr(data->ctx, data->object); // [detail][fsWatcher]
|
||||
duk_get_prop_string(data->ctx, -1, "emit"); // [detail][fsWatcher][emit]
|
||||
duk_swap_top(data->ctx, -2); // [detail][emit][this]
|
||||
duk_push_string(data->ctx, "change"); // [detail][emit][this][change]
|
||||
duk_push_string(data->ctx, changed == 0 ? "rename" : "change"); // [detail][emit][this][change][type]
|
||||
if (changed == 0)
|
||||
{
|
||||
duk_push_heapptr(data->ctx, data->OnChange); // [detail][change]
|
||||
duk_push_heapptr(data->ctx, data->object); // [detail][change][fsWatcher]
|
||||
duk_push_string(data->ctx, changed == 0 ? "rename" : "change"); // [detail][change][fsWatcher][type]
|
||||
if (changed == 0)
|
||||
{
|
||||
duk_get_prop_string(data->ctx, -4, "oldname"); // [detail][listener][fsWatcher][type][fileName]
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_get_prop_string(data->ctx, -4, "\xFF_FileName"); // [detail][listener][fsWatcher][type][fileName]
|
||||
}
|
||||
duk_dup(data->ctx, -5); // [detail][change][fsWatcher][type][fileName][detail]
|
||||
if (duk_pcall_method(data->ctx, 3) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
|
||||
duk_pop(data->ctx); // [detail]
|
||||
duk_get_prop_string(data->ctx, -4, "oldname"); // [detail][emit][this][change][type][fileName]
|
||||
}
|
||||
duk_pop(data->ctx); // ...
|
||||
else
|
||||
{
|
||||
duk_get_prop_string(data->ctx, -4, "\xFF_FileName"); // [detail][emit][this][change][type][fileName]
|
||||
}
|
||||
duk_dup(data->ctx, -5); // [detail][emit][this][change][type][fileName][detail]
|
||||
if (duk_pcall_method(data->ctx, 4) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
|
||||
duk_pop_2(data->ctx); // ...
|
||||
|
||||
memset(data->results, 0, sizeof(data->results));
|
||||
if (data->h != NULL)
|
||||
@@ -1001,7 +996,7 @@ void ILibDuktape_fs_notifyDispatcher_PostSelect(void* object, int slct, fd_set *
|
||||
wd.p = NULL;
|
||||
wd.i = evt->wd;
|
||||
watcher = (ILibDuktape_fs_watcherData*)ILibHashtable_Get(data->watchTable, wd.p, NULL, 0);
|
||||
if (watcher == NULL || watcher->OnChange == NULL) { continue; }
|
||||
if (watcher == NULL || ILibDuktape_EventEmitter_HasListeners(watcher->emitter, "change") == 0) { continue; }
|
||||
|
||||
duk_push_object(watcher->ctx); // [detail]
|
||||
|
||||
@@ -1021,21 +1016,19 @@ void ILibDuktape_fs_notifyDispatcher_PostSelect(void* object, int slct, fd_set *
|
||||
duk_push_string(watcher->ctx, evt->name);
|
||||
duk_put_prop_string(watcher->ctx, -2, "\xFF_FileName");
|
||||
}
|
||||
|
||||
duk_push_heapptr(watcher->ctx, watcher->OnChange); // [detail][change]
|
||||
duk_push_heapptr(watcher->ctx, watcher->object); // [detail][change][fsWatcher]
|
||||
duk_push_string(watcher->ctx, changed == 0 ? "rename" : "change"); // [detail][change][fsWatcher][type]
|
||||
ILibDuktape_EventEmitter_SetupEmit(watcher->ctx, watcher->object, "change");// [detail][emit][this][change]
|
||||
duk_push_string(watcher->ctx, changed == 0 ? "rename" : "change"); // [detail][emit][this][change][type]
|
||||
if (changed == 0)
|
||||
{
|
||||
duk_get_prop_string(watcher->ctx, -4, "oldname"); // [detail][listener][fsWatcher][type][fileName]
|
||||
duk_get_prop_string(watcher->ctx, -5, "oldname"); // [detail][emit][this][change][type][fileName]
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_get_prop_string(watcher->ctx, -4, "\xFF_FileName"); // [detail][listener][fsWatcher][type][fileName]
|
||||
duk_get_prop_string(watcher->ctx, -5, "\xFF_FileName"); // [detail][emit][this][change][type][fileName]
|
||||
}
|
||||
duk_dup(watcher->ctx, -5); // [detail][change][fsWatcher][type][fileName][detail]
|
||||
if (duk_pcall_method(watcher->ctx, 3) != 0) { ILibDuktape_Process_UncaughtException(watcher->ctx); }
|
||||
duk_pop_2(watcher->ctx); // ...
|
||||
duk_dup(watcher->ctx, -6); // [detail][emit][this][change][type][fileName][detail]
|
||||
if (duk_pcall_method(watcher->ctx, 4) != 0) { ILibDuktape_Process_UncaughtException(watcher->ctx); }
|
||||
duk_pop_2(watcher->ctx); // ...
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1099,6 +1092,7 @@ duk_ret_t ILibDuktape_fs_watch(duk_context *ctx)
|
||||
#endif
|
||||
|
||||
duk_push_object(ctx); // [FSWatcher]
|
||||
ILibDuktape_WriteID(ctx, "fs.fsWatcher");
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_fs_watcherData)); // [FSWatcher][data]
|
||||
data = (ILibDuktape_fs_watcherData*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_put_prop_string(ctx, -2, FS_WATCHER_DATA_PTR); // [FSWatcher]
|
||||
@@ -1117,7 +1111,7 @@ duk_ret_t ILibDuktape_fs_watch(duk_context *ctx)
|
||||
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "close", ILibDuktape_fs_watcher_close, 0);
|
||||
ILibDuktape_EventEmitter_CreateEvent(data->emitter, "change", &(data->OnChange));
|
||||
ILibDuktape_EventEmitter_CreateEventEx(data->emitter, "change");
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_fs_watcher_finalizer);
|
||||
|
||||
for (i = 1; i < nargs; ++i)
|
||||
@@ -1233,10 +1227,26 @@ duk_ret_t ILibDuktape_fs_readFileSync(duk_context *ctx)
|
||||
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_fs_existsSync(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx); // [fs]
|
||||
duk_get_prop_string(ctx, -1, "statSync"); // [fs][statSync]
|
||||
duk_swap_top(ctx, -2); // [statSync][this]
|
||||
duk_dup(ctx, 0); // [statSync][this][path]
|
||||
if (duk_pcall_method(ctx, 1) != 0)
|
||||
{
|
||||
duk_push_false(ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_true(ctx);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
void ILibDuktape_fs_PUSH(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx); // [fs]
|
||||
|
||||
ILibDuktape_WriteID(ctx, "fs");
|
||||
duk_push_pointer(ctx, chain); // [fs][chain]
|
||||
duk_put_prop_string(ctx, -2, FS_CHAIN_PTR); // [fs]
|
||||
|
||||
@@ -1256,6 +1266,7 @@ void ILibDuktape_fs_PUSH(duk_context *ctx, void *chain)
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "statSync", ILibDuktape_fs_statSync, 1);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "readDrivesSync", ILibDuktape_fs_readDrivesSync, 0);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "readFileSync", ILibDuktape_fs_readFileSync, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "existsSync", ILibDuktape_fs_existsSync, 1);
|
||||
#ifndef _NOFSWATCHER
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "watch", ILibDuktape_fs_watch, DUK_VARARGS);
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ___DUKTAPE_FS___
|
||||
#define ___DUKTAPE_FS___
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -41,14 +41,12 @@ limitations under the License.
|
||||
|
||||
duk_ret_t ILibDuktape_httpDigest_clientRequest_response2(duk_context *ctx)
|
||||
{
|
||||
ILibHTTPPacket *packet;
|
||||
duk_get_prop_string(ctx, 0, "PacketPtr");
|
||||
packet = (ILibHTTPPacket*)duk_get_pointer(ctx, -1);
|
||||
|
||||
duk_push_current_function(ctx);
|
||||
duk_get_prop_string(ctx, -1, "digestClientRequest");// [digestClientRequest]
|
||||
|
||||
if (packet->StatusCode == 200)
|
||||
int statusCode = Duktape_GetIntPropertyValue(ctx, 0, "statusCode", 0);
|
||||
|
||||
if (statusCode == 200)
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, "emit"); // [digestClientRequest][emit]
|
||||
duk_swap_top(ctx, -2); // [emit][this]
|
||||
@@ -60,8 +58,8 @@ duk_ret_t ILibDuktape_httpDigest_clientRequest_response2(duk_context *ctx)
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, "emit"); // [digestClientRequest][emit]
|
||||
duk_swap_top(ctx, -2); // [emit][this]
|
||||
duk_push_string(ctx, "error"); // [emit][this][response]
|
||||
duk_dup(ctx, 0); // [emit][this][response][imsg]
|
||||
duk_push_string(ctx, "error"); // [emit][this][error]
|
||||
duk_dup(ctx, 0); // [emit][this][error][imsg]
|
||||
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http-digest: Error dispatching response event"); }
|
||||
}
|
||||
|
||||
@@ -143,8 +141,8 @@ extern void ILibWebServer_Digest_ParseAuthenticationHeader(void* table, char* va
|
||||
char *ILibDuktape_httpDigest_generateAuthenticationHeader(duk_context *ctx, void *digestObj, void *optionsObj)
|
||||
{
|
||||
int top = duk_get_top(ctx);
|
||||
int NC;
|
||||
char *CNONCE;
|
||||
int NC = 0;
|
||||
char *CNONCE = NULL;
|
||||
|
||||
char *wwwauth, *username, *password;
|
||||
char *method, *path;
|
||||
@@ -188,7 +186,9 @@ char *ILibDuktape_httpDigest_generateAuthenticationHeader(duk_context *ctx, void
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, DIGEST2CNONCE); // [digest][buffer]
|
||||
CNONCE = (char*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_pop(ctx); // [digest]
|
||||
NC = Duktape_GetIntPropertyValue(ctx, -1, DIGEST2NC, 0) + 1;
|
||||
duk_push_int(ctx, NC); // [digest][NC]
|
||||
duk_put_prop_string(ctx, -2, DIGEST2NC); // [digest]
|
||||
@@ -198,14 +198,10 @@ char *ILibDuktape_httpDigest_generateAuthenticationHeader(duk_context *ctx, void
|
||||
util_md5hex(ILibScratchPad2, tmpLen, result3);
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\"", username, realm, nonce, path);
|
||||
if (opaque != NULL) { tmpLen += sprintf_s(ILibScratchPad2 + tmpLen, sizeof(ILibScratchPad2) - tmpLen, ", opaque=\"%s\"", opaque); }
|
||||
if (qop != NULL)
|
||||
{
|
||||
tmpLen += sprintf_s(ILibScratchPad2 + tmpLen, sizeof(ILibScratchPad2) - tmpLen, ", qop=\"%s\", nc=%08x, cnonce=\"%s\"", qop, NC, CNONCE);
|
||||
}
|
||||
|
||||
tmpLen += sprintf_s(ILibScratchPad2 + tmpLen, sizeof(ILibScratchPad2) - tmpLen, ", response=\"%s\"", result3);
|
||||
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "Digest username=\"%s\",realm=\"%s\",nonce=\"%s\",uri=\"%s\"", username, realm, nonce, path);
|
||||
if (opaque != NULL) { tmpLen += sprintf_s(ILibScratchPad2 + tmpLen, sizeof(ILibScratchPad2) - tmpLen, ",opaque=\"%s\"", opaque); }
|
||||
tmpLen += sprintf_s(ILibScratchPad2 + tmpLen, sizeof(ILibScratchPad2) - tmpLen, ",response=\"%s\"", result3);
|
||||
if (qop != NULL) { tmpLen += sprintf_s(ILibScratchPad2 + tmpLen, sizeof(ILibScratchPad2) - tmpLen, ",qop=\"%s\",nc=\"%08x\",cnonce=\"%s\"", qop, NC, CNONCE); }
|
||||
|
||||
if (realmLen > 0) { realm[realmLen] = '"'; }
|
||||
if (nonceLen > 0) { nonce[nonceLen] = '"'; }
|
||||
@@ -305,8 +301,8 @@ duk_ret_t ILibDuktape_httpDigest_clientRequest_response(duk_context *ctx)
|
||||
duk_dup(ctx, -2); // [clientRequest][buffer][clientRequest]
|
||||
duk_get_prop_string(ctx, -1, "write"); // [clientRequest][buffer][clientRequest][write]
|
||||
duk_swap_top(ctx, -2); // [clientRequest][buffer][write][this]
|
||||
duk_swap(ctx, -3, -2); // [clientRequest][write][buffer][this]
|
||||
duk_swap_top(ctx, -2); // [clientReqeust][write][this][buffer]
|
||||
duk_dup(ctx, -3); // [clientRequest][buffer][write][this][buffer]
|
||||
duk_remove(ctx, -4); // [clientRequest][write][this][buffer]
|
||||
if (duk_pcall_method(ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "httpDigest.clientRequest.onResponse(): Error calling clientRequest.write(): "); }
|
||||
duk_pop(ctx); // [clientRequest]
|
||||
}
|
||||
@@ -410,6 +406,12 @@ ILibTransport_DoneState ILibDuktape_httpDigest_http_request_WriteHandler(struct
|
||||
duk_put_prop_string(ctx, -2, DIGESTCLIENTREQUEST_TmpBuffer); // [digestClientRequest]
|
||||
memcpy_s(tmpBuffer, bufLen, buffer, (size_t)bufferLen);
|
||||
}
|
||||
|
||||
if (stream->endBytes > 0)
|
||||
{
|
||||
duk_push_true(ctx);
|
||||
duk_put_prop_string(ctx, -2, DIGESTCLIENTREQUEST_END_CALLED);
|
||||
}
|
||||
}
|
||||
|
||||
if (duk_has_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST))
|
||||
@@ -477,6 +479,7 @@ duk_ret_t ILibDuktape_httpDigest_http_request(duk_context *ctx)
|
||||
void *clientRequest = NULL;
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
char *auth = NULL;
|
||||
int needCallEnd = 0;
|
||||
|
||||
duk_push_this(ctx); // [digest]
|
||||
duk_get_prop_string(ctx, -1, HTTP_DIGEST); // [digest][http]
|
||||
@@ -489,6 +492,7 @@ duk_ret_t ILibDuktape_httpDigest_http_request(duk_context *ctx)
|
||||
duk_dup(ctx, -2); // [digest][request][this][parseUri][this]
|
||||
duk_dup(ctx, 0); // [digest][request][this][parseUri][this][uri]
|
||||
duk_call_method(ctx, 1); // [digest][request][this][options]
|
||||
needCallEnd = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -522,6 +526,13 @@ duk_ret_t ILibDuktape_httpDigest_http_request(duk_context *ctx)
|
||||
duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_response, DUK_VARARGS); // [once][this][response][method]
|
||||
|
||||
duk_push_object(ctx); // [once][this][response][method][digest-clientRequest]
|
||||
ILibDuktape_WriteID(ctx, "httpDigest.clientRequest");
|
||||
if (needCallEnd)
|
||||
{
|
||||
duk_push_true(ctx);
|
||||
duk_put_prop_string(ctx, -2, DIGESTCLIENTREQUEST_END_CALLED);
|
||||
}
|
||||
|
||||
duk_push_this(ctx); // [once][this][response][method][digest-clientRequest][digest]
|
||||
duk_put_prop_string(ctx, -2, DIGESTCLIENTREQUEST_DIGEST); // [once][this][response][method][digest-clientRequest]
|
||||
duk_push_heapptr(ctx, clientRequest); // [once][this][response][method][digest-clientRequest][clientRequest]
|
||||
@@ -557,6 +568,13 @@ duk_ret_t ILibDuktape_httpDigest_http_request(duk_context *ctx)
|
||||
ILibDuktape_EventEmitter_ForwardEvent(ctx, -2, "timeout", -1, "timeout");
|
||||
ILibDuktape_EventEmitter_ForwardEvent(ctx, -2, "drain", -1, "drain");
|
||||
|
||||
if (needCallEnd)
|
||||
{
|
||||
duk_get_prop_string(ctx, -2, "end"); // [clientRequest][digestClientRequest][end]
|
||||
duk_dup(ctx, -3); // [clientRequest][digestClientRequest][end][this]
|
||||
duk_call_method(ctx, 0); duk_pop(ctx); // [clientRequest][digestClientRequest]
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibduktape_httpDigest_create(duk_context *ctx)
|
||||
@@ -566,6 +584,7 @@ duk_ret_t ILibduktape_httpDigest_create(duk_context *ctx)
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
|
||||
duk_push_object(ctx); // [obj]
|
||||
ILibDuktape_WriteID(ctx, "httpDigest");
|
||||
ILibDuktape_CreateEventWithSetterEx(ctx, "clientRequest", ILibDuktape_httpDigest_clientRequest_setter);
|
||||
ILibDuktape_CreateEventWithSetterEx(ctx, "http", ILibDuktape_httpDigest_http_setter);
|
||||
emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
@@ -580,6 +599,7 @@ duk_ret_t ILibduktape_httpDigest_create(duk_context *ctx)
|
||||
duk_put_prop_string(ctx, -2, DIGEST_PASSWORD);
|
||||
duk_push_fixed_buffer(ctx, 16);
|
||||
util_randomtext(16, (char*)Duktape_GetBuffer(ctx, -1, NULL));
|
||||
((char*)Duktape_GetBuffer(ctx, -1, NULL))[15] = 0;
|
||||
duk_put_prop_string(ctx, -2, DIGEST2CNONCE);
|
||||
duk_push_int(ctx, 0);
|
||||
duk_put_prop_string(ctx, -2, DIGEST2NC);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -34,10 +34,6 @@ typedef struct ILibDuktape_net_socket
|
||||
void *net;
|
||||
void *duplexStream;
|
||||
void *chain;
|
||||
void *OnConnect;
|
||||
void *OnClose;
|
||||
void *OnError;
|
||||
void *OnTimeout;
|
||||
void *OnSetTimeout;
|
||||
int unshiftBytes;
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
@@ -53,9 +49,7 @@ typedef struct ILibDuktape_net_server
|
||||
void *self;
|
||||
ILibAsyncServerSocket_ServerModule server;
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
void *OnClose;
|
||||
void *OnListening;
|
||||
void *OnError;
|
||||
int isTLS;
|
||||
}ILibDuktape_net_server;
|
||||
typedef struct ILibDuktape_net_server_session
|
||||
{
|
||||
@@ -66,8 +60,6 @@ typedef struct ILibDuktape_net_server_session
|
||||
ILibDuktape_DuplexStream *stream;
|
||||
|
||||
int unshiftBytes;
|
||||
|
||||
void *OnTimeout;
|
||||
}ILibDuktape_net_server_session;
|
||||
|
||||
int ILibDuktape_TLS_ctx2socket = -1;
|
||||
@@ -83,6 +75,7 @@ int ILibDuktape_TLS_ctx2server = -1;
|
||||
#define ILibDuktape_SERVER2ContextTable "\xFF_Server2ContextTable"
|
||||
#define ILibDuktape_SERVER2OPTIONS "\xFF_ServerToOptions"
|
||||
#define ILibDuktape_SERVER2LISTENOPTIONS "\xFF_ServerToListenOptions"
|
||||
#define ILibDuktape_TLSSocket2SecureContext "\xFF_TLSSocket2SecureContext"
|
||||
|
||||
extern void ILibAsyncServerSocket_RemoveFromChain(ILibAsyncServerSocket_ServerModule serverModule);
|
||||
|
||||
@@ -143,28 +136,34 @@ void ILibDuktape_net_socket_OnConnect(ILibAsyncSocket_SocketModule socketModule,
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (ptrs->OnConnect != NULL)
|
||||
{
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->OnConnect); // [func]
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->object); // [func][this]
|
||||
if (duk_pcall_method(ptrs->ctx, 0) != 0) // [retVal]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(ptrs->ctx);
|
||||
}
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
}
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->object); // [this]
|
||||
duk_get_prop_string(ptrs->ctx, -1, "emit"); // [this][emit]
|
||||
duk_swap_top(ptrs->ctx, -2); // [emit][this]
|
||||
duk_push_string(ptrs->ctx, "connect"); // [emit][this][connect]
|
||||
if (duk_pcall_method(ptrs->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(ptrs->ctx); }
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
}
|
||||
else if(ptrs->OnError != NULL)
|
||||
else
|
||||
{
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->OnError); // [func]
|
||||
ILibDuktape_net_socket_PUSH(ptrs->ctx, socketModule); // [func][this]
|
||||
duk_push_object(ptrs->ctx); // [func][this][error]
|
||||
duk_push_string(ptrs->ctx, "Connection Failed"); // [func][this][error][msg]
|
||||
duk_put_prop_string(ptrs->ctx, -2, "message"); // [func][this][error]
|
||||
if (duk_pcall_method(ptrs->ctx, 1) != 0) // [retVal]
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->object); // [this]
|
||||
duk_get_prop_string(ptrs->ctx, -1, "emit"); // [this][emit]
|
||||
duk_swap_top(ptrs->ctx, -2); // [emit][this]
|
||||
duk_push_string(ptrs->ctx, "error"); // [emit][this][error]
|
||||
duk_push_object(ptrs->ctx); // [emit][this][error][errorObj]
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
if (ptrs->ssl != NULL && ILibAsyncSocket_TLS_WasHandshakeError(socketModule))
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(ptrs->ctx);
|
||||
duk_push_string(ptrs->ctx, "TLS Handshake Error"); // [emit][this][error][errorObj][msg]
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_string(ptrs->ctx, "Connection Failed"); // [emit][this][error][errorObj][msg]
|
||||
}
|
||||
#else
|
||||
duk_push_string(ptrs->ctx, "Connection Failed"); // [emit][this][error][errorObj][msg]
|
||||
#endif
|
||||
duk_put_prop_string(ptrs->ctx, -2, "message"); // [emit][this][error][errorObj]
|
||||
if (duk_pcall_method(ptrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(ptrs->ctx); }
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
}
|
||||
}
|
||||
@@ -338,13 +337,13 @@ duk_ret_t ILibDuktape_net_socket_address(duk_context *ctx)
|
||||
void ILibDuktape_net_socket_timeoutSink(ILibAsyncSocket_SocketModule socketModule, void *user)
|
||||
{
|
||||
ILibDuktape_net_socket *ptrs = (ILibDuktape_net_socket*)((ILibChain_Link*)socketModule)->ExtraMemoryPtr;
|
||||
if (ptrs->OnTimeout != NULL)
|
||||
{
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->OnTimeout); // [func]
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->object); // [func][this]
|
||||
if (duk_pcall_method(ptrs->ctx, 0) != 0) { ILibDuktape_Process_UncaughtException(ptrs->ctx); }
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
}
|
||||
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->object); // [this]
|
||||
duk_get_prop_string(ptrs->ctx, -1, "emit"); // [this][emit]
|
||||
duk_swap_top(ptrs->ctx, -2); // [emit][this]
|
||||
duk_push_string(ptrs->ctx, "timeout"); // [emit][this][timeout]
|
||||
if (duk_pcall_method(ptrs->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(ptrs->ctx); }
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
}
|
||||
duk_ret_t ILibDuktape_net_socket_setTimeout(duk_context *ctx)
|
||||
{
|
||||
@@ -378,9 +377,6 @@ duk_ret_t ILibDuktape_net_socket_finalizer(duk_context *ctx)
|
||||
if (ptrs->socketModule != NULL)
|
||||
{
|
||||
if (ILibAsyncSocket_IsConnected(ptrs->socketModule) != 0) { ILibAsyncSocket_Disconnect(ptrs->socketModule); }
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
if (ptrs->ssl_ctx != NULL) { SSL_CTX_free(ptrs->ssl_ctx); ptrs->ssl_ctx = NULL; }
|
||||
#endif
|
||||
ILibChain_SafeRemove(chain, ptrs->socketModule);
|
||||
}
|
||||
|
||||
@@ -423,10 +419,10 @@ void ILibDuktape_net_socket_PUSH(duk_context *ctx, ILibAsyncSocket_SocketModule
|
||||
ptrs->emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
ptrs->duplexStream = ILibDuktape_DuplexStream_InitEx(ctx, ILibDuktape_net_socket_WriteHandler, ILibDuktape_net_socket_EndHandler, ILibDuktape_net_socket_PauseHandler, ILibDuktape_net_socket_ResumeHandler, ILibDuktape_net_socket_unshift, ptrs);
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "close", &(ptrs->OnClose));
|
||||
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "connect", &(ptrs->OnConnect));
|
||||
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "error", &(ptrs->OnError));
|
||||
ILibDuktape_EventEmitter_CreateEvent(ptrs->emitter, "timeout", &(ptrs->OnTimeout));
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "close");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "connect");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "error");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ptrs->emitter, "timeout");
|
||||
|
||||
ILibDuktape_CreateProperty_InstanceMethod(ctx, "connect", ILibDuktape_net_socket_connect, DUK_VARARGS);
|
||||
|
||||
@@ -576,7 +572,7 @@ void ILibDuktape_net_server_OnConnect(ILibAsyncServerSocket_ServerModule AsyncSe
|
||||
session->emitter = ILibDuktape_EventEmitter_Create(ptr->ctx);
|
||||
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEvent(session->emitter, "timeout", &(session->OnTimeout));
|
||||
ILibDuktape_EventEmitter_CreateEventEx(session->emitter, "timeout");
|
||||
|
||||
session->stream = ILibDuktape_DuplexStream_InitEx(ptr->ctx, ILibDuktape_net_server_WriteSink, ILibDuktape_net_server_EndSink,
|
||||
ILibDuktape_net_server_PauseSink, ILibDuktape_net_server_ResumeSink, ILibDuktape_net_server_unshiftSink, session);
|
||||
@@ -587,7 +583,7 @@ void ILibDuktape_net_server_OnConnect(ILibAsyncServerSocket_ServerModule AsyncSe
|
||||
void ILibDuktape_net_server_OnDisconnect(ILibAsyncServerSocket_ServerModule AsyncServerSocketModule, ILibAsyncServerSocket_ConnectionToken ConnectionToken, void *user)
|
||||
{
|
||||
ILibDuktape_net_server_session *session = (ILibDuktape_net_server_session*)user;
|
||||
ILibDuktape_DuplexStream_WriteEnd(session->stream);
|
||||
ILibDuktape_DuplexStream_Closed(session->stream);
|
||||
}
|
||||
void ILibDuktape_net_server_OnReceive(ILibAsyncServerSocket_ServerModule AsyncServerSocketModule, ILibAsyncServerSocket_ConnectionToken ConnectionToken, char* buffer, int *p_beginPointer, int endPointer, ILibAsyncServerSocket_OnInterrupt *OnInterrupt, void **user, int *PAUSE)
|
||||
{
|
||||
@@ -689,34 +685,37 @@ duk_ret_t ILibDuktape_net_server_listen(duk_context *ctx)
|
||||
ILibAsyncServerSocket_SetTag(server->server, server);
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
{
|
||||
duk_push_this(ctx); // [server]
|
||||
if (duk_has_prop_string(ctx, -1, "addContext"))
|
||||
if (server->isTLS)
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, "addContext"); // [server][addContext]
|
||||
duk_swap_top(ctx, -2); // [addContext][this]
|
||||
duk_push_string(ctx, "*"); // [addContext][this][*]
|
||||
duk_eval_string(ctx, "require('tls');"); // [addContext][this][*][tls]
|
||||
duk_get_prop_string(ctx, -1, "createSecureContext"); // [addContext][this][*][tls][createSecureContext]
|
||||
duk_swap_top(ctx, -2); // [addContext][this][*][createSecureContext][this]
|
||||
duk_get_prop_string(ctx, -4, ILibDuktape_SERVER2OPTIONS); // [addContext][this][*][createSecureContext][this][options]
|
||||
duk_call_method(ctx, 1); // [addContext][this][*][secureContext]
|
||||
duk_call_method(ctx, 2); duk_pop(ctx); // ...
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_pop(ctx); // ...
|
||||
duk_push_this(ctx); // [server]
|
||||
if (duk_has_prop_string(ctx, -1, "addContext"))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, "addContext"); // [server][addContext]
|
||||
duk_swap_top(ctx, -2); // [addContext][this]
|
||||
duk_push_string(ctx, "*"); // [addContext][this][*]
|
||||
duk_eval_string(ctx, "require('tls');"); // [addContext][this][*][tls]
|
||||
duk_get_prop_string(ctx, -1, "createSecureContext"); // [addContext][this][*][tls][createSecureContext]
|
||||
duk_swap_top(ctx, -2); // [addContext][this][*][createSecureContext][this]
|
||||
duk_get_prop_string(ctx, -4, ILibDuktape_SERVER2OPTIONS); // [addContext][this][*][createSecureContext][this][options]
|
||||
duk_call_method(ctx, 1); // [addContext][this][*][secureContext]
|
||||
duk_call_method(ctx, 2); duk_pop(ctx); // ...
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (server->OnListening != NULL)
|
||||
{
|
||||
duk_push_heapptr(server->ctx, server->OnListening); // [func]
|
||||
duk_push_heapptr(server->ctx, server->self); // [func][this]
|
||||
if (duk_pcall_method(server->ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(server->ctx, "net.server.listen(): Error "); }
|
||||
duk_pop(server->ctx); // ...
|
||||
}
|
||||
|
||||
duk_push_heapptr(server->ctx, server->self); // [this]
|
||||
duk_get_prop_string(server->ctx, -1, "emit"); // [this][emit]
|
||||
duk_swap_top(server->ctx, -2); // [emit][this]
|
||||
duk_push_string(server->ctx, "listening"); // [emit][this][listenting]
|
||||
if (duk_pcall_method(server->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(server->ctx, "net.server.listen(): Error "); }
|
||||
duk_pop(server->ctx); // ...
|
||||
|
||||
#ifndef WIN32
|
||||
ignore_result(backlog);
|
||||
#endif
|
||||
@@ -783,11 +782,12 @@ duk_ret_t ILibDuktape_net_createServer(duk_context *ctx)
|
||||
server = (ILibDuktape_net_server*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
memset(server, 0, sizeof(ILibDuktape_net_server));
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_net_Server_buffer); // [server]
|
||||
|
||||
|
||||
server->isTLS = isTLS;
|
||||
server->self = duk_get_heapptr(ctx, -1);
|
||||
server->ctx = ctx;
|
||||
server->emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
ILibDuktape_EventEmitter_CreateEvent(server->emitter, "close", &(server->OnClose));
|
||||
ILibDuktape_EventEmitter_CreateEventEx(server->emitter, "close");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(server->emitter, "connection");
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
if (isTLS)
|
||||
@@ -799,8 +799,8 @@ duk_ret_t ILibDuktape_net_createServer(duk_context *ctx)
|
||||
if (ILibDuktape_TLS_ctx2server < 0) { ILibDuktape_TLS_ctx2server = SSL_get_ex_new_index(0, "ILibDuktape_TLS_Server index", NULL, NULL, NULL); }
|
||||
}
|
||||
#endif
|
||||
ILibDuktape_EventEmitter_CreateEvent(server->emitter, "error", &(server->OnError));
|
||||
ILibDuktape_EventEmitter_CreateEvent(server->emitter, "listening", &(server->OnListening));
|
||||
ILibDuktape_EventEmitter_CreateEventEx(server->emitter, "error");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(server->emitter, "listening");
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "listen", ILibDuktape_net_server_listen, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "address", ILibDuktape_net_server_address, 0);
|
||||
@@ -816,6 +816,13 @@ duk_ret_t ILibDuktape_net_createServer(duk_context *ctx)
|
||||
if (duk_is_object(ctx, i))
|
||||
{
|
||||
// Options
|
||||
if (isTLS && !duk_has_prop_string(ctx, i, "secureProtocol"))
|
||||
{
|
||||
duk_dup(ctx, i); // [options]
|
||||
duk_push_string(ctx, "SSLv23_server_method"); // [options][secureProtocol]
|
||||
duk_put_prop_string(ctx, -2, "secureProtocol"); // [options]
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -974,7 +981,7 @@ int ILibDuktape_TLS_verify(int preverify_ok, X509_STORE_CTX *storectx)
|
||||
if (Duktape_GetBooleanProperty(data->ctx, -1, "rejectUnauthorized", 1)) { duk_pop_2(data->ctx); return(preverify_ok); }
|
||||
void *OnVerify = Duktape_GetHeapptrProperty(data->ctx, -1, "checkServerIdentity");
|
||||
|
||||
if (OnVerify == NULL) { return(1); }
|
||||
if (OnVerify == NULL) { duk_pop_2(data->ctx); return(1); }
|
||||
|
||||
duk_push_heapptr(data->ctx, OnVerify); // [func]
|
||||
duk_push_heapptr(data->ctx, data->object); // [func][this]
|
||||
@@ -1141,10 +1148,6 @@ duk_ret_t ILibDuktape_TLS_connect(duk_context *ctx)
|
||||
ILibAsyncSocket_SocketModule module = ILibCreateAsyncSocketModuleWithMemory(Duktape_GetChain(ctx), 4096, ILibDuktape_net_socket_OnData, ILibDuktape_net_socket_OnConnect, ILibDuktape_net_socket_OnDisconnect, ILibDuktape_net_socket_OnSendOK, sizeof(ILibDuktape_net_socket));
|
||||
ILibDuktape_net_socket *data = (ILibDuktape_net_socket*)((ILibChain_Link*)module)->ExtraMemoryPtr;
|
||||
|
||||
data->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
|
||||
SSL_CTX_set_options(data->ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
|
||||
SSL_CTX_set_verify(data->ssl_ctx, SSL_VERIFY_PEER, ILibDuktape_TLS_verify); /* Ask for authentication */
|
||||
|
||||
if (ILibDuktape_TLS_ctx2socket < 0)
|
||||
{
|
||||
ILibDuktape_TLS_ctx2socket = SSL_get_ex_new_index(0, "ILibDuktape_TLS index", NULL, NULL, NULL);
|
||||
@@ -1152,6 +1155,28 @@ duk_ret_t ILibDuktape_TLS_connect(duk_context *ctx)
|
||||
|
||||
ILibDuktape_net_socket_PUSH(ctx, module); // [socket]
|
||||
ILibDuktape_WriteID(ctx, "tls.socket");
|
||||
duk_dup(ctx, 0); // [socket][options]
|
||||
if (duk_has_prop_string(ctx, -1, "secureContext"))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, "secureContext"); // [socket][options][secureContext]
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_this(ctx); // [socket][options][tls]
|
||||
duk_get_prop_string(ctx, -1, "createSecureContext"); // [socket][options][tls][createSecureContext]
|
||||
duk_swap_top(ctx, -2); // [socket][options][createSecureContext][this]
|
||||
duk_dup(ctx, -3); // [socket][options][createSecureContext][this][options]
|
||||
duk_call_method(ctx, 1); // [socket][options][secureContext]
|
||||
}
|
||||
if ((data->ssl_ctx = (SSL_CTX*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_SecureContext2SSLCTXPTR)) == NULL)
|
||||
{
|
||||
return(ILibDuktape_Error(ctx, "Invalid SecureContext Object"));
|
||||
}
|
||||
SSL_CTX_set_verify(data->ssl_ctx, SSL_VERIFY_PEER, ILibDuktape_TLS_verify); /* Ask for authentication */
|
||||
|
||||
duk_remove(ctx, -2); // [socket][secureContext]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_TLSSocket2SecureContext);
|
||||
|
||||
duk_dup(ctx, 0); // [socket][options]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_SOCKET2OPTIONS); // [socket]
|
||||
ILibDuktape_EventEmitter_CreateEventEx(data->emitter, "secureConnect");
|
||||
@@ -1197,6 +1222,7 @@ duk_ret_t ILibDuktape_TLS_connect(duk_context *ctx)
|
||||
SSL_set_ex_data(data->ssl, ILibDuktape_TLS_ctx2socket, data);
|
||||
SSL_set_tlsext_host_name(data->ssl, host);
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_TLS_secureContext_Finalizer(duk_context *ctx)
|
||||
@@ -1211,6 +1237,7 @@ duk_ret_t ILibDuktape_TLS_secureContext_Finalizer(duk_context *ctx)
|
||||
duk_ret_t ILibDuktape_TLS_createSecureContext(duk_context *ctx)
|
||||
{
|
||||
duk_push_object(ctx); // [secureContext]
|
||||
ILibDuktape_WriteID(ctx, "tls.secureContext");
|
||||
duk_push_fixed_buffer(ctx, sizeof(struct util_cert)); // [secureContext][cert]
|
||||
struct util_cert *cert = (struct util_cert*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_SecureContext2CertBuffer); // [secureContext]
|
||||
@@ -1218,14 +1245,69 @@ duk_ret_t ILibDuktape_TLS_createSecureContext(duk_context *ctx)
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_TLS_secureContext_Finalizer);
|
||||
|
||||
duk_size_t secureProtocolLen;
|
||||
char *secureProtocol = (char*)Duktape_GetStringPropertyValueEx(ctx, 0, "secureProtocol", "SSLv23_server_method", &secureProtocolLen);
|
||||
char *secureProtocol = (char*)Duktape_GetStringPropertyValueEx(ctx, 0, "secureProtocol", "SSLv23_method", &secureProtocolLen);
|
||||
SSL_CTX *ssl_ctx = NULL;
|
||||
|
||||
if (secureProtocolLen == 20 && strncmp(secureProtocol, "SSLv23_server_method", 20) == 0)
|
||||
if (secureProtocolLen == 13 && strncmp(secureProtocol, "SSLv23_method", 13) == 0)
|
||||
{
|
||||
ssl_ctx = SSL_CTX_new(SSLv23_server_method());
|
||||
ssl_ctx = SSL_CTX_new(TLS_method());
|
||||
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
|
||||
}
|
||||
else if (secureProtocolLen == 20 && strncmp(secureProtocol, "SSLv23_client_method", 20) == 0)
|
||||
{
|
||||
ssl_ctx = SSL_CTX_new(TLS_method());
|
||||
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
|
||||
}
|
||||
else if (secureProtocolLen == 20 && strncmp(secureProtocol, "SSLv23_server_method", 20) == 0)
|
||||
{
|
||||
ssl_ctx = SSL_CTX_new(TLS_method());
|
||||
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
|
||||
}
|
||||
else if (secureProtocolLen == 12 && strncmp(secureProtocol, "TLSv1_method", 12) == 0)
|
||||
{
|
||||
ssl_ctx = SSL_CTX_new(TLS_method());
|
||||
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2);
|
||||
}
|
||||
else if (secureProtocolLen == 19 && strncmp(secureProtocol, "TLSv1_client_method", 19) == 0)
|
||||
{
|
||||
ssl_ctx = SSL_CTX_new(TLS_method());
|
||||
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2);
|
||||
}
|
||||
else if (secureProtocolLen == 19 && strncmp(secureProtocol, "TLSv1_server_method", 19) == 0)
|
||||
{
|
||||
ssl_ctx = SSL_CTX_new(TLS_method());
|
||||
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2);
|
||||
}
|
||||
else if (secureProtocolLen == 14 && strncmp(secureProtocol, "TLSv1_1_method", 14) == 0)
|
||||
{
|
||||
ssl_ctx = SSL_CTX_new(TLS_method());
|
||||
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_2);
|
||||
}
|
||||
else if (secureProtocolLen == 21 && strncmp(secureProtocol, "TLSv1_1_client_method", 21) == 0)
|
||||
{
|
||||
ssl_ctx = SSL_CTX_new(TLS_method());
|
||||
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_2);
|
||||
}
|
||||
else if (secureProtocolLen == 21 && strncmp(secureProtocol, "TLSv1_1_server_method", 21) == 0)
|
||||
{
|
||||
ssl_ctx = SSL_CTX_new(TLS_method());
|
||||
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_2);
|
||||
}
|
||||
else if (secureProtocolLen == 14 && strncmp(secureProtocol, "TLSv1_2_method", 14) == 0)
|
||||
{
|
||||
ssl_ctx = SSL_CTX_new(TLS_method());
|
||||
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
|
||||
}
|
||||
else if (secureProtocolLen == 21 && strncmp(secureProtocol, "TLSv1_2_client_method", 21) == 0)
|
||||
{
|
||||
ssl_ctx = SSL_CTX_new(TLS_method());
|
||||
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
|
||||
}
|
||||
else if (secureProtocolLen == 21 && strncmp(secureProtocol, "TLSv1_2_server_method", 21) == 0)
|
||||
{
|
||||
ssl_ctx = SSL_CTX_new(TLS_method());
|
||||
SSL_CTX_set_options(ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
|
||||
}
|
||||
else if (secureProtocolLen == 11 && strncmp(secureProtocol, "DTLS_method", 11) == 0)
|
||||
{
|
||||
ssl_ctx = SSL_CTX_new(DTLS_method());
|
||||
@@ -1266,11 +1348,31 @@ duk_ret_t ILibDuktape_TLS_generateCertificate(duk_context *ctx)
|
||||
duk_push_fixed_buffer(ctx, len);
|
||||
memcpy_s((void*)Duktape_GetBuffer(ctx, -1, NULL), len, data, len);
|
||||
duk_push_buffer_object(ctx, -1, 0, len, DUK_BUFOBJ_NODEJS_BUFFER);
|
||||
|
||||
ILibDuktape_WriteID(ctx, "tls.pfxCertificate");
|
||||
util_free(data);
|
||||
util_freecert(&cert);
|
||||
return 1;
|
||||
}
|
||||
duk_ret_t ILibDuktape_TLS_loadpkcs7b(duk_context *ctx)
|
||||
{
|
||||
duk_size_t len;
|
||||
char *buffer = (char*)Duktape_GetBuffer(ctx, 0, &len);
|
||||
int val = util_from_pkcs7b_string(buffer, (int)len, NULL, 0);
|
||||
char *out;
|
||||
|
||||
if (val > 0)
|
||||
{
|
||||
duk_push_fixed_buffer(ctx, val);
|
||||
out = Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_push_buffer_object(ctx, -1, 0, val, DUK_BUFOBJ_NODEJS_BUFFER);
|
||||
util_from_pkcs7b_string(buffer, (int)len, out, val);
|
||||
return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(ILibDuktape_Error(ctx, "Error reading pkcs7b data"));
|
||||
}
|
||||
}
|
||||
void ILibDuktape_tls_PUSH(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx); // [TLS]
|
||||
@@ -1278,6 +1380,7 @@ void ILibDuktape_tls_PUSH(duk_context *ctx, void *chain)
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "connect", ILibDuktape_TLS_connect, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "createSecureContext", ILibDuktape_TLS_createSecureContext, 1);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "generateCertificate", ILibDuktape_TLS_generateCertificate, 1);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "loadpkcs7b", ILibDuktape_TLS_loadpkcs7b, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(_MINCORE)
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#include <crtdbg.h>
|
||||
@@ -7,6 +23,7 @@
|
||||
#include "ILibDuktape_EventEmitter.h"
|
||||
#include "ILibDuktapeModSearch.h"
|
||||
#include "ILibDuktape_Helpers.h"
|
||||
#include "ILibDuktape_Polyfills.h"
|
||||
|
||||
#define ILibDuktape_EventEmitter_MaxEventNameLen 255
|
||||
#define ILibDuktape_EventEmitter_Data "\xFF_EventEmitter_Data"
|
||||
@@ -127,39 +144,19 @@ void ILibDuktape_EventEmitter_FinalizerEx(ILibHashtable sender, void *Key1, char
|
||||
duk_pop_2(data->ctx); // ...
|
||||
}
|
||||
}
|
||||
duk_ret_t ILibDuktape_EventEmitter_Finalizer(duk_context *ctx)
|
||||
|
||||
int ILibDuktape_EventEmitter_HasListeners(ILibDuktape_EventEmitter *emitter, char *eventName)
|
||||
{
|
||||
ILibDuktape_EventEmitter *data;
|
||||
duk_get_prop_string(ctx, 0, ILibDuktape_EventEmitter_Data);
|
||||
data = (ILibDuktape_EventEmitter*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
|
||||
// Check to see if this is the process object going away
|
||||
if (ILibDuktape_GetProcessObject(ctx) == data->object)
|
||||
int retVal = 0;
|
||||
if (emitter->eventTable != NULL)
|
||||
{
|
||||
// We need to dispatch the 'exit' event
|
||||
int exitCode = 0;
|
||||
duk_push_heapptr(data->ctx, data->object); // [process]
|
||||
if (duk_has_prop_string(data->ctx, -1, "\xFF_ExitCode"))
|
||||
ILibLinkedList eventList = ILibHashtable_Get(emitter->eventTable, NULL, eventName, (int)strnlen_s(eventName, 255));
|
||||
if (eventList != NULL)
|
||||
{
|
||||
duk_get_prop_string(data->ctx, -1, "\xFF_ExitCode"); // [process][exitCode]
|
||||
exitCode = duk_get_int(data->ctx, -1);
|
||||
duk_pop(data->ctx); // [process]
|
||||
retVal = ILibLinkedList_GetCount(eventList);
|
||||
}
|
||||
duk_get_prop_string(data->ctx, -1, "emit"); // [process][emit]
|
||||
duk_swap_top(data->ctx, -2); // [emit][this]
|
||||
duk_push_string(data->ctx, "exit"); // [emit][this][eventName/exit]
|
||||
duk_push_int(data->ctx, exitCode); // [emit][this][eventName/exit][exitCode]
|
||||
duk_pcall_method(data->ctx, 2);
|
||||
duk_pop(data->ctx);
|
||||
}
|
||||
|
||||
|
||||
// We need to clear the Native Dispatcher, while destroying the Hashtable
|
||||
ILibHashtable_DestroyEx(data->eventTable, ILibDuktape_EventEmitter_FinalizerEx, data);
|
||||
|
||||
memset(data, 0, sizeof(ILibDuktape_EventEmitter));
|
||||
|
||||
return 0;
|
||||
return(retVal);
|
||||
}
|
||||
duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
|
||||
{
|
||||
@@ -170,25 +167,24 @@ duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
|
||||
void *self;
|
||||
int nargs = duk_get_top(ctx);
|
||||
ILibDuktape_EventEmitter *data;
|
||||
void *node, *nextNode, *func, *dispatcher;
|
||||
int i, j, count;
|
||||
void **hptr;
|
||||
void *node, *nextNode, *func;
|
||||
int i, j;
|
||||
void **emitList;
|
||||
char *objid;
|
||||
|
||||
duk_push_this(ctx);
|
||||
duk_push_this(ctx); // [this]
|
||||
objid = Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "unknown");
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_TempObject); // [this][tmp]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_Data); // [this][tmp][data]
|
||||
data = (ILibDuktape_EventEmitter*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_pop_2(ctx); // [this]
|
||||
self = duk_get_heapptr(ctx, -1);
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
if (data->eventTable == NULL) { duk_push_false(ctx); return(1); } // This probably means the finalizer was already run on the eventEmitter
|
||||
|
||||
eventList = ILibHashtable_Get(data->eventTable, NULL, name, (int)nameLen);
|
||||
if (eventList == NULL) { return ILibDuktape_Error(ctx, "EventEmitter.emit(): Event '%s' not found", name); }
|
||||
dispatcher = ILibHashtable_Get(data->eventTable, ILibDuktape_EventEmitter_SetterFunc, name, (int)nameLen);
|
||||
if (dispatcher == NULL) { return ILibDuktape_Error(ctx, "EventEmitter.emit(): Internal Error with event '%s'", name); }
|
||||
|
||||
if (eventList == NULL) { return ILibDuktape_Error(ctx, "EventEmitter.emit(): Event '%s' not found on object '%s'", name, objid); }
|
||||
|
||||
// Copy the list, so we can enumerate with local memory, so the list can be manipulated while we are dispatching
|
||||
#ifdef WIN32
|
||||
@@ -213,22 +209,6 @@ duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
|
||||
}
|
||||
emitList[i] = NULL;
|
||||
|
||||
// If no more listeners, we can set the hptr to NULL
|
||||
if (ILibLinkedList_GetCount(eventList) == 0)
|
||||
{
|
||||
duk_push_heapptr(ctx, dispatcher); // [dispatcher]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_HPTR_LIST); // [dispatcher][hptrList]
|
||||
count = (int)duk_get_length(ctx, -1);
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
duk_get_prop_index(ctx, -1, i); // [dispatcher][hptrList][hptr]
|
||||
hptr = (void**)duk_get_pointer(ctx, -1);
|
||||
*hptr = NULL;
|
||||
duk_pop(ctx); // [dispatcher][hptrList]
|
||||
}
|
||||
duk_pop_2(ctx); // ...
|
||||
}
|
||||
|
||||
// Now that we have all the housekeeping stuff out of the way, we can actually dispatch our events
|
||||
i = 0;
|
||||
while ((func = emitList[i++]) != NULL)
|
||||
@@ -241,13 +221,27 @@ duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
|
||||
}
|
||||
if (duk_pcall_method(ctx, nargs - 1) != 0)
|
||||
{
|
||||
return(ILibDuktape_Error(ctx, "EventEmitter.emit(): Event dispatch for '%s' threw an exception: %s", name, duk_safe_to_string(ctx, -1)));
|
||||
return(ILibDuktape_Error(ctx, "EventEmitter.emit(): Event dispatch for '%s' on '%s' threw an exception: %s", name, objid, duk_safe_to_string(ctx, -1)));
|
||||
}
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
duk_push_boolean(ctx, i > 1 ? 1 : 0);
|
||||
return(1);
|
||||
}
|
||||
int ILibDuktape_EventEmitter_PrependOnce(duk_context *ctx, duk_idx_t i, char *eventName, duk_c_function func)
|
||||
{
|
||||
int retVal = 1;
|
||||
|
||||
duk_dup(ctx, i); // [this]
|
||||
duk_get_prop_string(ctx, -1, "prependOnceListener"); // [this][prependOnce]
|
||||
duk_swap_top(ctx, -2); // [prependOnce][this]
|
||||
duk_push_string(ctx, eventName); // [prependOnce][this][eventName]
|
||||
duk_push_c_function(ctx, func, DUK_VARARGS); // [prependOnce][this][eventName][func]
|
||||
if (duk_pcall_method(ctx, 2) != 0) { retVal = 0; }
|
||||
duk_pop(ctx); // ...
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
int ILibDuktape_EventEmitter_AddOnce(ILibDuktape_EventEmitter *emitter, char *eventName, void *heapptr)
|
||||
{
|
||||
int retVal = 1;
|
||||
@@ -315,8 +309,9 @@ duk_ret_t ILibDuktape_EventEmitter_on(duk_context *ctx)
|
||||
void *callback = duk_require_heapptr(ctx, 1);
|
||||
ILibDuktape_EventEmitter *data;
|
||||
int once;
|
||||
void *eventList, *node, *dispatcher, **hptr;
|
||||
int i, count, prepend;
|
||||
void *eventList, *node;
|
||||
int prepend;
|
||||
ILibDuktape_EventEmitter_HookHandler hookHandler = NULL;
|
||||
|
||||
duk_push_current_function(ctx);
|
||||
once = Duktape_GetIntPropertyValue(ctx, -1, "once", 0);
|
||||
@@ -333,8 +328,7 @@ duk_ret_t ILibDuktape_EventEmitter_on(duk_context *ctx)
|
||||
{
|
||||
return(ILibDuktape_Error(ctx, "EventEmitter.on(): Event '%s' not found", propName));
|
||||
}
|
||||
dispatcher = ILibHashtable_Get(data->eventTable, ILibDuktape_EventEmitter_SetterFunc, propName, (int)propNameLen);
|
||||
if (dispatcher == NULL) { return(ILibDuktape_Error(ctx, "EventEmitter.on(): Internal error with Event '%s'", propName)); }
|
||||
hookHandler = ILibHashtable_Get(data->eventTable, ILibDuktape_EventEmitter_Hook, propName, (int)propNameLen);
|
||||
|
||||
node = prepend ? ILibLinkedList_AddHead(eventList, callback) : ILibLinkedList_AddTail(eventList, callback);
|
||||
((int*)ILibLinkedList_GetExtendedMemory(node))[0] = once;
|
||||
@@ -344,17 +338,7 @@ duk_ret_t ILibDuktape_EventEmitter_on(duk_context *ctx)
|
||||
duk_push_heapptr(ctx, callback);
|
||||
duk_put_prop_string(ctx, -2, Duktape_GetStashKey(callback)); // Save the callback to the tmp object, so it won't get GC'ed
|
||||
|
||||
duk_push_heapptr(ctx, dispatcher); // [dispatcher]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_HPTR_LIST); // [dispatcher][hptrList]
|
||||
count = (int)duk_get_length(ctx, -1);
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
duk_get_prop_index(ctx, -1, i); // [dispatcher][hptrList][hptr]
|
||||
hptr = (void**)duk_get_pointer(ctx, -1);
|
||||
*hptr = dispatcher;
|
||||
duk_pop(ctx); // [dispatcher][hptrList]
|
||||
}
|
||||
|
||||
if (hookHandler != NULL) { hookHandler(data, propName, callback); }
|
||||
return 0;
|
||||
}
|
||||
ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_GetEmitter_fromThis(duk_context *ctx)
|
||||
@@ -406,36 +390,69 @@ duk_ret_t ILibDuktape_EventEmitter_removeAllListeners(duk_context *ctx)
|
||||
duk_size_t eventNameLen;
|
||||
char *eventName = Duktape_GetBuffer(ctx, 0, &eventNameLen);
|
||||
ILibDuktape_EventEmitter *emitter = ILibDuktape_EventEmitter_GetEmitter_fromThis(ctx);
|
||||
void *eventList, *dispatcher;
|
||||
int count, i;
|
||||
void **hptr;
|
||||
void *eventList;
|
||||
|
||||
if (emitter != NULL)
|
||||
{
|
||||
eventList = ILibHashtable_Get(emitter->eventTable, NULL, eventName, (int)eventNameLen);
|
||||
if (eventList == NULL) { return(ILibDuktape_Error(ctx, "EventEmitter.removeAllListeners(): Event '%s' not found", eventName)); }
|
||||
dispatcher = ILibHashtable_Get(emitter->eventTable, ILibDuktape_EventEmitter_SetterFunc, eventName, (int)eventNameLen);
|
||||
if (dispatcher == NULL) { return(ILibDuktape_Error(ctx, "EventEmitter.removeAllListeners(): Internal error with Event '%s'", eventName)); }
|
||||
|
||||
|
||||
// NULL was passed, we'll need to clear all listeners.
|
||||
// Start by setting the Native Dispatcher to NULL, so it appears there are no subscribers
|
||||
duk_push_heapptr(ctx, dispatcher); // [dispatcher]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_HPTR_LIST); // [dispatcher][hptrList]
|
||||
count = (int)duk_get_length(ctx, -1);
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
duk_get_prop_index(ctx, -1, i); // [dispatcher][hptrList][hptr]
|
||||
hptr = (void**)duk_get_pointer(ctx, -1);
|
||||
*hptr = NULL;
|
||||
duk_pop(ctx); // [dispatcher][hptrList]
|
||||
}
|
||||
|
||||
ILibLinkedList_Clear(eventList);
|
||||
emitter->totalListeners[0] = 0;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
void ILibDuktape_EventEmitter_EmbeddedFinalizer2(ILibHashtable sender, void *Key1, char* Key2, int Key2Len, void *Data, void *user)
|
||||
{
|
||||
if (Key1 == NULL)
|
||||
{
|
||||
char *name = (char*)ILibMemory_AllocateA(Key2Len + 1);
|
||||
name[Key2Len] = 0;
|
||||
memcpy_s(name, Key2Len + 1, Key2, Key2Len);
|
||||
printf("%s ", name);
|
||||
}
|
||||
}
|
||||
duk_ret_t ILibDuktape_EventEmitter_EmbeddedFinalizer(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_EventEmitter_SetupEmit(ctx, duk_get_heapptr(ctx, 0), "~"); // [emit][this][~]
|
||||
duk_dup(ctx, 0); // [emit][this][~][self]
|
||||
if (g_displayFinalizerMessages)
|
||||
{
|
||||
printf("+-+- Finalizer Event for: %s [%p] -+-+\n", Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "UNKNOWN"), duk_get_heapptr(ctx, -1));
|
||||
if (strcmp(Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "UNKNOWN"), "UNKNOWN") == 0)
|
||||
{
|
||||
ILibDuktape_EventEmitter *emitter = ILibDuktape_EventEmitter_GetEmitter(ctx, -1);
|
||||
if (emitter != NULL)
|
||||
{
|
||||
printf("UNKNOWN: Listeners=%d\n", ILibDuktape_EventEmitter_HasListeners(emitter, "~"));
|
||||
|
||||
duk_enum(ctx, -1, DUK_ENUM_OWN_PROPERTIES_ONLY); // [enumerator]
|
||||
while (duk_next(ctx, -1, 1))
|
||||
{
|
||||
printf("Key: %s, Val: %s\n", duk_get_string(ctx, -2), duk_get_string(ctx, -1));// [enumerator][key][val]
|
||||
duk_pop_2(ctx); // [enumerator]
|
||||
}
|
||||
duk_pop(ctx); // ...
|
||||
printf("Event Names: ");
|
||||
if (emitter->eventTable != NULL) { ILibHashtable_Enumerate(emitter->eventTable, ILibDuktape_EventEmitter_EmbeddedFinalizer2, NULL); }
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (duk_pcall_method(ctx, 2) != 0)
|
||||
{
|
||||
ILibDuktape_Process_UncaughtExceptionEx(ctx, "Error in Finalizer: [Invalid C function means you forgot to return 0] ");
|
||||
}
|
||||
|
||||
ILibDuktape_EventEmitter *data = ILibDuktape_EventEmitter_GetEmitter(ctx, 0);
|
||||
if (data == NULL) { return(ILibDuktape_Error(ctx, "Internal Error")); } // This is deadcode, will never occur, but is here because Klockwork thinks this could happen
|
||||
|
||||
// We need to clear the Native Dispatcher, while destroying the Hashtable
|
||||
ILibHashtable_DestroyEx(data->eventTable, ILibDuktape_EventEmitter_FinalizerEx, data);
|
||||
memset(data, 0, sizeof(ILibDuktape_EventEmitter));
|
||||
return(0);
|
||||
}
|
||||
ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_EventEmitter *retVal;
|
||||
@@ -456,10 +473,8 @@ ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx)
|
||||
retVal->tmpObject = duk_get_heapptr(ctx, -2);
|
||||
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_Data); // [emitterTmp]
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_EventEmitter_Finalizer);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_TempObject); // [...parent...]
|
||||
|
||||
|
||||
retVal->ctx = ctx;
|
||||
retVal->object = duk_get_heapptr(ctx, -1);
|
||||
retVal->eventTable = ILibHashtable_Create();
|
||||
@@ -489,6 +504,10 @@ ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx)
|
||||
}
|
||||
duk_pop(ctx);
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEventEx(retVal, "~");
|
||||
duk_push_c_function(ctx, ILibDuktape_EventEmitter_EmbeddedFinalizer, 1);
|
||||
duk_set_finalizer(ctx, -2);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@@ -505,15 +524,10 @@ duk_ret_t ILibDuktape_EventEmitter_SetEvent(duk_context *ctx)
|
||||
duk_size_t propNameLen;
|
||||
ILibDuktape_EventEmitter *data;
|
||||
ILibLinkedList eventList = NULL;
|
||||
void **hptr;
|
||||
void *dispatcher;
|
||||
int i, count;
|
||||
|
||||
duk_push_current_function(ctx); // [func]
|
||||
duk_get_prop_string(ctx, -1, "name"); // [func][name]
|
||||
duk_get_prop_string(ctx, -1, "eventName"); // [func][name]
|
||||
propName = (char*)duk_get_lstring(ctx, -1, &propNameLen);
|
||||
duk_get_prop_string(ctx, -2, ILibDuktape_EventEmitter_DispatcherFunc); // [func][name][dispatcher]
|
||||
dispatcher = duk_get_heapptr(ctx, -1);
|
||||
|
||||
duk_push_this(ctx); // [obj]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_TempObject); // [this][tmp]
|
||||
@@ -526,142 +540,20 @@ duk_ret_t ILibDuktape_EventEmitter_SetEvent(duk_context *ctx)
|
||||
if (duk_is_null_or_undefined(ctx, 0))
|
||||
{
|
||||
// NULL was passed, we'll need to clear all listeners.
|
||||
// Start by setting the Native Dispatcher to NULL, so it appears there are no subscribers
|
||||
duk_push_heapptr(ctx, dispatcher); // [dispatcher]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_HPTR_LIST); // [dispatcher][hptrList]
|
||||
count = (int)duk_get_length(ctx, -1);
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
duk_get_prop_index(ctx, -1, i); // [dispatcher][hptrList][hptr]
|
||||
hptr = (void**)duk_get_pointer(ctx, -1);
|
||||
*hptr = NULL;
|
||||
duk_pop(ctx); // [dispatcher][hptrList]
|
||||
}
|
||||
|
||||
ILibLinkedList_Clear(eventList);
|
||||
duk_push_this(ctx); // [obj]
|
||||
duk_get_prop_string(ctx, -1, "removeAllListeners"); // [obj][removeAll]
|
||||
duk_swap_top(ctx, -2); // [removeAll][this]
|
||||
duk_push_string(ctx, propName); // [removeAll][this][name]
|
||||
duk_call_method(ctx, 1); duk_pop(ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
void *callback = duk_require_heapptr(ctx, 0);
|
||||
ILibDuktape_EventEmitter_HookHandler hookHandler = ILibHashtable_Get(data->eventTable, ILibDuktape_EventEmitter_Hook, propName, (int)propNameLen);
|
||||
|
||||
ILibLinkedList_AddTail(eventList, callback);
|
||||
duk_push_heapptr(ctx, data->tmpObject);
|
||||
duk_push_heapptr(ctx, callback);
|
||||
duk_put_prop_string(ctx, -2, Duktape_GetStashKey(callback)); // Save callback to tmpObject so it won't get GC'ed
|
||||
|
||||
duk_push_heapptr(ctx, dispatcher); // [dispatcher]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_HPTR_LIST); // [dispatcher][hptrList]
|
||||
count = (int)duk_get_length(ctx, -1);
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
duk_get_prop_index(ctx, -1, i); // [dispatcher][hptrList][hptr]
|
||||
hptr = (void**)duk_get_pointer(ctx, -1);
|
||||
*hptr = dispatcher; // Set this, so from Native, it looks like there is a subscriber.
|
||||
duk_pop(ctx); // [dispatcher][hptrList]
|
||||
}
|
||||
|
||||
if (hookHandler != NULL)
|
||||
{
|
||||
hookHandler(data, propName, callback);
|
||||
}
|
||||
ILibDuktape_EventEmitter_AddOn(data, propName, duk_get_heapptr(ctx, 0));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
duk_ret_t ILibDuktape_EventEmitter_Dispatcher(duk_context *ctx)
|
||||
{
|
||||
int nargs = duk_get_top(ctx);
|
||||
void *self;
|
||||
int i;
|
||||
char *name;
|
||||
|
||||
duk_push_current_function(ctx); // [func]
|
||||
duk_get_prop_string(ctx, -1, "name"); // [func][name]
|
||||
name = (char*)duk_get_string(ctx, -1);
|
||||
duk_get_prop_string(ctx, -2, "this"); // [func][name][this]
|
||||
self = duk_get_heapptr(ctx, -1);
|
||||
duk_get_prop_string(ctx, -1, "emit"); // [func][name][this][emitter]
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
duk_push_heapptr(ctx, self); // [emitter][this]
|
||||
duk_push_string(ctx, name); // [emitter][this][name]
|
||||
for (i = 0; i < nargs; ++i)
|
||||
{
|
||||
duk_dup(ctx, i); // [emitter][this][name][...args...]
|
||||
}
|
||||
duk_call_method(ctx, nargs + 1); // Exception will bubble up.
|
||||
|
||||
return 0;
|
||||
}
|
||||
duk_ret_t ILibDuktape_EventEmitter_NativeDispatch(duk_context *ctx)
|
||||
{
|
||||
int nargs = duk_get_top(ctx);
|
||||
char *name;
|
||||
ILibDuktape_EventEmitter_Handler handler;
|
||||
void *args;
|
||||
int i = 0;
|
||||
|
||||
duk_push_current_function(ctx); // [func]
|
||||
duk_get_prop_string(ctx, -1, "name"); // [func][name]
|
||||
name = (char*)duk_get_string(ctx, -1);
|
||||
duk_get_prop_string(ctx, -2, "handler"); // [func][name][handler]
|
||||
handler = (ILibDuktape_EventEmitter_Handler)duk_get_pointer(ctx, -1);
|
||||
|
||||
duk_push_array(ctx); // [func][name][handler][args]
|
||||
args = duk_get_heapptr(ctx, -1);
|
||||
|
||||
for (i = 0; i < nargs; ++i)
|
||||
{
|
||||
duk_dup(ctx, i); // [func][name][handler][args][...arg...]
|
||||
duk_put_prop_index(ctx, -2, i); // [func][name][handler][args]
|
||||
}
|
||||
|
||||
duk_push_this(ctx);
|
||||
handler(ctx, duk_get_heapptr(ctx, -1), name, args);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int ILibDuktape_EventEmitter_AddSink(ILibDuktape_EventEmitter *emitter, char *eventName, ILibDuktape_EventEmitter_Handler handler)
|
||||
{
|
||||
ILibLinkedList eventList;
|
||||
void *func;
|
||||
|
||||
duk_push_heapptr(emitter->ctx, emitter->tmpObject); // [tmp]
|
||||
duk_push_c_function(emitter->ctx, ILibDuktape_EventEmitter_NativeDispatch, DUK_VARARGS); // [tmp][dispatch]
|
||||
duk_push_string(emitter->ctx, eventName); // [tmp][dispatch][name]
|
||||
duk_put_prop_string(emitter->ctx, -2, "name"); // [tmp][dispatch]
|
||||
duk_push_pointer(emitter->ctx, handler); // [tmp][dispatch][nativePtr]
|
||||
duk_put_prop_string(emitter->ctx, -2, "handler"); // [tmp][dispatch]
|
||||
func = duk_get_heapptr(emitter->ctx, -1);
|
||||
eventList = ILibHashtable_Get(emitter->eventTable, NULL, eventName, (int)strnlen_s(eventName, ILibDuktape_EventEmitter_MaxEventNameLen));
|
||||
if (eventList == NULL) { return 1; }
|
||||
|
||||
((int*)ILibLinkedList_GetExtendedMemory(ILibLinkedList_AddTail(eventList, func)))[0] = 2;
|
||||
emitter->totalListeners[0]++;
|
||||
|
||||
duk_put_prop_string(emitter->ctx, -2, Duktape_GetStashKey(func)); // [tmp]
|
||||
duk_pop(emitter->ctx); // ...
|
||||
|
||||
return 0;
|
||||
}
|
||||
void ILibDuktape_EventEmitter_RemoveAllEx(ILibHashtable sender, void *Key1, char* Key2, int Key2Len, void *Data, void *user)
|
||||
{
|
||||
ILibDuktape_EventEmitter *data = (ILibDuktape_EventEmitter*)user;
|
||||
if (Key1 == ILibDuktape_EventEmitter_SetterFunc)
|
||||
{
|
||||
// If this is not NULL, this is the JavaScript Setter Func
|
||||
memcpy_s(ILibScratchPad, sizeof(ILibScratchPad), Key2, Key2Len);
|
||||
ILibScratchPad[Key2Len] = 0;
|
||||
duk_push_heapptr(data->ctx, Data); // [Setter]
|
||||
duk_del_prop_string(data->ctx, -1, ILibDuktape_EventEmitter_HPTR_LIST);
|
||||
duk_push_array(data->ctx); // [Setter][list]
|
||||
duk_put_prop_string(data->ctx, -2, ILibDuktape_EventEmitter_HPTR_LIST); // [Setter]
|
||||
|
||||
duk_pop(data->ctx); // ...
|
||||
}
|
||||
}
|
||||
void ILibDuktape_EventEmitter_RemoveAllListeners(ILibDuktape_EventEmitter *emitter, char *eventName)
|
||||
{
|
||||
duk_push_heapptr(emitter->ctx, emitter->object); // [this]
|
||||
@@ -671,125 +563,45 @@ void ILibDuktape_EventEmitter_RemoveAllListeners(ILibDuktape_EventEmitter *emitt
|
||||
if (duk_pcall_method(emitter->ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(emitter->ctx, "EventEmitter.removeAllListeners(): "); }
|
||||
duk_pop(emitter->ctx); // ...
|
||||
}
|
||||
void ILibDuktape_EventEmitter_RemoveAll(ILibDuktape_EventEmitter *emitter)
|
||||
void ILibDuktape_EventEmitter_GetEventCountSink(ILibHashtable sender, void *Key1, char* Key2, int Key2Len, void *Data, void *user)
|
||||
{
|
||||
if (emitter->eventTable != NULL) { ILibHashtable_Enumerate(emitter->eventTable, ILibDuktape_EventEmitter_RemoveAllEx, emitter); }
|
||||
}
|
||||
void ILibDuktape_EventEmitter_RemoveEventHeapptr(ILibDuktape_EventEmitter *emitter, char *eventName, void **heapptr)
|
||||
{
|
||||
int i, count;
|
||||
void *dispatcher = NULL;
|
||||
int eventNameLen = (int)strnlen_s(eventName, ILibDuktape_EventEmitter_MaxEventNameLen);
|
||||
if ((dispatcher = ILibHashtable_Get(emitter->eventTable, ILibDuktape_EventEmitter_SetterFunc, eventName, eventNameLen)) != NULL)
|
||||
int *count = (int*)user;
|
||||
if (Key1 == NULL)
|
||||
{
|
||||
// This event already exists... Let's hook up the hptr to the existing dispatcher
|
||||
duk_push_heapptr(emitter->ctx, dispatcher); // [dispatcher]
|
||||
if (heapptr != NULL)
|
||||
{
|
||||
duk_get_prop_string(emitter->ctx, -1, ILibDuktape_EventEmitter_HPTR_LIST); // [dispatcher][hptrList]
|
||||
count = (int)duk_get_length(emitter->ctx, -1);
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
duk_get_prop_index(emitter->ctx, -1, i); // [dispatcher][hptrList][hptr]
|
||||
if (duk_get_pointer(emitter->ctx, -1) == heapptr)
|
||||
{
|
||||
duk_pop(emitter->ctx); // [dispatcher][hptrList]
|
||||
duk_del_prop_index(emitter->ctx, -1, i);
|
||||
break;
|
||||
}
|
||||
duk_pop(emitter->ctx); // [dispatcher][hptrList]
|
||||
}
|
||||
duk_pop(emitter->ctx); // [dispatcher]
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_del_prop_string(emitter->ctx, -1, ILibDuktape_EventEmitter_HPTR_LIST); // [dispatcher]
|
||||
duk_push_array(emitter->ctx); // [dispatcher][hptrList]
|
||||
duk_put_prop_string(emitter->ctx, -2, ILibDuktape_EventEmitter_HPTR_LIST); // [dispatcher]
|
||||
}
|
||||
duk_pop(emitter->ctx); // ...
|
||||
++(*count);
|
||||
}
|
||||
}
|
||||
int ILibDuktape_EventEmitter_AddEventHeapptr(ILibDuktape_EventEmitter *emitter, char *eventName, void **heapptr)
|
||||
int ILibDuktape_EventEmitter_GetEventCount(ILibDuktape_EventEmitter *emitter)
|
||||
{
|
||||
ILibLinkedList eventList = NULL;
|
||||
void *dispatcher = NULL;
|
||||
int eventNameLen = (int)strnlen_s(eventName, ILibDuktape_EventEmitter_MaxEventNameLen);
|
||||
if ((dispatcher = ILibHashtable_Get(emitter->eventTable, ILibDuktape_EventEmitter_SetterFunc, eventName, eventNameLen)) != NULL)
|
||||
{
|
||||
// This event already exists... Let's hook up the hptr to the existing dispatcher
|
||||
duk_push_heapptr(emitter->ctx, dispatcher); // [dispatcher]
|
||||
duk_get_prop_string(emitter->ctx, -1, ILibDuktape_EventEmitter_HPTR_LIST); // [dispatcher][hptrList]
|
||||
duk_push_pointer(emitter->ctx, heapptr); // [dispatcher][hptrList][hptr]
|
||||
duk_put_prop_index(emitter->ctx, -2, (duk_uarridx_t)duk_get_length(emitter->ctx, -2)); // [dispatcher][hptrList]
|
||||
duk_pop_2(emitter->ctx); // ...
|
||||
int retVal = 0;
|
||||
if (emitter->eventTable != NULL) { ILibHashtable_Enumerate(emitter->eventTable, ILibDuktape_EventEmitter_GetEventCountSink, &retVal); }
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
// Now lets check if there was already a subscriber
|
||||
if ((eventList = ILibHashtable_Get(emitter->eventTable, NULL, eventName, eventNameLen)) != NULL && ILibLinkedList_GetCount(eventList) > 0)
|
||||
{
|
||||
*heapptr = dispatcher;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
void ILibDuktape_EventEmitter_CreateEventEx(ILibDuktape_EventEmitter *emitter, char *eventName)
|
||||
{
|
||||
void **heapptr;
|
||||
duk_push_heapptr(emitter->ctx, emitter->tmpObject); // [emitter]
|
||||
duk_push_object(emitter->ctx); // [emitter][tmp]
|
||||
duk_push_fixed_buffer(emitter->ctx, sizeof(void*)); // [emitter][tmp][buffer]
|
||||
heapptr = (void**)Duktape_GetBuffer(emitter->ctx, -1, NULL);
|
||||
memset((void*)heapptr, 0, sizeof(void*));
|
||||
duk_put_prop_string(emitter->ctx, -2, "\xFF_buffer"); // [emitter][tmp]
|
||||
duk_put_prop_string(emitter->ctx, -2, Duktape_GetStashKey(duk_get_heapptr(emitter->ctx, -1))); // [emitter]
|
||||
duk_pop(emitter->ctx); // ...
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEvent(emitter, eventName, heapptr);
|
||||
}
|
||||
void ILibDuktape_EventEmitter_CreateEvent(ILibDuktape_EventEmitter *emitter, char *eventName, void **hptr)
|
||||
{
|
||||
void *dispatcher = NULL;
|
||||
int eventNameLen = (int)strnlen_s(eventName, ILibDuktape_EventEmitter_MaxEventNameLen);
|
||||
if ((dispatcher = ILibHashtable_Get(emitter->eventTable, ILibDuktape_EventEmitter_SetterFunc, eventName, eventNameLen)) != NULL)
|
||||
|
||||
if (ILibHashtable_Get(emitter->eventTable, NULL, eventName, eventNameLen) != NULL)
|
||||
{
|
||||
// This event already exists... Let's hook up the hptr to the existing dispatcher
|
||||
duk_push_heapptr(emitter->ctx, dispatcher); // [dispatcher]
|
||||
duk_get_prop_string(emitter->ctx, -1, ILibDuktape_EventEmitter_HPTR_LIST); // [dispatcher][hptrList]
|
||||
duk_push_pointer(emitter->ctx, hptr); // [dispatcher][hptrList][hptr]
|
||||
duk_put_prop_index(emitter->ctx, -2, (duk_uarridx_t)duk_get_length(emitter->ctx, -2)); // [dispatcher][hptrList]
|
||||
duk_pop_2(emitter->ctx); // ...
|
||||
// This event already exists...
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
duk_push_heapptr(emitter->ctx, emitter->object); // [obj]
|
||||
|
||||
// Create the Property Setter
|
||||
duk_push_string(emitter->ctx, eventName); // [obj][prop]
|
||||
duk_push_c_function(emitter->ctx, ILibDuktape_EventEmitter_SetEvent, 1); // [obj][prop][setFunc]
|
||||
duk_push_string(emitter->ctx, eventName); // [obj][prop][setFunc][name]
|
||||
duk_put_prop_string(emitter->ctx, -2, "name"); // [obj][prop][setFunc]
|
||||
|
||||
// Set some custom properties into the setter func, so we can access it later
|
||||
duk_push_c_function(emitter->ctx, ILibDuktape_EventEmitter_Dispatcher, DUK_VARARGS); // [obj][prop][setFunc][dispatcher]
|
||||
dispatcher = duk_get_heapptr(emitter->ctx, -1);
|
||||
duk_push_heapptr(emitter->ctx, emitter->object); // [obj][prop][setFunc][dispatcher][this]
|
||||
duk_put_prop_string(emitter->ctx, -2, "this"); // [obj][prop][setFunc][dispatcher]
|
||||
duk_push_string(emitter->ctx, eventName); // [obj][prop][setFunc][dispatcher][name]
|
||||
duk_put_prop_string(emitter->ctx, -2, "name"); // [obj][prop][setFunc][dispatcher]
|
||||
duk_push_array(emitter->ctx); // [obj][prop][setFunc][dispatcher][hptrList]
|
||||
duk_push_pointer(emitter->ctx, hptr); // [obj][prop][setFunc][dispatcher][hptrList][hptr]
|
||||
duk_put_prop_index(emitter->ctx, -2, 0); // [obj][prop][setFunc][dispatcher][hptrList]
|
||||
duk_put_prop_string(emitter->ctx, -2, ILibDuktape_EventEmitter_HPTR_LIST); // [obj][prop][setFunc][dispatcher]
|
||||
duk_put_prop_string(emitter->ctx, -2, ILibDuktape_EventEmitter_DispatcherFunc); // [obj][prop][setFunc]
|
||||
duk_put_prop_string(emitter->ctx, -2, "eventName"); // [obj][prop][setFunc]
|
||||
|
||||
duk_def_prop(emitter->ctx, -3, DUK_DEFPROP_FORCE | DUK_DEFPROP_HAVE_SETTER); // [obj]
|
||||
duk_pop(emitter->ctx); // ...
|
||||
|
||||
ILibHashtable_Put(emitter->eventTable, NULL, eventName, eventNameLen, ILibLinkedList_CreateEx(sizeof(int)));
|
||||
ILibHashtable_Put(emitter->eventTable, ILibDuktape_EventEmitter_SetterFunc, eventName, eventNameLen, dispatcher);
|
||||
}
|
||||
|
||||
void *ILibDuktape_EventEmitter_GetDispatcher(ILibDuktape_EventEmitter *emitter, char *eventName)
|
||||
{
|
||||
return ILibHashtable_Get(emitter->eventTable, ILibDuktape_EventEmitter_SetterFunc, eventName, (int)strnlen_s(eventName, ILibDuktape_EventEmitter_MaxEventNameLen));
|
||||
@@ -798,16 +610,13 @@ duk_ret_t ILibDuktape_EventEmitter_Inherits_createEvent(duk_context *ctx)
|
||||
{
|
||||
char *name = (char*)duk_require_string(ctx, 0);
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
void **hptr;
|
||||
|
||||
duk_push_this(ctx); // [emitterUtils]
|
||||
duk_get_prop_string(ctx, -1, "emitter"); // [emitterUtils][ptr]
|
||||
emitter = (ILibDuktape_EventEmitter*)duk_get_pointer(ctx, -1);
|
||||
duk_pop(ctx); // [emitterUtils]
|
||||
duk_push_fixed_buffer(ctx, sizeof(void*)); // [emitterUtils][buffer]
|
||||
hptr = (void**)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_put_prop_string(ctx, -2, name); // [emitterUtils]
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEvent(emitter, name, hptr);
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, name);
|
||||
return 0;
|
||||
}
|
||||
duk_ret_t ILibDuktape_EventEmitter_Inherits_addMethod(duk_context *ctx)
|
||||
@@ -878,8 +687,22 @@ duk_ret_t ILibDuktape_EventEmitter_ForwardEvent_Sink(duk_context *ctx)
|
||||
if (duk_pcall_method(ctx, 1 + nargs) != 0) { return(ILibDuktape_Error(ctx, "EventEmitter.ForwardEvent() [%s]: %s", name, duk_safe_to_string(ctx, -1))); }
|
||||
return(0);
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_EventEmitter_ForwardEvent_Finalizer(duk_context *ctx)
|
||||
{
|
||||
duk_push_current_function(ctx); // [func]
|
||||
duk_get_prop_string(ctx, -1, "fptr"); // [func][fptr]
|
||||
duk_get_prop_string(ctx, -1, "targetObject"); // [func][fptr][target]
|
||||
duk_del_prop_string(ctx, -2, "targetObject");
|
||||
if (g_displayFinalizerMessages) { printf("EventEmitter.Forwarder[%s]: Deleted reference to [%s] RC=%d\n", Duktape_GetStringPropertyValue(ctx, -3, "targetName", "UNKNOWN"), Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "UNKNOWN"), ILibDuktape_GetReferenceCount(ctx, -1) - 1); }
|
||||
duk_pop_n(ctx, 3);
|
||||
|
||||
if (g_displayFinalizerMessages) { duk_eval_string(ctx, "_debugGC();"); duk_pop(ctx); }
|
||||
return(0);
|
||||
}
|
||||
void ILibDuktape_EventEmitter_ForwardEvent(duk_context *ctx, duk_idx_t eventSourceIndex, char *sourceEventName, duk_idx_t eventTargetIndex, char *targetEventName)
|
||||
{
|
||||
void *fptr;
|
||||
void *target;
|
||||
duk_dup(ctx, eventTargetIndex); // [targetObject]
|
||||
target = duk_get_heapptr(ctx, -1);
|
||||
@@ -889,12 +712,26 @@ void ILibDuktape_EventEmitter_ForwardEvent(duk_context *ctx, duk_idx_t eventSour
|
||||
duk_swap_top(ctx, -2); // [on][this]
|
||||
duk_push_string(ctx, sourceEventName); // [on][this][name]
|
||||
duk_push_c_function(ctx, ILibDuktape_EventEmitter_ForwardEvent_Sink, DUK_VARARGS); // [on][this][name][sink]
|
||||
fptr = duk_get_heapptr(ctx, -1);
|
||||
duk_push_heapptr(ctx, target); // [on][this][name][sink][targetObject]
|
||||
duk_put_prop_string(ctx, -2, "targetObject"); // [on][this][name][sink]
|
||||
duk_push_string(ctx, targetEventName); // [on][this][name][sink][targetName]
|
||||
duk_put_prop_string(ctx, -2, "targetName"); // [on][this][name][sink]
|
||||
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "EventEmitter_ForwardEvent(): "); }
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
duk_dup(ctx, eventSourceIndex); // [sourceObject]
|
||||
duk_get_prop_string(ctx, -1, "prependOnceListener"); // [sourceObject][prependOnce]
|
||||
duk_swap_top(ctx, -2); // [prependOnce][this]
|
||||
duk_push_string(ctx, "~"); // [prependOnce][this]['~']
|
||||
duk_push_c_function(ctx, ILibDuktape_EventEmitter_ForwardEvent_Finalizer, DUK_VARARGS); // [prependOnce][this]['~'][func]
|
||||
duk_push_heapptr(ctx, fptr); // [prependOnce][this]['~'][func][fptr]
|
||||
duk_put_prop_string(ctx, -2, "fptr"); // [prependOnce][this]['~'][func]
|
||||
duk_push_string(ctx, targetEventName); // [prependOnce][this]['~'][func][name]
|
||||
duk_put_prop_string(ctx, -2, "targetName"); // [prependOnce][this]['~'][func]
|
||||
|
||||
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "EventEmitter_ForwardEvent_SetFinalizer(): "); }
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
int ILibDuktape_EventEmitter_AddOnEx(duk_context *ctx, duk_idx_t idx, char *eventName, duk_c_function func)
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
471
microscript/duk_module_duktape.c
Normal file
471
microscript/duk_module_duktape.c
Normal file
@@ -0,0 +1,471 @@
|
||||
/*
|
||||
* Duktape 1.x compatible module loading framework
|
||||
*/
|
||||
|
||||
#include "duktape.h"
|
||||
#include "duk_module_duktape.h"
|
||||
|
||||
/* (v)snprintf() is missing before MSVC 2015. Note that _(v)snprintf() does
|
||||
* NOT NUL terminate on truncation, but that's OK here.
|
||||
* http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010
|
||||
*/
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1900)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
#if 0 /* Enable manually */
|
||||
#define DUK__ASSERT(x) do { \
|
||||
if (!(x)) { \
|
||||
fprintf(stderr, "ASSERTION FAILED at %s:%d: " #x "\n", __FILE__, __LINE__); \
|
||||
fflush(stderr); \
|
||||
} \
|
||||
} while (0)
|
||||
#define DUK__ASSERT_TOP(ctx,val) do { \
|
||||
DUK__ASSERT(duk_get_top((ctx)) == (val)); \
|
||||
} while (0)
|
||||
#else
|
||||
#define DUK__ASSERT(x) do { (void) (x); } while (0)
|
||||
#define DUK__ASSERT_TOP(ctx,val) do { (void) ctx; (void) (val); } while (0)
|
||||
#endif
|
||||
|
||||
static void duk__resolve_module_id(duk_context *ctx, const char *req_id, const char *mod_id) {
|
||||
duk_uint8_t buf[DUK_COMMONJS_MODULE_ID_LIMIT];
|
||||
duk_uint8_t *p;
|
||||
duk_uint8_t *q;
|
||||
duk_uint8_t *q_last; /* last component */
|
||||
duk_int_t int_rc;
|
||||
|
||||
DUK__ASSERT(req_id != NULL);
|
||||
/* mod_id may be NULL */
|
||||
|
||||
/*
|
||||
* A few notes on the algorithm:
|
||||
*
|
||||
* - Terms are not allowed to begin with a period unless the term
|
||||
* is either '.' or '..'. This simplifies implementation (and
|
||||
* is within CommonJS modules specification).
|
||||
*
|
||||
* - There are few output bound checks here. This is on purpose:
|
||||
* the resolution input is length checked and the output is never
|
||||
* longer than the input. The resolved output is written directly
|
||||
* over the input because it's never longer than the input at any
|
||||
* point in the algorithm.
|
||||
*
|
||||
* - Non-ASCII characters are processed as individual bytes and
|
||||
* need no special treatment. However, U+0000 terminates the
|
||||
* algorithm; this is not an issue because U+0000 is not a
|
||||
* desirable term character anyway.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Set up the resolution input which is the requested ID directly
|
||||
* (if absolute or no current module path) or with current module
|
||||
* ID prepended (if relative and current module path exists).
|
||||
*
|
||||
* Suppose current module is 'foo/bar' and relative path is './quux'.
|
||||
* The 'bar' component must be replaced so the initial input here is
|
||||
* 'foo/bar/.././quux'.
|
||||
*/
|
||||
|
||||
if (mod_id != NULL && req_id[0] == '.') {
|
||||
int_rc = snprintf((char *) buf, sizeof(buf), "%s/../%s", mod_id, req_id);
|
||||
} else {
|
||||
int_rc = snprintf((char *) buf, sizeof(buf), "%s", req_id);
|
||||
}
|
||||
if (int_rc >= (duk_int_t) sizeof(buf) || int_rc < 0) {
|
||||
/* Potentially truncated, NUL not guaranteed in any case.
|
||||
* The (int_rc < 0) case should not occur in practice.
|
||||
*/
|
||||
goto resolve_error;
|
||||
}
|
||||
DUK__ASSERT(strlen((const char *) buf) < sizeof(buf)); /* at most sizeof(buf) - 1 */
|
||||
|
||||
/*
|
||||
* Resolution loop. At the top of the loop we're expecting a valid
|
||||
* term: '.', '..', or a non-empty identifier not starting with a period.
|
||||
*/
|
||||
|
||||
p = buf;
|
||||
q = buf;
|
||||
for (;;) {
|
||||
duk_uint_fast8_t c;
|
||||
|
||||
/* Here 'p' always points to the start of a term.
|
||||
*
|
||||
* We can also unconditionally reset q_last here: if this is
|
||||
* the last (non-empty) term q_last will have the right value
|
||||
* on loop exit.
|
||||
*/
|
||||
|
||||
DUK__ASSERT(p >= q); /* output is never longer than input during resolution */
|
||||
|
||||
q_last = q;
|
||||
|
||||
c = *p++;
|
||||
if (c == 0) {
|
||||
goto resolve_error;
|
||||
} else if (c == '.') {
|
||||
c = *p++;
|
||||
if (c == '/') {
|
||||
/* Term was '.' and is eaten entirely (including dup slashes). */
|
||||
goto eat_dup_slashes;
|
||||
}
|
||||
if (c == '.' && *p == '/') {
|
||||
/* Term was '..', backtrack resolved name by one component.
|
||||
* q[-1] = previous slash (or beyond start of buffer)
|
||||
* q[-2] = last char of previous component (or beyond start of buffer)
|
||||
*/
|
||||
p++; /* eat (first) input slash */
|
||||
DUK__ASSERT(q >= buf);
|
||||
if (q == buf) {
|
||||
goto resolve_error;
|
||||
}
|
||||
DUK__ASSERT(*(q - 1) == '/');
|
||||
q--; /* Backtrack to last output slash (dups already eliminated). */
|
||||
for (;;) {
|
||||
/* Backtrack to previous slash or start of buffer. */
|
||||
DUK__ASSERT(q >= buf);
|
||||
if (q == buf) {
|
||||
break;
|
||||
}
|
||||
if (*(q - 1) == '/') {
|
||||
break;
|
||||
}
|
||||
q--;
|
||||
}
|
||||
goto eat_dup_slashes;
|
||||
}
|
||||
goto resolve_error;
|
||||
} else if (c == '/') {
|
||||
/* e.g. require('/foo'), empty terms not allowed */
|
||||
goto resolve_error;
|
||||
} else {
|
||||
for (;;) {
|
||||
/* Copy term name until end or '/'. */
|
||||
*q++ = c;
|
||||
c = *p++;
|
||||
if (c == 0) {
|
||||
/* This was the last term, and q_last was
|
||||
* updated to match this term at loop top.
|
||||
*/
|
||||
goto loop_done;
|
||||
} else if (c == '/') {
|
||||
*q++ = '/';
|
||||
break;
|
||||
} else {
|
||||
/* write on next loop */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eat_dup_slashes:
|
||||
for (;;) {
|
||||
/* eat dup slashes */
|
||||
c = *p;
|
||||
if (c != '/') {
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
loop_done:
|
||||
/* Output #1: resolved absolute name. */
|
||||
DUK__ASSERT(q >= buf);
|
||||
duk_push_lstring(ctx, (const char *) buf, (size_t) (q - buf));
|
||||
|
||||
/* Output #2: last component name. */
|
||||
DUK__ASSERT(q >= q_last);
|
||||
DUK__ASSERT(q_last >= buf);
|
||||
duk_push_lstring(ctx, (const char *) q_last, (size_t) (q - q_last));
|
||||
return;
|
||||
|
||||
resolve_error:
|
||||
(void) duk_type_error(ctx, "cannot resolve module id: %s", (const char *) req_id);
|
||||
}
|
||||
|
||||
/* Stack indices for better readability. */
|
||||
#define DUK__IDX_REQUESTED_ID 0 /* module id requested */
|
||||
#define DUK__IDX_REQUIRE 1 /* current require() function */
|
||||
#define DUK__IDX_REQUIRE_ID 2 /* the base ID of the current require() function, resolution base */
|
||||
#define DUK__IDX_RESOLVED_ID 3 /* resolved, normalized absolute module ID */
|
||||
#define DUK__IDX_LASTCOMP 4 /* last component name in resolved path */
|
||||
#define DUK__IDX_DUKTAPE 5 /* Duktape object */
|
||||
#define DUK__IDX_MODLOADED 6 /* Duktape.modLoaded[] module cache */
|
||||
#define DUK__IDX_UNDEFINED 7 /* 'undefined', artifact of lookup */
|
||||
#define DUK__IDX_FRESH_REQUIRE 8 /* new require() function for module, updated resolution base */
|
||||
#define DUK__IDX_EXPORTS 9 /* default exports table */
|
||||
#define DUK__IDX_MODULE 10 /* module object containing module.exports, etc */
|
||||
|
||||
static duk_ret_t duk__require(duk_context *ctx) {
|
||||
const char *str_req_id; /* requested identifier */
|
||||
const char *str_mod_id; /* require.id of current module */
|
||||
duk_int_t pcall_rc;
|
||||
|
||||
/* NOTE: we try to minimize code size by avoiding unnecessary pops,
|
||||
* so the stack looks a bit cluttered in this function. DUK__ASSERT_TOP()
|
||||
* assertions are used to ensure stack configuration is correct at each
|
||||
* step.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Resolve module identifier into canonical absolute form.
|
||||
*/
|
||||
|
||||
str_req_id = duk_require_string(ctx, DUK__IDX_REQUESTED_ID);
|
||||
duk_push_current_function(ctx);
|
||||
duk_get_prop_string(ctx, -1, "id");
|
||||
str_mod_id = duk_get_string(ctx, DUK__IDX_REQUIRE_ID); /* ignore non-strings */
|
||||
duk__resolve_module_id(ctx, str_req_id, str_mod_id);
|
||||
str_req_id = NULL;
|
||||
str_mod_id = NULL;
|
||||
|
||||
/* [ requested_id require require.id resolved_id last_comp ] */
|
||||
DUK__ASSERT_TOP(ctx, DUK__IDX_LASTCOMP + 1);
|
||||
|
||||
/*
|
||||
* Cached module check.
|
||||
*
|
||||
* If module has been loaded or its loading has already begun without
|
||||
* finishing, return the same cached value (module.exports). The
|
||||
* value is registered when module load starts so that circular
|
||||
* references can be supported to some extent.
|
||||
*/
|
||||
|
||||
duk_push_global_stash(ctx);
|
||||
duk_get_prop_string(ctx, -1, "\xff" "module:Duktape");
|
||||
duk_remove(ctx, -2); /* Lookup stashed, original 'Duktape' object. */
|
||||
duk_get_prop_string(ctx, DUK__IDX_DUKTAPE, "modLoaded"); /* Duktape.modLoaded */
|
||||
duk_require_type_mask(ctx, DUK__IDX_MODLOADED, DUK_TYPE_MASK_OBJECT);
|
||||
DUK__ASSERT_TOP(ctx, DUK__IDX_MODLOADED + 1);
|
||||
|
||||
duk_dup(ctx, DUK__IDX_RESOLVED_ID);
|
||||
if (duk_get_prop(ctx, DUK__IDX_MODLOADED)) {
|
||||
/* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded Duktape.modLoaded[id] ] */
|
||||
duk_get_prop_string(ctx, -1, "exports"); /* return module.exports */
|
||||
return 1;
|
||||
}
|
||||
DUK__ASSERT_TOP(ctx, DUK__IDX_UNDEFINED + 1);
|
||||
|
||||
/* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded undefined ] */
|
||||
|
||||
/*
|
||||
* Module not loaded (and loading not started previously).
|
||||
*
|
||||
* Create a new require() function with 'id' set to resolved ID
|
||||
* of module being loaded. Also create 'exports' and 'module'
|
||||
* tables but don't register exports to the loaded table yet.
|
||||
* We don't want to do that unless the user module search callbacks
|
||||
* succeeds in finding the module.
|
||||
*/
|
||||
|
||||
/* Fresh require: require.id is left configurable (but not writable)
|
||||
* so that is not easy to accidentally tweak it, but it can still be
|
||||
* done with Object.defineProperty().
|
||||
*
|
||||
* XXX: require.id could also be just made non-configurable, as there
|
||||
* is no practical reason to touch it (at least from Ecmascript code).
|
||||
*/
|
||||
duk_push_c_function(ctx, duk__require, 1 /*nargs*/);
|
||||
duk_push_string(ctx, "name");
|
||||
duk_push_string(ctx, "require");
|
||||
duk_def_prop(ctx, DUK__IDX_FRESH_REQUIRE, DUK_DEFPROP_HAVE_VALUE); /* not writable, not enumerable, not configurable */
|
||||
duk_push_string(ctx, "id");
|
||||
duk_dup(ctx, DUK__IDX_RESOLVED_ID);
|
||||
duk_def_prop(ctx, DUK__IDX_FRESH_REQUIRE, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_SET_CONFIGURABLE); /* a fresh require() with require.id = resolved target module id */
|
||||
|
||||
/* Module table:
|
||||
* - module.exports: initial exports table (may be replaced by user)
|
||||
* - module.id is non-writable and non-configurable, as the CommonJS
|
||||
* spec suggests this if possible
|
||||
* - module.filename: not set, defaults to resolved ID if not explicitly
|
||||
* set by modSearch() (note capitalization, not .fileName, matches Node.js)
|
||||
* - module.name: not set, defaults to last component of resolved ID if
|
||||
* not explicitly set by modSearch()
|
||||
*/
|
||||
duk_push_object(ctx); /* exports */
|
||||
duk_push_object(ctx); /* module */
|
||||
duk_push_string(ctx, "exports");
|
||||
duk_dup(ctx, DUK__IDX_EXPORTS);
|
||||
duk_def_prop(ctx, DUK__IDX_MODULE, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_CONFIGURABLE); /* module.exports = exports */
|
||||
duk_push_string(ctx, "id");
|
||||
duk_dup(ctx, DUK__IDX_RESOLVED_ID); /* resolved id: require(id) must return this same module */
|
||||
duk_def_prop(ctx, DUK__IDX_MODULE, DUK_DEFPROP_HAVE_VALUE); /* module.id = resolved_id; not writable, not enumerable, not configurable */
|
||||
duk_compact(ctx, DUK__IDX_MODULE); /* module table remains registered to modLoaded, minimize its size */
|
||||
DUK__ASSERT_TOP(ctx, DUK__IDX_MODULE + 1);
|
||||
|
||||
/* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded undefined fresh_require exports module ] */
|
||||
|
||||
/* Register the module table early to modLoaded[] so that we can
|
||||
* support circular references even in modSearch(). If an error
|
||||
* is thrown, we'll delete the reference.
|
||||
*/
|
||||
duk_dup(ctx, DUK__IDX_RESOLVED_ID);
|
||||
duk_dup(ctx, DUK__IDX_MODULE);
|
||||
duk_put_prop(ctx, DUK__IDX_MODLOADED); /* Duktape.modLoaded[resolved_id] = module */
|
||||
|
||||
/*
|
||||
* Call user provided module search function and build the wrapped
|
||||
* module source code (if necessary). The module search function
|
||||
* can be used to implement pure Ecmacsript, pure C, and mixed
|
||||
* Ecmascript/C modules.
|
||||
*
|
||||
* The module search function can operate on the exports table directly
|
||||
* (e.g. DLL code can register values to it). It can also return a
|
||||
* string which is interpreted as module source code (if a non-string
|
||||
* is returned the module is assumed to be a pure C one). If a module
|
||||
* cannot be found, an error must be thrown by the user callback.
|
||||
*
|
||||
* Because Duktape.modLoaded[] already contains the module being
|
||||
* loaded, circular references for C modules should also work
|
||||
* (although expected to be quite rare).
|
||||
*/
|
||||
|
||||
duk_push_string(ctx, "(function(require,exports,module){");
|
||||
|
||||
/* Duktape.modSearch(resolved_id, fresh_require, exports, module). */
|
||||
duk_get_prop_string(ctx, DUK__IDX_DUKTAPE, "modSearch"); /* Duktape.modSearch */
|
||||
duk_dup(ctx, DUK__IDX_RESOLVED_ID);
|
||||
duk_dup(ctx, DUK__IDX_FRESH_REQUIRE);
|
||||
duk_dup(ctx, DUK__IDX_EXPORTS);
|
||||
duk_dup(ctx, DUK__IDX_MODULE); /* [ ... Duktape.modSearch resolved_id last_comp fresh_require exports module ] */
|
||||
pcall_rc = duk_pcall(ctx, 4 /*nargs*/); /* -> [ ... source ] */
|
||||
DUK__ASSERT_TOP(ctx, DUK__IDX_MODULE + 3);
|
||||
|
||||
if (pcall_rc != DUK_EXEC_SUCCESS) {
|
||||
/* Delete entry in Duktape.modLoaded[] and rethrow. */
|
||||
goto delete_rethrow;
|
||||
}
|
||||
|
||||
/* If user callback did not return source code, module loading
|
||||
* is finished (user callback initialized exports table directly).
|
||||
*/
|
||||
if (!duk_is_string(ctx, -1)) {
|
||||
/* User callback did not return source code, so module loading
|
||||
* is finished: just update modLoaded with final module.exports
|
||||
* and we're done.
|
||||
*/
|
||||
goto return_exports;
|
||||
}
|
||||
|
||||
/* Finish the wrapped module source. Force module.filename as the
|
||||
* function .fileName so it gets set for functions defined within a
|
||||
* module. This also ensures loggers created within the module get
|
||||
* the module ID (or overridden filename) as their default logger name.
|
||||
* (Note capitalization: .filename matches Node.js while .fileName is
|
||||
* used elsewhere in Duktape.)
|
||||
*/
|
||||
duk_push_string(ctx, "\n})"); /* Newline allows module last line to contain a // comment. */
|
||||
duk_concat(ctx, 3);
|
||||
if (!duk_get_prop_string(ctx, DUK__IDX_MODULE, "filename")) {
|
||||
/* module.filename for .fileName, default to resolved ID if
|
||||
* not present.
|
||||
*/
|
||||
duk_pop(ctx);
|
||||
duk_dup(ctx, DUK__IDX_RESOLVED_ID);
|
||||
}
|
||||
pcall_rc = duk_pcompile(ctx, DUK_COMPILE_EVAL);
|
||||
if (pcall_rc != DUK_EXEC_SUCCESS) {
|
||||
goto delete_rethrow;
|
||||
}
|
||||
pcall_rc = duk_pcall(ctx, 0); /* -> eval'd function wrapper (not called yet) */
|
||||
if (pcall_rc != DUK_EXEC_SUCCESS) {
|
||||
goto delete_rethrow;
|
||||
}
|
||||
|
||||
/* Module has now evaluated to a wrapped module function. Force its
|
||||
* .name to match module.name (defaults to last component of resolved
|
||||
* ID) so that it is shown in stack traces too. Note that we must not
|
||||
* introduce an actual name binding into the function scope (which is
|
||||
* usually the case with a named function) because it would affect the
|
||||
* scope seen by the module and shadow accesses to globals of the same name.
|
||||
* This is now done by compiling the function as anonymous and then forcing
|
||||
* its .name without setting a "has name binding" flag.
|
||||
*/
|
||||
|
||||
duk_push_string(ctx, "name");
|
||||
if (!duk_get_prop_string(ctx, DUK__IDX_MODULE, "name")) {
|
||||
/* module.name for .name, default to last component if
|
||||
* not present.
|
||||
*/
|
||||
duk_pop(ctx);
|
||||
duk_dup(ctx, DUK__IDX_LASTCOMP);
|
||||
}
|
||||
duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_FORCE);
|
||||
|
||||
/*
|
||||
* Call the wrapped module function.
|
||||
*
|
||||
* Use a protected call so that we can update Duktape.modLoaded[resolved_id]
|
||||
* even if the module throws an error.
|
||||
*/
|
||||
|
||||
/* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded undefined fresh_require exports module mod_func ] */
|
||||
DUK__ASSERT_TOP(ctx, DUK__IDX_MODULE + 2);
|
||||
|
||||
duk_dup(ctx, DUK__IDX_EXPORTS); /* exports (this binding) */
|
||||
duk_dup(ctx, DUK__IDX_FRESH_REQUIRE); /* fresh require (argument) */
|
||||
duk_get_prop_string(ctx, DUK__IDX_MODULE, "exports"); /* relookup exports from module.exports in case it was changed by modSearch */
|
||||
duk_dup(ctx, DUK__IDX_MODULE); /* module (argument) */
|
||||
DUK__ASSERT_TOP(ctx, DUK__IDX_MODULE + 6);
|
||||
|
||||
/* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded undefined fresh_require exports module mod_func exports fresh_require exports module ] */
|
||||
|
||||
pcall_rc = duk_pcall_method(ctx, 3 /*nargs*/);
|
||||
if (pcall_rc != DUK_EXEC_SUCCESS) {
|
||||
/* Module loading failed. Node.js will forget the module
|
||||
* registration so that another require() will try to load
|
||||
* the module again. Mimic that behavior.
|
||||
*/
|
||||
goto delete_rethrow;
|
||||
}
|
||||
|
||||
/* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded undefined fresh_require exports module result(ignored) ] */
|
||||
DUK__ASSERT_TOP(ctx, DUK__IDX_MODULE + 2);
|
||||
|
||||
/* fall through */
|
||||
|
||||
return_exports:
|
||||
duk_get_prop_string(ctx, DUK__IDX_MODULE, "exports");
|
||||
duk_compact(ctx, -1); /* compact the exports table */
|
||||
return 1; /* return module.exports */
|
||||
|
||||
delete_rethrow:
|
||||
duk_dup(ctx, DUK__IDX_RESOLVED_ID);
|
||||
duk_del_prop(ctx, DUK__IDX_MODLOADED); /* delete Duktape.modLoaded[resolved_id] */
|
||||
(void) duk_throw(ctx); /* rethrow original error */
|
||||
return 0; /* not reachable */
|
||||
}
|
||||
|
||||
void duk_module_duktape_init(duk_context *ctx) {
|
||||
/* Stash 'Duktape' in case it's modified. */
|
||||
duk_push_global_stash(ctx);
|
||||
duk_get_global_string(ctx, "Duktape");
|
||||
duk_put_prop_string(ctx, -2, "\xff" "module:Duktape");
|
||||
duk_pop(ctx);
|
||||
|
||||
/* Register `require` as a global function. */
|
||||
duk_eval_string(ctx,
|
||||
"(function(req){"
|
||||
"var D=Object.defineProperty;"
|
||||
"D(req,'name',{value:'require'});"
|
||||
"D(this,'require',{value:req,writable:true,configurable:true});"
|
||||
"D(Duktape,'modLoaded',{value:Object.create(null),writable:true,configurable:true});"
|
||||
"})");
|
||||
duk_push_c_function(ctx, duk__require, 1 /*nargs*/);
|
||||
duk_call(ctx, 1);
|
||||
duk_pop(ctx);
|
||||
}
|
||||
|
||||
#undef DUK__ASSERT
|
||||
#undef DUK__ASSERT_TOP
|
||||
#undef DUK__IDX_REQUESTED_ID
|
||||
#undef DUK__IDX_REQUIRE
|
||||
#undef DUK__IDX_REQUIRE_ID
|
||||
#undef DUK__IDX_RESOLVED_ID
|
||||
#undef DUK__IDX_LASTCOMP
|
||||
#undef DUK__IDX_DUKTAPE
|
||||
#undef DUK__IDX_MODLOADED
|
||||
#undef DUK__IDX_UNDEFINED
|
||||
#undef DUK__IDX_FRESH_REQUIRE
|
||||
#undef DUK__IDX_EXPORTS
|
||||
#undef DUK__IDX_MODULE
|
||||
14
microscript/duk_module_duktape.h
Normal file
14
microscript/duk_module_duktape.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#if !defined(DUK_MODULE_DUKTAPE_H_INCLUDED)
|
||||
#define DUK_MODULE_DUKTAPE_H_INCLUDED
|
||||
|
||||
#include "duktape.h"
|
||||
|
||||
/* Maximum length of CommonJS module identifier to resolve. Length includes
|
||||
* both current module ID, requested (possibly relative) module ID, and a
|
||||
* slash in between.
|
||||
*/
|
||||
#define DUK_COMMONJS_MODULE_ID_LIMIT 256
|
||||
|
||||
extern void duk_module_duktape_init(duk_context *ctx);
|
||||
|
||||
#endif /* DUK_MODULE_DUKTAPE_H_INCLUDED */
|
||||
71294
microscript/duktape.c
71294
microscript/duktape.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -145,46 +145,13 @@ void ILibAsyncServerSocket_OnInterruptSink(ILibAsyncSocket_SocketModule socketMo
|
||||
void ILibAsyncServerSocket_PreSelect(void* socketModule, fd_set *readset, fd_set *writeset, fd_set *errorset, int* blocktime)
|
||||
{
|
||||
struct ILibAsyncServerSocketModule *module = (struct ILibAsyncServerSocketModule*)socketModule;
|
||||
int flags,i;
|
||||
int i;
|
||||
|
||||
UNREFERENCED_PARAMETER( writeset );
|
||||
UNREFERENCED_PARAMETER( errorset );
|
||||
UNREFERENCED_PARAMETER( blocktime );
|
||||
|
||||
//
|
||||
// The socket isn't put in listening mode, until the chain is started.
|
||||
// If this variable == 0, that means we need to do that.
|
||||
//
|
||||
if (module->listening == 0)
|
||||
{
|
||||
//
|
||||
// Set the socket to non-block mode, so we can play nice and share the thread
|
||||
//
|
||||
#ifdef _WIN32_WCE
|
||||
flags = 1;
|
||||
ioctlsocket(module->ListenSocket, FIONBIO, &flags);
|
||||
#elif WIN32
|
||||
flags = 1;
|
||||
ioctlsocket(module->ListenSocket, FIONBIO, (u_long *)(&flags));
|
||||
#elif _POSIX
|
||||
flags = fcntl(module->ListenSocket, F_GETFL,0);
|
||||
fcntl(module->ListenSocket, F_SETFL, O_NONBLOCK | flags);
|
||||
#endif
|
||||
|
||||
//
|
||||
// Put the socket in Listen, and add it to the fdset for the Select loop
|
||||
//
|
||||
module->listening = 1;
|
||||
listen(module->ListenSocket, 4);
|
||||
#if defined(WIN32)
|
||||
#pragma warning( push, 3 ) // warning C4127: conditional expression is constant
|
||||
#endif
|
||||
FD_SET(module->ListenSocket, readset);
|
||||
#if defined(WIN32)
|
||||
#pragma warning( pop )
|
||||
#endif
|
||||
}
|
||||
else if (module->ListenSocket != ~0)
|
||||
if (module->ListenSocket != ~0)
|
||||
{
|
||||
// Only put the ListenSocket in the readset, if we are able to handle a new socket
|
||||
for(i = 0; i < module->MaxConnection; ++i)
|
||||
@@ -714,8 +681,28 @@ ILibAsyncServerSocket_ServerModule ILibCreateAsyncServerSocketModuleWithMemoryEx
|
||||
//
|
||||
ILibAsyncSocket_SetReAllocateNotificationCallback(RetVal->AsyncSockets[i], &ILibAsyncServerSocket_OnBufferReAllocated);
|
||||
}
|
||||
ILibAddToChain(Chain, RetVal);
|
||||
|
||||
|
||||
//
|
||||
// Set the socket to non-block mode, so we can play nice and share the thread
|
||||
//
|
||||
int flags = 1;
|
||||
#ifdef _WIN32_WCE
|
||||
ioctlsocket(RetVal->ListenSocket, FIONBIO, &flags);
|
||||
#elif WIN32
|
||||
ioctlsocket(RetVal->ListenSocket, FIONBIO, (u_long *)(&flags));
|
||||
#elif _POSIX
|
||||
flags = fcntl(RetVal->ListenSocket, F_GETFL, 0);
|
||||
fcntl(RetVal->ListenSocket, F_SETFL, O_NONBLOCK | flags);
|
||||
#endif
|
||||
|
||||
RetVal->listening = 1;
|
||||
listen(RetVal->ListenSocket, 4);
|
||||
#if defined(WIN32)
|
||||
#pragma warning( push, 3 ) // warning C4127: conditional expression is constant
|
||||
#endif
|
||||
|
||||
ILibAddToChain(Chain, RetVal);
|
||||
return RetVal;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -176,6 +176,7 @@ typedef struct ILibAsyncSocketModule
|
||||
|
||||
// Added for TLS support
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
int TLS_HandshakeError_Occurred;
|
||||
int SSLConnect;
|
||||
SSL* ssl;
|
||||
SSL_CTX *ssl_ctx;
|
||||
@@ -577,6 +578,7 @@ ILibAsyncSocket_SendStatus ILibAsyncSocket_SendTo_MultiWrite(ILibAsyncSocket_Soc
|
||||
module->TotalBytesSent += bytesSent;
|
||||
module->PendingBytesToSend = (unsigned int)(module->writeBioBuffer->length);
|
||||
}
|
||||
retVal = ILibAsyncSocket_NOT_ALL_DATA_SENT_YET;
|
||||
}
|
||||
else if (bytesSent == module->writeBioBuffer->length)
|
||||
{
|
||||
@@ -607,6 +609,7 @@ ILibAsyncSocket_SendStatus ILibAsyncSocket_SendTo_MultiWrite(ILibAsyncSocket_Soc
|
||||
}
|
||||
|
||||
if (lockOverride == 0) { sem_post(&(module->SendLock)); }
|
||||
if (retVal != ILibAsyncSocket_ALL_DATA_SENT && !ILibIsRunningOnChainThread(module->Transport.ChainLink.ParentChain)) ILibForceUnBlockChain(module->Transport.ChainLink.ParentChain);
|
||||
return retVal;
|
||||
}
|
||||
#endif
|
||||
@@ -719,7 +722,7 @@ ILibAsyncSocket_SendStatus ILibAsyncSocket_SendTo_MultiWrite(ILibAsyncSocket_Soc
|
||||
|
||||
if (lockOverride == 0) { sem_post(&(module->SendLock)); }
|
||||
|
||||
if (retVal != ILibAsyncSocket_ALL_DATA_SENT) ILibForceUnBlockChain(module->Transport.ChainLink.ParentChain);
|
||||
if (retVal != ILibAsyncSocket_ALL_DATA_SENT && !ILibIsRunningOnChainThread(module->Transport.ChainLink.ParentChain)) ILibForceUnBlockChain(module->Transport.ChainLink.ParentChain);
|
||||
return (retVal);
|
||||
}
|
||||
|
||||
@@ -1034,7 +1037,7 @@ void ILibProcessAsyncSocket(struct ILibAsyncSocketModule *Reader, int pendingRea
|
||||
int bytesReceived = 0;
|
||||
int len;
|
||||
char *temp;
|
||||
|
||||
|
||||
if (Reader->PAUSE > 0)
|
||||
{
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(Reader->Transport.ChainLink.ParentChain), ILibRemoteLogging_Modules_Microstack_AsyncSocket, ILibRemoteLogging_Flags_VerbosityLevel_2, "AsyncSocket[%p] is PAUSED", (void*)Reader);
|
||||
@@ -1105,7 +1108,15 @@ void ILibProcessAsyncSocket(struct ILibAsyncSocketModule *Reader, int pendingRea
|
||||
default:
|
||||
// SSL_WANT_READ most likely
|
||||
sslerror = SSL_get_error(Reader->ssl, sslerror);
|
||||
ILibAsyncSocket_ProcessEncryptedBuffer(Reader);
|
||||
if (sslerror == SSL_ERROR_SSL)
|
||||
{
|
||||
Reader->TLS_HandshakeError_Occurred = 1;
|
||||
bytesReceived = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ILibAsyncSocket_ProcessEncryptedBuffer(Reader);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2288,6 +2299,10 @@ void ILibAsyncSocket_UpdateCallbacks(ILibAsyncSocket_SocketModule module, ILibAs
|
||||
((ILibAsyncSocketModule*)module)->OnSendOK = OnSendOK;
|
||||
}
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
int ILibAsyncSocket_TLS_WasHandshakeError(ILibAsyncSocket_SocketModule socketModule)
|
||||
{
|
||||
return(((struct ILibAsyncSocketModule*)socketModule)->TLS_HandshakeError_Occurred || ((struct ILibAsyncSocketModule*)socketModule)->TLSHandshakeCompleted == 0 ? 1 : 0);
|
||||
}
|
||||
//! Gets the Peer's TLS Certificate
|
||||
/*!
|
||||
\ingroup TLSGroup
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -239,6 +239,7 @@ void ILibAsyncSocket_SetTimeoutEx(ILibAsyncSocket_SocketModule module, int timeo
|
||||
#define ILibAsyncSocket_SetTimeout(module, timeoutSeconds, timeoutHandler) ILibAsyncSocket_SetTimeoutEx(module, timeoutSeconds*1000, timeoutHandler)
|
||||
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
int ILibAsyncSocket_TLS_WasHandshakeError(ILibAsyncSocket_SocketModule socketModule);
|
||||
X509 *ILibAsyncSocket_SslGetCert(ILibAsyncSocket_SocketModule socketModule);
|
||||
STACK_OF(X509) *ILibAsyncSocket_SslGetCerts(ILibAsyncSocket_SocketModule socketModule);
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined(WIN32) && !defined(_WIN32_WCE)
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#include <crtdbg.h>
|
||||
@@ -481,6 +497,56 @@ int __fastcall util_from_cer(char* data, int datalen, struct util_cert* cert)
|
||||
return ((cert->x509) == NULL);
|
||||
}
|
||||
|
||||
int __fastcall util_from_pkcs7b_string(char *data, int datalen, char *out, int outLen)
|
||||
{
|
||||
BIO* bio = BIO_new_mem_buf((void*)data, datalen);
|
||||
BIO* bio_out = BIO_new(BIO_s_mem());
|
||||
BUF_MEM *outBuffer;
|
||||
int retVal = 0, i = 0;
|
||||
PKCS7 *p7 = NULL;
|
||||
STACK_OF(X509) *certs = NULL;
|
||||
STACK_OF(X509_ALGOR) *md_algs = NULL;
|
||||
STACK_OF(PKCS7_SIGNER_INFO) *sinfo = NULL;
|
||||
|
||||
BIO_get_mem_ptr(bio_out, &outBuffer);
|
||||
p7 = d2i_PKCS7_bio(bio, NULL);
|
||||
|
||||
md_algs = p7->d.sign->md_algs;
|
||||
sinfo = p7->d.sign->signer_info;
|
||||
|
||||
for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfo); i++)
|
||||
{
|
||||
printf("Hash Algorithm: %s\n", OBJ_nid2ln(OBJ_obj2nid(sk_PKCS7_SIGNER_INFO_value(sinfo, i)->digest_alg->algorithm)));
|
||||
printf("Enc Algorithm: %s\n", OBJ_nid2ln(OBJ_obj2nid(sk_PKCS7_SIGNER_INFO_value(sinfo, i)->digest_enc_alg->algorithm)));
|
||||
}
|
||||
|
||||
for (i = 0; i < sk_X509_ALGOR_num(md_algs); i++)
|
||||
{
|
||||
printf("Algorithm: %s\n", OBJ_nid2ln(OBJ_obj2nid(sk_X509_ALGOR_value(md_algs, i)->algorithm)));
|
||||
}
|
||||
|
||||
certs = p7->d.sign->cert;
|
||||
for (i = 0; certs && i < sk_X509_num(certs); i++)
|
||||
{
|
||||
PEM_write_bio_X509(bio_out, sk_X509_value(certs, i));
|
||||
}
|
||||
|
||||
if (outLen >= (int)outBuffer->length)
|
||||
{
|
||||
memcpy_s(out, outLen, outBuffer->data, outBuffer->length);
|
||||
out[outBuffer->length] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = (int)(outBuffer->length) + 1;
|
||||
}
|
||||
|
||||
BIO_free(bio);
|
||||
BIO_free(bio_out);
|
||||
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
int __fastcall util_from_pem_string(char *data, int datalen, struct util_cert* cert)
|
||||
{
|
||||
BIO* bio = BIO_new_mem_buf((void*)data, datalen);
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __ILIB_CRYPTO__
|
||||
#define __ILIB_CRYPTO__
|
||||
|
||||
@@ -95,6 +111,7 @@ int __fastcall util_to_cer(struct util_cert cert, char** data);
|
||||
int __fastcall util_from_cer(char* data, int datalen, struct util_cert* cert);
|
||||
int __fastcall util_from_pem(char* filename, struct util_cert* cert);
|
||||
int __fastcall util_from_pem_string(char *data, int datalen, struct util_cert* cert);
|
||||
int __fastcall util_from_pkcs7b_string(char *data, int datalen, char *out, int outLen);
|
||||
int __fastcall util_mkCert(struct util_cert *rootcert, struct util_cert* cert, int bits, int days, char* name, enum CERTIFICATE_TYPES certtype, struct util_cert* initialcert);
|
||||
void __fastcall util_printcert(struct util_cert cert);
|
||||
void __fastcall util_printcert_pk(struct util_cert cert);
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
@@ -23,7 +39,7 @@ typedef struct _ILibIPAddressMonitor
|
||||
#ifdef WIN32
|
||||
SOCKET mSocket;
|
||||
DWORD bytesReturned;
|
||||
WSAOVERLAPPED reserved;
|
||||
OVERLAPPED *reserved;
|
||||
#elif defined (_POSIX)
|
||||
int mSocket;
|
||||
struct sockaddr_nl addr;
|
||||
@@ -46,12 +62,16 @@ void CALLBACK ILibIPAddressMonitor_dispatch(
|
||||
_ILibIPAddressMonitor *obj = (_ILibIPAddressMonitor*)lpOverlapped->hEvent;
|
||||
ILibChain_RunOnMicrostackThread(obj->chainLink.ParentChain, ILibIPAddressMonitor_MicrostackThreadDispatch, obj);
|
||||
}
|
||||
else if (lpOverlapped->hEvent == NULL)
|
||||
{
|
||||
free(lpOverlapped);
|
||||
}
|
||||
}
|
||||
void ILibIPAddressMonitor_MicrostackThreadDispatch(void *chain, void *user)
|
||||
{
|
||||
_ILibIPAddressMonitor *obj = (_ILibIPAddressMonitor*)user;
|
||||
if (obj->onUpdate != NULL) { obj->onUpdate(obj, obj->user); }
|
||||
WSAIoctl(obj->mSocket, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &(obj->bytesReturned), &(obj->reserved), ILibIPAddressMonitor_dispatch);
|
||||
WSAIoctl(obj->mSocket, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &(obj->bytesReturned), (LPWSAOVERLAPPED)&(obj->reserved), ILibIPAddressMonitor_dispatch);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -60,7 +80,7 @@ void ILibIPAddressMonitor_Destroy(void *object)
|
||||
_ILibIPAddressMonitor *obj = (_ILibIPAddressMonitor*)object;
|
||||
|
||||
#ifdef WIN32
|
||||
obj->reserved.hEvent = NULL;
|
||||
obj->reserved->hEvent = NULL;
|
||||
closesocket(obj->mSocket);
|
||||
obj->mSocket = INVALID_SOCKET;
|
||||
#elif defined(_POSIX)
|
||||
@@ -108,9 +128,10 @@ ILibIPAddressMonitor ILibIPAddressMonitor_Create(void *chain, ILibIPAddressMonit
|
||||
obj->onUpdate = handler;
|
||||
obj->user = user;
|
||||
#ifdef WIN32
|
||||
obj->reserved.hEvent = (HANDLE)obj;
|
||||
obj->reserved = ILibMemory_Allocate(sizeof(OVERLAPPED), 0, NULL, NULL);
|
||||
obj->reserved->hEvent = (HANDLE)obj;
|
||||
obj->mSocket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
WSAIoctl(obj->mSocket, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &(obj->bytesReturned), &(obj->reserved), ILibIPAddressMonitor_dispatch);
|
||||
WSAIoctl(obj->mSocket, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, &(obj->bytesReturned), obj->reserved, ILibIPAddressMonitor_dispatch);
|
||||
#elif defined (_POSIX)
|
||||
obj->mSocket = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
|
||||
int flags = fcntl(obj->mSocket, F_GETFL, 0);
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __ILIBIPADDRESSMONITOR__
|
||||
#define __ILIBIPADDRESSMONITOR__
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -1555,6 +1555,12 @@ void ILibChain_RunOnMicrostackThreadEx(void *chain, ILibChain_StartEvent handler
|
||||
value[2] = user;
|
||||
ILibLifeTime_AddEx(ILibGetBaseTimer(chain), value, 0, &ILibChain_RunOnMicrostackThreadSink, &ILibChain_RunOnMicrostackThreadSink);
|
||||
}
|
||||
#ifdef WIN32
|
||||
HANDLE ILibChain_GetMicrostackThreadHandle(void *chain)
|
||||
{
|
||||
return(((struct ILibBaseChain*)chain)->MicrostackThreadHandle);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ILibChain_Safe_Destroy(void *object)
|
||||
{
|
||||
@@ -1911,6 +1917,8 @@ ILibExportMethod void ILibChain_EndContinue(void *chain)
|
||||
ILibForceUnBlockChain(chain);
|
||||
}
|
||||
|
||||
char* g_ILibCrashID = NULL;
|
||||
|
||||
#if defined(WIN32)
|
||||
int ILib_WindowsExceptionFilter(DWORD exceptionCode, void *exceptionInfo, CONTEXT *exceptionContext)
|
||||
{
|
||||
@@ -1981,7 +1989,7 @@ void ILib_WindowsExceptionDebug(CONTEXT *exceptionContext)
|
||||
psym->MaxNameLen = MAX_SYM_NAME;
|
||||
pimg->SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
||||
|
||||
len = sprintf_s(buffer, sizeof(buffer), "FATAL EXCEPTION @ ");
|
||||
len = sprintf_s(buffer, sizeof(buffer), "FATAL EXCEPTION [%s] @ ", (g_ILibCrashID!=NULL? g_ILibCrashID:""));
|
||||
|
||||
if (SymFromAddr(GetCurrentProcess(), StackFrame.AddrPC.Offset, &tmp, psym))
|
||||
{
|
||||
@@ -2027,6 +2035,18 @@ void ILib_POSIX_CrashHandler(int code)
|
||||
{
|
||||
memcpy_s(msgBuffer + msgLen, sizeof(msgBuffer) - msgLen, "** CRASH **\n", 12);
|
||||
msgLen += 12;
|
||||
if (g_ILibCrashID != NULL)
|
||||
{
|
||||
int idlen = strnlen_s(g_ILibCrashID, 255);
|
||||
memcpy_s(msgBuffer + msgLen, sizeof(msgBuffer) - msgLen, "[", 1);
|
||||
msgLen += 1;
|
||||
|
||||
memcpy_s(msgBuffer + msgLen, sizeof(msgBuffer) - msgLen, g_ILibCrashID, idlen);
|
||||
msgLen += idlen;
|
||||
|
||||
memcpy_s(msgBuffer + msgLen, sizeof(msgBuffer) - msgLen, "]\n", 2);
|
||||
msgLen += 2;
|
||||
}
|
||||
}
|
||||
else if (code == 254)
|
||||
{
|
||||
@@ -5894,7 +5914,7 @@ void ILibLifeTime_AddEx(void *LifetimeMonitorObject,void *data, int ms, ILibLife
|
||||
}
|
||||
|
||||
// If this notification is sooner than the existing one, replace it.
|
||||
if (LifeTimeMonitor->NextTriggerTick > ltms->ExpirationTick) LifeTimeMonitor->NextTriggerTick = ltms->ExpirationTick;
|
||||
if (LifeTimeMonitor->NextTriggerTick > ltms->ExpirationTick || LifeTimeMonitor->NextTriggerTick == -1) LifeTimeMonitor->NextTriggerTick = ltms->ExpirationTick;
|
||||
|
||||
ILibLinkedList_UnLock(LifeTimeMonitor->ObjectList);
|
||||
}
|
||||
@@ -5972,7 +5992,7 @@ void ILibLifeTime_Check(void *LifeTimeMonitorObject, fd_set *readset, fd_set *wr
|
||||
// If it is, that means we shouldn't fire this item anymore.
|
||||
//
|
||||
ILibLinkedList_Lock(LifeTimeMonitor->Reserved);
|
||||
removed = ILibLinkedList_Remove_ByData(LifeTimeMonitor->Reserved,node);
|
||||
removed = ILibLinkedList_Remove_ByData(LifeTimeMonitor->Reserved,((struct LifeTimeMonitorData*)node)->data);
|
||||
ILibLinkedList_UnLock(LifeTimeMonitor->Reserved);
|
||||
|
||||
EVT = (struct LifeTimeMonitorData*)node;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -859,6 +859,9 @@ int ILibIsRunningOnChainThread(void* chain);
|
||||
void ILibForceUnBlockChain(void *Chain);
|
||||
void ILibChain_RunOnMicrostackThreadEx(void *chain, ILibChain_StartEvent handler, void *user);
|
||||
#define ILibChain_RunOnMicrostackThread(chain, handler, user) if(ILibIsRunningOnChainThread(chain)==0){ILibChain_RunOnMicrostackThreadEx(chain, handler, user);}else{handler(chain,user);}
|
||||
#ifdef WIN32
|
||||
HANDLE ILibChain_GetMicrostackThreadHandle(void *chain);
|
||||
#endif
|
||||
/* \} */
|
||||
|
||||
/*! \defgroup SparseArrayGroup Sparse Array
|
||||
@@ -1279,6 +1282,7 @@ int ILibIsRunningOnChainThread(void* chain);
|
||||
//
|
||||
void ILibChain_DebugOffset(char *buffer, int bufferLen, uint64_t addrOffset);
|
||||
char* ILibChain_Debug(void *chain, char* buffer, int bufferLen);
|
||||
extern char* g_ILibCrashID;
|
||||
#if defined(WIN32)
|
||||
int ILib_WindowsExceptionFilter(DWORD exceptionCode, void *exceptionInfo, CONTEXT *exceptionContext);
|
||||
void ILib_WindowsExceptionDebug(CONTEXT *exceptionContext);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -727,6 +727,8 @@ typedef struct ILibStun_dTlsSession
|
||||
char* holdingQueueTail;
|
||||
|
||||
ILibLinkedList receiveHoldBuffer;
|
||||
BIO *writeBIO;
|
||||
BUF_MEM *writeBIOBuffer;
|
||||
|
||||
char* rpacket;
|
||||
int rpacketptr;
|
||||
@@ -753,6 +755,7 @@ typedef struct ILibStun_dTlsSession
|
||||
ILibSCTP_OnSCTPDebug onRTTCalculated;
|
||||
|
||||
ILibSCTP_OnSCTPDebug onTSNFloorNotRaised;
|
||||
ILibSCTP_OnSCTPDebug onRetryPacket;
|
||||
#endif
|
||||
|
||||
unsigned int PARTIAL_BYTES_ACKED;
|
||||
@@ -845,6 +848,8 @@ unsigned int ILibStun_CRC32(char *buf, int len)
|
||||
#define ILibWebRTC_DTLS_TO_SCTP_HEARTBEAT_TIMER_OBJECT(d) d
|
||||
#define ILibWebRTC_DTLS_FROM_SCTP_HEARTBEAT_TIMER_OBJECT(d) ((ILibStun_dTlsSession*)d)
|
||||
#define ILibWebRTC_STUN_TO_CONNECTIVITY_CHECK_TIMER(s) ((char*)s+1)
|
||||
#define ILibWebRTC_STUN_TO_PERIODIC_CHECK_TIMER(s) ((char*)s+3)
|
||||
#define ILibWebRTC_STUN_FROM_PERIODIC_CHECK_TIMER(s) ((ILibStun_Module*)((char*)s-3))
|
||||
#define ILibWebRTC_STUN_FROM_CONNECTIVITY_CHECK_TIMER(s) ((ILibStun_Module*)((char*)s-1))
|
||||
int ILibStunClientIndex = -1;
|
||||
|
||||
@@ -1134,6 +1139,7 @@ void ILibStun_OnDestroy(void *object)
|
||||
if (obj->turnUsername != NULL) { free(obj->turnUsername); obj->turnUsername = NULL; }
|
||||
if (obj->turnPassword != NULL) { free(obj->turnPassword); obj->turnPassword = NULL; }
|
||||
|
||||
ILibLifeTime_Remove(obj->Timer, ILibWebRTC_STUN_TO_PERIODIC_CHECK_TIMER(obj));
|
||||
if (extraClean == 0) return;
|
||||
|
||||
#ifdef WIN32
|
||||
@@ -1147,6 +1153,7 @@ void ILibStun_OnDestroy(void *object)
|
||||
// Clean up OpenSSL dTLS session
|
||||
if (obj->dTlsSessions[i] != NULL)
|
||||
{
|
||||
ILibLifeTime_Remove(obj->Timer, ILibWebRTC_DTLS_TO_SCTP_HEARTBEAT_TIMER_OBJECT(obj->dTlsSessions[i]));
|
||||
free(obj->dTlsSessions[i]);
|
||||
obj->dTlsSessions[i] = NULL;
|
||||
}
|
||||
@@ -1655,6 +1662,110 @@ void ILibStun_FireResults(ILibStun_Module *StunModule, ILibStun_Results Result,
|
||||
if (StunModule->OnResult != NULL) { StunModule->OnResult(StunModule, Result, PublicIP, node); }
|
||||
}
|
||||
}
|
||||
#ifdef _WEBRTCDEBUG
|
||||
void _DebugSTUN(char *buffer, int bufferLen)
|
||||
{
|
||||
char tid[25];
|
||||
printf(" --> DEBUG Outbound STUN Packet\n");
|
||||
unsigned short messageType = ntohs(((unsigned short*)buffer)[0]); // Get the message type
|
||||
//unsigned short messageLength = ntohs(((unsigned short*)buffer)[1]) + 20; // Get the message length
|
||||
|
||||
switch (messageType)
|
||||
{
|
||||
case STUN_BINDING_REQUEST:
|
||||
printf("STUN_BINDING_REQUEST");
|
||||
break;
|
||||
case STUN_BINDING_RESPONSE:
|
||||
printf("STUN_BINDING_RESPONSE");
|
||||
break;
|
||||
case STUN_BINDING_ERROR_RESPONSE:
|
||||
printf("STUN_BINDING_ERROR_RESPONSE");
|
||||
break;
|
||||
case STUN_SHAREDSECRET_REQUEST:
|
||||
printf("STUN_SHARED_SECRET_REQUEST");
|
||||
break;
|
||||
case STUN_SHAREDSECRET_RESPONSE:
|
||||
printf("STUN_SHARED_SECRET_RESPONSE");
|
||||
break;
|
||||
case STUN_SHAREDSECRET_ERROR_RESPONSE:
|
||||
printf("STUN_SHARED_SECRET_ERROR_RESPONSE");
|
||||
break;
|
||||
case TURN_ALLOCATE:
|
||||
printf("TURN_ALLOCATE");
|
||||
break;
|
||||
case TURN_ALLOCATE_RESPONSE:
|
||||
printf("TURN_ALLOCATE_RESPONSE");
|
||||
break;
|
||||
case TURN_ALLOCATE_ERROR:
|
||||
printf("TURN_ALLOCATE_ERROR");
|
||||
break;
|
||||
case TURN_REFRESH:
|
||||
printf("TURN_REFRESH");
|
||||
break;
|
||||
case TURN_REFRESH_RESPONSE:
|
||||
printf("TURN_REFRESH_RESPONSE");
|
||||
break;
|
||||
case TURN_REFRESH_ERROR:
|
||||
printf("TURN_REFRESH_ERROR");
|
||||
break;
|
||||
case TURN_SEND:
|
||||
printf("TURN_SEND");
|
||||
break;
|
||||
case TURN_DATA:
|
||||
printf("TURN_DATA");
|
||||
break;
|
||||
case TURN_CREATE_PERMISSION:
|
||||
printf("TURN_CREATE_PERMISSION");
|
||||
break;
|
||||
case TURN_CREATE_PERMISSION_RESPONSE:
|
||||
printf("TURN_CREATE_PERMISSION_RESPONSE");
|
||||
break;
|
||||
case TURN_CREATE_PERMISSION_ERROR:
|
||||
printf("TURN_CREATE_PERMISSION_ERROR");
|
||||
break;
|
||||
case TURN_CHANNEL_BIND:
|
||||
printf("TURN_CHANNEL_BIND");
|
||||
break;
|
||||
case TURN_CHANNEL_BIND_RESPONSE:
|
||||
printf("TURN_CHANNEL_BIND_RESPONSE");
|
||||
break;
|
||||
case TURN_CHANNEL_BIND_ERROR:
|
||||
printf("TURN_CHANNEL_BIND_ERROR");
|
||||
break;
|
||||
case TURN_TCP_CONNECT:
|
||||
printf("TURN_TCP_CONNECT");
|
||||
break;
|
||||
case TURN_TCP_CONNECT_RESPONSE:
|
||||
printf("TURN_TCP_CONNECT_RESPONSE");
|
||||
break;
|
||||
case TURN_TCP_CONNECT_ERROR:
|
||||
printf("TURN_TCP_CONNECT_ERROR");
|
||||
break;
|
||||
case TURN_TCP_CONNECTION_BIND:
|
||||
printf("TURN_TCP_CONNECTION_BIND");
|
||||
break;
|
||||
case TURN_TCP_CONNECTION_BIND_RESPONSE:
|
||||
printf("TURN_TCP_CONNECTION_BIND_RESPONSE");
|
||||
break;
|
||||
case TURN_TCP_CONNECTION_BIND_ERROR:
|
||||
printf("TURN_TCP_CONNECTION_BIND_ERROR");
|
||||
break;
|
||||
case TURN_TCP_CONNECTION_ATTEMPT:
|
||||
printf("TURN_TCP_CONNECTION_ATTEMPT");
|
||||
break;
|
||||
default:
|
||||
printf("UNKNOWN");
|
||||
break;
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
|
||||
util_tohex(buffer + 8, 12, tid);
|
||||
printf("...TransactionID: %s\n", tid);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
int ILibStun_ProcessStunPacket(void *j, char* buffer, int bufferLength, struct sockaddr_in6 *remoteInterface)
|
||||
{
|
||||
@@ -1682,7 +1793,7 @@ int ILibStun_ProcessStunPacket(void *j, char* buffer, int bufferLength, struct s
|
||||
messageLength = ntohs(((unsigned short*)buffer)[1]) + 20; // Get the message length
|
||||
|
||||
// Check the length and magic string
|
||||
if (messageLength != bufferLength || ntohl(((int*)buffer)[1]) != 0x2112A442) { ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_STUN_ICE, ILibRemoteLogging_Flags_VerbosityLevel_3, "Skipping: Not a STUN Packet (Magic String)"); return 0; }
|
||||
if (messageLength != bufferLength || ntohl(((int*)buffer)[1]) != 0x2112A442) { ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_STUN_ICE, ILibRemoteLogging_Flags_VerbosityLevel_4, "Skipping: Not a STUN Packet (Magic String)"); return 0; }
|
||||
|
||||
memset(&mappedAddress, 0, sizeof(mappedAddress));
|
||||
memset(&changedAddress, 0, sizeof(changedAddress));
|
||||
@@ -2048,9 +2159,12 @@ int ILibStun_ProcessStunPacket(void *j, char* buffer, int bufferLength, struct s
|
||||
((unsigned int*)(rbuffer + 20))[2] = ((struct sockaddr_in*)remoteInterface)->sin_addr.s_addr ^ 0x42A41221; // IPv4 address
|
||||
|
||||
rptr += ILibStun_AddMessageIntegrityAttr(rbuffer, rptr, integritykey, 32);
|
||||
rptr += ILibStun_AddFingerprint(rbuffer, rptr); // Set the length in this function
|
||||
rptr += ILibStun_AddFingerprint(rbuffer, rptr); // Set the length in this function
|
||||
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_STUN_ICE, ILibRemoteLogging_Flags_VerbosityLevel_3, "...Sending Response to %s:%u", ILibRemoteLogging_ConvertAddress((struct sockaddr*)remoteInterface), ntohs(remoteInterface->sin6_port));
|
||||
#ifdef _WEBRTCDEBUG
|
||||
_DebugSTUN(rbuffer, rptr);
|
||||
#endif
|
||||
}
|
||||
else if ((obj->IceStates[EncodedSlot]->peerHasActiveOffer == 1 && isControlled != 0 &&
|
||||
ILibNTOHLL(((unsigned long long*)obj->IceStates[EncodedSlot]->tieBreaker)[0]) < tiebreakValue) ||
|
||||
@@ -2084,12 +2198,13 @@ int ILibStun_ProcessStunPacket(void *j, char* buffer, int bufferLength, struct s
|
||||
|
||||
// Send the data in plain text
|
||||
ILibStun_SendPacket(obj, rbuffer, 0, rptr, remoteInterface, ILibAsyncSocket_MemoryOwnership_USER);
|
||||
|
||||
//ILibAsyncUDPSocket_SendTo(((struct ILibStun_Module*)obj)->UDP, (struct sockaddr*)remoteInterface, rbuffer, rptr, ILibAsyncSocket_MemoryOwnership_USER);
|
||||
|
||||
// Send an ICE request back. This is needed to unlock Chrome/Opera inbound port for TLS. Don't do more than ILibSTUN_MaxSlots of these.
|
||||
if (obj->IceStates[EncodedSlot]->hostcandidates != NULL && obj->IceStates[EncodedSlot]->hostcandidatecount > 0)
|
||||
{
|
||||
if (obj->IceStates[EncodedSlot] != NULL && obj->IceStates[EncodedSlot]->requerycount < ILibSTUN_MaxSlots)
|
||||
if (obj->IceStates[EncodedSlot] != NULL && obj->IceStates[EncodedSlot]->requerycount < ILibSTUN_MaxSlots && obj->IceStates[EncodedSlot]->dtlsSession < 0)
|
||||
{
|
||||
char TransactionID[12];
|
||||
util_random(12, TransactionID);
|
||||
@@ -2557,7 +2672,7 @@ void ILibStun_ICE_FinalizeConnectivityChecks(void *object)
|
||||
|
||||
void ILibStun_PeriodicStunCheckEx(void *obj)
|
||||
{
|
||||
ILibStun_PeriodicStunCheck((struct ILibStun_Module*)obj - 3);
|
||||
ILibStun_PeriodicStunCheck(ILibWebRTC_STUN_FROM_PERIODIC_CHECK_TIMER(obj));
|
||||
}
|
||||
|
||||
void ILibStun_PeriodicStunCheck(struct ILibStun_Module* obj)
|
||||
@@ -2565,7 +2680,7 @@ void ILibStun_PeriodicStunCheck(struct ILibStun_Module* obj)
|
||||
int i;
|
||||
int needRecheck = 0;
|
||||
|
||||
ILibLifeTime_Remove(obj->Timer, obj + 3);
|
||||
ILibLifeTime_Remove(obj->Timer, ILibWebRTC_STUN_TO_PERIODIC_CHECK_TIMER(obj));
|
||||
|
||||
for (i = 0; i < ILibSTUN_MaxSlots; ++i)
|
||||
{
|
||||
@@ -2580,8 +2695,9 @@ void ILibStun_PeriodicStunCheck(struct ILibStun_Module* obj)
|
||||
|
||||
if (needRecheck != 0)
|
||||
{
|
||||
|
||||
ILibLifeTime_Add(obj->Timer,
|
||||
obj + 3,
|
||||
ILibWebRTC_STUN_TO_PERIODIC_CHECK_TIMER(obj),
|
||||
ILibStun_GetNextPeriodicInterval(ILibSTUN_MinNATKeepAliveIntervalSeconds, ILibSTUN_MaxNATKeepAliveIntervalSeconds),
|
||||
ILibStun_PeriodicStunCheckEx,
|
||||
NULL);
|
||||
@@ -2930,27 +3046,27 @@ void ILibORTC_AddRemoteCandidate(void *stunModule, char* localUsername, struct s
|
||||
ILibTransport_DoneState ILibStun_SendDtls(struct ILibStun_Module *obj, int session, char* buffer, int bufferLength)
|
||||
{
|
||||
ILibTransport_DoneState r = ILibTransport_DoneState_ERROR;
|
||||
char exBuffer[4096];
|
||||
int j;
|
||||
if (obj == NULL || session < 0 || session > (ILibSTUN_MaxSlots-1) || obj->dTlsSessions[session] == NULL || SSL_get_state(obj->dTlsSessions[session]->ssl) != TLS_ST_OK) return ILibTransport_DoneState_ERROR;
|
||||
|
||||
#ifdef _WEBRTCDEBUG
|
||||
// Simulated Inbound Packet Loss
|
||||
if ((obj->lossPercentage) > 0 && ((rand() % 100) >= (100 - obj->lossPercentage))) { return; }
|
||||
if ((obj->lossPercentage) > 0 && ((rand() % 100) >= (100 - obj->lossPercentage))) { return(ILibTransport_DoneState_COMPLETE); }
|
||||
#endif
|
||||
|
||||
SSL_write(obj->dTlsSessions[session]->ssl, buffer, bufferLength);
|
||||
while (BIO_ctrl_pending(SSL_get_wbio(obj->dTlsSessions[session]->ssl)) > 0)
|
||||
|
||||
if(obj->dTlsSessions[session]->writeBIOBuffer->length > 0)
|
||||
{
|
||||
BIO_clear_retry_flags(obj->dTlsSessions[session]->writeBIO); // Klocwork reports this could block, but this is a memory bio, so it will never block.
|
||||
|
||||
// Data is pending in the write buffer, send it out
|
||||
j = BIO_read(SSL_get_wbio(obj->dTlsSessions[session]->ssl), exBuffer, 4096);
|
||||
if (obj->IceStates[obj->dTlsSessions[session]->iceStateSlot]->useTurn != 0)
|
||||
{
|
||||
if ((((int*)ILibMemory_GetExtraMemory(obj->dTlsSessions[session]->remoteInterface, sizeof(struct sockaddr_in6)))[0] & ILibTURN_FLAGS_CHANNEL_DATA) == ILibTURN_FLAGS_CHANNEL_DATA)
|
||||
{
|
||||
if (ILibTURN_GetPendingBytesToSend(obj->mTurnClientModule) == 0)
|
||||
{
|
||||
r = (ILibTransport_DoneState)ILibTURN_SendChannelData(obj->mTurnClientModule, (unsigned short)session, exBuffer, 0, j);
|
||||
r = (ILibTransport_DoneState)ILibTURN_SendChannelData(obj->mTurnClientModule, (unsigned short)session, obj->dTlsSessions[session]->writeBIOBuffer->data, 0, (int)obj->dTlsSessions[session]->writeBIOBuffer->length);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2962,7 +3078,7 @@ ILibTransport_DoneState ILibStun_SendDtls(struct ILibStun_Module *obj, int sessi
|
||||
{
|
||||
if (ILibTURN_GetPendingBytesToSend(obj->mTurnClientModule) == 0)
|
||||
{
|
||||
r = (ILibTransport_DoneState)ILibTURN_SendIndication(obj->mTurnClientModule, obj->dTlsSessions[session]->remoteInterface, exBuffer, 0, j);
|
||||
r = (ILibTransport_DoneState)ILibTURN_SendIndication(obj->mTurnClientModule, obj->dTlsSessions[session]->remoteInterface, obj->dTlsSessions[session]->writeBIOBuffer->data, 0, (int)obj->dTlsSessions[session]->writeBIOBuffer->length);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2972,13 +3088,15 @@ ILibTransport_DoneState ILibStun_SendDtls(struct ILibStun_Module *obj, int sessi
|
||||
}
|
||||
else
|
||||
{
|
||||
r = (ILibTransport_DoneState)ILibAsyncUDPSocket_SendTo(((struct ILibStun_Module*)obj)->UDP, (struct sockaddr*)obj->dTlsSessions[session]->remoteInterface, exBuffer, j, ILibAsyncSocket_MemoryOwnership_USER);
|
||||
r = (ILibTransport_DoneState)ILibAsyncUDPSocket_SendTo(((struct ILibStun_Module*)obj)->UDP, (struct sockaddr*)obj->dTlsSessions[session]->remoteInterface, obj->dTlsSessions[session]->writeBIOBuffer->data, obj->dTlsSessions[session]->writeBIOBuffer->length, ILibAsyncSocket_MemoryOwnership_USER);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
r = (ILibTransport_DoneState)ILibAsyncUDPSocket_SendTo(((struct ILibStun_Module*)obj)->UDP, (struct sockaddr*)obj->dTlsSessions[session]->remoteInterface, exBuffer, j, ILibAsyncSocket_MemoryOwnership_USER);
|
||||
r = (ILibTransport_DoneState)ILibAsyncUDPSocket_SendTo(((struct ILibStun_Module*)obj)->UDP, (struct sockaddr*)obj->dTlsSessions[session]->remoteInterface, obj->dTlsSessions[session]->writeBIOBuffer->data, obj->dTlsSessions[session]->writeBIOBuffer->length, ILibAsyncSocket_MemoryOwnership_USER);
|
||||
}
|
||||
obj->dTlsSessions[session]->writeBIOBuffer->data += (obj->dTlsSessions[session]->writeBIOBuffer->length);
|
||||
obj->dTlsSessions[session]->writeBIOBuffer->length = 0;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@@ -3153,7 +3271,6 @@ ILibTransport_DoneState ILibStun_SctpSendDataEx(struct ILibStun_Module *obj, int
|
||||
if (obj->dTlsSessions[session]->T3RTXTIME == 0)
|
||||
{
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_2, "...Start T3RTX Timer");
|
||||
|
||||
// Only set the T3RTX timer if it is not already running
|
||||
obj->dTlsSessions[session]->T3RTXTIME = rpacket->LastSentTimeStamp;
|
||||
#ifdef _WEBRTCDEBUG
|
||||
@@ -3180,7 +3297,7 @@ ILibTransport_DoneState ILibStun_SctpSendDataEx(struct ILibStun_Module *obj, int
|
||||
#endif
|
||||
|
||||
// Send the packet now
|
||||
if ((flags & 0x03) == 0x03 && obj->dTlsSessions[session]->rpacketptr > 0 && obj->dTlsSessions[session]->rpacketsize > (obj->dTlsSessions[session]->rpacketptr + 16 + datalen + 4))
|
||||
if ((flags & 0x03) == 0x03 && obj->dTlsSessions[session]->rpacketptr > 0 && obj->dTlsSessions[session]->rpacketsize > (obj->dTlsSessions[session]->rpacketptr + 16 + datalen + 4) && (obj->dTlsSessions[session]->rpacketptr + 16 + datalen + 4) < 1400)
|
||||
{
|
||||
int st;
|
||||
// Merge this data chunk in packet that is going to be sent
|
||||
@@ -3757,7 +3874,13 @@ void ILibStun_SctpResent(struct ILibStun_dTlsSession *obj)
|
||||
// 0xFD means this packet is marked as ABANDONED
|
||||
if(rpacket->PacketGAPCounter != 0xFE && rpacket->PacketGAPCounter != 0xFD)
|
||||
{
|
||||
if ((rpacket->LastSentTimeStamp + obj->RTO) > time) { break; } // T3RTX did not expire for this packet
|
||||
if ((rpacket->LastSentTimeStamp + obj->RTO) > time)
|
||||
{
|
||||
#ifdef _WEBRTCDEBUG
|
||||
if (obj->onT3RTX != NULL) { obj->onT3RTX(obj, "OnT3RTX", -2); } // Debug event informing of the T3RTX timer non-expiration
|
||||
#endif
|
||||
break; // T3RTX did not expire for this packet
|
||||
}
|
||||
if ((rpacket->Reliability & 0x2000) == 0x2000 && rpacket->PacketResendCounter >= (rpacket->Reliability & 0x1FFF))
|
||||
{
|
||||
// Partial-Reliability REXMIT : Exceeded Max Retransmit
|
||||
@@ -3786,12 +3909,25 @@ void ILibStun_SctpResent(struct ILibStun_dTlsSession *obj)
|
||||
|
||||
obj->senderCredits -= rpacket->PacketSize; // Deduct CWND
|
||||
if (obj->T3RTXTIME == 0)
|
||||
{
|
||||
{
|
||||
// Only set the T3-RTX timer if it's not already running
|
||||
obj->T3RTXTIME = time;
|
||||
#ifdef _WEBRTCDEBUG
|
||||
if (obj->onT3RTX != NULL) { obj->onT3RTX(obj, "OnT3RTX", obj->RTO); } // Debug event informing of the T3RTX timer expiration
|
||||
#endif
|
||||
}
|
||||
|
||||
ILibStun_SendSctpPacket(obj->parent, obj->sessionId, rpacket->Data - 12, rpacket->PacketSize);
|
||||
#ifdef _WEBRTCDEBUG
|
||||
//if (obj->onSendRetry != NULL) { obj->onSendRetry(obj, "OnSendRetry", ((unsigned short*)(rpacket->Data + sizeof(char*)))[0]); }
|
||||
if (obj->onSendRetry != NULL) { obj->onSendRetry(obj, "OnSendRetry", ntohl(((unsigned int*)rpacket->Data)[1])); }
|
||||
if (obj->onRetryPacket != NULL)
|
||||
{
|
||||
char *tmp = ILibMemory_AllocateA(rpacket->PacketSize + 14);
|
||||
sprintf_s(tmp, 14, "OnRetryPacket");
|
||||
memcpy_s(tmp + 14, rpacket->PacketSize, rpacket->Data - 12, rpacket->PacketSize);
|
||||
obj->onRetryPacket(obj, tmp, rpacket->PacketSize);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3822,6 +3958,7 @@ void ILibStun_SctpOnTimeout(void *object)
|
||||
else
|
||||
{
|
||||
// Close the connection
|
||||
printf("************************************\n");
|
||||
sem_post(&(obj->Lock));
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->Transport.ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_1, "SCTP Timeout on Session: %d", obj->sessionId);
|
||||
ILibStun_SctpDisconnect(obj->parent, obj->sessionId);
|
||||
@@ -4321,7 +4458,8 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_1, "......Responding with Outbound Reset Request");
|
||||
outRequest = (ILibSCTP_Reconfig_OutgoingSSNResetRequest*)((char*)(&outChunk->reconfigurationParameter) + outOffset); // Ignore Klocwork Error, it's not a problem in this case
|
||||
outRequest->parameterType = htons(SCTP_RECONFIG_TYPE_OUTGOING_SSN_RESET_REQUEST);
|
||||
outRequest->parameterLength = htons(16 + 2 * streamCount);
|
||||
//outRequest->parameterLength = htons(16 + 2 * streamCount);
|
||||
outRequest->parameterLength = 16 + 2 * streamCount;
|
||||
outRequest->LastTSN = htonl(o->outtsn - 1);
|
||||
outRequest->RReqSeqNum = htonl(o->RREQSEQ++);
|
||||
outRequest->RResSeqNum = htonl(o->RRESSEQ++);
|
||||
@@ -4551,6 +4689,12 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
|
||||
o->zeroWindowProbeTime = 0;
|
||||
o->lastSackTime = (unsigned int)ILibGetUptime();
|
||||
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_1, "SCTP [SACK] Received");
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_1, "... TSN = %u", tsn);
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_1, "... GAP Count = %u", GapAckCount);
|
||||
|
||||
|
||||
|
||||
if (o->FastRetransmitExitPoint != 0 && tsn >= o->FastRetransmitExitPoint)
|
||||
{
|
||||
// We have exited Fast Recovery Mode
|
||||
@@ -4579,16 +4723,20 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
|
||||
// This packet that was ACK'ed and was NOT retransmitted, and NO OTHER packets
|
||||
// were retransmitted since this packet was originally sent
|
||||
int r = (int)(o->lastSackTime - ((ILibSCTP_RPACKET*)o->pendingQueueHead)->LastSentTimeStamp);
|
||||
o->RTTVAR = (int)((double)(1 - RTO_BETA) * (double)o->RTTVAR + RTO_BETA * (double)abs(o->SRTT - r));
|
||||
o->SRTT = (int)((double)(1 - RTO_ALPHA) * (double)o->SRTT + RTO_ALPHA * (double)r);
|
||||
o->RTO = o->SRTT + 4 * o->RTTVAR;
|
||||
if (o->RTO < RTO_MIN) { o->RTO = RTO_MIN; }
|
||||
if (o->RTO > RTO_MAX) { o->RTO = RTO_MAX; }
|
||||
rttCalculated = 1; // We only need to calculate this once for each packet received
|
||||
|
||||
if (r >= 0)
|
||||
{
|
||||
o->RTTVAR = (int)((double)(1 - RTO_BETA) * (double)o->RTTVAR + RTO_BETA * (double)abs(o->SRTT - r));
|
||||
o->SRTT = (int)((double)(1 - RTO_ALPHA) * (double)o->SRTT + RTO_ALPHA * (double)r);
|
||||
o->RTO = o->SRTT + 4 * o->RTTVAR;
|
||||
if (o->RTO < RTO_MIN) { o->RTO = RTO_MIN; }
|
||||
if (o->RTO > RTO_MAX) { o->RTO = RTO_MAX; }
|
||||
rttCalculated = 1; // We only need to calculate this once for each packet received
|
||||
#ifdef _WEBRTCDEBUG
|
||||
if (o->onRTTCalculated != NULL) { o->onRTTCalculated(o, "OnRTTCalculated", o->SRTT); }
|
||||
if (o->onRTTCalculated != NULL) { o->onRTTCalculated(o, "OnRTTCalculated", o->SRTT); }
|
||||
if (o->onRTTCalculated != NULL) { o->onRTTCalculated(o, "OnLastSackTime", o->lastSackTime); }
|
||||
if (o->onRTTCalculated != NULL) { o->onRTTCalculated(o, "OnLastSentTime", ((ILibSCTP_RPACKET*)o->pendingQueueHead)->LastSentTimeStamp); }
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
cumulativeTSNAdvanced += (((ILibSCTP_RPACKET*)o->pendingQueueHead)->PacketSize - (12 + 16));
|
||||
@@ -4753,7 +4901,7 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
|
||||
|
||||
FastRetryDisabled = 1;
|
||||
#ifdef _WEBRTCDEBUG
|
||||
if (o->onSendFastRetry != NULL) { o->onSendFastRetry(o, "OnSendFastRetry", ((unsigned short*)(packet + sizeof(char*)))[0]); }
|
||||
if (o->onSendFastRetry != NULL) { o->onSendFastRetry(o, "OnSendFastRetry", ((unsigned short*)(rpacket->Data + sizeof(char*)))[0]); }
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -4775,10 +4923,11 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
|
||||
o->senderCredits -= (rpacket->PacketSize - (12 + 16)); // Update sender credits
|
||||
o->lastRetransmitTime = o->lastSackTime; // Every time we retransmit, we need to take note of it, for RTT purposes
|
||||
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_ConsolePrint | ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "SCTP[%d]: Retransmitting/T3RTX Expired", o->sessionId);
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "SCTP[%d]: Retransmitting/T3RTX Expired", o->sessionId);
|
||||
ILibStun_SendSctpPacket(obj, session, rpacket->Data - 12, rpacket->PacketSize);
|
||||
#ifdef _WEBRTCDEBUG
|
||||
if (o->onSendRetry != NULL) { o->onSendRetry(obj, "OnSendRetry", ((unsigned short*)(packet + sizeof(char*)))[0]); }
|
||||
//if (o->onSendRetry != NULL) { o->onSendRetry(obj, "OnSendRetry", ((unsigned short*)(rpacket->Data + sizeof(char*)))[0]); }
|
||||
if (o->onSendRetry != NULL) { o->onSendRetry(o, "OnSendRetry", ntohl(((unsigned int*)rpacket->Data)[1])); }
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -4799,7 +4948,8 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
|
||||
|
||||
ILibStun_SendSctpPacket(obj, session, rpacket->Data - 12, rpacket->PacketSize);
|
||||
#ifdef _WEBRTCDEBUG
|
||||
if (o->onSendRetry != NULL) { o->onSendRetry(obj, "OnSendRetry", ((unsigned short*)(packet + sizeof(char*)))[0]); }
|
||||
//if (o->onSendRetry != NULL) { o->onSendRetry(obj, "OnSendRetry", ((unsigned short*)(rpacket->Data + sizeof(char*)))[0]); }
|
||||
if (o->onSendRetry != NULL) { o->onSendRetry(o, "OnSendRetry", ntohl(((unsigned int*)rpacket->Data)[1])); }
|
||||
#endif
|
||||
}
|
||||
rpacket->PacketGAPCounter = frt; // Possibly add to the packet gap counter
|
||||
@@ -5026,7 +5176,7 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "... UserTSN = %u", o->userTSN);
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "... InTSN = %u", o->intsn);
|
||||
}
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_ConsolePrint | ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "SCTP: %d, exiting processing loop due to PAUSE state", o->sessionId);
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "SCTP: %d, exiting processing loop due to PAUSE state", o->sessionId);
|
||||
break;
|
||||
}
|
||||
else
|
||||
@@ -5040,7 +5190,7 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
|
||||
{
|
||||
unsigned int tsnx = ntohl(((ILibSCTP_DataPayload*)ILibLinkedList_GetDataFromNode(rqptr))->TSN);
|
||||
if (tsnx != o->intsn + 1) break;
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_ConsolePrint | ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "TSN Moved Forward to: %u", tsnx);
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "TSN Moved Forward to: %u", tsnx);
|
||||
o->intsn = tsnx;
|
||||
RCTPRCVDEBUG(printf("MOVED TSN to %u\r\n", o->intsn);)
|
||||
rqptr = ILibLinkedList_GetNextNode(rqptr);
|
||||
@@ -5081,7 +5231,7 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
|
||||
pid = ntohl(payload->ProtocolID);
|
||||
o->userTSN = o->intsn = tsnx;
|
||||
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_ConsolePrint|ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "SCTP: %d Packet: %u Pulled from Holding Queue", o->sessionId, o->userTSN);
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "SCTP: %d Packet: %u Pulled from Holding Queue", o->sessionId, o->userTSN);
|
||||
|
||||
if (ILibSCTP_GetHoldingQueueFlags(ILibLinkedList_GetNode_Head(o->receiveHoldBuffer))->DataPropagated == 0)
|
||||
{
|
||||
@@ -5096,7 +5246,7 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
|
||||
ILibLinkedList_Remove(ILibLinkedList_GetNode_Head(o->receiveHoldBuffer));
|
||||
if((o->flags & DTLS_PAUSE_FLAG)==DTLS_PAUSE_FLAG)
|
||||
{
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_ConsolePrint | ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "SCTP_2: %d, exiting processing loop due to PAUSE state", o->sessionId);
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_3, "SCTP_2: %d, exiting processing loop due to PAUSE state", o->sessionId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -5114,9 +5264,9 @@ void ILibStun_ProcessSctpPacket(struct ILibStun_Module *obj, int session, char*
|
||||
}
|
||||
else
|
||||
{
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_ConsolePrint | ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_1, "SCTP: %d Packet: %u DROPPED, because holding Queue is FULL", o->sessionId, ntohl(data->TSN));
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_ConsolePrint | ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_1, "... UserTSN = %u", o->userTSN);
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_ConsolePrint | ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_1, "... InTSN = %u", o->intsn);
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_1, "SCTP: %d Packet: %u DROPPED, because holding Queue is FULL", o->sessionId, ntohl(data->TSN));
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_1, "... UserTSN = %u", o->userTSN);
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(obj->ChainLink.ParentChain), ILibRemoteLogging_Modules_WebRTC_SCTP, ILibRemoteLogging_Flags_VerbosityLevel_1, "... InTSN = %u", o->intsn);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -5518,10 +5668,11 @@ void ILibStun_InitiateDTLS(struct ILibStun_IceState *IceState, int IceSlot, stru
|
||||
|
||||
// Start a new dTLS session
|
||||
ILibStun_CreateDtlsSession(obj, j, IceSlot, remoteInterface);
|
||||
|
||||
|
||||
// Set up the memory-buffer BIOs
|
||||
read = BIO_new(BIO_s_mem());
|
||||
write = BIO_new(BIO_s_mem());
|
||||
obj->dTlsSessions[j]->writeBIO = write = BIO_new(BIO_s_mem());
|
||||
BIO_get_mem_ptr(obj->dTlsSessions[j]->writeBIO, &(obj->dTlsSessions[j]->writeBIOBuffer));
|
||||
BIO_set_mem_eof_return(read, -1);
|
||||
BIO_set_mem_eof_return(write, -1);
|
||||
|
||||
@@ -5823,7 +5974,8 @@ void ILibStun_OnUDP(ILibAsyncUDPSocket_SocketModule socketModule, char* buffer,
|
||||
|
||||
// Set up the memory-buffer BIOs
|
||||
read = BIO_new(BIO_s_mem());
|
||||
write = BIO_new(BIO_s_mem());
|
||||
obj->dTlsSessions[j]->writeBIO = write = BIO_new(BIO_s_mem());
|
||||
BIO_get_mem_ptr(obj->dTlsSessions[j]->writeBIO, &(obj->dTlsSessions[j]->writeBIOBuffer));
|
||||
BIO_set_mem_eof_return(read, -1);
|
||||
BIO_set_mem_eof_return(write, -1);
|
||||
|
||||
@@ -5941,28 +6093,32 @@ void ILibStun_OnUDP(ILibAsyncUDPSocket_SocketModule socketModule, char* buffer,
|
||||
if (obj->dTlsSessions[existingSession] != NULL && obj->dTlsSessions[existingSession]->state != 0)
|
||||
{
|
||||
sem_wait(&(obj->dTlsSessions[existingSession]->Lock));
|
||||
while (BIO_ctrl_pending(SSL_get_wbio(obj->dTlsSessions[existingSession]->ssl)) > 0)
|
||||
if(obj->dTlsSessions[existingSession]->writeBIOBuffer->length > 0)
|
||||
{
|
||||
BIO_clear_retry_flags(obj->dTlsSessions[existingSession]->writeBIO); // Klocwork reports this could block, but this is a memory bio, so it will never block.
|
||||
|
||||
// Data is pending in the write buffer, send it out
|
||||
j = BIO_read(SSL_get_wbio(obj->dTlsSessions[existingSession]->ssl), tbuffer, 4096);
|
||||
if (socketModule == NULL)
|
||||
{
|
||||
// Response was from TURN
|
||||
if (remoteInterface->sin6_family == 0)
|
||||
{
|
||||
ILibTURN_SendChannelData(obj->mTurnClientModule, remoteInterface->sin6_port, tbuffer, 0, j);
|
||||
ILibTURN_SendChannelData(obj->mTurnClientModule, remoteInterface->sin6_port, obj->dTlsSessions[existingSession]->writeBIOBuffer->data, 0, (int)obj->dTlsSessions[existingSession]->writeBIOBuffer->length);
|
||||
}
|
||||
else
|
||||
{
|
||||
ILibTURN_SendIndication(obj->mTurnClientModule, remoteInterface, tbuffer, 0, j);
|
||||
ILibTURN_SendIndication(obj->mTurnClientModule, remoteInterface, obj->dTlsSessions[existingSession]->writeBIOBuffer->data, 0, (int)obj->dTlsSessions[existingSession]->writeBIOBuffer->length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Response was from a local Socket
|
||||
ILibAsyncUDPSocket_SendTo(((struct ILibStun_Module*)obj)->UDP, (struct sockaddr*)remoteInterface, tbuffer, j, ILibAsyncSocket_MemoryOwnership_USER);
|
||||
ILibAsyncUDPSocket_SendTo(((struct ILibStun_Module*)obj)->UDP, (struct sockaddr*)remoteInterface, obj->dTlsSessions[existingSession]->writeBIOBuffer->data, obj->dTlsSessions[existingSession]->writeBIOBuffer->length, ILibAsyncSocket_MemoryOwnership_USER);
|
||||
}
|
||||
if(obj->dTlsSessions[existingSession]->state == 4) {ILibWebRTC_DTLS_HandshakeDetect(obj, "S ", tbuffer, 0, j);}
|
||||
if(obj->dTlsSessions[existingSession]->state == 4) {ILibWebRTC_DTLS_HandshakeDetect(obj, "S ", obj->dTlsSessions[existingSession]->writeBIOBuffer->data, 0, (int)obj->dTlsSessions[existingSession]->writeBIOBuffer->length);}
|
||||
|
||||
obj->dTlsSessions[existingSession]->writeBIOBuffer->data += (obj->dTlsSessions[existingSession]->writeBIOBuffer->length);
|
||||
obj->dTlsSessions[existingSession]->writeBIOBuffer->length = 0;
|
||||
}
|
||||
sem_post(&(obj->dTlsSessions[existingSession]->Lock));
|
||||
}
|
||||
@@ -7263,12 +7419,12 @@ int ILibSCTP_Debug_SetDebugCallback(void* dtlsSession, char* debugFieldName, ILi
|
||||
if (strcmp(debugFieldName, "OnHold") == 0)
|
||||
{
|
||||
session->onHold = handler;
|
||||
handler(session, "OnHold", session->holdingCount);
|
||||
if (handler != NULL) { handler(session, "OnHold", session->holdingCount); }
|
||||
}
|
||||
else if (strcmp(debugFieldName, "OnReceiverCredits") == 0)
|
||||
{
|
||||
session->onReceiverCredits = handler;
|
||||
handler(session, "OnReceiverCredits", session->receiverCredits);
|
||||
if (handler != NULL) { handler(session, "OnReceiverCredits", session->receiverCredits); }
|
||||
}
|
||||
else if (strcmp(debugFieldName, "OnSendFastRetry") == 0)
|
||||
{
|
||||
@@ -7281,7 +7437,7 @@ int ILibSCTP_Debug_SetDebugCallback(void* dtlsSession, char* debugFieldName, ILi
|
||||
else if (strcmp(debugFieldName, "OnCongestionWindowSizeChanged") == 0)
|
||||
{
|
||||
session->onCongestionWindowSizeChanged = handler;
|
||||
handler(session, "OnCongestionWindowSizeChanged", session->congestionWindowSize);
|
||||
if (handler != NULL) { handler(session, "OnCongestionWindowSizeChanged", session->congestionWindowSize); }
|
||||
}
|
||||
else if (strcmp(debugFieldName, "OnSACKReceived") == 0)
|
||||
{
|
||||
@@ -7303,6 +7459,10 @@ int ILibSCTP_Debug_SetDebugCallback(void* dtlsSession, char* debugFieldName, ILi
|
||||
{
|
||||
session->onTSNFloorNotRaised = handler;
|
||||
}
|
||||
else if (strcmp(debugFieldName, "OnRetryPacket") == 0)
|
||||
{
|
||||
session->onRetryPacket = handler;
|
||||
}
|
||||
else { return 1; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2006 - 2017 Intel Corporation
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user