1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-06 00:13:33 +00:00

Improved agent that can update the MeshCentral1 agent

This commit is contained in:
Ylian Saint-Hilaire
2017-11-09 16:07:39 -08:00
parent 34e09c2304
commit becf71557f
36 changed files with 1520 additions and 208 deletions

205
Debug/AMT.js Normal file
View File

@@ -0,0 +1,205 @@
var http = require('http');
var digest = require('http-digest').create("admin", "P@ssw0rd");
console.log("Starting AMT Test");
digest.http = require('http');
//console.log("First Test: HTTP/GET on '/'");
//var req = digest.request({ protocol: "http:", method: "GET", host: "172.16.2.249", path: "/", port: 16992 }, OnGet1);
//req.end();
//console.log('First Test: POST /wsman');
//WSManTest();
console.log('First Test: POST /wsman, [immediate]');
WSManTest_Immediate();
function OnGet1(imsg)
{
if(imsg.statusCode == 303)
{
console.log("...SUCCESS!");
console.log("Next Test: Redirect to '" + imsg.header['Location'] + "'");
req = digest.request({ protocol: "http:", method: "GET", host: "172.16.2.249", path: imsg.header['Location'], port: 16992 }, OnGet2);
req.end();
}
else
{
console.log("...FAILED!");
}
}
function OnGet2(imsg)
{
if (imsg.statusCode == 200)
{
console.log("...SUCCESS!");
console.log("...Reading body of message");
imsg.on('end', function ()
{
console.log("...Finished");
console.log("Next Test: '/index.htm'");
req = digest.request({ protocol: "http:", method: "GET", host: "172.16.2.249", path: "/index.htm", port: 16992 }, OnGet3);
req.end();
});
}
else
{
console.log("...FAILED, status code was: " + imsg.statusCode);
}
}
function OnGet3(imsg)
{
if (imsg.statusCode == 200)
{
console.log("...SUCCESS!");
console.log("Next Test: 'POST /wsman'");
WSManTest();
}
}
function WSManTest()
{
req = digest.request({ protocol: "http:", method: "POST", host: "172.16.2.249", path: "/wsman", port: 16992, headers: { Expect: '100-Continue' }, timeout: 2000 });
req.on('continue', WSManTest_Continue);
req.on('timeout', WSManTest_Timeout);
req.on('response', WSManTest_Response);
}
function WSManTest_Immediate()
{
req = digest.request({ protocol: "http:", method: "POST", host: "172.16.2.249", path: "/wsman", port: 16992 });
req.on('response', WSManTest_Response);
var xml = 'PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW52ZWxvcGUgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeG1sbnM6eHNkPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIgeG1sbnM6YT0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nIiB4bWxuczp3PSJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzbWFuLzEvd3NtYW4ueHNkIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMy8wNS9zb2FwLWVudmVsb3BlIiA+PEhlYWRlcj48YTpBY3Rpb24+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOS90cmFuc2Zlci9HZXQ8L2E6QWN0aW9uPjxhOlRvPi93c21hbjwvYTpUbz48dzpSZXNvdXJjZVVSST5odHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzY2ltLzEvY2ltLXNjaGVtYS8yL0NJTV9Db21wdXRlclN5c3RlbVBhY2thZ2U8L3c6UmVzb3VyY2VVUkk+PGE6TWVzc2FnZUlEPjQ8L2E6TWVzc2FnZUlEPjxhOlJlcGx5VG8+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48L2E6UmVwbHlUbz48dzpPcGVyYXRpb25UaW1lb3V0PlBUNjBTPC93Ok9wZXJhdGlvblRpbWVvdXQ+PC9IZWFkZXI+PEJvZHkgLz48L0VudmVsb3BlPg==';
var b = Buffer.from(xml, 'base64');
req.write(b);
req.end();
}
function WSManTest_Continue()
{
console.log("Got Continue!");
}
function WSManTest_Timeout()
{
console.log("Timeout waiting for 100 Continue... Sending body anyways...");
var xml = 'PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48RW52ZWxvcGUgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeG1sbnM6eHNkPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIgeG1sbnM6YT0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nIiB4bWxuczp3PSJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzbWFuLzEvd3NtYW4ueHNkIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMy8wNS9zb2FwLWVudmVsb3BlIiA+PEhlYWRlcj48YTpBY3Rpb24+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOS90cmFuc2Zlci9HZXQ8L2E6QWN0aW9uPjxhOlRvPi93c21hbjwvYTpUbz48dzpSZXNvdXJjZVVSST5odHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzY2ltLzEvY2ltLXNjaGVtYS8yL0NJTV9Db21wdXRlclN5c3RlbVBhY2thZ2U8L3c6UmVzb3VyY2VVUkk+PGE6TWVzc2FnZUlEPjQ8L2E6TWVzc2FnZUlEPjxhOlJlcGx5VG8+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48L2E6UmVwbHlUbz48dzpPcGVyYXRpb25UaW1lb3V0PlBUNjBTPC93Ok9wZXJhdGlvblRpbWVvdXQ+PC9IZWFkZXI+PEJvZHkgLz48L0VudmVsb3BlPg==';
var b = Buffer.from(xml, 'base64');
this.write(b);
this.end();
}
function WSManTest_Response(imsg)
{
imsg.on('data', function (chunk) { console.log(chunk); });
}
//var req = digest.request({ protocol: "ws:", method: "GET", host: "127.0.0.1", path: "/", port: 9093 }, function (imsg) { console.log(imsg.statusCode == 200 ? "SUCCESS!" : "FAIL!"); });
//var req = http.request({ protocol: "http:", method: "POST", host: "127.0.0.1", path: "/", port: 9093, headers: { Expect: '100-Continue' } }, function (imsg) { console.log(imsg.statusCode == 200 ? "SUCCESS!" : "FAIL!"); });
//var req = digest.request({ protocol: "http:", method: "POST", host: "127.0.0.1", path: "/", port: 9093, headers: { Expect: '100-Continue' } }, function (imsg) { console.log(imsg.statusCode == 200 ? "SUCCESS!" : "FAIL!"); });
//req.on('upgrade', function (res, sk, h) { console.log("Upgraded to WebSocket!"); });
//req.on('error', function () { console.log("Error occured"); });
//req.on('continue', function () { console.log("Received Continue"); this.write("test"); this.end(); });
//function OnCheckContinue(imsg, resp)
//{
// console.log("Recevied: Expect-100 Continue");
// if (imsg.Digest_IsAuthenticated('www.meshcentral.com') == 1)
// {
// var uname = imsg.Digest_GetUsername();
// console.log("Digest Username was: " + uname);
// if (uname == 'bryan' && imsg.Digest_ValidatePassword('roe') == 1)
// {
// console.log("Validated");
// imsg.on('data', function (chunk) { console.log('Received: ' + chunk.toString()); });
// imsg.on('end', function () { console.log('Received Complete'); });
// resp.writeContinue();
// }
// else
// {
// console.log("Bad Username/Password");
// resp.statusCode = "500";
// resp.statusMessage = "Error";
// resp.end();
// }
// }
// else
// {
// console.log("Sending Unauthorized");
// imsg.Digest_SendUnauthorized('www.meshcentral.com', 'oops');
// }
//}
//function OnCheckContinue_NoDigest(imsg, resp)
//{
// console.log("Recevied: Expect-100 Continue");
// imsg.on('data', function (chunk) { console.log('Received: ' + chunk.toString()); });
// imsg.on('end', function () { console.log('Received Complete'); });
// resp.writeContinue();
//}
//function OnServerUpgrade(imsg, sck, head)
//{
// if(imsg.Digest_IsAuthenticated('www.meshcentral.com')==1)
// {
// var uname = imsg.Digest_GetUsername();
// console.log("Digest Username was: " + uname);
// if(uname == 'bryan' && imsg.Digest_ValidatePassword('roe')==1)
// {
// console.log("Upgrading to WebSocket");
// sck.upgradeWebSocket();
// }
// else
// {
// console.log("Bad Username/Password");
// sck.end();
// }
// }
// else
// {
// console.log("Sending Unauthorized");
// imsg.Digest_SendUnauthorized('www.meshcentral.com', 'oops');
// }
//}
//function onVerifyServer(clientName, certs) {
// console.log("Server Name = " + clientName + "\n");
// for (var i = 0; i < certs.length; ++i) {
// console.log(" Fingerprint = " + certs[i].fingerprint + "\n");
// }
// //throw ("Not Valid");
//}
//function onVerifyClient(clientName, certs)
//{
// console.log("Client Name = " + clientName + "\n");
// for (var i = 0; i < certs.length; ++i) {
// console.log(" Fingerprint = " + certs[i].fingerprint + "\n");
// }
// //throw ("Not Valid");
//}
//function onVerify(serverName, certs)
//{
// console.log("ServerName = " + serverName + "\n");
// for (var i = 0; i < certs.length;++i)
// {
// console.log(" Fingerprint = " + certs[i].fingerprint + "\n");
// }
// //throw ("Not Valid");
//}
//function OnRequest(req, res)
//{
// console.log("Received Request for: " + req.url);
//}

27
Debug/ChildProcessTest.js Normal file
View File

@@ -0,0 +1,27 @@
var child = require('child_process');
var childProcess = null;
if (process.platform == 'win32')
{
childProcess = child.execFile(process.env['windir'] + '\\system32\\cmd.exe', ['/c', 'dir'], OnChild);
}
else if (process.platform == 'linux')
{
childProcess = child.execFile('/bin/sh', ['sh', '-c', 'ls'], OnChild);
}
if (childProcess != null)
{
console.log('PID = ' + childProcess.pid);
childProcess.stdout.on('data', function (chunk) { console.log(chunk.toString()); });
childProcess.on('exit', function (code, sig) { console.log("Process Exited with code: " + code.toString()); });
}
//for (var envkey in process.env)
//{
// console.log("Environment Variable: [" + envkey + "] = " + process.env[envkey]);
//}
function OnChild(err, stdErr, stdOut)
{
}

View File

@@ -4,11 +4,15 @@ var req = "";
var gtunnel = ""; var gtunnel = "";
var digest = require('http-digest').create("bryan", "roe"); var digest = require('http-digest').create("bryan", "roe");
console.log("Process.execPath = " + process.execPath);
console.log("Starting POST Digest Test"); console.log("Starting POST Digest Test");
server = http.createServer(OnRequest); server = http.createServer(OnRequest);
server.listen(9093); server.listen(9093);
console.log("Server Address", server._address());
server.on('upgrade', OnServerUpgrade); server.on('upgrade', OnServerUpgrade);
server.on('checkContinue', OnCheckContinue); server.on('checkContinue', OnCheckContinue);
//server.on('checkContinue', OnCheckContinue_NoDigest); //server.on('checkContinue', OnCheckContinue_NoDigest);

View File

@@ -39,6 +39,7 @@ SOURCES += microscript/ILibWebServer_Duktape.c microscript/ILibDuktape_SimpleDat
SOURCES += microscript/ILibDuktape_ProcessPipe.c microscript/ILibDuktape_fs.c microscript/ILibDuktape_SHA256.c microscript/ILibduktape_EventEmitter.c SOURCES += microscript/ILibDuktape_ProcessPipe.c microscript/ILibDuktape_fs.c microscript/ILibDuktape_SHA256.c microscript/ILibduktape_EventEmitter.c
SOURCES += microscript/ILibDuktape_EncryptionStream.c microscript/ILibDuktape_Polyfills.c microscript/ILibDuktape_Dgram.c SOURCES += microscript/ILibDuktape_EncryptionStream.c microscript/ILibDuktape_Polyfills.c microscript/ILibDuktape_Dgram.c
SOURCES += microscript/ILibDuktape_ScriptContainer.c microscript/ILibDuktape_MemoryStream.c microscript/ILibDuktape_NetworkMonitor.c SOURCES += microscript/ILibDuktape_ScriptContainer.c microscript/ILibDuktape_MemoryStream.c microscript/ILibDuktape_NetworkMonitor.c
SOURCES += microscript/ILibDuktape_ChildProcess.c
# Mesh Agent core # Mesh Agent core
SOURCES += meshcore/agentcore.c meshconsole/main.c meshcore/meshinfo.c SOURCES += meshcore/agentcore.c meshconsole/main.c meshcore/meshinfo.c

View File

@@ -31,6 +31,7 @@
<ClCompile Include="..\microscript\duktape.c" /> <ClCompile Include="..\microscript\duktape.c" />
<ClCompile Include="..\microscript\ILibAsyncSocket_Duktape.c" /> <ClCompile Include="..\microscript\ILibAsyncSocket_Duktape.c" />
<ClCompile Include="..\microscript\ILibDuktapeModSearch.c" /> <ClCompile Include="..\microscript\ILibDuktapeModSearch.c" />
<ClCompile Include="..\microscript\ILibDuktape_ChildProcess.c" />
<ClCompile Include="..\microscript\ILibDuktape_Debugger.c" /> <ClCompile Include="..\microscript\ILibDuktape_Debugger.c" />
<ClCompile Include="..\microscript\ILibDuktape_Dgram.c" /> <ClCompile Include="..\microscript\ILibDuktape_Dgram.c" />
<ClCompile Include="..\microscript\ILibDuktape_DuplexStream.c" /> <ClCompile Include="..\microscript\ILibDuktape_DuplexStream.c" />
@@ -91,6 +92,7 @@
<ClInclude Include="..\microscript\duk_config.h" /> <ClInclude Include="..\microscript\duk_config.h" />
<ClInclude Include="..\microscript\ILibAsyncSocket_Duktape.h" /> <ClInclude Include="..\microscript\ILibAsyncSocket_Duktape.h" />
<ClInclude Include="..\microscript\ILibDuktapeModSearch.h" /> <ClInclude Include="..\microscript\ILibDuktapeModSearch.h" />
<ClInclude Include="..\microscript\ILibDuktape_ChildProcess.h" />
<ClInclude Include="..\microscript\ILibDuktape_Debugger.h" /> <ClInclude Include="..\microscript\ILibDuktape_Debugger.h" />
<ClInclude Include="..\microscript\ILibDuktape_Dgram.h" /> <ClInclude Include="..\microscript\ILibDuktape_Dgram.h" />
<ClInclude Include="..\microscript\ILibDuktape_DuplexStream.h" /> <ClInclude Include="..\microscript\ILibDuktape_DuplexStream.h" />

View File

@@ -187,6 +187,9 @@
<ClInclude Include="..\microscript\ILibDuktape_NetworkMonitor.h"> <ClInclude Include="..\microscript\ILibDuktape_NetworkMonitor.h">
<Filter>Microscript</Filter> <Filter>Microscript</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\microscript\ILibDuktape_ChildProcess.h">
<Filter>Microscript</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\microscript\duktape.c"> <ClCompile Include="..\microscript\duktape.c">
@@ -337,6 +340,9 @@
<ClCompile Include="..\microscript\ILibDuktape_NetworkMonitor.c"> <ClCompile Include="..\microscript\ILibDuktape_NetworkMonitor.c">
<Filter>Microscript</Filter> <Filter>Microscript</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\microscript\ILibDuktape_ChildProcess.c">
<Filter>Microscript</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="MeshConsole.rc" /> <ResourceCompile Include="MeshConsole.rc" />

View File

@@ -29,6 +29,8 @@ limitations under the License.
#include <crtdbg.h> #include <crtdbg.h>
#endif #endif
#include "microscript/ILibDuktape_ScriptContainer.h"
MeshAgentHostContainer *agentHost = NULL; MeshAgentHostContainer *agentHost = NULL;
#ifdef WIN32 #ifdef WIN32
@@ -64,45 +66,12 @@ void BreakSink(int s)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
// Check if .JS file is integrated with executable // Check if .JS file is integrated with executable
FILE *tmpFile;
char *integratedJavaScript = NULL; char *integratedJavaScript = NULL;
int integratedJavaScriptLen = 0; int integratedJavaScriptLen = 0;
#ifdef WIN32
if (ILibString_EndsWith(argv[0], -1, ".exe", 4) == 0)
{
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "%s.exe", argv[0]);
tmpFile = fopen(ILibScratchPad, "rb");
}
else
{
tmpFile = fopen(argv[0], "rb");
}
#else
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]))
{
fseek(tmpFile, ftell(tmpFile) - 8, 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);
ignore_result(fread(integratedJavaScript, 1, integratedJavaScriptLen, tmpFile));
integratedJavaScript[integratedJavaScriptLen] = 0;
}
fclose(tmpFile);
}
int retCode = 0; int retCode = 0;
ILibDuktape_ScriptContainer_CheckEmbedded(argv, &integratedJavaScript, &integratedJavaScriptLen);
if (argc > 2 && memcmp(argv[1], "-faddr", 6) == 0) if (argc > 2 && memcmp(argv[1], "-faddr", 6) == 0)
{ {
uint64_t addrOffset; uint64_t addrOffset;

View File

@@ -111,6 +111,11 @@ typedef struct ScriptContainerSettings
}ScriptContainerSettings; }ScriptContainerSettings;
#pragma pack(push, 1) #pragma pack(push, 1)
typedef struct MeshCommand_BinaryPacket_ServerId
{
unsigned short command;
char serverId[UTIL_HASHSIZE];
}MeshCommand_BinaryPacket_ServerId;
typedef struct MeshCommand_BinaryPacket_AuthRequest typedef struct MeshCommand_BinaryPacket_AuthRequest
{ {
unsigned short command; unsigned short command;
@@ -1087,12 +1092,10 @@ int agent_GenerateCertificates(MeshAgentHostContainer *agent, char* certfile)
{ {
// Generate a new random node certificate // Generate a new random node certificate
ILibRemoteLogging_printf(ILibChainGetLogger(agent->chain), ILibRemoteLogging_Modules_Agent_GuardPost, ILibRemoteLogging_Flags_VerbosityLevel_1, "...Generating new Node Certificate"); ILibRemoteLogging_printf(ILibChainGetLogger(agent->chain), ILibRemoteLogging_Modules_Agent_GuardPost, ILibRemoteLogging_Flags_VerbosityLevel_1, "...Generating new Node Certificate");
do do
{ {
if (util_mkCert(NULL, &(agent->selfcert), 3072, 10000, "MeshNodeCertificate", CERTIFICATE_ROOT, NULL) == 0) return -1; if (util_mkCert(NULL, &(agent->selfcert), 3072, 10000, "MeshNodeCertificate", CERTIFICATE_ROOT, NULL) == 0) return -1;
util_keyhash(agent->selfcert, agent->g_selfid); util_keyhash(agent->selfcert, agent->g_selfid);
} while (((int*)agent->g_selfid)[0] == 0); // This removes any chance that the self_id starts with 32 bits of zeros. } while (((int*)agent->g_selfid)[0] == 0); // This removes any chance that the self_id starts with 32 bits of zeros.
ILibRemoteLogging_printf(ILibChainGetLogger(agent->chain), ILibRemoteLogging_Modules_Agent_GuardPost, ILibRemoteLogging_Flags_VerbosityLevel_1, "...g_selfid = %s", ILibRemoteLogging_ConvertToHex(agent->g_selfid, (int)sizeof(agent->g_selfid))); ILibRemoteLogging_printf(ILibChainGetLogger(agent->chain), ILibRemoteLogging_Modules_Agent_GuardPost, ILibRemoteLogging_Flags_VerbosityLevel_1, "...g_selfid = %s", ILibRemoteLogging_ConvertToHex(agent->g_selfid, (int)sizeof(agent->g_selfid)));
} }
@@ -1361,7 +1364,6 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
// Hash the server's web certificate and check if it matches the one in the auth request // Hash the server's web certificate and check if it matches the one in the auth request
util_keyhash2(peer, ILibScratchPad2); // Hash the server certificate public key and place it util_keyhash2(peer, ILibScratchPad2); // Hash the server certificate public key and place it
if (memcmp(ILibScratchPad2, AuthRequest->serverHash, sizeof(AuthRequest->serverHash)) != 0) { printf("Bad server certificate hash\r\n"); break; } // TODO: Disconnect if (memcmp(ILibScratchPad2, AuthRequest->serverHash, sizeof(AuthRequest->serverHash)) != 0) { printf("Bad server certificate hash\r\n"); break; } // TODO: Disconnect
memcpy_s(agent->serverNonce, sizeof(agent->serverNonce), AuthRequest->serverNonce, sizeof(AuthRequest->serverNonce)); memcpy_s(agent->serverNonce, sizeof(agent->serverNonce), AuthRequest->serverNonce, sizeof(AuthRequest->serverNonce));
@@ -1418,8 +1420,13 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
if (!d2i_X509(&serverCert, (const unsigned char**)&AuthVerify->cert, AuthVerify->certLen)) { printf("Invalid server certificate\r\n"); break; } // TODO: Disconnect if (!d2i_X509(&serverCert, (const unsigned char**)&AuthVerify->cert, AuthVerify->certLen)) { printf("Invalid server certificate\r\n"); break; } // TODO: Disconnect
// Check if this certificate public key hash matches what we want // Check if this certificate public key hash matches what we want
X509_pubkey_digest(serverCert, EVP_sha384(), (unsigned char*)ILibScratchPad, (unsigned int*)&hashlen); // OpenSSL 1.1 X509_pubkey_digest(serverCert, EVP_sha384(), (unsigned char*)ILibScratchPad, (unsigned int*)&hashlen); // OpenSSL 1.1, SHA384
if (memcmp(ILibScratchPad, agent->serverHash, UTIL_HASHSIZE) != 0) { printf("Server certificate mismatch\r\n"); break; } // TODO: Disconnect if (memcmp(ILibScratchPad, agent->serverHash, UTIL_HASHSIZE) != 0) {
X509_pubkey_digest(serverCert, EVP_sha256(), (unsigned char*)ILibScratchPad, (unsigned int*)&hashlen); // OpenSSL 1.1, SHA256 (For older .mshx policy file)
if (memcmp(ILibScratchPad, agent->serverHash, 32) != 0) {
printf("Server certificate mismatch\r\n"); break; // TODO: Disconnect
}
}
// Compute the authentication hash // Compute the authentication hash
SHA384_Init(&c); SHA384_Init(&c);
@@ -1440,6 +1447,7 @@ void MeshServer_ProcessCommand(ILibWebClient_StateObject WebStateObject, MeshAge
// Send to the server information about this agent (TODO: Replace this with a struct) // Send to the server information about this agent (TODO: Replace this with a struct)
MeshCommand_BinaryPacket_AuthInfo *info = (MeshCommand_BinaryPacket_AuthInfo*)ILibScratchPad2; MeshCommand_BinaryPacket_AuthInfo *info = (MeshCommand_BinaryPacket_AuthInfo*)ILibScratchPad2;
memset(info, 0, sizeof(MeshCommand_BinaryPacket_AuthInfo)); // Required because if hash are SHA256, they will not fully fill the struct.
info->command = htons(MeshCommand_AuthInfo); info->command = htons(MeshCommand_AuthInfo);
info->infoVersion = htonl(1); info->infoVersion = htonl(1);
info->agentId = htonl(MESH_AGENTID); info->agentId = htonl(MESH_AGENTID);
@@ -1777,6 +1785,12 @@ void MeshServer_OnResponse(ILibWebClient_StateObject WebStateObject, int Interru
agent->serverAuthState = 0; // We are not authenticated. Bitmask: 1 = Server Auth, 2 = Agent Auth. agent->serverAuthState = 0; // We are not authenticated. Bitmask: 1 = Server Auth, 2 = Agent Auth.
agent->serverConnectionState = 2; agent->serverConnectionState = 2;
// Send the ServerID to the server, this is useful for the server to use the correct certificate to authenticate.
MeshCommand_BinaryPacket_ServerId *serveridcmd = (MeshCommand_BinaryPacket_ServerId*)ILibScratchPad2;
serveridcmd->command = htons(MeshCommand_ServerId);
memcpy_s(serveridcmd->serverId, sizeof(serveridcmd->serverId), agent->serverHash, sizeof(agent->serverHash)); // Place our mesh agent nonce
ILibWebClient_WebSocket_Send(WebStateObject, ILibWebClient_WebSocket_DataType_BINARY, (char*)serveridcmd, sizeof(MeshCommand_BinaryPacket_ServerId), ILibAsyncSocket_MemoryOwnership_USER, ILibWebClient_WebSocket_FragmentFlag_Complete);
// Start authentication by sending a auth nonce & server TLS cert hash. // Start authentication by sending a auth nonce & server TLS cert hash.
// Send 384 bits SHA384 hash of TLS cert public key + 384 bits nonce // Send 384 bits SHA384 hash of TLS cert public key + 384 bits nonce
util_random(sizeof(agent->agentNonce), agent->agentNonce); // Generate a new mesh agent connection nonce util_random(sizeof(agent->agentNonce), agent->agentNonce); // Generate a new mesh agent connection nonce
@@ -1977,11 +1991,14 @@ void MeshServer_ConnectEx(MeshAgentHostContainer *agent)
return; return;
} }
memset(agent->serverHash, 0, sizeof(agent->serverHash));
util_hexToBuf(f->data, f->datalength, agent->serverHash); util_hexToBuf(f->data, f->datalength, agent->serverHash);
ILibDestructParserResults(rs); ILibDestructParserResults(rs);
if (ILibSimpleDataStore_Get(agent->masterDb, "MeshID", ILibScratchPad, sizeof(ILibScratchPad)) == 0) { printf("MeshID entry not found in Db!\n"); return; } len = ILibSimpleDataStore_Get(agent->masterDb, "MeshID", ILibScratchPad, sizeof(ILibScratchPad));
memcpy_s(agent->meshId, sizeof(agent->meshId), ILibScratchPad, UTIL_HASHSIZE); if ((len != 32) && (len != 48)) { printf("MeshID entry not found in db or bad size.\n"); return; } // Make sure MeshID is both present and SHA256 or SHA384.
memset(agent->meshId, 0, sizeof(agent->meshId)); // Clear the meshid first in case we copy SHA256
memcpy_s(agent->meshId, sizeof(agent->meshId), ILibScratchPad, len); // Copy the correct length
#ifndef MICROSTACK_NOTLS #ifndef MICROSTACK_NOTLS
util_keyhash(agent->selfcert, agent->g_selfid); // Compute our own identifier using our certificate util_keyhash(agent->selfcert, agent->g_selfid); // Compute our own identifier using our certificate
@@ -2393,6 +2410,7 @@ int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char **
#endif #endif
// Check to see if we need to import a settings file // 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")); importSettings(agentHost, MeshAgent_MakeAbsolutePath(agentHost->exePath, ".msh"));
#ifdef WIN32 #ifdef WIN32

View File

@@ -92,6 +92,7 @@ typedef enum MeshCommands_Binary
MeshCommand_AuthVerify = 2, // Agent or server signature MeshCommand_AuthVerify = 2, // Agent or server signature
MeshCommand_AuthInfo = 3, // Agent information MeshCommand_AuthInfo = 3, // Agent information
MeshCommand_AuthConfirm = 4, // Server confirm to the agent that is it authenticated MeshCommand_AuthConfirm = 4, // Server confirm to the agent that is it authenticated
MeshCommand_ServerId = 5, // Optional, agent sends the expected serverid to the server. Useful if the server has many server certificates.
MeshCommand_CoreModule = 10, // New core modules to be used instead of the old one, if empty, remove the core module MeshCommand_CoreModule = 10, // New core modules to be used instead of the old one, if empty, remove the core module
MeshCommand_CoreModuleHash = 11, // Request/return the SHA384 hash of the core module MeshCommand_CoreModuleHash = 11, // Request/return the SHA384 hash of the core module
MeshCommand_AgentHash = 12, // Request/return the SHA384 hash of the agent executable MeshCommand_AgentHash = 12, // Request/return the SHA384 hash of the agent executable

View File

@@ -259,6 +259,7 @@
<ClCompile Include="..\microscript\duktape.c" /> <ClCompile Include="..\microscript\duktape.c" />
<ClCompile Include="..\microscript\ILibAsyncSocket_Duktape.c" /> <ClCompile Include="..\microscript\ILibAsyncSocket_Duktape.c" />
<ClCompile Include="..\microscript\ILibDuktapeModSearch.c" /> <ClCompile Include="..\microscript\ILibDuktapeModSearch.c" />
<ClCompile Include="..\microscript\ILibDuktape_ChildProcess.c" />
<ClCompile Include="..\microscript\ILibDuktape_Debugger.c" /> <ClCompile Include="..\microscript\ILibDuktape_Debugger.c" />
<ClCompile Include="..\microscript\ILibDuktape_Dgram.c" /> <ClCompile Include="..\microscript\ILibDuktape_Dgram.c" />
<ClCompile Include="..\microscript\ILibDuktape_DuplexStream.c" /> <ClCompile Include="..\microscript\ILibDuktape_DuplexStream.c" />
@@ -321,6 +322,7 @@
<ClInclude Include="..\microscript\duk_config.h" /> <ClInclude Include="..\microscript\duk_config.h" />
<ClInclude Include="..\microscript\ILibAsyncSocket_Duktape.h" /> <ClInclude Include="..\microscript\ILibAsyncSocket_Duktape.h" />
<ClInclude Include="..\microscript\ILibDuktapeModSearch.h" /> <ClInclude Include="..\microscript\ILibDuktapeModSearch.h" />
<ClInclude Include="..\microscript\ILibDuktape_ChildProcess.h" />
<ClInclude Include="..\microscript\ILibDuktape_Debugger.h" /> <ClInclude Include="..\microscript\ILibDuktape_Debugger.h" />
<ClInclude Include="..\microscript\ILibDuktape_Dgram.h" /> <ClInclude Include="..\microscript\ILibDuktape_Dgram.h" />
<ClInclude Include="..\microscript\ILibDuktape_DuplexStream.h" /> <ClInclude Include="..\microscript\ILibDuktape_DuplexStream.h" />

View File

@@ -184,6 +184,9 @@
<ClCompile Include="..\microstack\ILibIPAddressMonitor.c"> <ClCompile Include="..\microstack\ILibIPAddressMonitor.c">
<Filter>Microstack</Filter> <Filter>Microstack</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\microscript\ILibDuktape_ChildProcess.c">
<Filter>Microscript</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\microscript\duk_config.h"> <ClInclude Include="..\microscript\duk_config.h">
@@ -358,5 +361,8 @@
<ClInclude Include="..\microstack\ILibIPAddressMonitor.h"> <ClInclude Include="..\microstack\ILibIPAddressMonitor.h">
<Filter>Microstack</Filter> <Filter>Microstack</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\microscript\ILibDuktape_ChildProcess.h">
<Filter>Microscript</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -35,6 +35,8 @@ limitations under the License.
#include "microstack/ILibCrypto.h" #include "microstack/ILibCrypto.h"
#include "meshcore/agentcore.h" #include "meshcore/agentcore.h"
#include "microscript/ILibDuktape_ScriptContainer.h"
#ifndef _MINCORE #ifndef _MINCORE
// #include "../kvm/kvm.h" // #include "../kvm/kvm.h"
int SetupWindowsFirewall(wchar_t* processname); int SetupWindowsFirewall(wchar_t* processname);
@@ -702,6 +704,10 @@ int main(int argc, char* argv[])
return(0); return(0);
} }
char *integratedJavaScript;
int integragedJavaScriptLen;
ILibDuktape_ScriptContainer_CheckEmbedded(argv, &integratedJavaScript, &integragedJavaScriptLen);
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
// Process extra switches // Process extra switches
@@ -759,7 +765,7 @@ int main(int argc, char* argv[])
return 0; return 0;
} }
#else #else
else if (argc > 1 && ((strcasecmp(argv[1], "run") == 0) || (strcasecmp(argv[1], "--slave") == 0))) else if (integratedJavaScript != NULL || (argc > 1 && ((strcasecmp(argv[1], "run") == 0) || (strcasecmp(argv[1], "--slave") == 0))))
{ {
// Run the mesh agent in console mode, since the agent is compiled for windows service, the KVM will not work right. This is only good for testing. // Run the mesh agent in console mode, since the agent is compiled for windows service, the KVM will not work right. This is only good for testing.
SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE); // Set SIGNAL on windows to listen for Ctrl-C SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE); // Set SIGNAL on windows to listen for Ctrl-C
@@ -767,6 +773,8 @@ int main(int argc, char* argv[])
__try __try
{ {
agent = MeshAgent_Create(); agent = MeshAgent_Create();
agent->meshCoreCtx_embeddedScript = integratedJavaScript;
agent->meshCoreCtx_embeddedScriptLen = integragedJavaScriptLen;
MeshAgent_Start(agent, argc, argv); MeshAgent_Start(agent, argc, argv);
retCode = agent->exitCode; retCode = agent->exitCode;
MeshAgent_Destroy(agent); MeshAgent_Destroy(agent);

View File

@@ -136,7 +136,7 @@ void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
// Run the MicroLMS Service // Run the MicroLMS Service
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
Chain = ILibCreateChain(); Chain = ILibCreateChain();
MicroLMS = ILibLMS_Create(Chain, selfexe); MicroLMS = ILibLMS_Create(Chain, selfexe, NULL);
if (MicroLMS != NULL) if (MicroLMS != NULL)
{ {
printf("Starting MicroLMS.\r\n"); printf("Starting MicroLMS.\r\n");
@@ -580,7 +580,7 @@ int main(int argc, char* argv[])
{ {
// Run as an command line application // Run as an command line application
Chain = ILibCreateChain(); Chain = ILibCreateChain();
MicroLMS = ILibLMS_Create(Chain, selfexe); MicroLMS = ILibLMS_Create(Chain, selfexe, NULL);
if (MicroLMS != NULL) if (MicroLMS != NULL)
{ {
#ifdef NOCOMMANDER #ifdef NOCOMMANDER

View File

@@ -0,0 +1,285 @@
#include "ILibDuktape_ChildProcess.h"
#include "ILibDuktapeModSearch.h"
#include "../microstack/ILibParsers.h"
#include "../microstack/ILibProcessPipe.h"
#include "ILibDuktape_Helpers.h"
#include "ILibDuktape_ReadableStream.h"
#include "ILibDuktape_WritableStream.h"
#include "ILibDuktape_EventEmitter.h"
#define ILibDuktape_ChildProcess_Manager "\xFF_ChildProcess_Manager"
#define ILibDuktape_ChildProcess_Process "\xFF_ChildProcess_Process"
#define ILibDuktape_ChildProcess_MemBuf "\xFF_ChildProcess_MemBuf"
typedef struct ILibDuktape_ChildProcess_SubProcess
{
duk_context *ctx;
void *subProcess;
void *chain;
ILibProcessPipe_Process childProcess;
ILibDuktape_readableStream *stdOut;
ILibDuktape_readableStream *stdErr;
ILibDuktape_WritableStream *stdIn;
int exitCode;
}ILibDuktape_ChildProcess_SubProcess;
void ILibDuktape_ChildProcess_SubProcess_StdOut_OnPause(ILibDuktape_readableStream *sender, void *user)
{
ILibDuktape_ChildProcess_SubProcess *p = (ILibDuktape_ChildProcess_SubProcess*)user;
ILibProcessPipe_Pipe_Pause(ILibProcessPipe_Process_GetStdOut(p->childProcess));
}
void ILibDuktape_ChildProcess_SubProcess_StdOut_OnResume(ILibDuktape_readableStream *sender, void *user)
{
ILibDuktape_ChildProcess_SubProcess *p = (ILibDuktape_ChildProcess_SubProcess*)user;
ILibProcessPipe_Pipe_Resume(ILibProcessPipe_Process_GetStdOut(p->childProcess));
}
void ILibDuktape_ChildProcess_SubProcess_StdErr_OnPause(ILibDuktape_readableStream *sender, void *user)
{
ILibDuktape_ChildProcess_SubProcess *p = (ILibDuktape_ChildProcess_SubProcess*)user;
ILibProcessPipe_Pipe_Pause(ILibProcessPipe_Process_GetStdErr(p->childProcess));
}
void ILibDuktape_ChildProcess_SubProcess_StdErr_OnResume(ILibDuktape_readableStream *sender, void *user)
{
ILibDuktape_ChildProcess_SubProcess *p = (ILibDuktape_ChildProcess_SubProcess*)user;
ILibProcessPipe_Pipe_Resume(ILibProcessPipe_Process_GetStdErr(p->childProcess));
}
ILibTransport_DoneState ILibDuktape_ChildProcess_SubProcess_StdIn_WriteHandler(ILibDuktape_WritableStream *stream, char *buffer, int bufferLen, void *user)
{
ILibDuktape_ChildProcess_SubProcess *p = (ILibDuktape_ChildProcess_SubProcess*)user;
return(ILibProcessPipe_Process_WriteStdIn(p->childProcess, buffer, bufferLen, ILibTransport_MemoryOwnership_USER));
}
void ILibDuktape_ChildProcess_SubProcess_StdIn_EndHandler(ILibDuktape_WritableStream *sender, void *user)
{
}
void ILibDuktape_ChildProcess_SubProcess_ExitHandler(ILibProcessPipe_Process sender, int exitCode, void* user)
{
ILibDuktape_ChildProcess_SubProcess *p = (ILibDuktape_ChildProcess_SubProcess*)user;
p->exitCode = exitCode;
duk_push_heapptr(p->ctx, p->subProcess); // [childProcess]
duk_get_prop_string(p->ctx, -1, "emit"); // [childProcess][emit]
duk_swap_top(p->ctx, -2); // [emit][this]
duk_push_string(p->ctx, "exit"); // [emit][this][exit]
duk_push_int(p->ctx, p->exitCode); // [emit][this][exit][exitCode]
duk_push_null(p->ctx); // [emit][this][exit][exitCode][sig]
if (duk_pcall_method(p->ctx, 3) != 0) { ILibDuktape_Process_UncaughtExceptionEx(p->ctx, "child_process.subProcess.exit(): "); }
duk_pop(p->ctx);
}
void ILibDuktape_ChildProcess_SubProcess_StdOutHandler(ILibProcessPipe_Process sender, char *buffer, int bufferLen, int* bytesConsumed, void* user)
{
ILibDuktape_ChildProcess_SubProcess *p = (ILibDuktape_ChildProcess_SubProcess*)user;
ILibDuktape_readableStream_WriteData(p->stdOut, buffer, bufferLen);
*bytesConsumed = bufferLen;
}
void ILibDuktape_ChildProcess_SubProcess_StdErrHandler(ILibProcessPipe_Process sender, char *buffer, int bufferLen, int* bytesConsumed, void* user)
{
ILibDuktape_ChildProcess_SubProcess *p = (ILibDuktape_ChildProcess_SubProcess*)user;
ILibDuktape_readableStream_WriteData(p->stdErr, buffer, bufferLen);
*bytesConsumed = bufferLen;
}
void ILibDuktape_ChildProcess_SubProcess_SendOK(ILibProcessPipe_Process sender, void* user)
{
ILibDuktape_ChildProcess_SubProcess *p = (ILibDuktape_ChildProcess_SubProcess*)user;
ILibDuktape_WritableStream_Ready(p->stdIn);
}
duk_ret_t ILibDuktape_ChildProcess_Kill(duk_context *ctx)
{
duk_push_this(ctx);
duk_get_prop_string(ctx, -1, ILibDuktape_ChildProcess_MemBuf);
ILibDuktape_ChildProcess_SubProcess *p = (ILibDuktape_ChildProcess_SubProcess*)Duktape_GetBuffer(ctx, -1, NULL);
ILibProcessPipe_Process_SoftKill(p->childProcess);
return(0);
}
ILibDuktape_ChildProcess_SubProcess* ILibDuktape_ChildProcess_SpawnedProcess_PUSH(duk_context *ctx, ILibProcessPipe_Process mProcess, void *callback)
{
duk_push_object(ctx); // [ChildProcess]
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]
ILibDuktape_ChildProcess_SubProcess *retVal = (ILibDuktape_ChildProcess_SubProcess*)Duktape_GetBuffer(ctx, -1, NULL);
duk_put_prop_string(ctx, -2, ILibDuktape_ChildProcess_MemBuf); // [ChildProcess]
memset(retVal, 0, sizeof(ILibDuktape_ChildProcess_SubProcess));
retVal->ctx = ctx;
retVal->subProcess = duk_get_heapptr(ctx, -1);
retVal->childProcess = mProcess;
retVal->chain = Duktape_GetChain(ctx);
ILibDuktape_CreateReadonlyProperty_int(ctx, "pid", ILibProcessPipe_Process_GetPID(mProcess));
ILibDuktape_EventEmitter *emitter = ILibDuktape_EventEmitter_Create(ctx);
ILibDuktape_EventEmitter_CreateEventEx(emitter, "exit");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "error");
ILibDuktape_CreateInstanceMethod(ctx, "kill", ILibDuktape_ChildProcess_Kill, 0);
duk_push_object(ctx);
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);
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);
retVal->stdIn = ILibDuktape_WritableStream_Init(ctx, ILibDuktape_ChildProcess_SubProcess_StdIn_WriteHandler, ILibDuktape_ChildProcess_SubProcess_StdIn_EndHandler, retVal);
ILibDuktape_CreateReadonlyProperty(ctx, "stdin");
if (callback != NULL) { ILibDuktape_EventEmitter_AddOnce(emitter, "exit", callback); }
ILibProcessPipe_Process_AddHandlers(mProcess, 4096, ILibDuktape_ChildProcess_SubProcess_ExitHandler,
ILibDuktape_ChildProcess_SubProcess_StdOutHandler,
ILibDuktape_ChildProcess_SubProcess_StdErrHandler,
ILibDuktape_ChildProcess_SubProcess_SendOK, retVal);
return(retVal);
}
duk_ret_t ILibDuktape_ChildProcess_Manager_Finalizer(duk_context *ctx)
{
duk_get_prop_string(ctx, 0, ILibDuktape_ChildProcess_Manager);
ILibProcessPipe_Manager manager = (ILibProcessPipe_Manager)duk_get_pointer(ctx, -1);
ILibChain_SafeRemove(((ILibChain_Link*)manager)->ParentChain, manager);
return(0);
}
duk_ret_t ILibDuktape_ChildProcess_execFile(duk_context *ctx)
{
int nargs = duk_get_top(ctx);
duk_push_this(ctx);
duk_get_prop_string(ctx, -1, ILibDuktape_ChildProcess_Manager);
ILibProcessPipe_Manager manager = (ILibProcessPipe_Manager)duk_get_pointer(ctx, -1);
duk_size_t targetLen;
char *target = (char*)duk_get_lstring(ctx, 0, &targetLen);
char **args = NULL;
int i, x;
void *callback = NULL;
ILibProcessPipe_Process p = NULL;
for (i = 0; i < nargs; ++i)
{
if (duk_is_array(ctx, i) != 0)
{
int arrLen = duk_get_length(ctx, i);
#ifdef WIN32
args = (char**)_alloca((arrLen + 1) * sizeof(char*));
#else
args = (char**)alloca((arrLen + 1) * sizeof(char*));
#endif
for (x = 0; x < arrLen; ++x)
{
duk_get_prop_index(ctx, i, x);
args[x] = (char*)duk_get_string(ctx, -1);
}
args[x] = NULL;
}
else if (duk_is_function(ctx, i))
{
callback = duk_get_heapptr(ctx, i);
}
}
#ifdef WIN32
if (target[0] == '%')
{
size_t evsize;
int pctx = ILibString_IndexOf(target + 1, (int)targetLen - 1, "%", 1);
if (pctx > 0)
{
memcpy_s(ILibScratchPad, sizeof(ILibScratchPad), target + 1, pctx);
ILibScratchPad[pctx] = 0;
getenv_s(&evsize, ILibScratchPad2, sizeof(ILibScratchPad2), ILibScratchPad);
if (evsize > 0)
{
strncpy_s(ILibScratchPad2 + evsize - 1, sizeof(ILibScratchPad2) - evsize, target + pctx + 2, targetLen - pctx - 2);
target = ILibScratchPad2;
}
}
}
#endif
p = ILibProcessPipe_Manager_SpawnProcess(manager, target, args);
if (p == NULL)
{
return(ILibDuktape_Error(ctx, "child_process.execFile(): Could not exec [%s]", target));
}
ILibDuktape_ChildProcess_SpawnedProcess_PUSH(ctx, p, callback);
return(1);
}
void ILibDuktape_ChildProcess_PUSH(duk_context *ctx, void *chain)
{
duk_push_object(ctx);
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);
ILibDuktape_CreateInstanceMethod(ctx, "execFile", ILibDuktape_ChildProcess_execFile, DUK_VARARGS);
}
void ILibDuktape_ChildProcess_Init(duk_context *ctx)
{
ILibDuktape_ModSearch_AddHandler(ctx, "child_process", ILibDuktape_ChildProcess_PUSH);
}
#ifdef __DOXY__
/*!
\implements EventEmitter
\brief The child_process module provides the ability to spawn child processes. <b>Note:</b> To use, must <b>require('child_process')</b>
*/
class ChildProcess
{
public:
/*!
\brief The specified file is spawned as a child process
\param file \<String\> Required. The name or path of the executable file to run
\param args \<String[]\> Optional. List of string arguments
\param options <Object> Optional. \n
cwd \<String\> Current working directory\n
env <Object> Environment key-value pairs\n
timeout <number> <b>Default</b>: 0\n
\returns \<ChildProcess\>
*/
static ChildProcess execFile(file[, args][, options][, callback]);
/*!
\brief Event emitted whenever process cannot be killed or spawned
\param err <Error> The Error
*/
void error;
/*!
\brief Event emitted after the child process ends
\param code <number> Exit code
\param signal \<String\> Not used.
*/
void exit;
/*!
\brief Process ID of the child process
*/
Integer pid;
/*!
\brief Sends SIGTERM to child process
*/
void kill();
/*!
\brief StdOut ReadableStream
*/
ReadableStream stdout;
/*!
\brief StdErr ReadableStream
*/
ReadableStream stderr;
/*!
\brief StdIn WritableStream
*/
WritableStream stdin;
};
#endif

View File

@@ -0,0 +1,9 @@
#ifndef __ILIBDUKTAPE_CHILDPROCESS__
#define __ILIBDUKTAPE_CHILDPROCESS__
#include "duktape.h"
void ILibDuktape_ChildProcess_Init(duk_context *ctx);
#endif

View File

@@ -30,8 +30,11 @@ void ILibDuktape_EventEmitter_RemoveEventHeapptr(ILibDuktape_EventEmitter *emitt
int ILibDuktape_EventEmitter_AddEventHeapptr(ILibDuktape_EventEmitter *emitter, char *eventName, void **heapptr); // Add Callback after the fact 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_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_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_AddOnceEx2(duk_context *ctx, duk_idx_t idx, char *eventName, duk_c_function func, duk_idx_t funcArgs);
int ILibDuktape_EventEmitter_AddOn(ILibDuktape_EventEmitter *emitter, char *eventName, void *heapptr); // Add native event handler int ILibDuktape_EventEmitter_AddOn(ILibDuktape_EventEmitter *emitter, char *eventName, void *heapptr); // Add native event handler
void ILibDuktape_EventEmitter_AddHook(ILibDuktape_EventEmitter *emitter, char *eventName, ILibDuktape_EventEmitter_HookHandler handler); void ILibDuktape_EventEmitter_AddHook(ILibDuktape_EventEmitter *emitter, char *eventName, ILibDuktape_EventEmitter_HookHandler handler);

View File

@@ -37,7 +37,21 @@ struct sockaddr_in6 duktape_internalAddress;
#define ILibDuktape_EventEmitter_Table "\xFF_EventEmitterTable" #define ILibDuktape_EventEmitter_Table "\xFF_EventEmitterTable"
#define ILibDuktape_Process_ExitCode "\xFF_ExitCode" #define ILibDuktape_Process_ExitCode "\xFF_ExitCode"
#define ILibDuktape_Memory_AllocTable "\xFF_MemoryAllocTable" #define ILibDuktape_Memory_AllocTable "\xFF_MemoryAllocTable"
#define ILibDuktape_ObjectStashKey "\xFF_ObjectStashKey"
void ILibDuktape_Push_ObjectStash(duk_context *ctx)
{
if (duk_has_prop_string(ctx, -1, ILibDuktape_ObjectStashKey))
{
duk_get_prop_string(ctx, -1, ILibDuktape_ObjectStashKey); // [obj][stash]
}
else
{
duk_push_object(ctx); // [obj][stash]
duk_dup(ctx, -1); // [obj][stash][stash]
duk_put_prop_string(ctx, -3, ILibDuktape_ObjectStashKey); // [obj][stash]
}
}
duk_ret_t ILibDuktape_Error(duk_context *ctx, char *format, ...) duk_ret_t ILibDuktape_Error(duk_context *ctx, char *format, ...)
{ {
char dest[4096]; char dest[4096];
@@ -444,27 +458,15 @@ void ILibDuktape_Process_UncaughtException(duk_context *ctx)
char* Duktape_GetContextGuidHex(duk_context *ctx) char* Duktape_GetContextGuidHex(duk_context *ctx)
{ {
char *retVal = NULL; char *retVal = NULL;
char *guid;
duk_size_t guidLength;
int i;
duk_push_heap_stash(ctx); // [stash] duk_push_heap_stash(ctx); // [stash]
if (duk_has_prop_string(ctx, -1, CONTEXT_GUID_BUFFER)) if (duk_has_prop_string(ctx, -1, "\xFF_ScriptContainerSettings_DB"))
{ {
duk_get_prop_string(ctx, -1, CONTEXT_GUID_BUFFER); // [stash][str] duk_get_prop_string(ctx, -1, "\xFF_ScriptContainerSettings_DB"); // [stash][db]
guid = (char*)Duktape_GetBuffer(ctx, -1, &guidLength); if (duk_get_pointer(ctx, -1) != NULL) { retVal = "0"; }
for (i = (int)guidLength-1; i > 1 && guid[i] == 0; --i) duk_pop(ctx); // [stash]
{
}
util_tohex(guid, (int)guidLength, ILibScratchPad);
duk_pop(ctx); // [stash]
for (i = ((int)guidLength * 2) - 1; i > 1 && ILibScratchPad[i] == 48; --i)
{
}
retVal = ILibScratchPad;
retVal[i] = 0;
} }
duk_pop(ctx); // ... duk_pop(ctx); // ...
return retVal; return retVal;
} }
void *Duktape_GetChain(duk_context *ctx) void *Duktape_GetChain(duk_context *ctx)

View File

@@ -83,4 +83,6 @@ void ILibDuktape_CreateReadonlyProperty(duk_context *ctx, char *propName);
void *ILibDuktape_Memory_Alloc(duk_context *ctx, duk_size_t size); void *ILibDuktape_Memory_Alloc(duk_context *ctx, duk_size_t size);
void ILibDuktape_Helper_AddHeapFinalizer(duk_context *ctx, ILibDuktape_HelperEvent handler, void *user); void ILibDuktape_Helper_AddHeapFinalizer(duk_context *ctx, ILibDuktape_HelperEvent handler, void *user);
void ILibDuktape_Push_ObjectStash(duk_context *ctx);
#endif #endif

View File

@@ -81,7 +81,17 @@ duk_ret_t ILibDuktape_Polyfills_Buffer_from(duk_context *ctx)
char *buffer; char *buffer;
int bufferLen; int bufferLen;
if (!(nargs == 2 && duk_is_string(ctx, 0) && duk_is_string(ctx, 1))) if (nargs == 1)
{
str = (char*)duk_get_lstring(ctx, 0, &strlength);
duk_push_fixed_buffer(ctx, strlength + 1);
buffer = Duktape_GetBuffer(ctx, -1, NULL);
memcpy_s(buffer, strlength + 1, str, strlength);
buffer[strlength] = 0;
duk_push_buffer_object(ctx, -1, 0, strlength+1, DUK_BUFOBJ_ARRAYBUFFER);
return(1);
}
else if(!(nargs == 2 && duk_is_string(ctx, 0) && duk_is_string(ctx, 1)))
{ {
duk_push_string(ctx, "Buffer.from(): Usage not supported yet."); duk_push_string(ctx, "Buffer.from(): Usage not supported yet.");
duk_throw(ctx); duk_throw(ctx);
@@ -97,14 +107,14 @@ duk_ret_t ILibDuktape_Polyfills_Buffer_from(duk_context *ctx)
duk_push_fixed_buffer(ctx, ILibBase64DecodeLength((int)strlength)); duk_push_fixed_buffer(ctx, ILibBase64DecodeLength((int)strlength));
buffer = Duktape_GetBuffer(ctx, -1, NULL); buffer = Duktape_GetBuffer(ctx, -1, NULL);
bufferLen = ILibBase64Decode((unsigned char*)str, (int)strlength, (unsigned char**)&buffer); bufferLen = ILibBase64Decode((unsigned char*)str, (int)strlength, (unsigned char**)&buffer);
duk_push_buffer_object(ctx, -1, 0, bufferLen, DUK_BUFOBJ_DUKTAPE_BUFFER); duk_push_buffer_object(ctx, -1, 0, bufferLen, DUK_BUFOBJ_ARRAYBUFFER);
} }
else if (strcmp(encoding, "hex") == 0) else if (strcmp(encoding, "hex") == 0)
{ {
duk_push_fixed_buffer(ctx, strlength / 2); duk_push_fixed_buffer(ctx, strlength / 2);
buffer = Duktape_GetBuffer(ctx, -1, NULL); buffer = Duktape_GetBuffer(ctx, -1, NULL);
bufferLen = util_hexToBuf(str, (int)strlength, buffer); bufferLen = util_hexToBuf(str, (int)strlength, buffer);
duk_push_buffer_object(ctx, -1, 0, bufferLen, DUK_BUFOBJ_DUKTAPE_BUFFER); duk_push_buffer_object(ctx, -1, 0, bufferLen, DUK_BUFOBJ_ARRAYBUFFER);
} }
else else
{ {
@@ -219,7 +229,25 @@ duk_ret_t ILibDuktape_Polyfills_Console_log(duk_context *ctx)
else else
{ {
duk_dup(ctx, i); duk_dup(ctx, i);
printf("%s%s", (i == 0 ? "" : ", "), duk_to_string(ctx, -1)); if (strcmp("[object Object]", duk_to_string(ctx, -1)) == 0)
{
duk_pop(ctx);
duk_dup(ctx, i);
printf("%s", (i == 0 ? "{" : ", {"));
duk_enum(ctx, -1, DUK_ENUM_OWN_PROPERTIES_ONLY);
int propNum = 0;
while (duk_next(ctx, -1, 1))
{
printf("%s%s: %s", ((propNum++ == 0) ? " " : ", "), (char*)duk_to_string(ctx, -2), (char*)duk_to_string(ctx, -1));
duk_pop_2(ctx);
}
duk_pop(ctx);
printf(" }");
}
else
{
printf("%s%s", (i == 0 ? "" : ", "), duk_to_string(ctx, -1));
}
} }
} }
printf("\n"); printf("\n");

View File

@@ -386,10 +386,13 @@ int ILibDuktape_readableStream_WriteDataEx(ILibDuktape_readableStream *stream, i
else else
{ {
// Need to PAUSE, and context switch to Chain Thread, so we can dispatch into JavaScript // Need to PAUSE, and context switch to Chain Thread, so we can dispatch into JavaScript
if (stream->paused == 0 && stream->PauseHandler != NULL) { stream->paused = 1; stream->PauseHandler(stream, stream->user); } sem_wait(&(stream->pipeLock));
stream->extBuffer_Reserved = streamReserved; stream->extBuffer_Reserved = streamReserved;
stream->extBuffer_buffer = buffer; stream->extBuffer_buffer = buffer;
stream->extBuffer_bufferLen = bufferLen; stream->extBuffer_bufferLen = bufferLen;
sem_post(&(stream->pipeLock));
if (stream->paused == 0 && stream->PauseHandler != NULL) { stream->paused = 1; stream->PauseHandler(stream, stream->user); }
ILibChain_RunOnMicrostackThread(stream->chain, ILibDuktape_readableStream_WriteData_OnData_ChainThread, stream); ILibChain_RunOnMicrostackThread(stream->chain, ILibDuktape_readableStream_WriteData_OnData_ChainThread, stream);
} }
} }

View File

@@ -57,7 +57,11 @@ limitations under the License.
#include "ILibDuktape_SHA256.h" #include "ILibDuktape_SHA256.h"
#include "ILibDuktape_EncryptionStream.h" #include "ILibDuktape_EncryptionStream.h"
#include "ILibDuktape_ChildProcess.h"
#ifdef _POSIX
extern char **environ;
#endif
#define SCRIPT_ENGINE_PIPE_BUFFER_SIZE 65535 #define SCRIPT_ENGINE_PIPE_BUFFER_SIZE 65535
#define ILibDuktape_ScriptContainer_MasterPtr "\xFF_ScriptContainer_MasterPtr" #define ILibDuktape_ScriptContainer_MasterPtr "\xFF_ScriptContainer_MasterPtr"
#define ILibDuktape_ScriptContainer_SlavePtr "\xFF_ScriptContainer_SlavePtr" #define ILibDuktape_ScriptContainer_SlavePtr "\xFF_ScriptContainer_SlavePtr"
@@ -183,6 +187,58 @@ void ILibDuktape_ScriptContainer_Slave_OnBrokenPipe(ILibProcessPipe_Pipe sender)
ILibStopChain(((ILibDuktape_ScriptContainer_Slave*)((void**)ILibMemory_GetExtraMemory(sender, ILibMemory_ILibProcessPipe_Pipe_CONTAINERSIZE))[0])->chain); ILibStopChain(((ILibDuktape_ScriptContainer_Slave*)((void**)ILibMemory_GetExtraMemory(sender, ILibMemory_ILibProcessPipe_Pipe_CONTAINERSIZE))[0])->chain);
} }
void ILibDuktape_ScriptContainer_CheckEmbedded(char **argv, char **script, int *scriptLen)
{
// Check if .JS file is integrated with executable
FILE *tmpFile;
char *integratedJavaScript = NULL;
int integratedJavaScriptLen = 0;
#ifdef WIN32
if (ILibString_EndsWith(argv[0], -1, ".exe", 4) == 0)
{
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "%s.exe", argv[0]);
tmpFile = fopen(ILibScratchPad, "rb");
}
else
{
tmpFile = fopen(argv[0], "rb");
}
#else
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]))
{
fseek(tmpFile, ftell(tmpFile) - 8, 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);
ignore_result(fread(integratedJavaScript, 1, integratedJavaScriptLen, tmpFile));
integratedJavaScript[integratedJavaScriptLen] = 0;
}
fclose(tmpFile);
}
*script = integratedJavaScript;
*scriptLen = integratedJavaScriptLen;
}
// Polyfill process object: // Polyfill process object:
void ILibDuktape_ScriptContainer_Process_ExitCallback(void *obj) void ILibDuktape_ScriptContainer_Process_ExitCallback(void *obj)
{ {
@@ -247,6 +303,49 @@ duk_ret_t ILibDuktape_ScriptContainer_Process_Argv(duk_context *ctx)
return 1; return 1;
} }
duk_ret_t ILibDuktape_ScriptContainer_Process_env(duk_context *ctx)
{
duk_push_object(ctx); // [env]
#ifdef WIN32
int i;
char *envStrings = GetEnvironmentStringsA();
int envStringsLen = ILibString_IndexOf(envStrings, INT_MAX, "\0\0", 2);
if (envStringsLen > 0)
{
parser_result *r = ILibParseString(envStrings, 0, envStringsLen, "\0", 1);
parser_result_field *f = r->FirstResult;
while (f != NULL)
{
i = ILibString_IndexOf(f->data, f->datalength, "=", 1);
if (i > 0)
{ // [env]
duk_push_lstring(ctx, f->data, i); // [env][key]
duk_push_string(ctx, f->data + i + 1); // [env][key][val]
duk_put_prop(ctx, -3); // [env]
}
f = f->NextResult;
}
ILibDestructParserResults(r);
}
FreeEnvironmentStringsA(envStrings);
#elif defined(_POSIX)
for (char **env = environ; *env; ++env)
{
int envLen = (int)strnlen_s(*env, INT_MAX);
int i = ILibString_IndexOf(*env, envLen, "=", 1);
if (i > 0)
{
duk_push_lstring(ctx, *env, i);
duk_push_string(ctx, *env + i + 1);
duk_put_prop(ctx, -3);
}
}
#endif
return(1);
}
void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList) void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList)
{ {
int i = 0; int i = 0;
@@ -254,6 +353,8 @@ void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList)
duk_push_global_object(ctx); // [g] duk_push_global_object(ctx); // [g]
duk_push_object(ctx); // [g][process] duk_push_object(ctx); // [g][process]
ILibDuktape_CreateEventWithGetter(ctx, "env", ILibDuktape_ScriptContainer_Process_env);
#if defined(WIN32) // [g][process][platform] #if defined(WIN32) // [g][process][platform]
duk_push_string(ctx, "win32"); duk_push_string(ctx, "win32");
#elif defined(__APPLE__) #elif defined(__APPLE__)
@@ -263,6 +364,19 @@ void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList)
#endif #endif
duk_put_prop_string(ctx, -2, "platform"); // [g][process] duk_put_prop_string(ctx, -2, "platform"); // [g][process]
duk_push_heap_stash(ctx); // [g][process][stash]
if (duk_has_prop_string(ctx, -1, ILibDuktape_ScriptContainer_ExePath))
{
duk_get_prop_string(ctx, -1, ILibDuktape_ScriptContainer_ExePath); // [g][process][stash][path]
duk_swap_top(ctx, -2); // [g][process][path][stash]
duk_pop(ctx); // [g][process][path]
ILibDuktape_CreateReadonlyProperty(ctx, "execPath"); // [g][process]
}
else
{
duk_pop(ctx); // [g][process]
}
if (argList != NULL) if (argList != NULL)
{ {
duk_push_array(ctx); // [g][process][array] duk_push_array(ctx); // [g][process][array]
@@ -691,7 +805,7 @@ duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx(SCRIPT_ENG
ILibDuktape_DGram_Init(ctx); // Datagram Sockets ILibDuktape_DGram_Init(ctx); // Datagram Sockets
} }
if ((securityFlags & SCRIPT_ENGINE_NO_GENERIC_MARSHAL_ACCESS) == 0) { ILibDuktape_GenericMarshal_init(ctx); } if ((securityFlags & SCRIPT_ENGINE_NO_GENERIC_MARSHAL_ACCESS) == 0) { ILibDuktape_GenericMarshal_init(ctx); }
if ((securityFlags & SCRIPT_ENGINE_NO_PROCESS_SPAWNING) == 0) { ILibDuktape_ProcessPipe_Init(ctx, chain); } if ((securityFlags & SCRIPT_ENGINE_NO_PROCESS_SPAWNING) == 0) { ILibDuktape_ProcessPipe_Init(ctx, chain); ILibDuktape_ChildProcess_Init(ctx); }
if ((securityFlags & SCRIPT_ENGINE_NO_FILE_SYSTEM_ACCESS) == 0) { ILibDuktape_fs_init(ctx); } if ((securityFlags & SCRIPT_ENGINE_NO_FILE_SYSTEM_ACCESS) == 0) { ILibDuktape_fs_init(ctx); }

View File

@@ -140,6 +140,7 @@ typedef struct SCRIPT_ENGINE_SETTINGS
}SCRIPT_ENGINE_SETTINGS; }SCRIPT_ENGINE_SETTINGS;
void ILibDuktape_ScriptContainer_CheckEmbedded(char **argv, char **script, int *scriptLen);
void ILibDuktape_ScriptContainer_InitMaster(void *chain, char *exePath, ILibProcessPipe_Manager manager); void ILibDuktape_ScriptContainer_InitMaster(void *chain, char *exePath, ILibProcessPipe_Manager manager);
int ILibDuktape_ScriptContainer_StartSlave(void *chain, ILibProcessPipe_Manager manager); int ILibDuktape_ScriptContainer_StartSlave(void *chain, ILibProcessPipe_Manager manager);

View File

@@ -35,6 +35,7 @@ limitations under the License.
#include "ILibDuktape_DuplexStream.h" #include "ILibDuktape_DuplexStream.h"
#include "ILibDuktape_EventEmitter.h" #include "ILibDuktape_EventEmitter.h"
#include "microstack/ILibCrypto.h" #include "microstack/ILibCrypto.h"
#include "microstack/ILibRemoteLogging.h"
#define HTTP_SERVER_PTR "\xFF_ServerPtr" #define HTTP_SERVER_PTR "\xFF_ServerPtr"
#define HTTP_WEBCLIENT_MGR "_RequestManagerPtr" #define HTTP_WEBCLIENT_MGR "_RequestManagerPtr"
@@ -52,13 +53,20 @@ limitations under the License.
#define HTTP_STREAM_WRAPPER_BUFSIZE 4096 #define HTTP_STREAM_WRAPPER_BUFSIZE 4096
#define HTTP_CLIENTREQUEST_PARAMETER "\xFF_http_clientRequest_parameter" #define HTTP_CLIENTREQUEST_PARAMETER "\xFF_http_clientRequest_parameter"
#define CLIENTREQUEST_HTTP "\xFF_clientRequest_HTTP" #define CLIENTREQUEST_HTTP "\xFF_clientRequest_HTTP"
#define CLIENTREQUEST_SOCKET_WCDO "\xFF_clientRequest_SOCKET_WCDO"
#define HTTP_INCOMINGMSG_WebStateObject "\xFF_incomingMessage_WebStateObject" #define HTTP_INCOMINGMSG_WebStateObject "\xFF_incomingMessage_WebStateObject"
#define DIGEST_USERNAME "\xFF_DigestUsername" #define DIGEST_USERNAME "\xFF_DigestUsername"
#define DIGEST_PASSWORD "\xFF_DigestPassword" #define DIGEST_PASSWORD "\xFF_DigestPassword"
#define DIGEST_WCDO "\xFF_DIGEST_WCDO"
#define HTTP_DIGEST "\xFF_HTTP_DIGEST" #define HTTP_DIGEST "\xFF_HTTP_DIGEST"
#define DIGEST_CLIENT_REQUEST "\xFF_DIGEST_CLIENT_REQUEST" #define DIGEST_CLIENT_REQUEST "\xFF_DIGEST_CLIENT_REQUEST"
#define HTTP_CLIENTREQUEST_DATAPTR "\xFF_CLIENTREQUEST_DATAPTR" #define HTTP_CLIENTREQUEST_DATAPTR "\xFF_CLIENTREQUEST_DATAPTR"
#define CLIENTREQUEST_EVENT_NAME "\xFF_CLIENTREQUEST_EVENT_NAME" #define CLIENTREQUEST_EVENT_NAME "\xFF_CLIENTREQUEST_EVENT_NAME"
#define CLIENTREQUEST_IMSG_RSPTR "\xFF_CLIENTREQUEST_IMSG_RSPTR"
#define DIGESTCLIENTREQUEST_END_CALLED "\xFF_DIGESTCLIENTREQUEST_END_CALLED"
#define DIGESTCLIENTREQUEST_CONTINUE "\xFF_DIGESTCLIENTREQUEST_CONTINUE"
#define DIGESTCLIENTREQUEST_TmpBuffer "\xFF_DIGESTCLIENTREQUEST_TmpBuffer"
#define DIGESTCLIENTREQUEST_DIGEST "\xFF_DIGESTCLIENTREQUEST_DIGEST"
extern duk_idx_t ILibWebServer_DukTape_Push_ILibWebServerSession(duk_context *ctx, ILibWebServer_Session *session); extern duk_idx_t ILibWebServer_DukTape_Push_ILibWebServerSession(duk_context *ctx, ILibWebServer_Session *session);
void* ILibDuktape_http_request_PUSH_clientRequest(duk_context *ctx, ILibWebClient_RequestToken token, int isWebSocket); void* ILibDuktape_http_request_PUSH_clientRequest(duk_context *ctx, ILibWebClient_RequestToken token, int isWebSocket);
@@ -84,6 +92,7 @@ typedef struct ILibDuktape_http_requestClient_callbacks
void *requestStream; void *requestStream;
void *OnReceive; void *OnReceive;
void *OnContinue; void *OnContinue;
void *OnSocket;
#ifndef MICROSTACK_NOTLS #ifndef MICROSTACK_NOTLS
int rejectUnauthorized; int rejectUnauthorized;
void *checkServerIdentity; void *checkServerIdentity;
@@ -954,6 +963,33 @@ duk_ret_t ILibDuktape_http_server_tlsSettings_Finalizer(duk_context *ctx)
{ {
return 0; return 0;
} }
duk_ret_t ILibDuktape_http_server_address(duk_context *ctx)
{
duk_push_this(ctx);
if (!duk_has_prop_string(ctx, -1, HTTP_SERVER_PTR))
{
return(ILibDuktape_Error(ctx, "http.server.address(): Not listening"));
}
duk_get_prop_string(ctx, -1, HTTP_SERVER_PTR);
ILibAsyncServerSocket_ServerModule s = ILibWebServer_GetServerSocketModule((ILibWebServer_ServerToken)duk_get_pointer(ctx, -1));
struct sockaddr_in6 local;
memset(&local, 0, sizeof(struct sockaddr_in6));
ILibAsyncServerSocket_GetLocal(s, (struct sockaddr*)&local, sizeof(struct sockaddr_in6));
if (local.sin6_family == AF_UNSPEC) { return(ILibDuktape_Error(ctx, "net.server.address(): call to getsockname() failed")); }
duk_push_object(ctx);
duk_push_string(ctx, local.sin6_family == AF_INET6 ? "IPv6" : "IPv4");
duk_put_prop_string(ctx, -2, "family");
duk_push_int(ctx, (int)ntohs(local.sin6_port));
duk_put_prop_string(ctx, -2, "port");
duk_push_string(ctx, ILibRemoteLogging_ConvertAddress((struct sockaddr*)&local));
duk_put_prop_string(ctx, -2, "address");
return(1);
}
duk_ret_t ILibDuktape_http_createServer(duk_context *ctx) duk_ret_t ILibDuktape_http_createServer(duk_context *ctx)
{ {
int nargs = duk_get_top(ctx); int nargs = duk_get_top(ctx);
@@ -1060,6 +1096,7 @@ duk_ret_t ILibDuktape_http_createServer(duk_context *ctx)
duk_push_c_function(ctx, ILibDuktape_http_server_listen, DUK_VARARGS); // [http][server][func] duk_push_c_function(ctx, ILibDuktape_http_server_listen, DUK_VARARGS); // [http][server][func]
duk_put_prop_string(ctx, -2, "listen"); // [http][server] duk_put_prop_string(ctx, -2, "listen"); // [http][server]
ILibDuktape_CreateInstanceMethod(ctx, "_address", ILibDuktape_http_server_address, 0);
return 1; return 1;
} }
@@ -1096,15 +1133,13 @@ void ILibDuktape_http_request_OnResponse(ILibWebClient_StateObject WebStateObjec
{ {
if (ctx != NULL) if (ctx != NULL)
{ {
duk_push_heapptr(ctx, ptrs->OnReceive); // [func] duk_push_heapptr(ctx, ptrs->clientRequest); // [clientRequest]
duk_push_heapptr(ctx, ptrs->clientRequest); // [func][this] duk_get_prop_string(ctx, -1, "emit"); // [clientRequest][emit]
duk_del_prop_string(ctx, -1, HTTP_REQUEST_TOKEN_PTR); // (Prevents crash in Request Finalizer) duk_swap_top(ctx, -2); // [emit][this]
duk_push_null(ctx); // [func][this][null] duk_push_string(ctx, "error"); // [emit][this][error]
if (duk_pcall_method(ctx, 1) != 0) // [retVal] duk_push_error_object(ctx, DUK_ERR_ERROR, "Socket was unexpectedly closed"); // [emit][this][error][err]
{ if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.request.OnError(): "); }
ILibDuktape_Process_UncaughtException(ctx); duk_pop(ctx); // ...
}
duk_pop(ctx); // ...
} }
return; return;
} }
@@ -1147,6 +1182,7 @@ void ILibDuktape_http_request_OnResponse(ILibWebClient_StateObject WebStateObjec
{ {
duk_push_heapptr(ctx, ptrs->clientRequest); // [clientRequest] duk_push_heapptr(ctx, ptrs->clientRequest); // [clientRequest]
duk_del_prop_string(ctx, -1, HTTP_REQUEST_TOKEN_PTR); duk_del_prop_string(ctx, -1, HTTP_REQUEST_TOKEN_PTR);
duk_del_prop_string(ctx, -1, HTTP_REQUEST_USER_PTR);
ILibDuktape_EventEmitter_RemoveAll(ILibDuktape_EventEmitter_GetEmitter(ctx, -1)); ILibDuktape_EventEmitter_RemoveAll(ILibDuktape_EventEmitter_GetEmitter(ctx, -1));
duk_pop(ctx); // ... duk_pop(ctx); // ...
} }
@@ -1479,8 +1515,27 @@ void ILibDuktape_http_webSocket_onSendOk(ILibWebClient_StateObject sender, void
ILibDuktape_DuplexStream_Ready(ptrs->stream); ILibDuktape_DuplexStream_Ready(ptrs->stream);
} }
} }
void ILibDuktape_http_request_idleTimeout(ILibAsyncSocket_SocketModule sender, void *user)
{
ILibWebClient_RequestToken token = ILibWebClient_GetRequestToken_FromStateObject(user);
void ** u = ILibWebClient_RequestToken_GetUserObjects(token);
if (u[1] != NULL && ((ILibDuktape_http_request_dataType*)u[1])->STRUCT_TYPE == ILibDuktape_http_request_dataType_request &&
((ILibDuktape_http_requestClient_callbacks*)u[1])->clientRequest != NULL)
{
duk_context *ctx = (duk_context*)u[0];
ILibDuktape_http_requestClient_callbacks *cb = (ILibDuktape_http_requestClient_callbacks*)u[1];
duk_push_heapptr(ctx, cb->clientRequest); // [clientRequest]
duk_get_prop_string(ctx, -1, "emit"); // [clientRequest][emit]
duk_swap_top(ctx, -2); // [emit][this]
duk_push_string(ctx, "timeout"); // [emit][this][timeout]
if (duk_pcall_method(ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.clientRequest.onTimeout(): "); }
duk_pop(ctx);
}
}
duk_ret_t ILibDuktape_http_request(duk_context *ctx) duk_ret_t ILibDuktape_http_request(duk_context *ctx)
{ {
union { int i; void*p; }u;
ILibHTTPPacket *packet; ILibHTTPPacket *packet;
char *host; char *host;
duk_size_t hostLen; duk_size_t hostLen;
@@ -1509,6 +1564,10 @@ duk_ret_t ILibDuktape_http_request(duk_context *ctx)
{ {
duk_get_prop_string(ctx, -1, HTTP_WEBCLIENT_MGR); duk_get_prop_string(ctx, -1, HTTP_WEBCLIENT_MGR);
wcm = (ILibWebClient_RequestManager)duk_to_pointer(ctx, -1); wcm = (ILibWebClient_RequestManager)duk_to_pointer(ctx, -1);
if (protocol == ILibWebClient_RequestToken_USE_HTTPS)
{
ILibWebClient_EnableHTTPS(wcm, NULL, NULL, ILibDuktape_http_request_tls_verify);
}
} }
else else
{ {
@@ -1589,7 +1648,6 @@ duk_ret_t ILibDuktape_http_request(duk_context *ctx)
if (isWebSocket != 0) if (isWebSocket != 0)
{ {
union { int i; void*p; }u;
int len; int len;
char value[32]; char value[32];
char nonce[16]; char nonce[16];
@@ -1607,6 +1665,13 @@ duk_ret_t ILibDuktape_http_request(duk_context *ctx)
ILibHTTPPacket_Stash_Put(packet, "_WebSocketOnSendOK", -1, ILibDuktape_http_webSocket_onSendOk); ILibHTTPPacket_Stash_Put(packet, "_WebSocketOnSendOK", -1, ILibDuktape_http_webSocket_onSendOk);
} }
u.i = Duktape_GetIntPropertyValue(ctx, 0, "timeout", 0);
if (u.i > 0)
{
ILibHTTPPacket_Stash_Put(packet, "_idleTimeout", -1, u.p);
ILibHTTPPacket_Stash_Put(packet, "_idleTimeoutHandler", -1, ILibDuktape_http_request_idleTimeout);
}
if (duk_has_prop_string(ctx, 0, "headers")) if (duk_has_prop_string(ctx, 0, "headers"))
{ {
duk_get_prop_string(ctx, 0, "headers"); duk_get_prop_string(ctx, 0, "headers");
@@ -1750,10 +1815,66 @@ duk_ret_t ILibDuktape_http_request_no_op(duk_context *ctx)
{ {
return 0; return 0;
} }
void ILibDuktape_http_request_connect(ILibWebClient_RequestToken token)
{
ILibWebClient_StateObject wcdo = ILibWebClient_GetStateObjectFromRequestToken(token);
void **user = ILibWebClient_RequestToken_GetUserObjects(token);
duk_context *ctx = (duk_context*)user[0];
ILibDuktape_http_requestClient_callbacks *ptr = (ILibDuktape_http_requestClient_callbacks*)user[1];
if (ctx != NULL && ptr != NULL && ptr->OnSocket != NULL)
{
duk_push_object(ctx); // [socket]
duk_push_pointer(ctx, wcdo); // [socket][wcdo]
duk_put_prop_string(ctx, -2, CLIENTREQUEST_SOCKET_WCDO); // [socket]
duk_push_heapptr(ctx, ptr->clientRequest); // [socket][clientRequest]
duk_dup(ctx, -2); // [socket][clientRequest][socket]
ILibDuktape_CreateReadonlyProperty(ctx, "socket"); // [socket][clientRequest]
duk_pop(ctx); // [socket]
duk_push_heapptr(ctx, ptr->clientRequest); // [socket][clientRequest]
ILibDuktape_Push_ObjectStash(ctx); // [socket][clientRequest][stash]
duk_dup(ctx, -3); // [socket][clientRequest][stash][socket]
duk_put_prop_string(ctx, -2, Duktape_GetStashKey(wcdo)); // [socket][clientRequest][stash]
duk_pop_2(ctx); // [socket]
ILibDuktape_EventEmitter *emitter = ILibDuktape_EventEmitter_Create(ctx);
ILibDuktape_EventEmitter_CreateEventEx(emitter, "end");
duk_push_heapptr(ctx, ptr->OnSocket); // [socket][OnSocket]
duk_push_heapptr(ctx, ptr->clientRequest); // [socket][OnSocket][this]
duk_dup(ctx, -3); // [socket][OnSocket][this][socket]
if (duk_pcall_method(ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.request_connect.onSocket(): "); }
duk_pop_2(ctx); // ...
}
}
void ILibDuktape_http_request_disconnect(ILibWebClient_RequestToken token)
{
ILibWebClient_StateObject wcdo = ILibWebClient_GetStateObjectFromRequestToken(token);
char *key = Duktape_GetStashKey(wcdo);
void **user = ILibWebClient_RequestToken_GetUserObjects(token);
if (user == NULL) { return; }
duk_context *ctx = (duk_context*)user[0];
ILibDuktape_http_requestClient_callbacks *ptr = (ILibDuktape_http_requestClient_callbacks*)user[1];
if (ctx != NULL && ptr != NULL)
{
duk_push_heapptr(ctx, ptr->clientRequest); // [clientRequest]
ILibDuktape_Push_ObjectStash(ctx); // [clientRequest][stash]
if (duk_has_prop_string(ctx, -1, key))
{
duk_get_prop_string(ctx, -1, key); // [clientRequest][stash][socket]
duk_get_prop_string(ctx, -1, "emit"); // [clientRequest][stash][socket][emit]
duk_swap_top(ctx, -2); // [clientRequest][stash][emit][this]
duk_push_string(ctx, "end"); // [clientRequest][stash][emit][this][end]
if (duk_pcall_method(ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.request_disconnect(): "); }
duk_pop(ctx); // [clientRequest][stash]
duk_del_prop_string(ctx, -2, key);
}
duk_pop_2(ctx); // ...
}
}
void* ILibDuktape_http_request_PUSH_clientRequest(duk_context *ctx, ILibWebClient_RequestToken token, int isWebSocket) void* ILibDuktape_http_request_PUSH_clientRequest(duk_context *ctx, ILibWebClient_RequestToken token, int isWebSocket)
{ {
ILibDuktape_EventEmitter *emitter = NULL; ILibDuktape_EventEmitter *emitter = NULL;
void **user = ILibWebClient_RequestToken_GetUserObjects_Tail(token); void **user = ILibWebClient_RequestToken_GetUserObjects(token);
if (user[1] != NULL && ((ILibDuktape_http_request_dataType*)user[1])->STRUCT_TYPE == ILibDuktape_http_request_dataType_request && if (user[1] != NULL && ((ILibDuktape_http_request_dataType*)user[1])->STRUCT_TYPE == ILibDuktape_http_request_dataType_request &&
((ILibDuktape_http_requestClient_callbacks*)user[1])->clientRequest != NULL) ((ILibDuktape_http_requestClient_callbacks*)user[1])->clientRequest != NULL)
@@ -1762,6 +1883,11 @@ void* ILibDuktape_http_request_PUSH_clientRequest(duk_context *ctx, ILibWebClien
return(user[1]); return(user[1]);
} }
if (isWebSocket == 0)
{
ILibWebClient_RequestToken_ConnectionHandler_Set(token, ILibDuktape_http_request_connect, ILibDuktape_http_request_disconnect);
}
duk_push_object(ctx); // [obj] duk_push_object(ctx); // [obj]
duk_push_pointer(ctx, user); duk_push_pointer(ctx, user);
duk_put_prop_string(ctx, -2, HTTP_REQUEST_USER_PTR); duk_put_prop_string(ctx, -2, HTTP_REQUEST_USER_PTR);
@@ -1783,6 +1909,9 @@ void* ILibDuktape_http_request_PUSH_clientRequest(duk_context *ctx, ILibWebClien
{ {
ILibDuktape_EventEmitter_CreateEvent(emitter, "response", &(((ILibDuktape_http_requestClient_callbacks*)user[1])->OnReceive)); ILibDuktape_EventEmitter_CreateEvent(emitter, "response", &(((ILibDuktape_http_requestClient_callbacks*)user[1])->OnReceive));
ILibDuktape_EventEmitter_CreateEvent(emitter, "continue", &(((ILibDuktape_http_requestClient_callbacks*)user[1])->OnContinue)); ILibDuktape_EventEmitter_CreateEvent(emitter, "continue", &(((ILibDuktape_http_requestClient_callbacks*)user[1])->OnContinue));
ILibDuktape_EventEmitter_CreateEvent(emitter, "socket", &(((ILibDuktape_http_requestClient_callbacks*)user[1])->OnSocket));
ILibDuktape_EventEmitter_CreateEventEx(emitter, "timeout");
((ILibDuktape_http_requestClient_callbacks*)user[1])->requestStream = ILibDuktape_WritableStream_Init(ctx, ILibDuktape_http_request_write, ILibDuktape_http_request_end, token); ((ILibDuktape_http_requestClient_callbacks*)user[1])->requestStream = ILibDuktape_WritableStream_Init(ctx, ILibDuktape_http_request_write, ILibDuktape_http_request_end, token);
((ILibDuktape_http_requestClient_callbacks*)user[1])->clientRequest = duk_get_heapptr(ctx, -1); ((ILibDuktape_http_requestClient_callbacks*)user[1])->clientRequest = duk_get_heapptr(ctx, -1);
} }
@@ -2433,6 +2562,14 @@ duk_ret_t ILibDuktape_httpDigest_clientRequest_response2(duk_context *ctx)
duk_dup(ctx, 0); // [emit][this][response][imsg] duk_dup(ctx, 0); // [emit][this][response][imsg]
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http-digest: Error dispatching response event"); } if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http-digest: Error dispatching response event"); }
} }
else
{
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]
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http-digest: Error dispatching response event"); }
}
return(0); return(0);
} }
@@ -2469,15 +2606,81 @@ duk_ret_t ILibDuktape_httpDigest_clientRequest_propagateEvent(duk_context *ctx)
} }
extern void* ILibWebClient_Digest_GenerateTable(ILibWebClient_StateObject state); extern void* ILibWebClient_Digest_GenerateTable(ILibWebClient_StateObject state);
void ILibDuktape_httpDigest_clientRequest_IncomingMessage_PauseHandler(ILibDuktape_readableStream *sender, void *user)
{
duk_push_heapptr(sender->ctx, user); // [imsg]
duk_get_prop_string(sender->ctx, -1, "pause"); // [imsg][pause]
duk_swap_top(sender->ctx, -2); // [pause][this]
if (duk_pcall_method(sender->ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(sender->ctx, "ILibDuktape_httpDigest_clientRequest_IncomingMessage_PauseHandler: Error Invoking Pause on ClientRequest: "); }
duk_pop(sender->ctx); // ...
}
void ILibDuktape_httpDigest_clientRequest_IncomingMessage_ResumeHandler(ILibDuktape_readableStream *sender, void *user)
{
duk_push_heapptr(sender->ctx, user); // [imsg]
duk_get_prop_string(sender->ctx, -1, "resume"); // [imsg][pause]
duk_swap_top(sender->ctx, -2); // [pause][this]
if (duk_pcall_method(sender->ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(sender->ctx, "ILibDuktape_httpDigest_clientRequest_IncomingMessage_ResumeHandler: Error Invoking Resume on ClientRequest: "); }
duk_pop(sender->ctx); // ...
}
duk_ret_t ILibDuktape_httpDigest_clientRequest_OnData(duk_context *ctx)
{
duk_push_current_function(ctx);
duk_get_prop_string(ctx, -1, CLIENTREQUEST_IMSG_RSPTR);
ILibDuktape_readableStream *rs = (ILibDuktape_readableStream*)duk_get_pointer(ctx, -1);
duk_size_t bufferLen;
char *buffer;
buffer = Duktape_GetBuffer(ctx, 0, &bufferLen);
ILibDuktape_readableStream_WriteData(rs, buffer, (int)bufferLen);
return(0);
}
duk_ret_t ILibDuktape_httpDigest_clientRequest_OnEnd(duk_context *ctx)
{
duk_push_current_function(ctx);
duk_get_prop_string(ctx, -1, CLIENTREQUEST_IMSG_RSPTR);
ILibDuktape_readableStream *rs = (ILibDuktape_readableStream*)duk_get_pointer(ctx, -1);
ILibDuktape_readableStream_WriteEnd(rs);
return(0);
}
duk_ret_t ILibDuktape_httpDigest_http_request_socketEvent_end(duk_context *ctx)
{
duk_push_this(ctx); // [socket]
duk_get_prop_string(ctx, -1, CLIENTREQUEST_SOCKET_WCDO);// [socket][wcdo]
duk_get_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [socket][wcdo][digest]
duk_get_prop_string(ctx, -1, DIGEST_WCDO); // [socket][wcdo][digest][wcdo]
if (duk_get_pointer(ctx, -1) == duk_get_pointer(ctx, -3))
{
duk_del_prop_string(ctx, -2, DIGEST_WCDO);
}
return(0);
}
duk_ret_t ILibDuktape_httpDigest_http_request_socketEvent(duk_context *ctx)
{
duk_push_this(ctx); // [clientRequest]
duk_get_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST); // [clientRequest][digestClientRequest]
duk_get_prop_string(ctx, -1, DIGESTCLIENTREQUEST_DIGEST); // [clientRequest][digestClientRequest][digest]
duk_get_prop_string(ctx, 0, CLIENTREQUEST_SOCKET_WCDO); // [clientRequest][digestClientRequest][digest][wcdo]
duk_put_prop_string(ctx, -2, DIGEST_WCDO); // [clientRequest][digestClientRequest][digest]
duk_dup(ctx, 0); // [clientRequest][digestClientRequest][digest][socket]
duk_swap_top(ctx, -2); // [clientRequest][digestClientRequest][socket][digest]
duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [clientRequest][digestClientRequest][socket]
ILibDuktape_EventEmitter_AddOnceEx(ILibDuktape_EventEmitter_GetEmitter(ctx, 0), "end", ILibDuktape_httpDigest_http_request_socketEvent_end, 0);
return(0);
}
duk_ret_t ILibDuktape_httpDigest_clientRequest_response(duk_context *ctx) duk_ret_t ILibDuktape_httpDigest_clientRequest_response(duk_context *ctx)
{ {
ILibHTTPPacket *packet; ILibHTTPPacket *packet;
ILibWebClient_StateObject wcdo; ILibWebClient_StateObject wcdo;
char *username, *password; char *username, *password;
int tmpLen = 0;
char *uri = NULL; char *uri = NULL;
void *digestClientPtr; void *digestClientPtr;
void *paramPtr = NULL; void *paramPtr = NULL;
void *cr_self;
duk_push_current_function(ctx); duk_push_current_function(ctx);
duk_get_prop_string(ctx, -1, "digestClientRequest"); duk_get_prop_string(ctx, -1, "digestClientRequest");
@@ -2494,7 +2697,8 @@ duk_ret_t ILibDuktape_httpDigest_clientRequest_response(duk_context *ctx)
if (packet->StatusCode == 401) if (packet->StatusCode == 401)
{ {
duk_push_heapptr(ctx, digestClientPtr); // [digestClientRequest] duk_push_heapptr(ctx, digestClientPtr); // [digestClientRequest]
if (duk_has_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST)) int endCalledAlready = Duktape_GetBooleanProperty(ctx, -1, DIGESTCLIENTREQUEST_END_CALLED, 0);
if (endCalledAlready == 0 && duk_has_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST))
{ {
duk_get_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST); // [digestClientRequest][clientRequest] duk_get_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST); // [digestClientRequest][clientRequest]
duk_get_prop_string(ctx, -1, "end"); // [digestClientRequest][clientRequest][end] duk_get_prop_string(ctx, -1, "end"); // [digestClientRequest][clientRequest][end]
@@ -2508,16 +2712,14 @@ duk_ret_t ILibDuktape_httpDigest_clientRequest_response(duk_context *ctx)
duk_get_prop_string(ctx, 0, HTTP_INCOMINGMSG_WebStateObject); duk_get_prop_string(ctx, 0, HTTP_INCOMINGMSG_WebStateObject);
wcdo = (ILibWebClient_StateObject)duk_get_pointer(ctx, -1); wcdo = (ILibWebClient_StateObject)duk_get_pointer(ctx, -1);
int freePath = 0; duk_size_t methodLen, pathLen;
char *method, *path; int authLen;
char result1[33]; char *method, *path, *auth;
char result2[33];
char result3[33]; void *ReservedMemory = ILibMemory_AllocateA(8000);
void* table = ILibWebClient_Digest_GenerateTable(wcdo); ILibHTTPPacket *pk = ILibCreateEmptyPacketEx(ReservedMemory);
char* realm = (char*)ILibGetEntry(table, "realm", 5); pk->Version = "1.1";
char* nonce = (char*)ILibGetEntry(table, "nonce", 5); pk->VersionLength = 3;
char* opaque = (char*)ILibGetEntry(table, "opaque", 6);
ILibDestroyHashTree(table);
duk_push_this(ctx); // [clientRequest] duk_push_this(ctx); // [clientRequest]
duk_get_prop_string(ctx, -1, HTTP_CLIENTREQUEST_PARAMETER); // [clientRequest][param] duk_get_prop_string(ctx, -1, HTTP_CLIENTREQUEST_PARAMETER); // [clientRequest][param]
@@ -2528,31 +2730,25 @@ duk_ret_t ILibDuktape_httpDigest_clientRequest_response(duk_context *ctx)
unsigned short tmpPort; unsigned short tmpPort;
uri = (char*)duk_get_string(ctx, -1); uri = (char*)duk_get_string(ctx, -1);
ILibParseUri(uri, &tmpHost, &tmpPort, &path, NULL); ILibParseUri(uri, &tmpHost, &tmpPort, &path, NULL);
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s:%s", (method = "GET"), path); ILibSetDirective(pk, "GET", 3, path, -1);
util_md5hex(ILibScratchPad2, tmpLen, result2);
free(tmpHost); free(tmpHost);
freePath = 1; free(path);
} }
else else
{ {
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s:%s", (method = Duktape_GetStringPropertyValue(ctx, -1, "method", "GET")), (path = Duktape_GetStringPropertyValue(ctx, -1, "path", "/"))); method = (char*)Duktape_GetStringPropertyValueEx(ctx, -1, "method", "GET", &methodLen);
util_md5hex(ILibScratchPad2, tmpLen, result2); path = (char*)Duktape_GetStringPropertyValueEx(ctx, -1, "path", "/", &pathLen);
ILibSetDirective(pk, method, (int)methodLen, path, (int)pathLen);
paramPtr = duk_get_heapptr(ctx, -1); paramPtr = duk_get_heapptr(ctx, -1);
} }
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s:%s:%s", username, realm, password); ILibWebClient_GenerateAuthenticationHeader(wcdo, pk, username, password);
util_md5hex(ILibScratchPad2, tmpLen, result1); auth = ILibGetHeaderLineEx(pk, "Authorization", 13, &authLen);
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s:%s:%s", result1, nonce, result2); duk_push_this(ctx); // [clientReqeust]
util_md5hex(ILibScratchPad2, tmpLen, result3); duk_get_prop_string(ctx, -1, CLIENTREQUEST_HTTP); // [clientReqeust][http]
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", opaque=\"%s\", response=\"%s\"", username, realm, nonce, path, opaque, result3);
duk_push_this(ctx); // [clientReqeust]
duk_get_prop_string(ctx, -1, CLIENTREQUEST_HTTP); // [clientReqeust][http]
if (freePath != 0) { free(path); }
if (paramPtr == NULL) if (paramPtr == NULL)
{ {
duk_get_prop_string(ctx, -1, "get"); // [clientRequest][http][get] duk_get_prop_string(ctx, -1, "get"); // [clientRequest][http][get]
@@ -2566,6 +2762,7 @@ duk_ret_t ILibDuktape_httpDigest_clientRequest_response(duk_context *ctx)
duk_get_prop_string(ctx, -1, "request"); // [clientRequest][http][request] duk_get_prop_string(ctx, -1, "request"); // [clientRequest][http][request]
duk_swap_top(ctx, -2); // [clientRequest][request][this] duk_swap_top(ctx, -2); // [clientRequest][request][this]
duk_push_heapptr(ctx, paramPtr); // [clientRequest][request][this][options] duk_push_heapptr(ctx, paramPtr); // [clientRequest][request][this][options]
duk_del_prop_string(ctx, -1, "timeout");
} }
if(!duk_has_prop_string(ctx, -1, "headers")) if(!duk_has_prop_string(ctx, -1, "headers"))
@@ -2577,15 +2774,17 @@ duk_ret_t ILibDuktape_httpDigest_clientRequest_response(duk_context *ctx)
duk_get_prop_string(ctx, -1, "headers"); // [clientReqeust][get][this][options][headers] duk_get_prop_string(ctx, -1, "headers"); // [clientReqeust][get][this][options][headers]
} }
duk_push_lstring(ctx, ILibScratchPad2, tmpLen); // [clientReqeust][get][this][options][headers][Auth] duk_push_lstring(ctx, auth, authLen); // [clientReqeust][get][this][options][headers][Auth]
duk_put_prop_string(ctx, -2, "Authorization"); // [clientReqeust][get][this][options][headers] duk_put_prop_string(ctx, -2, "Authorization"); // [clientReqeust][get][this][options][headers]
duk_put_prop_string(ctx, -2, "headers"); // [clientReqeust][get][this][options] duk_put_prop_string(ctx, -2, "headers"); // [clientReqeust][get][this][options]
duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_response2, DUK_VARARGS); // [clientReqeust][get][this][options][callback] duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_response2, DUK_VARARGS); // [clientReqeust][get][this][options][callback]
duk_push_heapptr(ctx, digestClientPtr); // [clientReqeust][get][this][options][callback][digestClientRequest] duk_push_heapptr(ctx, digestClientPtr); // [clientReqeust][get][this][options][callback][digestClientRequest]
duk_put_prop_string(ctx, -2, "digestClientRequest"); // [clientReqeust][get][this][options][callback] duk_put_prop_string(ctx, -2, "digestClientRequest"); // [clientReqeust][get][this][options][callback]
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "digest_onResponse: Error Invoking http.get"); } if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "digest_onResponse: Error Invoking http.get"); }
duk_push_heapptr(ctx, digestClientPtr); // [clientRequest][digestClientRequest]
duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [clientRequest]
ILibDuktape_EventEmitter_AddOnceEx2(ctx, -1, "socket", ILibDuktape_httpDigest_http_request_socketEvent, 1);
duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_propagateEvent, DUK_VARARGS); // [clientReqeust][EventDispatcher] duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_propagateEvent, DUK_VARARGS); // [clientReqeust][EventDispatcher]
duk_push_heapptr(ctx, digestClientPtr); // [clientReqeust][EventDispatcher][digestClientRequest] duk_push_heapptr(ctx, digestClientPtr); // [clientReqeust][EventDispatcher][digestClientRequest]
@@ -2612,17 +2811,87 @@ duk_ret_t ILibDuktape_httpDigest_clientRequest_response(duk_context *ctx)
ILibDuktape_EventEmitter_AddOnce(ILibDuktape_EventEmitter_GetEmitter(ctx, -2), "continue", duk_get_heapptr(ctx, -1)); ILibDuktape_EventEmitter_AddOnce(ILibDuktape_EventEmitter_GetEmitter(ctx, -2), "continue", duk_get_heapptr(ctx, -1));
duk_pop(ctx); // [clientReqeust] duk_pop(ctx); // [clientReqeust]
duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_propagateEvent, DUK_VARARGS); // [clientReqeust][EventDispatcher]
duk_push_heapptr(ctx, digestClientPtr); // [clientReqeust][EventDispatcher][digestClientRequest]
duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [clientReqeust][EventDispatcher]
duk_push_string(ctx, "timeout"); // [clientReqeust][EventDispatcher][eventName]
duk_put_prop_string(ctx, -2, CLIENTREQUEST_EVENT_NAME); // [clientReqeust][EventDispatcher]
ILibDuktape_EventEmitter_AddOnce(ILibDuktape_EventEmitter_GetEmitter(ctx, -2), "timeout", duk_get_heapptr(ctx, -1));
duk_pop(ctx); // [clientReqeust]
duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_onDrain, DUK_VARARGS); // [clientReqeust][onDrain] duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_onDrain, DUK_VARARGS); // [clientReqeust][onDrain]
duk_push_heapptr(ctx, digestClientPtr); // [clientReqeust][onDrain][digestClientRequest] duk_push_heapptr(ctx, digestClientPtr); // [clientReqeust][onDrain][digestClientRequest]
duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [clientReqeust][onDrain] duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [clientReqeust][onDrain]
ILibDuktape_EventEmitter_AddOn(ILibDuktape_EventEmitter_GetEmitter(ctx, -2), "drain", duk_get_heapptr(ctx, -1)); ILibDuktape_EventEmitter_AddOn(ILibDuktape_EventEmitter_GetEmitter(ctx, -2), "drain", duk_get_heapptr(ctx, -1));
duk_pop(ctx); // [clientReqeust] duk_pop(ctx); // [clientReqeust]
if (endCalledAlready != 0)
{
duk_push_heapptr(ctx, digestClientPtr);
if (duk_has_prop_string(ctx, -1, DIGESTCLIENTREQUEST_TmpBuffer))
{
duk_get_prop_string(ctx, -1, DIGESTCLIENTREQUEST_TmpBuffer); // [clientReqeust][digestClientRequest][buffer]
duk_swap_top(ctx, -2); // [clientRequesat][buffer][digestClientRequest]
duk_pop(ctx); // [clientRequest][buffer]
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]
if (duk_pcall_method(ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "httpDigest.clientRequest.onResponse(): Error calling clientRequest.write(): "); }
duk_pop(ctx); // [clientRequest]
}
else
{
duk_pop(ctx); // [clientRequest]
}
duk_dup(ctx, -1); // [clientReqeust][clientReqeust]
duk_get_prop_string(ctx, -1, "end"); // [clientReqeust][clientReqeust][end]
duk_swap_top(ctx, -2); // [clientReqeust][end][this]
if (duk_pcall_method(ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "httpDigest.onResponse(): Error invoking ClientRequest.end(): "); }
duk_pop(ctx); // [clientRequest]
}
duk_push_heapptr(ctx, digestClientPtr); // [clientRequest][digestClientRequest] duk_push_heapptr(ctx, digestClientPtr); // [clientRequest][digestClientRequest]
duk_swap_top(ctx, -2); // [digestClientRequest][clientRequest] duk_swap_top(ctx, -2); // [digestClientRequest][clientRequest]
duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [digestClientRequest] duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [digestClientRequest]
} }
else
{
duk_dup(ctx, 0);
cr_self = duk_get_heapptr(ctx, -1);
duk_pop(ctx);
duk_push_heapptr(ctx, digestClientPtr); // [digestClientRequest]
duk_get_prop_string(ctx, -1, "emit"); // [digestClientRequest][emit]
duk_swap_top(ctx, -2); // [emit][this]
duk_push_string(ctx, "response"); // [emit][this][response]
ILibDuktape_http_server_PUSH_IncomingMessage(ctx, packet, NULL); // [emit][this][response][imsg]
ILibDuktape_readableStream *rs = ILibDuktape_ReadableStream_Init(ctx, ILibDuktape_httpDigest_clientRequest_IncomingMessage_PauseHandler, ILibDuktape_httpDigest_clientRequest_IncomingMessage_ResumeHandler, cr_self);
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "digestClientRequest.onResponse(): "); }
duk_pop(ctx); // ...
duk_dup(ctx, 0); // [imsg]
duk_get_prop_string(ctx, -1, "on"); // [imsg][on]
duk_swap_top(ctx, -2); // [on][this]
duk_push_string(ctx, "data"); // [on][this][data]
duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_OnData, DUK_VARARGS); // [on][this][data][func]
duk_push_pointer(ctx, rs); // [on][this][data][func][ptr]
duk_put_prop_string(ctx, -2, CLIENTREQUEST_IMSG_RSPTR); // [on][this][data][func]
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "digestClientRequst.onResponse(): Error attaching event to clientRequest.on('data'): "); }
duk_pop(ctx);
duk_dup(ctx, 0); // [imsg]
duk_get_prop_string(ctx, -1, "on"); // [imsg][on]
duk_swap_top(ctx, -2); // [on][this]
duk_push_string(ctx, "end"); // [on][this][end]
duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_OnEnd, DUK_VARARGS); // [on][this][end][func]
duk_push_pointer(ctx, rs); // [on][this][end][func][ptr]
duk_put_prop_string(ctx, -2, CLIENTREQUEST_IMSG_RSPTR); // [on][this][end][func]
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "digestClientRequst.onResponse(): Error attaching event to clientRequest.on('end'): "); }
duk_pop(ctx);
}
return(0); return(0);
} }
duk_ret_t ILibDuktape_httpDigest_clientRequest_setter(duk_context *ctx) duk_ret_t ILibDuktape_httpDigest_clientRequest_setter(duk_context *ctx)
@@ -2673,7 +2942,31 @@ ILibTransport_DoneState ILibDuktape_httpDigest_http_request_WriteHandler(struct
ILibTransport_DoneState retVal = ILibTransport_DoneState_ERROR; ILibTransport_DoneState retVal = ILibTransport_DoneState_ERROR;
duk_context *ctx = stream->ctx; duk_context *ctx = stream->ctx;
duk_push_heapptr(ctx, stream->obj); // [digestClientRequest] duk_push_heapptr(ctx, stream->obj); // [digestClientRequest]
if (Duktape_GetBooleanProperty(ctx, -1, DIGESTCLIENTREQUEST_CONTINUE, 0) == 0)
{
duk_size_t bufLen;
char *tmpBuffer;
if (duk_has_prop_string(ctx, -1, DIGESTCLIENTREQUEST_TmpBuffer))
{
duk_get_prop_string(ctx, -1, DIGESTCLIENTREQUEST_TmpBuffer); // [digestClientRequest][oldBuffer]
bufLen = duk_get_length(ctx, -1);
duk_resize_buffer(ctx, -1, bufLen + bufferLen);
tmpBuffer = (char*)Duktape_GetBuffer(ctx, -1, &bufLen);
memcpy_s(tmpBuffer + bufLen - (size_t)bufferLen, (size_t)bufferLen, buffer, (size_t)bufferLen);
duk_pop(ctx); // [digestClientRequest]
}
else
{
duk_push_dynamic_buffer(ctx, (duk_size_t)bufferLen); // [digestClientRequest][buffer]
tmpBuffer = (char*)Duktape_GetBuffer(ctx, -1, &bufLen);
duk_put_prop_string(ctx, -2, DIGESTCLIENTREQUEST_TmpBuffer); // [digestClientRequest]
memcpy_s(tmpBuffer, bufLen, buffer, (size_t)bufferLen);
}
}
if (duk_has_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST)) if (duk_has_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST))
{ {
duk_get_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST); // [digestClientRequest][clientRequest] duk_get_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST); // [digestClientRequest][clientRequest]
@@ -2710,6 +3003,9 @@ void ILibDuktape_httpDigest_http_request_DoneHandler(struct ILibDuktape_Writable
duk_context *ctx = stream->ctx; duk_context *ctx = stream->ctx;
duk_push_heapptr(ctx, stream->obj); // [digestClientRequest] duk_push_heapptr(ctx, stream->obj); // [digestClientRequest]
duk_push_true(ctx);
duk_put_prop_string(ctx, -2, DIGESTCLIENTREQUEST_END_CALLED);
if (duk_has_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST)) if (duk_has_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST))
{ {
duk_get_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST); // [digestClientRequest][clientRequest] duk_get_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST); // [digestClientRequest][clientRequest]
@@ -2722,16 +3018,33 @@ void ILibDuktape_httpDigest_http_request_DoneHandler(struct ILibDuktape_Writable
} }
duk_pop(ctx); // ... duk_pop(ctx); // ...
} }
duk_ret_t ILibDuktape_httpDigest_http_request_continueOccured(duk_context *ctx)
{
duk_push_this(ctx); // [digestClientRequest]
duk_push_true(ctx);
duk_put_prop_string(ctx, -2, DIGESTCLIENTREQUEST_CONTINUE);
return(0);
}
duk_ret_t ILibDuktape_httpDigest_http_request(duk_context *ctx) duk_ret_t ILibDuktape_httpDigest_http_request(duk_context *ctx)
{ {
int nargs = duk_get_top(ctx); int nargs = duk_get_top(ctx);
void *clientRequest = NULL; void *clientRequest = NULL;
ILibDuktape_EventEmitter *emitter; ILibDuktape_EventEmitter *emitter;
ILibDuktape_EventEmitter *crEmitter; ILibDuktape_EventEmitter *crEmitter;
char *username = NULL;
char *password = NULL;
duk_push_current_function(ctx); // [func] duk_push_current_function(ctx); // [func]
duk_get_prop_string(ctx, -1, "isGet"); // [func][isGet] duk_get_prop_string(ctx, -1, "isGet"); // [func][isGet]
duk_push_this(ctx); // [func][isGet][digest] duk_push_this(ctx); // [func][isGet][digest]
duk_get_prop_string(ctx, -1, DIGEST_USERNAME); // [func][isGet][digest][username]
duk_get_prop_string(ctx, -2, DIGEST_PASSWORD); // [func][isGet][digest][username][password]
username = (char*)duk_get_string(ctx, -2);
password = (char*)duk_get_string(ctx, -1);
duk_pop_2(ctx); // [func][isGet][digest]
duk_get_prop_string(ctx, -1, HTTP_DIGEST); // [func][isGet][digest][http] duk_get_prop_string(ctx, -1, HTTP_DIGEST); // [func][isGet][digest][http]
if (duk_get_int(ctx, -3) != 0) if (duk_get_int(ctx, -3) != 0)
{ {
@@ -2744,6 +3057,46 @@ duk_ret_t ILibDuktape_httpDigest_http_request(duk_context *ctx)
duk_swap_top(ctx, -2); // [func][isGet][digest][get/request][this] duk_swap_top(ctx, -2); // [func][isGet][digest][get/request][this]
duk_dup(ctx, 0); // [func][isGet][digest][get/request][this][param1] duk_dup(ctx, 0); // [func][isGet][digest][get/request][this][param1]
//
// Check to see if we can insert Auth Headers, in case we already authenticated
//
if (duk_has_prop_string(ctx, -4, DIGEST_WCDO))
{
void *wcdo = NULL;
ILibHTTPPacket *pk = ILibCreateEmptyPacketEx(ILibMemory_AllocateA(4096));
duk_size_t methodLen, pathLen;
char *method, *path;
pk->Version = "1.1";
pk->VersionLength = 3;
method = (char*)Duktape_GetStringPropertyValueEx(ctx, -1, "method", "GET", &methodLen);
path = (char*)Duktape_GetStringPropertyValueEx(ctx, -1, "path", "/", &pathLen);
ILibSetDirective(pk, method, (int)methodLen, path, (int)pathLen);
duk_get_prop_string(ctx, -4, DIGEST_WCDO);
wcdo = duk_get_pointer(ctx, -1);
duk_pop(ctx);
ILibWebClient_GenerateAuthenticationHeader(wcdo, pk, username, password);
char *auth = ILibGetHeaderLine(pk, "Authorization", 13);
if (auth != NULL)
{
if (duk_has_prop_string(ctx, -1, "headers")) // [func][isGet][digest][get/request][this][param1]
{
duk_get_prop_string(ctx, -1, "headers"); // [func][isGet][digest][get/request][this][param1][headers]
}
else
{
duk_push_object(ctx); // [func][isGet][digest][get/request][this][param1][headers]
duk_dup(ctx, -1); // [func][isGet][digest][get/request][this][param1][headers][headers]
duk_put_prop_string(ctx, -3, "headers"); // [func][isGet][digest][get/request][this][param1][headers]
}
duk_push_string(ctx, auth); // [func][isGet][digest][get/request][this][param1][headers][auth]
duk_put_prop_string(ctx, -2, "Authorization"); // [func][isGet][digest][get/request][this][param1][headers]
duk_pop(ctx); // [func][isGet][digest][get/request][this][param1]
}
}
if (duk_pcall_method(ctx, 1) != 0) { duk_throw(ctx); return(DUK_RET_ERROR); } if (duk_pcall_method(ctx, 1) != 0) { duk_throw(ctx); return(DUK_RET_ERROR); }
// [clientRequest] // [clientRequest]
clientRequest = duk_get_heapptr(ctx, -1); clientRequest = duk_get_heapptr(ctx, -1);
@@ -2755,6 +3108,8 @@ 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_c_function(ctx, ILibDuktape_httpDigest_clientRequest_response, DUK_VARARGS); // [once][this][response][method]
duk_push_object(ctx); // [once][this][response][method][digest-clientRequest] duk_push_object(ctx); // [once][this][response][method][digest-clientRequest]
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] duk_push_heapptr(ctx, clientRequest); // [once][this][response][method][digest-clientRequest][clientRequest]
duk_dup(ctx, -2); // [once][this][response][method][digest-clientRequest][clientRequest][digest-clientRequest] duk_dup(ctx, -2); // [once][this][response][method][digest-clientRequest][clientRequest][digest-clientRequest]
duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [once][this][response][method][digest-clientRequest][clientRequest] duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [once][this][response][method][digest-clientRequest][clientRequest]
@@ -2764,7 +3119,11 @@ duk_ret_t ILibDuktape_httpDigest_http_request(duk_context *ctx)
ILibDuktape_EventEmitter_CreateEventEx(emitter, "error"); ILibDuktape_EventEmitter_CreateEventEx(emitter, "error");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "upgrade"); ILibDuktape_EventEmitter_CreateEventEx(emitter, "upgrade");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "continue"); ILibDuktape_EventEmitter_CreateEventEx(emitter, "continue");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "timeout");
ILibDuktape_EventEmitter_AddOnceEx(emitter, "continue", ILibDuktape_httpDigest_http_request_continueOccured, 0);
ILibDuktape_EventEmitter_AddOnceEx(crEmitter, "socket", ILibDuktape_httpDigest_http_request_socketEvent, 1);
ILibDuktape_WritableStream_Init(ctx, ILibDuktape_httpDigest_http_request_WriteHandler, ILibDuktape_httpDigest_http_request_DoneHandler, NULL); ILibDuktape_WritableStream_Init(ctx, ILibDuktape_httpDigest_http_request_WriteHandler, ILibDuktape_httpDigest_http_request_DoneHandler, NULL);
if (nargs > 1 && duk_is_function(ctx, 1)) if (nargs > 1 && duk_is_function(ctx, 1))
@@ -2803,6 +3162,14 @@ duk_ret_t ILibDuktape_httpDigest_http_request(duk_context *ctx)
ILibDuktape_EventEmitter_AddOnce(crEmitter, "continue", duk_get_heapptr(ctx, -1)); // [digestClientRequest][EventDispatcher] ILibDuktape_EventEmitter_AddOnce(crEmitter, "continue", duk_get_heapptr(ctx, -1)); // [digestClientRequest][EventDispatcher]
duk_pop(ctx); // [digestClientRequest] duk_pop(ctx); // [digestClientRequest]
duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_propagateEvent, DUK_VARARGS); // [digestClientRequest][EventDispatcher]
duk_dup(ctx, -2); // [digestClientRequest][EventDispatcher][digestClientRequest]
duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [digestClientRequest][EventDispatcher]
duk_push_string(ctx, "timeout"); // [digestClientRequest][EventDispatcher][eventName]
duk_put_prop_string(ctx, -2, CLIENTREQUEST_EVENT_NAME); // [digestClientRequest][EventDispatcher]
ILibDuktape_EventEmitter_AddOnce(crEmitter, "timeout", duk_get_heapptr(ctx, -1)); // [digestClientRequest][EventDispatcher]
duk_pop(ctx); // [digestClientRequest]
duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_onDrain, DUK_VARARGS); // [digestClientRequest][onDrain] duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_onDrain, DUK_VARARGS); // [digestClientRequest][onDrain]
duk_dup(ctx, -2); // [digestClientRequest][onDrain][digestClientRequest] duk_dup(ctx, -2); // [digestClientRequest][onDrain][digestClientRequest]
duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [digestClientRequest][onDrain] duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [digestClientRequest][onDrain]

View File

@@ -24,6 +24,7 @@ limitations under the License.
#include "microstack/ILibAsyncSocket.h" #include "microstack/ILibAsyncSocket.h"
#include "microstack/ILibCrypto.h" #include "microstack/ILibCrypto.h"
#include "microstack/ILibAsyncServerSocket.h" #include "microstack/ILibAsyncServerSocket.h"
#include "microstack/ILibRemoteLogging.h"
typedef struct ILibDuktape_net_socket typedef struct ILibDuktape_net_socket
{ {
@@ -264,6 +265,7 @@ duk_ret_t ILibDuktape_net_socket_address(duk_context *ctx)
duk_push_string(ctx, ILibInet_ntop2((struct sockaddr*)&local, ILibScratchPad, sizeof(ILibScratchPad))); duk_push_string(ctx, ILibInet_ntop2((struct sockaddr*)&local, ILibScratchPad, sizeof(ILibScratchPad)));
duk_put_prop_string(ctx, -2, "address"); duk_put_prop_string(ctx, -2, "address");
return 1; return 1;
} }
@@ -918,6 +920,29 @@ duk_ret_t ILibDuktape_net_server_Finalizer(duk_context *ctx)
return 0; return 0;
} }
duk_ret_t ILibDuktape_net_server_address(duk_context *ctx)
{
duk_push_this(ctx); // [server]
duk_get_prop_string(ctx, -1, ILibDuktape_net_Server_buffer); // [server][buffer]
ILibDuktape_net_server *server = (ILibDuktape_net_server*)Duktape_GetBuffer(ctx, -1, NULL);
struct sockaddr_in6 local;
memset(&local, 0, sizeof(struct sockaddr_in6));
ILibAsyncServerSocket_GetLocal(server->server, (struct sockaddr*)&local, sizeof(struct sockaddr_in6));
if (local.sin6_family == AF_UNSPEC) { return(ILibDuktape_Error(ctx, "net.server.address(): call to getsockname() failed")); }
duk_push_object(ctx);
duk_push_string(ctx, local.sin6_family == AF_INET6 ? "IPv6" : "IPv4");
duk_put_prop_string(ctx, -2, "family");
duk_push_int(ctx, (int)ntohs(local.sin6_port));
duk_put_prop_string(ctx, -2, "port");
duk_push_string(ctx, ILibRemoteLogging_ConvertAddress((struct sockaddr*)&local));
duk_put_prop_string(ctx, -2, "address");
return(1);
}
duk_ret_t ILibDuktape_net_createServer(duk_context *ctx) duk_ret_t ILibDuktape_net_createServer(duk_context *ctx)
{ {
int nargs = duk_get_top(ctx); int nargs = duk_get_top(ctx);
@@ -939,6 +964,7 @@ duk_ret_t ILibDuktape_net_createServer(duk_context *ctx)
ILibDuktape_EventEmitter_CreateEvent(server->emitter, "listening", &(server->OnListening)); ILibDuktape_EventEmitter_CreateEvent(server->emitter, "listening", &(server->OnListening));
ILibDuktape_CreateInstanceMethod(ctx, "listen", ILibDuktape_net_server_listen, DUK_VARARGS); ILibDuktape_CreateInstanceMethod(ctx, "listen", ILibDuktape_net_server_listen, DUK_VARARGS);
ILibDuktape_CreateInstanceMethod(ctx, "address", ILibDuktape_net_server_address, 0);
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_net_server_Finalizer); ILibDuktape_CreateFinalizer(ctx, ILibDuktape_net_server_Finalizer);
for (i = 0; i < 2 && i < nargs; ++i) for (i = 0; i < 2 && i < nargs; ++i)

View File

@@ -261,6 +261,39 @@ int ILibDuktape_EventEmitter_AddOnce(ILibDuktape_EventEmitter *emitter, char *ev
return retVal; return retVal;
} }
int ILibDuktape_EventEmitter_AddOnceEx2(duk_context *ctx, duk_idx_t idx, char *eventName, duk_c_function func, duk_idx_t funcArgs)
{
int retVal = 1;
duk_dup(ctx, idx); // [obj]
ILibDuktape_Push_ObjectStash(ctx); // [obj][stash]
duk_push_c_function(ctx, func, funcArgs); // [obj][stash][func]
duk_dup(ctx, -1); // [obj][stash][func][func]
duk_put_prop_string(ctx, -3, Duktape_GetStashKey(duk_get_heapptr(ctx, -1))); // [obj][stash][func]
duk_get_prop_string(ctx, -3, "once"); // [obj][stash][func][once]
duk_swap(ctx, -3, -1); // [obj][once][func][stash]
duk_swap(ctx, -4, -3); // [once][this][func][stash]
duk_pop(ctx); // [once][this][func]
duk_push_string(ctx, eventName); // [once][this][func][eventName]
duk_swap_top(ctx, -2); // [once][this][eventName][func]
retVal = duk_pcall_method(ctx, 2); // [retVal]
duk_pop(ctx); // ...
return(retVal);
}
int ILibDuktape_EventEmitter_AddOnceEx(ILibDuktape_EventEmitter *emitter, char *eventName, duk_c_function func, duk_idx_t funcArgs)
{
int retVal = 1;
duk_push_heapptr(emitter->ctx, emitter->object); // [obj]
ILibDuktape_Push_ObjectStash(emitter->ctx); // [obj][stash]
duk_push_c_function(emitter->ctx, func, funcArgs); // [obj][stash][func]
retVal = ILibDuktape_EventEmitter_AddOnce(emitter, eventName, duk_get_heapptr(emitter->ctx, -1));
duk_put_prop_string(emitter->ctx, -2, Duktape_GetStashKey(duk_get_heapptr(emitter->ctx, -1))); // [obj][stash]
duk_pop_2(emitter->ctx); // ...
return(retVal);
}
int ILibDuktape_EventEmitter_AddOn(ILibDuktape_EventEmitter *emitter, char *eventName, void *heapptr) int ILibDuktape_EventEmitter_AddOn(ILibDuktape_EventEmitter *emitter, char *eventName, void *heapptr)
{ {
int retVal = 1; int retVal = 1;

View File

@@ -715,6 +715,14 @@ ILibAsyncServerSocket_ServerModule ILibCreateAsyncServerSocketModuleWithMemory(v
return RetVal; return RetVal;
} }
void ILibAsyncServerSocket_GetLocal(ILibAsyncServerSocket_ServerModule ServerSocketModule, struct sockaddr* addr, size_t addrLen)
{
socklen_t ssize = (socklen_t)addrLen;
if (getsockname(((struct ILibAsyncServerSocketModule*)ServerSocketModule)->ListenSocket, addr, &ssize) != 0)
{
((struct sockaddr_in6*)addr)->sin6_family = AF_UNSPEC;
}
}
/*! \fn ILibAsyncServerSocket_GetPortNumber(ILibAsyncServerSocket_ServerModule ServerSocketModule) /*! \fn ILibAsyncServerSocket_GetPortNumber(ILibAsyncServerSocket_ServerModule ServerSocketModule)
\brief Returns the port number the server is bound to \brief Returns the port number the server is bound to
\param ServerSocketModule The ILibAsyncServer to query \param ServerSocketModule The ILibAsyncServer to query

View File

@@ -134,6 +134,7 @@ void ILibAsyncServerSocket_StopListening(ILibAsyncServerSocket_ServerModule modu
void ILibAsyncServerSocket_ResumeListening(ILibAsyncServerSocket_ServerModule module); void ILibAsyncServerSocket_ResumeListening(ILibAsyncServerSocket_ServerModule module);
unsigned short ILibAsyncServerSocket_GetPortNumber(ILibAsyncServerSocket_ServerModule ServerSocketModule); unsigned short ILibAsyncServerSocket_GetPortNumber(ILibAsyncServerSocket_ServerModule ServerSocketModule);
void ILibAsyncServerSocket_GetLocal(ILibAsyncServerSocket_ServerModule ServerSocketModule, struct sockaddr* addr, size_t addrLen);
/*! \def ILibAsyncServerSocket_Send /*! \def ILibAsyncServerSocket_Send
\brief Sends data onto the TCP stream \brief Sends data onto the TCP stream

View File

@@ -962,7 +962,7 @@ void ILibAsyncSocket_ConnectToProxy(void* socketModule, struct sockaddr *localIn
ILibAsyncSocket_ConnectTo(socketModule, localInterface, remoteAddress, InterruptPtr, user); ILibAsyncSocket_ConnectTo(socketModule, localInterface, remoteAddress, InterruptPtr, user);
} }
#endif #endif
#ifndef MICROSTACK_NOTLS
ILibAsyncSocket_SendStatus ILibAsyncSocket_ProcessEncryptedBuffer(ILibAsyncSocketModule *Reader) ILibAsyncSocket_SendStatus ILibAsyncSocket_ProcessEncryptedBuffer(ILibAsyncSocketModule *Reader)
{ {
int j; int j;
@@ -1019,7 +1019,7 @@ ILibAsyncSocket_SendStatus ILibAsyncSocket_ProcessEncryptedBuffer(ILibAsyncSocke
sem_post(&(Reader->SendLock)); sem_post(&(Reader->SendLock));
return retVal; return retVal;
} }
#endif
// //
// Internal method called when data is ready to be processed on an ILibAsyncSocket // Internal method called when data is ready to be processed on an ILibAsyncSocket
// //
@@ -1342,10 +1342,10 @@ void ILibAsyncSocket_SetUser3(ILibAsyncSocket_SocketModule socketModule, int use
((struct ILibAsyncSocketModule*)socketModule)->user3 = user3; ((struct ILibAsyncSocketModule*)socketModule)->user3 = user3;
} }
void ILibAsyncSocket_SetTimeout(ILibAsyncSocket_SocketModule socketModule, int timeoutSeconds, ILibAsyncSocket_TimeoutHandler timeoutHandler) void ILibAsyncSocket_SetTimeoutEx(ILibAsyncSocket_SocketModule socketModule, int timeoutMilliseconds, ILibAsyncSocket_TimeoutHandler timeoutHandler)
{ {
struct ILibAsyncSocketModule *module = (struct ILibAsyncSocketModule*)socketModule; struct ILibAsyncSocketModule *module = (struct ILibAsyncSocketModule*)socketModule;
module->timeout_milliSeconds = timeoutSeconds * 1000; module->timeout_milliSeconds = timeoutMilliseconds;
module->timeout_handler = timeoutHandler; module->timeout_handler = timeoutHandler;
} }
@@ -1848,7 +1848,11 @@ void ILibAsyncSocket_PostSelect(void* socketModule, int slct, fd_set *readset, f
if (module->PendingSend_Head == NULL && bytesSent != -1) { TriggerSendOK = 1; } if (module->PendingSend_Head == NULL && bytesSent != -1) { TriggerSendOK = 1; }
SEM_TRACK(AsyncSocket_TrackUnLock("ILibAsyncSocket_PostSelect", 2, module);) SEM_TRACK(AsyncSocket_TrackUnLock("ILibAsyncSocket_PostSelect", 2, module);)
sem_post(&(module->SendLock)); sem_post(&(module->SendLock));
#ifndef MICROSTACK_NOTLS
if (TriggerSendOK != 0 && (module->ssl == NULL || module->SSLConnect != 0)) if (TriggerSendOK != 0 && (module->ssl == NULL || module->SSLConnect != 0))
#else
if (TriggerSendOK != 0)
#endif
{ {
module->OnSendOK(module, module->user); module->OnSendOK(module, module->user);
if (module->Transport.SendOkPtr != NULL) { module->Transport.SendOkPtr(module); } if (module->Transport.SendOkPtr != NULL) { module->Transport.SendOkPtr(module); }

View File

@@ -234,7 +234,8 @@ int ILibAsyncSocket_IsIPv6LinkLocal(struct sockaddr *LocalAddress);
int ILibAsyncSocket_IsModuleIPv6LinkLocal(ILibAsyncSocket_SocketModule module); int ILibAsyncSocket_IsModuleIPv6LinkLocal(ILibAsyncSocket_SocketModule module);
typedef void(*ILibAsyncSocket_TimeoutHandler)(ILibAsyncSocket_SocketModule module, void *user); typedef void(*ILibAsyncSocket_TimeoutHandler)(ILibAsyncSocket_SocketModule module, void *user);
void ILibAsyncSocket_SetTimeout(ILibAsyncSocket_SocketModule module, int timeoutSeconds, ILibAsyncSocket_TimeoutHandler timeoutHandler); void ILibAsyncSocket_SetTimeoutEx(ILibAsyncSocket_SocketModule module, int timeoutMilliseconds, ILibAsyncSocket_TimeoutHandler timeoutHandler);
#define ILibAsyncSocket_SetTimeout(module, timeoutSeconds, timeoutHandler) ILibAsyncSocket_SetTimeoutEx(module, timeoutSeconds*1000, timeoutHandler)
#ifndef MICROSTACK_NOTLS #ifndef MICROSTACK_NOTLS
X509 *ILibAsyncSocket_SslGetCert(ILibAsyncSocket_SocketModule socketModule); X509 *ILibAsyncSocket_SslGetCert(ILibAsyncSocket_SocketModule socketModule);

View File

@@ -210,6 +210,7 @@ struct HashNode_Root
{ {
struct HashNode *Root; struct HashNode *Root;
int CaseInSensitive; int CaseInSensitive;
void *Reserved;
sem_t LOCK; sem_t LOCK;
}; };
struct HashNode struct HashNode
@@ -1063,7 +1064,30 @@ typedef struct ILibBaseChain
}ILibBaseChain; }ILibBaseChain;
const int ILibMemory_CHAIN_CONTAINERSIZE = sizeof(ILibBaseChain); const int ILibMemory_CHAIN_CONTAINERSIZE = sizeof(ILibBaseChain);
void* ILibMemory_AllocateA_InitMem(void *buffer, size_t bufferLen)
{
char *retVal = ((char*)buffer + 8 + sizeof(void*));
((int*)(retVal - 4))[0] = (int)(bufferLen - 8 - sizeof(void*)); // Size
((void**)(retVal - 4 - sizeof(void*)))[0] = retVal; // Next
((int*)buffer)[0] = (int)bufferLen; // RawSize
memset(retVal, 0, bufferLen - 8 - sizeof(void*));
return((void*)retVal);
}
void* ILibMemory_AllocateA_Get(void *buffer, size_t sz)
{
char *retVal = NULL;
if (ILibMemory_AllocateA_Size(buffer) > (int)sz)
{
retVal = ILibMemory_AllocateA_Next(buffer);
ILibMemory_AllocateA_Size(buffer) -= (int)sz;
ILibMemory_AllocateA_Next(buffer) = (char*)ILibMemory_AllocateA_Next(buffer) + (int)sz;
}
return(retVal);
}
void* ILibMemory_Allocate(int containerSize, int extraMemorySize, void** allocatedContainer, void **extraMemory) void* ILibMemory_Allocate(int containerSize, int extraMemorySize, void** allocatedContainer, void **extraMemory)
{ {
char* retVal = (char*)malloc(containerSize + extraMemorySize + (extraMemorySize > 0 ? 4 : 0)); char* retVal = (char*)malloc(containerSize + extraMemorySize + (extraMemorySize > 0 ? 4 : 0));
@@ -3671,26 +3695,47 @@ void ILibHashTree_GetValueEx(void *tree_enumerator, char **key, int *keyLength,
\brief Creates an empty ILibHashTree, whose keys are <B>case sensitive</B>. \brief Creates an empty ILibHashTree, whose keys are <B>case sensitive</B>.
\return An empty ILibHashTree \return An empty ILibHashTree
*/ */
void* ILibInitHashTree() void* ILibInitHashTreeEx(void *ReservedMemory)
{ {
struct HashNode_Root *Root; struct HashNode_Root *Root;
struct HashNode *RetVal; struct HashNode *RetVal;
if ((Root = (struct HashNode_Root*)malloc(sizeof(struct HashNode_Root))) == NULL) ILIBCRITICALEXIT(254);
if ((RetVal = (struct HashNode*)malloc(sizeof(struct HashNode))) == NULL) ILIBCRITICALEXIT(254); if (ReservedMemory != NULL)
memset(RetVal, 0, sizeof(struct HashNode)); {
memset(Root, 0, sizeof(struct HashNode_Root)); if (ILibMemory_AllocateA_Size(ReservedMemory) > sizeof(struct HashNode_Root) + sizeof(struct HashNode))
{
Root = (struct HashNode_Root*)ILibMemory_AllocateA_Get(ReservedMemory, sizeof(struct HashNode_Root));
RetVal = (struct HashNode*)ILibMemory_AllocateA_Get(ReservedMemory, sizeof(struct HashNode));
if (Root == NULL || RetVal == NULL) { ILIBCRITICALEXIT(254); }
memset(RetVal, 0, sizeof(struct HashNode));
memset(Root, 0, sizeof(struct HashNode_Root));
Root->Reserved = ReservedMemory;
}
else
{
return(NULL);
}
}
else
{
if ((Root = (struct HashNode_Root*)malloc(sizeof(struct HashNode_Root))) == NULL) ILIBCRITICALEXIT(254);
if ((RetVal = (struct HashNode*)malloc(sizeof(struct HashNode))) == NULL) ILIBCRITICALEXIT(254);
memset(RetVal, 0, sizeof(struct HashNode));
memset(Root, 0, sizeof(struct HashNode_Root));
}
Root->Root = RetVal; Root->Root = RetVal;
sem_init(&(Root->LOCK), 0, 1); if (ReservedMemory == NULL) { sem_init(&(Root->LOCK), 0, 1); }
return(Root); return(Root);
} }
/*! \fn void* ILibInitHashTree_CaseInSensitive() /*! \fn void* ILibInitHashTree_CaseInSensitive()
\brief Creates an empty ILibHashTree, whose keys are <B>case insensitive</B>. \brief Creates an empty ILibHashTree, whose keys are <B>case insensitive</B>.
\return An empty ILibHashTree \return An empty ILibHashTree
*/ */
void* ILibInitHashTree_CaseInSensitive() void* ILibInitHashTree_CaseInSensitiveEx(void *ReservedMemory)
{ {
struct HashNode_Root *Root = (struct HashNode_Root*)ILibInitHashTree(); struct HashNode_Root *Root = (struct HashNode_Root*)ILibInitHashTreeEx(ReservedMemory);
Root->CaseInSensitive = 1; if (Root != NULL) { Root->CaseInSensitive = 1; }
return(Root); return(Root);
} }
@@ -3865,11 +3910,11 @@ struct HashNode* ILibFindEntry(void *hashtree, void *key, int keylength, int cre
// //
// If there is no match, and the create flag is set, we need to create an entry // If there is no match, and the create flag is set, we need to create an entry
// //
if ((current->Next = (struct HashNode*)malloc(sizeof(struct HashNode))) == NULL) ILIBCRITICALEXIT(254); if ((current->Next = (struct HashNode*)(root->Reserved == NULL ? (malloc(sizeof(struct HashNode))) : ILibMemory_AllocateA_Get(root->Reserved, sizeof(struct HashNode)))) == NULL) ILIBCRITICALEXIT(254);
memset(current->Next,0,sizeof(struct HashNode)); memset(current->Next,0,sizeof(struct HashNode));
current->Next->Prev = current; current->Next->Prev = current;
current->Next->KeyHash = HashValue; current->Next->KeyHash = HashValue;
if ((current->Next->KeyValue = (void*)malloc(keylength + 1)) == NULL) ILIBCRITICALEXIT(254); if ((current->Next->KeyValue = (root->Reserved == NULL ? (void*)malloc(keylength + 1) : ILibMemory_AllocateA_Get(root->Reserved, keylength + 1))) == NULL) ILIBCRITICALEXIT(254);
memcpy_s(current->Next->KeyValue, keylength + 1, key ,keylength); memcpy_s(current->Next->KeyValue, keylength + 1, key ,keylength);
current->Next->KeyValue[keylength] = 0; current->Next->KeyValue[keylength] = 0;
current->Next->KeyLength = keylength; current->Next->KeyLength = keylength;
@@ -5171,17 +5216,18 @@ ILibParseUriResult ILibParseUriEx (const char* URI, size_t URILen, char** Addr,
\brief Creates an empty packetheader structure \brief Creates an empty packetheader structure
\return An empty packet \return An empty packet
*/ */
struct packetheader *ILibCreateEmptyPacket() struct packetheader *ILibCreateEmptyPacketEx(void *ReservedMemory)
{ {
struct packetheader *RetVal; ILibHTTPPacket *RetVal = ReservedMemory == NULL ? (ILibHTTPPacket*)malloc(sizeof(ILibHTTPPacket)) : (ILibHTTPPacket*)ILibMemory_AllocateA_Get(ReservedMemory, sizeof(ILibHTTPPacket));
if ((RetVal = (struct packetheader*)malloc(sizeof(struct packetheader))) == NULL) ILIBCRITICALEXIT(254); if (RetVal == NULL) { ILIBCRITICALEXIT(254); }
memset(RetVal,0,sizeof(struct packetheader)); memset(RetVal,0,sizeof(struct packetheader));
RetVal->ReservedMemory = ReservedMemory;
RetVal->UserAllocStrings = -1; RetVal->UserAllocStrings = -1;
RetVal->StatusCode = -1; RetVal->StatusCode = -1;
RetVal->Version = "1.0"; RetVal->Version = "1.0";
RetVal->VersionLength = 3; RetVal->VersionLength = 3;
RetVal->HeaderTable = ILibInitHashTree_CaseInSensitive(); RetVal->HeaderTable = ILibInitHashTree_CaseInSensitiveEx(ReservedMemory);
return RetVal; return RetVal;
} }
@@ -5285,16 +5331,32 @@ void ILibSetDirective(struct packetheader *packet, char* Directive, int Directiv
if (DirectiveLength < 0)DirectiveLength = (int)strnlen_s(Directive, 255); if (DirectiveLength < 0)DirectiveLength = (int)strnlen_s(Directive, 255);
if (DirectiveObjLength < 0)DirectiveObjLength = (int)strnlen_s(DirectiveObj, 255); if (DirectiveObjLength < 0)DirectiveObjLength = (int)strnlen_s(DirectiveObj, 255);
if ((packet->Directive = (char*)malloc(DirectiveLength+1)) == NULL) ILIBCRITICALEXIT(254); if (packet->ReservedMemory != NULL)
{
if (ILibMemory_AllocateA_Size(packet->ReservedMemory) > (DirectiveLength + DirectiveObjLength + 2))
{
packet->Directive = (char*)ILibMemory_AllocateA_Get(packet->ReservedMemory, (size_t)DirectiveLength + 1);
packet->DirectiveObj = (char*)ILibMemory_AllocateA_Get(packet->ReservedMemory, (size_t)DirectiveObjLength + 1);
}
else
{
ILIBCRITICALEXIT(254);
}
}
else
{
if ((packet->Directive = (char*)malloc(DirectiveLength + 1)) == NULL) ILIBCRITICALEXIT(254);
if ((packet->DirectiveObj = (char*)malloc(DirectiveObjLength + 1)) == NULL) ILIBCRITICALEXIT(254);
packet->UserAllocStrings = -1;
}
memcpy_s(packet->Directive, DirectiveLength + 1, Directive,DirectiveLength); memcpy_s(packet->Directive, DirectiveLength + 1, Directive,DirectiveLength);
packet->Directive[DirectiveLength] = '\0'; packet->Directive[DirectiveLength] = '\0';
packet->DirectiveLength = DirectiveLength; packet->DirectiveLength = DirectiveLength;
if ((packet->DirectiveObj = (char*)malloc(DirectiveObjLength+1)) == NULL) ILIBCRITICALEXIT(254);
memcpy_s(packet->DirectiveObj, DirectiveObjLength + 1, DirectiveObj, DirectiveObjLength); memcpy_s(packet->DirectiveObj, DirectiveObjLength + 1, DirectiveObj, DirectiveObjLength);
packet->DirectiveObj[DirectiveObjLength] = '\0'; packet->DirectiveObj[DirectiveObjLength] = '\0';
packet->DirectiveObjLength = DirectiveObjLength; packet->DirectiveObjLength = DirectiveObjLength;
packet->UserAllocStrings = -1;
} }
void ILibHTTPPacket_Stash_Put(ILibHTTPPacket *packet, char* key, int keyLen, void *data) void ILibHTTPPacket_Stash_Put(ILibHTTPPacket *packet, char* key, int keyLen, void *data)
@@ -5335,26 +5397,41 @@ void ILibAddHeaderLine(struct packetheader *packet, const char* FieldName, int F
struct packetheader_field_node *node; struct packetheader_field_node *node;
if (FieldNameLength < 0) { FieldNameLength = (int)strnlen_s(FieldName, 255); } if (FieldNameLength < 0) { FieldNameLength = (int)strnlen_s(FieldName, 255); }
if (FieldDataLength < 0) { FieldDataLength = (int)strnlen_s(FieldData, 255); } if (FieldDataLength < 0) { FieldDataLength = (int)strnlen_s(FieldData, 255); }
if (packet->ReservedMemory != NULL)
{
if (ILibMemory_AllocateA_Size(packet->ReservedMemory) > (sizeof(struct packetheader_field_node) + FieldNameLength + FieldDataLength + 2))
{
node = (packetheader_field_node*)ILibMemory_AllocateA_Get(packet->ReservedMemory, sizeof(packetheader_field_node));
node->Field = (char*)ILibMemory_AllocateA_Get(packet->ReservedMemory, (size_t)FieldNameLength + 1);
node->FieldData = (char*)ILibMemory_AllocateA_Get(packet->ReservedMemory, (size_t)FieldDataLength + 1);
}
else
{
return;
}
}
else
{
//
// Create the Header Node
//
if ((node = (struct packetheader_field_node*)malloc(sizeof(struct packetheader_field_node))) == NULL) ILIBCRITICALEXIT(254);
node->UserAllocStrings = -1;
if ((node->Field = (char*)malloc(FieldNameLength + 1)) == NULL) ILIBCRITICALEXIT(254);
if ((node->FieldData = (char*)malloc(FieldDataLength + 1)) == NULL) ILIBCRITICALEXIT(254);
}
//
// Create the Header Node
//
if ((node = (struct packetheader_field_node*)malloc(sizeof(struct packetheader_field_node))) == NULL) ILIBCRITICALEXIT(254);
node->UserAllocStrings = -1;
if ((node->Field = (char*)malloc(FieldNameLength+1)) == NULL) ILIBCRITICALEXIT(254);
memcpy_s(node->Field, FieldNameLength + 1, (char*)FieldName, FieldNameLength); memcpy_s(node->Field, FieldNameLength + 1, (char*)FieldName, FieldNameLength);
node->Field[FieldNameLength] = '\0'; node->Field[FieldNameLength] = '\0';
node->FieldLength = FieldNameLength; node->FieldLength = FieldNameLength;
if ((node->FieldData = (char*)malloc(FieldDataLength+1)) == NULL) ILIBCRITICALEXIT(254);
memcpy_s(node->FieldData, FieldDataLength + 1, (char*)FieldData, FieldDataLength); memcpy_s(node->FieldData, FieldDataLength + 1, (char*)FieldData, FieldDataLength);
node->FieldData[FieldDataLength] = '\0'; node->FieldData[FieldDataLength] = '\0';
node->FieldDataLength = FieldDataLength; node->FieldDataLength = FieldDataLength;
node->NextField = NULL; node->NextField = NULL;
ILibAddEntryEx(packet->HeaderTable,node->Field,node->FieldLength,node->FieldData,node->FieldDataLength); if (packet->HeaderTable != NULL) { ILibAddEntryEx(packet->HeaderTable, node->Field, node->FieldLength, node->FieldData, node->FieldDataLength); }
// //
// And attach it to the linked list // And attach it to the linked list
// //

View File

@@ -224,7 +224,7 @@ long ILibGetTimeStamp();
#endif #endif
#ifndef strnlen_s #ifndef strnlen_s
#define strnlen_s(source, maxCount) (strlen(source) < (maxCount) ? strlen(source) : (maxCount)) #define strnlen_s(source, maxCount) (strlen(source) < (maxCount) ? strlen(source) : ((size_t)(maxCount)))
#endif #endif
#ifndef sprintf_s #ifndef sprintf_s
@@ -233,10 +233,6 @@ long ILibGetTimeStamp();
int sprintf_s(void *dest, size_t destSize, char *format, ...); int sprintf_s(void *dest, size_t destSize, char *format, ...);
#endif #endif
#ifndef strnlen_s
#define strnlen_s(source, maxLen) strnlen(source, maxLen)
#endif
#endif #endif
@@ -305,6 +301,18 @@ int ILibIsRunningOnChainThread(void* chain);
ILibChain_Link* ILibChain_Link_Allocate(int structSize, int extraMemorySize); ILibChain_Link* ILibChain_Link_Allocate(int structSize, int extraMemorySize);
int ILibChain_Link_GetExtraMemorySize(ILibChain_Link* link); int ILibChain_Link_GetExtraMemorySize(ILibChain_Link* link);
#ifdef WIN32
#define ILibMemory_AllocateA(bufferLen) ILibMemory_AllocateA_InitMem(_alloca(8+bufferLen+sizeof(void*)), (size_t)(8+bufferLen+sizeof(void*)))
#else
#define ILibMemory_AllocateA(bufferLen) ILibMemory_AllocateA_InitMem(alloca(8+bufferLen+sizeof(void*)), (size_t)(8+bufferLen+sizeof(void*)))
#endif
#define ILibMemory_AllocateA_Size(buffer) (((int*)((char*)(buffer)-4))[0])
#define ILibMemory_AllocateA_Next(buffer) (((void**)((char*)(buffer)-4-sizeof(void*)))[0])
#define ILibMemory_AllocateA_Raw(buffer) ((void*)((char*)(buffer)-4-sizeof(void*)-4))
#define ILibMemory_AllocateA_RawSize(buffer) (((int*)((char*)(buffer)-4-sizeof(void*)-4))[0])
void* ILibMemory_AllocateA_Get(void *buffer, size_t sz);
void* ILibMemory_AllocateA_InitMem(void *buffer, size_t bufferLen);
void* ILibMemory_Allocate(int containerSize, int extraMemorySize, void** allocatedContainer, void **extraMemory); void* ILibMemory_Allocate(int containerSize, int extraMemorySize, void** allocatedContainer, void **extraMemory);
int ILibMemory_GetExtraMemorySize(void* extraMemory); int ILibMemory_GetExtraMemorySize(void* extraMemory);
ILibExportMethod void* ILibMemory_GetExtraMemory(void *container, int containerSize); ILibExportMethod void* ILibMemory_GetExtraMemory(void *container, int containerSize);
@@ -534,6 +542,7 @@ int ILibIsRunningOnChainThread(void* chain);
*/ */
void *Reserved; void *Reserved;
char *ReservedMemory;
int DirectiveObjLength; int DirectiveObjLength;
/*! \var StatusCode /*! \var StatusCode
@@ -1049,9 +1058,10 @@ int ILibIsRunningOnChainThread(void* chain);
\b Note: Duplicate key entries will be overwritten. \b Note: Duplicate key entries will be overwritten.
*@{ *@{
*/ */
#define ILibInitHashTree() ILibInitHashTreeEx(NULL)
void* ILibInitHashTree(); void* ILibInitHashTreeEx(void *ReservedMemory);
void* ILibInitHashTree_CaseInSensitive(); void* ILibInitHashTree_CaseInSensitiveEx(void *ReservedMemory);
#define ILibInitHashTree_CaseInSensitive() ILibInitHashTree_CaseInSensitiveEx(NULL)
void ILibDestroyHashTree(void *tree); void ILibDestroyHashTree(void *tree);
int ILibHasEntry(void *hashtree, char* key, int keylength); int ILibHasEntry(void *hashtree, char* key, int keylength);
void ILibAddEntry(void* hashtree, char* key, int keylength, void *value); void ILibAddEntry(void* hashtree, char* key, int keylength, void *value);
@@ -1187,7 +1197,8 @@ int ILibIsRunningOnChainThread(void* chain);
/* Packet Methods */ /* Packet Methods */
struct packetheader *ILibCreateEmptyPacket(); struct packetheader *ILibCreateEmptyPacketEx(void *ReservedMemory);
#define ILibCreateEmptyPacket() ILibCreateEmptyPacketEx(NULL)
void ILibAddHeaderLine(struct packetheader *packet, const char* FieldName, int FieldNameLength, const char* FieldData, int FieldDataLength); void ILibAddHeaderLine(struct packetheader *packet, const char* FieldName, int FieldNameLength, const char* FieldData, int FieldDataLength);
void ILibDeleteHeaderLine(struct packetheader *packet, char* FieldName, int FieldNameLength); void ILibDeleteHeaderLine(struct packetheader *packet, char* FieldName, int FieldNameLength);
void ILibHTTPPacket_Stash_Put(ILibHTTPPacket *packet, char* key, int keyLen, void *data); void ILibHTTPPacket_Stash_Put(ILibHTTPPacket *packet, char* key, int keyLen, void *data);

View File

@@ -109,6 +109,7 @@ typedef struct ILibProcessPipe_Process_Object
ILibProcessPipe_Process_ExitHandler exitHandler; ILibProcessPipe_Process_ExitHandler exitHandler;
#ifdef WIN32 #ifdef WIN32
HANDLE hProcess; HANDLE hProcess;
int hProcess_needAdd;
#endif #endif
void *chain; void *chain;
}ILibProcessPipe_Process_Object; }ILibProcessPipe_Process_Object;
@@ -153,6 +154,7 @@ ILibProcessPipe_Pipe ILibProcessPipe_Process_GetStdOut(ILibProcessPipe_Process p
} }
#ifdef WIN32 #ifdef WIN32
BOOL ILibProcessPipe_Process_OnExit(HANDLE event, void* user);
typedef struct ILibProcessPipe_WaitHandle typedef struct ILibProcessPipe_WaitHandle
{ {
ILibProcessPipe_Manager_Object *parent; ILibProcessPipe_Manager_Object *parent;
@@ -203,6 +205,7 @@ void ILibProcessPipe_WaitHandle_AddEx(ILibProcessPipe_Manager mgr, ILibProcessPi
{ {
// We're on the same thread, so we can just add it in // We're on the same thread, so we can just add it in
ILibLinkedList_AddTail(manager->ActivePipes, waitHandle); ILibLinkedList_AddTail(manager->ActivePipes, waitHandle);
SetEvent(manager->updateEvent); SetEvent(manager->updateEvent);
} }
else else
@@ -222,7 +225,6 @@ void ILibProcessPipe_WaitHandle_Add(ILibProcessPipe_Manager mgr, HANDLE event, v
waitHandle->user = user; waitHandle->user = user;
waitHandle->callback = callback; waitHandle->callback = callback;
ILibProcessPipe_WaitHandle_AddEx(mgr, waitHandle); ILibProcessPipe_WaitHandle_AddEx(mgr, waitHandle);
} }
@@ -740,9 +742,9 @@ void ILibProcessPipe_Pipe_SwapBuffers(ILibProcessPipe_Pipe obj, char* newBuffer,
ILibProcessPipe_PipeObject *pipeObject = (ILibProcessPipe_PipeObject*)obj; ILibProcessPipe_PipeObject *pipeObject = (ILibProcessPipe_PipeObject*)obj;
*oldBuffer = pipeObject->buffer; *oldBuffer = pipeObject->buffer;
*oldBufferLen = pipeObject->bufferSize; if (oldBufferLen != NULL) { *oldBufferLen = pipeObject->bufferSize; }
*oldBufferReadOffset = pipeObject->readOffset; if (oldBufferReadOffset != NULL) { *oldBufferReadOffset = pipeObject->readOffset; }
*oldBufferTotalBytesRead = pipeObject->totalRead; if (oldBufferTotalBytesRead != NULL) { *oldBufferTotalBytesRead = pipeObject->totalRead; }
pipeObject->buffer = newBuffer; pipeObject->buffer = newBuffer;
pipeObject->bufferSize = newBufferLen; pipeObject->bufferSize = newBufferLen;
@@ -1129,6 +1131,11 @@ void ILibProcessPipe_Pipe_Resume(ILibProcessPipe_Pipe pipeObject)
else else
{ {
ILibProcessPipe_Pipe_ResumeEx(p); ILibProcessPipe_Pipe_ResumeEx(p);
if (p->mProcess != NULL && p->mProcess->hProcess_needAdd != 0)
{
p->mProcess->hProcess_needAdd = 0;
ILibProcessPipe_WaitHandle_Add(p->manager, p->mProcess->hProcess, p->mProcess, ILibProcessPipe_Process_OnExit);
}
} }
#else #else
ILibProcessPipe_Pipe_ResumeEx(p); ILibProcessPipe_Pipe_ResumeEx(p);
@@ -1231,6 +1238,7 @@ void ILibProcessPipe_Process_PipeHandler_StdIn(void *user1, void *user2)
if (sendOk != NULL) sendOk(j, j->userObject); if (sendOk != NULL) sendOk(j, j->userObject);
} }
#ifdef WIN32 #ifdef WIN32
void ILibProcessPipe_Process_OnExit_ChainSink(void *chain, void *user) void ILibProcessPipe_Process_OnExit_ChainSink(void *chain, void *user)
{ {
@@ -1241,9 +1249,9 @@ void ILibProcessPipe_Process_OnExit_ChainSink(void *chain, void *user)
result = GetExitCodeProcess(j->hProcess, &exitCode); result = GetExitCodeProcess(j->hProcess, &exitCode);
j->exiting = 1; j->exiting = 1;
j->exitHandler(j, exitCode, j->userObject); j->exitHandler(j, exitCode, j->userObject);
j->exiting = 0; j->exiting ^= 1;
ILibProcessPipe_Process_Destroy(j); if (j->exiting == 0) { ILibProcessPipe_Process_Destroy(j); }
} }
BOOL ILibProcessPipe_Process_OnExit(HANDLE event, void* user) BOOL ILibProcessPipe_Process_OnExit(HANDLE event, void* user)
{ {
@@ -1251,15 +1259,21 @@ BOOL ILibProcessPipe_Process_OnExit(HANDLE event, void* user)
UNREFERENCED_PARAMETER(event); UNREFERENCED_PARAMETER(event);
ILibProcessPipe_WaitHandle_Remove(j->parent, j->hProcess); ILibProcessPipe_WaitHandle_Remove(j->parent, j->hProcess);
if (j->stdOut->PAUSED != 0 || j->stdErr->PAUSED != 0)
if (j->exitHandler != NULL)
{ {
// Everyone's lifes is made easier, by context switching to chain thread before making this call j->hProcess_needAdd = 1;
ILibChain_RunOnMicrostackThread(j->parent->ChainLink.ParentChain, ILibProcessPipe_Process_OnExit_ChainSink, user);
} }
else else
{ {
ILibProcessPipe_Process_Destroy(j); if (j->exitHandler != NULL)
{
// Everyone's lifes is made easier, by context switching to chain thread before making this call
ILibChain_RunOnMicrostackThread(j->parent->ChainLink.ParentChain, ILibProcessPipe_Process_OnExit_ChainSink, user);
}
else
{
ILibProcessPipe_Process_Destroy(j);
}
} }
return(FALSE); return(FALSE);
} }

View File

@@ -149,6 +149,8 @@ struct ILibWebClient_StreamedRequestState
int done; int done;
int canceled; int canceled;
int doNotSendRightAway; int doNotSendRightAway;
int idleTimeout;
ILibAsyncSocket_TimeoutHandler idleTimeoutHandler;
}; };
struct ILibWebClientManager struct ILibWebClientManager
@@ -204,9 +206,12 @@ typedef struct ILibWebClientDataObject
int IsOrphan; int IsOrphan;
int PipelineFlag; int PipelineFlag;
int ActivityCounter; int ActivityCounter;
int NC;
char CNONCE[17];
struct sockaddr_in6 remote; struct sockaddr_in6 remote;
struct sockaddr_in6 proxy; struct sockaddr_in6 proxy;
struct ILibWebClientManager *Parent; struct ILibWebClientManager *Parent;
char* DigestData;
int PendingConnectionIndex; int PendingConnectionIndex;
@@ -248,6 +253,7 @@ typedef struct ILibWebClientDataObject
char CertificateHash[32]; // Used by the Mesh to store NodeID of this session char CertificateHash[32]; // Used by the Mesh to store NodeID of this session
}ILibWebClientDataObject; }ILibWebClientDataObject;
struct ILibWebRequest;
typedef struct ILibWebClient_PipelineRequestToken typedef struct ILibWebClient_PipelineRequestToken
{ {
struct ILibWebClientDataObject *wcdo; struct ILibWebClientDataObject *wcdo;
@@ -255,6 +261,7 @@ typedef struct ILibWebClient_PipelineRequestToken
char* WebSocketKey; char* WebSocketKey;
int WebSocketMaxBuffer; int WebSocketMaxBuffer;
ILibWebClient_OnSendOK WebSocketSendOK; ILibWebClient_OnSendOK WebSocketSendOK;
struct ILibWebRequest *parent;
char host[255]; char host[255];
char reserved[29]; char reserved[29];
}ILibWebClient_PipelineRequestToken; }ILibWebClient_PipelineRequestToken;
@@ -277,6 +284,8 @@ typedef struct ILibWebRequest
ILibWebRequest_buffer *buffered; ILibWebRequest_buffer *buffered;
struct sockaddr_in6 remote; struct sockaddr_in6 remote;
void *user1,*user2; void *user1,*user2;
ILibWebClient_OnConnectHandler ConnectSink, DisconnectSink;
int connectionCloseWasSpecified;
struct ILibWebClient_PipelineRequestToken *requestToken; struct ILibWebClient_PipelineRequestToken *requestToken;
struct ILibWebClient_StreamedRequestState *streamedState; struct ILibWebClient_StreamedRequestState *streamedState;
@@ -332,6 +341,7 @@ void ILibWebClient_DestroyWebRequest(struct ILibWebRequest *wr)
struct ILibWebClient_StreamedRequestBuffer *b; struct ILibWebClient_StreamedRequestBuffer *b;
if (wr == NULL) return; if (wr == NULL) return;
if (wr != NULL && wr->connectionCloseWasSpecified != 0 && wr->DisconnectSink != NULL) { wr->DisconnectSink(wr->requestToken); }
if (wr->buffered != NULL) { free(wr->buffered); } if (wr->buffered != NULL) { free(wr->buffered); }
if (wr->streamedState != NULL) if (wr->streamedState != NULL)
{ {
@@ -455,12 +465,13 @@ void ILibWebClient_DestroyWebClientDataObject(ILibWebClient_StateObject token)
{ {
free(((ILibWebClient_WebSocketState*)wr->Buffer[0])->WebSocketFragmentBuffer); free(((ILibWebClient_WebSocketState*)wr->Buffer[0])->WebSocketFragmentBuffer);
} }
wr->connectionCloseWasSpecified = 2;
ILibWebClient_DestroyWebRequest(wr); ILibWebClient_DestroyWebRequest(wr);
ILibQueue_DeQueue(wcdo->RequestQueue); ILibQueue_DeQueue(wcdo->RequestQueue);
} }
ILibQueue_Destroy(wcdo->RequestQueue); ILibQueue_Destroy(wcdo->RequestQueue);
if (wcdo->DigestData != NULL) { free(ILibMemory_AllocateA_Raw(wcdo->DigestData)); }
free(wcdo); free(wcdo);
} }
@@ -674,7 +685,7 @@ void ILibWebClient_FinishedResponse(ILibAsyncSocket_SocketModule socketModule, s
{ {
int i; int i;
struct ILibWebRequest *wr; struct ILibWebRequest *wr;
int closeSpecified = 0;
UNREFERENCED_PARAMETER( socketModule ); UNREFERENCED_PARAMETER( socketModule );
if (wcdo == NULL) return; if (wcdo == NULL) return;
@@ -718,6 +729,7 @@ void ILibWebClient_FinishedResponse(ILibAsyncSocket_SocketModule socketModule, s
} }
// Reset the flags // Reset the flags
closeSpecified = wcdo->ConnectionCloseSpecified;
ILibWebClient_ResetWCDO(wcdo); ILibWebClient_ResetWCDO(wcdo);
// If this socket isn't connected, it's because it was previously closed, // If this socket isn't connected, it's because it was previously closed,
@@ -726,7 +738,9 @@ void ILibWebClient_FinishedResponse(ILibAsyncSocket_SocketModule socketModule, s
{ {
SEM_TRACK(WebClient_TrackLock("ILibWebClient_FinishedResponse", 1, wcdo->Parent);) SEM_TRACK(WebClient_TrackLock("ILibWebClient_FinishedResponse", 1, wcdo->Parent);)
sem_wait(&(wcdo->Parent->QLock)); sem_wait(&(wcdo->Parent->QLock));
ILibWebClient_DestroyWebRequest((struct ILibWebRequest*)ILibQueue_DeQueue(wcdo->RequestQueue)); wr = (struct ILibWebRequest*)ILibQueue_DeQueue(wcdo->RequestQueue);
wr->connectionCloseWasSpecified = 2;
ILibWebClient_DestroyWebRequest(wr);
SEM_TRACK(WebClient_TrackUnLock("ILibWebClient_FinishedResponse", 2, wcdo->Parent);) SEM_TRACK(WebClient_TrackUnLock("ILibWebClient_FinishedResponse", 2, wcdo->Parent);)
sem_post(&(wcdo->Parent->QLock)); sem_post(&(wcdo->Parent->QLock));
return; return;
@@ -741,6 +755,7 @@ void ILibWebClient_FinishedResponse(ILibAsyncSocket_SocketModule socketModule, s
// Only execute this logic, if there was a pending request. If there wasn't one, that means // Only execute this logic, if there was a pending request. If there wasn't one, that means
// that this session was closed the last time the app as called with data, making this next step unnecessary. // that this session was closed the last time the app as called with data, making this next step unnecessary.
// //
wr->connectionCloseWasSpecified = closeSpecified;
ILibWebClient_DestroyWebRequest(wr); ILibWebClient_DestroyWebRequest(wr);
wr = (struct ILibWebRequest*)ILibQueue_PeekQueue(wcdo->RequestQueue); wr = (struct ILibWebRequest*)ILibQueue_PeekQueue(wcdo->RequestQueue);
if (wr == NULL) if (wr == NULL)
@@ -764,7 +779,7 @@ void ILibWebClient_FinishedResponse(ILibAsyncSocket_SocketModule socketModule, s
// //
// There are still pending requests in the queue, so try to send them // There are still pending requests in the queue, so try to send them
// //
if (wcdo->PipelineFlag != PIPELINE_NO) if (wcdo->PipelineFlag != PIPELINE_NO && closeSpecified == 0)
{ {
ILibWebRequest_buffer *b; ILibWebRequest_buffer *b;
// //
@@ -789,7 +804,7 @@ void ILibWebClient_FinishedResponse(ILibAsyncSocket_SocketModule socketModule, s
} }
} }
} }
if (wcdo->PipelineFlag == PIPELINE_NO) if (wcdo->PipelineFlag == PIPELINE_NO || closeSpecified != 0)
{ {
//{{{ <--REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT }}} //{{{ <--REMOVE_THIS_FOR_HTTP/1.0_ONLY_SUPPORT }}}
/* Pipelining is not supported, so we should just close the socket, instead /* Pipelining is not supported, so we should just close the socket, instead
@@ -2012,6 +2027,7 @@ void ILibWebClient_OnConnect(ILibAsyncSocket_SocketModule socketModule, int Conn
//printf("ILibWebClient_OnConnect(). Connected=%d, DisconnectSent=%d\r\n", Connected, wcdo->DisconnectSent); //printf("ILibWebClient_OnConnect(). Connected=%d, DisconnectSent=%d\r\n", Connected, wcdo->DisconnectSent);
if (wcdo->Closing != 0) return; // Already closing, exit now if (wcdo->Closing != 0) return; // Already closing, exit now
wcdo->SOCK = socketModule; wcdo->SOCK = socketModule;
@@ -2031,6 +2047,7 @@ void ILibWebClient_OnConnect(ILibAsyncSocket_SocketModule socketModule, int Conn
sem_post(&(wcdo->Parent->QLock)); sem_post(&(wcdo->Parent->QLock));
if (r != NULL) if (r != NULL)
{ {
if (r->ConnectSink != NULL) { r->ConnectSink(r->requestToken); }
ILibWebRequest_buffer *b; ILibWebRequest_buffer *b;
for(i = 0; i < r->NumberOfBuffers; ++i) for(i = 0; i < r->NumberOfBuffers; ++i)
{ {
@@ -2044,7 +2061,11 @@ void ILibWebClient_OnConnect(ILibAsyncSocket_SocketModule socketModule, int Conn
r->buffered = r->buffered->next; r->buffered = r->buffered->next;
free(b); free(b);
} }
if (r->streamedState != NULL) ILibWebClient_OnSendOKSink(socketModule, wcdo); if (r->streamedState != NULL)
{
if (r->streamedState->idleTimeout > 0 && r->streamedState->idleTimeoutHandler != NULL) { ILibAsyncSocket_SetTimeoutEx(socketModule, r->streamedState->idleTimeout, r->streamedState->idleTimeoutHandler); }
ILibWebClient_OnSendOKSink(socketModule, wcdo);
}
} }
} }
else else
@@ -2162,7 +2183,8 @@ void ILibWebClient_OnDisconnectSink(ILibAsyncSocket_SocketModule socketModule, v
} }
ILibWebClient_ResetWCDO(wcdo); ILibWebClient_ResetWCDO(wcdo);
if (wcdo->DisconnectSent == 1) wcdo->DisconnectSent = 0; if (wcdo->DisconnectSent == 1) wcdo->DisconnectSent = 0;
if (wr != NULL) ILibWebClient_DestroyWebRequest(wr); if (wr != NULL && wr->DisconnectSink != NULL) { wr->DisconnectSink(wr->requestToken); }
if (wr != NULL) { wr->connectionCloseWasSpecified = 3; ILibWebClient_DestroyWebRequest(wr); }
if (h != NULL) ILibDestructPacket(h); if (h != NULL) ILibDestructPacket(h);
} }
@@ -2209,6 +2231,7 @@ void ILibWebClient_OnDisconnectSink(ILibAsyncSocket_SocketModule socketModule, v
{ {
free(((ILibWebClient_WebSocketState*)wr->Buffer[0])->WebSocketFragmentBuffer); free(((ILibWebClient_WebSocketState*)wr->Buffer[0])->WebSocketFragmentBuffer);
} }
wr->connectionCloseWasSpecified = 2;
ILibWebClient_DestroyWebRequest(wr); ILibWebClient_DestroyWebRequest(wr);
} }
} }
@@ -2634,7 +2657,7 @@ ILibWebClient_RequestToken ILibWebClient_PipelineRequestEx2(
request->UserFree[0] = headerBuffer_FREE; request->UserFree[0] = headerBuffer_FREE;
ILibMemory_Allocate(sizeof(ILibWebClient_PipelineRequestToken), 32, (void**)&(request->requestToken), NULL); ILibMemory_Allocate(sizeof(ILibWebClient_PipelineRequestToken), 32, (void**)&(request->requestToken), NULL);
request->requestToken->parent = request;
request->requestToken->timer = wcm->timer; request->requestToken->timer = wcm->timer;
if (headerBufferLength > 5 && strncasecmp("HEAD ", headerBuffer, 5) == 0) if (headerBufferLength > 5 && strncasecmp("HEAD ", headerBuffer, 5) == 0)
@@ -2727,11 +2750,9 @@ ILibWebClient_RequestToken ILibWebClient_PipelineRequestEx2(
RequestTokenLength = ILibCreateTokenStr(RemoteEndpoint, 0, RequestToken); RequestTokenLength = ILibCreateTokenStr(RemoteEndpoint, 0, RequestToken);
} }
if (ILibHasEntry(wcm->DataTable, RequestToken, RequestTokenLength)!=0) if ((wcdo = (struct ILibWebClientDataObject*)ILibGetEntry(wcm->DataTable, RequestToken, RequestTokenLength)) != NULL)
{ {
// Yes it does! // Previous connection exists!
wcdo = (struct ILibWebClientDataObject*)ILibGetEntry(wcm->DataTable, RequestToken, RequestTokenLength);
if (wcdo == NULL) ILIBCRITICALEXIT(253); // TODO: Better handling....
request->requestToken->wcdo = wcdo; request->requestToken->wcdo = wcdo;
if (ILibQueue_IsEmpty(wcdo->RequestQueue) != 0) if (ILibQueue_IsEmpty(wcdo->RequestQueue) != 0)
{ {
@@ -2739,14 +2760,14 @@ ILibWebClient_RequestToken ILibWebClient_PipelineRequestEx2(
ILibQueue_EnQueue(wcdo->RequestQueue, request); ILibQueue_EnQueue(wcdo->RequestQueue, request);
// Take out of Idle State // Take out of Idle State
wcm->idleCount = wcm->idleCount == 0?0:wcm->idleCount-1; wcm->idleCount = wcm->idleCount == 0 ? 0 : wcm->idleCount - 1;
ILibDeleteEntry(wcm->idleTable, RequestToken, RequestTokenLength); ILibDeleteEntry(wcm->idleTable, RequestToken, RequestTokenLength);
ILibLifeTime_Remove(wcm->timer, wcdo); ILibLifeTime_Remove(wcm->timer, wcdo);
if (wcdo->DisconnectSent == 0 && (wcdo->SOCK == NULL || ILibAsyncSocket_IsFree(wcdo->SOCK))) if (wcdo->DisconnectSent == 0 && (wcdo->SOCK == NULL || ILibAsyncSocket_IsFree(wcdo->SOCK)))
{ {
// If this was in our idleTable, then most likely the select doesn't know about // If this was in our idleTable, then most likely the select doesn't know about
// it, so we need to force it to unblock // it, so we need to force it to unblock
ILibQueue_EnQueue(wcm->backlogQueue, wcdo); ILibQueue_EnQueue(wcm->backlogQueue, wcdo);
ForceUnBlock = 1; ForceUnBlock = 1;
} }
else if (wcdo->SOCK != NULL) else if (wcdo->SOCK != NULL)
@@ -2754,13 +2775,14 @@ ILibWebClient_RequestToken ILibWebClient_PipelineRequestEx2(
// Socket is still there // Socket is still there
if (wcdo->WaitForClose == 0) if (wcdo->WaitForClose == 0)
{ {
for(i = 0; i < request->NumberOfBuffers; ++i) for (i = 0; i < request->NumberOfBuffers; ++i)
{ {
// TODO: Sandeep: This function call can be locking!! // TODO: Sandeep: This function call can be locking!!
ILibAsyncSocket_Send(wcdo->SOCK, request->Buffer[i], request->BufferLength[i], ILibAsyncSocket_MemoryOwnership_STATIC); ILibAsyncSocket_Send(wcdo->SOCK, request->Buffer[i], request->BufferLength[i], ILibAsyncSocket_MemoryOwnership_STATIC);
} }
if (request->streamedState != NULL) if (request->streamedState != NULL)
{ {
if (request->streamedState->idleTimeout > 0 && request->streamedState->idleTimeoutHandler != NULL) { ILibAsyncSocket_SetTimeoutEx(wcdo->SOCK, request->streamedState->idleTimeout, request->streamedState->idleTimeoutHandler); }
ILibWebClient_OnSendOKSink(wcdo->SOCK, wcdo); ILibWebClient_OnSendOKSink(wcdo->SOCK, wcdo);
} }
} }
@@ -3162,22 +3184,8 @@ ILibWebClient_RequestToken ILibWebClient_GetRequestToken_FromStateObject(ILibWeb
void **ILibWebClient_RequestToken_GetUserObjects(ILibWebClient_RequestToken tok) void **ILibWebClient_RequestToken_GetUserObjects(ILibWebClient_RequestToken tok)
{ {
struct ILibWebClientDataObject *wcdo = (struct ILibWebClientDataObject*)ILibWebClient_GetStateObjectFromRequestToken(tok); ILibWebClient_PipelineRequestToken *prt = (ILibWebClient_PipelineRequestToken*)tok;
struct ILibWebRequest *wr; return(prt->parent != NULL ? &(prt->parent->user1) : NULL);
if (wcdo == NULL) return(NULL);
wr = (struct ILibWebRequest*)ILibQueue_PeekQueue(wcdo->RequestQueue);
if (wr != NULL) { return(&(wr->user1)); } else { return(NULL); }
}
void **ILibWebClient_RequestToken_GetUserObjects_Tail(ILibWebClient_RequestToken tok)
{
struct ILibWebClientDataObject *wcdo = (struct ILibWebClientDataObject*)ILibWebClient_GetStateObjectFromRequestToken(tok);
struct ILibWebRequest *wr;
if (wcdo == NULL) return(NULL);
wr = (struct ILibWebRequest*)ILibQueue_PeekTail(wcdo->RequestQueue);
if (wr != NULL) { return(&(wr->user1)); }
else { return(NULL); }
} }
/*! \fn ILibWebClient_StateObject ILibWebClient_GetStateObjectFromRequestToken(ILibWebClient_RequestToken token) /*! \fn ILibWebClient_StateObject ILibWebClient_GetStateObjectFromRequestToken(ILibWebClient_RequestToken token)
@@ -3210,6 +3218,13 @@ ILibWebClient_RequestToken ILibWebClient_PipelineStreamedRequest(ILibWebClient_R
state->BufferQueue = ILibQueue_Create(); state->BufferQueue = ILibQueue_Create();
state->OnSendOK = OnSendOK; state->OnSendOK = OnSendOK;
state->doNotSendRightAway = 1; state->doNotSendRightAway = 1;
if (ILibHTTPPacket_Stash_HasKey(packet, "_idleTimeout", 12) != 0)
{
union { int i; void*p; }u;
u.p = ILibHTTPPacket_Stash_Get(packet, "_idleTimeout", 12);
state->idleTimeout = u.i;
state->idleTimeoutHandler = (ILibAsyncSocket_TimeoutHandler)ILibHTTPPacket_Stash_Get(packet, "_idleTimeoutHandler", 19);
}
ILibAddHeaderLine(packet,"Transfer-Encoding",17,"chunked",7); ILibAddHeaderLine(packet,"Transfer-Encoding",17,"chunked",7);
@@ -3662,14 +3677,27 @@ int ILibWebClient_Digest_NeedAuthenticate(ILibWebClient_StateObject state)
char* authenticate = ILibGetHeaderLine(wcdo->header, "WWW-Authenticate", 16); char* authenticate = ILibGetHeaderLine(wcdo->header, "WWW-Authenticate", 16);
return(wcdo->header->StatusCode == 401 && authenticate != NULL); return(wcdo->header->StatusCode == 401 && authenticate != NULL);
} }
void* ILibWebClient_Digest_GenerateTable(ILibWebClient_StateObject state) void* ILibWebClient_Digest_GenerateTableEx(ILibWebClient_StateObject state, void *ReservedMemory)
{ {
ILibWebClientDataObject *wcdo = (ILibWebClientDataObject*)state;
char* authenticate = ILibGetHeaderLineSP(((ILibWebClientDataObject*)state)->header, "WWW-Authenticate", 16); char* authenticate = ILibGetHeaderLineSP(((ILibWebClientDataObject*)state)->header, "WWW-Authenticate", 16);
void* table = ILibInitHashTree_CaseInSensitive();
if (wcdo->DigestData == NULL) { wcdo->DigestData = ILibMemory_AllocateA_InitMem(ILibMemory_Allocate(1024, 0, NULL, NULL), 1024); }
if (authenticate != NULL)
{
ILibMemory_AllocateA_InitMem(ILibMemory_AllocateA_Raw(wcdo->DigestData), ILibMemory_AllocateA_RawSize(wcdo->DigestData));
strncpy_s(wcdo->DigestData, ILibMemory_AllocateA_Size(wcdo->DigestData), authenticate, strnlen_s(authenticate, sizeof(ILibScratchPad)));
}
else
{
authenticate = wcdo->DigestData;
}
void* table = ILibInitHashTree_CaseInSensitiveEx(ReservedMemory);
ILibWebServer_Digest_ParseAuthenticationHeader(table, authenticate, (int)strnlen_s(authenticate, sizeof(ILibScratchPad) - sizeof(void*))); ILibWebServer_Digest_ParseAuthenticationHeader(table, authenticate, (int)strnlen_s(authenticate, sizeof(ILibScratchPad) - sizeof(void*)));
return(table); return(table);
} }
#define ILibWebClient_Digest_GenerateTable(state) ILibWebClient_Digest_GenerateTableEx(state, NULL)
char* ILibWebClient_Digest_GetRealm(ILibWebClient_StateObject state) char* ILibWebClient_Digest_GetRealm(ILibWebClient_StateObject state)
{ {
void* table = ILibWebClient_Digest_GenerateTable(state); void* table = ILibWebClient_Digest_GenerateTable(state);
@@ -3681,15 +3709,18 @@ char* ILibWebClient_Digest_GetRealm(ILibWebClient_StateObject state)
void ILibWebClient_GenerateAuthenticationHeader(ILibWebClient_StateObject state, ILibHTTPPacket *packet, char* username, char* password) void ILibWebClient_GenerateAuthenticationHeader(ILibWebClient_StateObject state, ILibHTTPPacket *packet, char* username, char* password)
{ {
ILibWebClientDataObject *wcdo = (ILibWebClientDataObject*)state;
int tmpLen; int tmpLen;
char result1[33]; char result1[33];
char result2[33]; char result2[33];
char result3[33]; char result3[33];
void* table = ILibWebClient_Digest_GenerateTable(state);
void *ReservedMemory = packet->ReservedMemory == NULL ? ILibMemory_AllocateA(8000) : packet->ReservedMemory;
void* table = ILibWebClient_Digest_GenerateTableEx(state, ReservedMemory);
char* realm = (char*)ILibGetEntry(table, "realm", 5); char* realm = (char*)ILibGetEntry(table, "realm", 5);
char* nonce = (char*)ILibGetEntry(table, "nonce", 5); char* nonce = (char*)ILibGetEntry(table, "nonce", 5);
char* opaque = (char*)ILibGetEntry(table, "opaque", 6); char* opaque = (char*)ILibGetEntry(table, "opaque", 6);
ILibDestroyHashTree(table); char *qop = (char*)ILibGetEntry(table, "qop", 3);
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s:%s:%s", username, realm, password); tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s:%s:%s", username, realm, password);
util_md5hex(ILibScratchPad2, tmpLen, result1); util_md5hex(ILibScratchPad2, tmpLen, result1);
@@ -3699,10 +3730,30 @@ void ILibWebClient_GenerateAuthenticationHeader(ILibWebClient_StateObject state,
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s:%s", packet->Directive, packet->DirectiveObj); tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s:%s", packet->Directive, packet->DirectiveObj);
util_md5hex(ILibScratchPad2, tmpLen, result2); util_md5hex(ILibScratchPad2, tmpLen, result2);
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s:%s:%s", result1, nonce, result2); if (qop == NULL)
{
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s:%s:%s", result1, nonce, result2);
}
else
{
if (wcdo->NC == 0)
{
util_randomtext(sizeof(wcdo->CNONCE)-1, wcdo->CNONCE);
wcdo->CNONCE[sizeof(wcdo->CNONCE) - 1] = 0;
}
wcdo->NC++;
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s:%s:%08x:%s:%s:%s", result1, nonce, wcdo->NC, wcdo->CNONCE, qop, result2);
}
util_md5hex(ILibScratchPad2, tmpLen, result3); util_md5hex(ILibScratchPad2, tmpLen, result3);
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", opaque=\"%s\", response=\"%s\"", username, realm, nonce, packet->DirectiveObj, opaque, result3); tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\"", username, realm, nonce, packet->DirectiveObj);
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, wcdo->NC, wcdo->CNONCE);
}
tmpLen += sprintf_s(ILibScratchPad2 + tmpLen, sizeof(ILibScratchPad2) - tmpLen, ", response=\"%s\"", result3);
ILibAddHeaderLine(packet, "Authorization", 13, ILibScratchPad2, tmpLen); ILibAddHeaderLine(packet, "Authorization", 13, ILibScratchPad2, tmpLen);
} }
void ILibWebClient_AddWebSocketRequestHeaders(ILibHTTPPacket *packet, int FragmentReassemblyMaxBufferSize, ILibWebClient_OnSendOK OnSendOK) void ILibWebClient_AddWebSocketRequestHeaders(ILibHTTPPacket *packet, int FragmentReassemblyMaxBufferSize, ILibWebClient_OnSendOK OnSendOK)
@@ -3725,6 +3776,23 @@ void ILibWebClient_AddWebSocketRequestHeaders(ILibHTTPPacket *packet, int Fragme
ILibHTTPPacket_Stash_Put(packet, "_WebSocketBufferSize", 20, u.p); ILibHTTPPacket_Stash_Put(packet, "_WebSocketBufferSize", 20, u.p);
ILibHTTPPacket_Stash_Put(packet, "_WebSocketOnSendOK", 18, OnSendOK); ILibHTTPPacket_Stash_Put(packet, "_WebSocketOnSendOK", 18, OnSendOK);
} }
void ILibWebClient_RequestToken_ConnectionHandler_Set(ILibWebClient_RequestToken token, ILibWebClient_OnConnectHandler OnConnect, ILibWebClient_OnConnectHandler OnDisconnect)
{
ILibWebClientDataObject *wcdo = ILibWebClient_GetStateObjectFromRequestToken(token);
struct ILibWebRequest *wr;
if (wcdo != NULL)
{
sem_wait(&(wcdo->Parent->QLock));
wr = (struct ILibWebRequest*)ILibQueue_PeekTail(wcdo->RequestQueue);
if (wr != NULL)
{
wr->ConnectSink = OnConnect;
wr->DisconnectSink = OnDisconnect;
}
sem_post(&(wcdo->Parent->QLock));
}
}
#ifdef MICROSTACK_PROXY #ifdef MICROSTACK_PROXY
struct sockaddr_in6* ILibWebClient_SetProxy(ILibWebClient_RequestToken token, char *proxyHost, unsigned short proxyPort, char *username, char *password) struct sockaddr_in6* ILibWebClient_SetProxy(ILibWebClient_RequestToken token, char *proxyHost, unsigned short proxyPort, char *username, char *password)
{ {

View File

@@ -133,6 +133,7 @@ typedef void(*ILibWebClient_OnResponse)(ILibWebClient_StateObject WebStateObject
\param user2 User2 object that was associated with this connection \param user2 User2 object that was associated with this connection
*/ */
typedef void(*ILibWebClient_OnSendOK)(ILibWebClient_StateObject sender, void *user1, void *user2); typedef void(*ILibWebClient_OnSendOK)(ILibWebClient_StateObject sender, void *user1, void *user2);
typedef void(*ILibWebClient_OnConnectHandler)(ILibWebClient_RequestToken sender);
/*! \typedef ILibWebClient_OnDisconnect /*! \typedef ILibWebClient_OnDisconnect
\brief Handler for when the session has disconnected \brief Handler for when the session has disconnected
\param sender The \a ILibWebClient_StateObject that has been disconnected \param sender The \a ILibWebClient_StateObject that has been disconnected
@@ -241,7 +242,8 @@ void ILibWebClient_ResetUserObjects(ILibWebClient_StateObject webstate, void *us
ILibWebClient_RequestToken ILibWebClient_GetRequestToken_FromStateObject(ILibWebClient_StateObject WebStateObject); ILibWebClient_RequestToken ILibWebClient_GetRequestToken_FromStateObject(ILibWebClient_StateObject WebStateObject);
ILibWebClient_StateObject ILibWebClient_GetStateObjectFromRequestToken(ILibWebClient_RequestToken token); ILibWebClient_StateObject ILibWebClient_GetStateObjectFromRequestToken(ILibWebClient_RequestToken token);
void **ILibWebClient_RequestToken_GetUserObjects(ILibWebClient_RequestToken tok); void **ILibWebClient_RequestToken_GetUserObjects(ILibWebClient_RequestToken tok);
void **ILibWebClient_RequestToken_GetUserObjects_Tail(ILibWebClient_RequestToken tok);
void ILibWebClient_RequestToken_ConnectionHandler_Set(ILibWebClient_RequestToken tok, ILibWebClient_OnConnectHandler OnConnect, ILibWebClient_OnConnectHandler OnDisconnect);
void ILibWebClient_Parse_ContentRange(char *contentRange, int *Start, int *End, int *TotalLength); void ILibWebClient_Parse_ContentRange(char *contentRange, int *Start, int *End, int *TotalLength);
enum ILibWebClient_Range_Result ILibWebClient_Parse_Range(char *Range, long *Start, long *Length, long TotalLength); enum ILibWebClient_Range_Result ILibWebClient_Parse_Range(char *Range, long *Start, long *Length, long TotalLength);

View File

@@ -1910,7 +1910,10 @@ int ILibWebServer_GetLocalInterface(struct ILibWebServer_Session *session, struc
return ILibAsyncSocket_GetLocalInterface(ILibWebServer_Session_GetSystemData(session)->ConnectionToken, localAddress); return ILibAsyncSocket_GetLocalInterface(ILibWebServer_Session_GetSystemData(session)->ConnectionToken, localAddress);
} }
ILibAsyncServerSocket_ServerModule ILibWebServer_GetServerSocketModule(ILibWebServer_ServerToken server)
{
return(((ILibWebServer_StateModule*)server)->ServerSocket);
}
/*! \fn ILibWebServer_RegisterVirtualDirectory(ILibWebServer_ServerToken WebServerToken, char *vd, int vdLength, ILibWebServer_VirtualDirectory OnVirtualDirectory, void *user) /*! \fn ILibWebServer_RegisterVirtualDirectory(ILibWebServer_ServerToken WebServerToken, char *vd, int vdLength, ILibWebServer_VirtualDirectory OnVirtualDirectory, void *user)
\brief Registers a Virtual Directory with the ILibWebServer \brief Registers a Virtual Directory with the ILibWebServer

View File

@@ -197,6 +197,7 @@ ILibWebServer_ServerToken ILibWebServer_CreateEx(void *Chain, int MaxConnections
ILibExportMethod ILibWebServer_ServerToken ILibWebServer_CreateEx2(void *Chain, int MaxConnections, unsigned short PortNumber, int loopbackFlag, ILibWebServer_Session_OnSession OnSession, int ExtraMemorySize, void *User); ILibExportMethod ILibWebServer_ServerToken ILibWebServer_CreateEx2(void *Chain, int MaxConnections, unsigned short PortNumber, int loopbackFlag, ILibWebServer_Session_OnSession OnSession, int ExtraMemorySize, void *User);
#define ILibWebServer_Create(Chain, MaxConnections, PortNumber, OnSession, User) ILibWebServer_CreateEx(Chain, MaxConnections, PortNumber, INADDR_ANY, OnSession, User) #define ILibWebServer_Create(Chain, MaxConnections, PortNumber, OnSession, User) ILibWebServer_CreateEx(Chain, MaxConnections, PortNumber, INADDR_ANY, OnSession, User)
#define ILibWebServer_Create2(Chain, MaxConnections, PortNumber, OnSession, ExtraMemorySize, User) ILibWebServer_CreateEx2(Chain, MaxConnections, PortNumber, INADDR_ANY, OnSession, ExtraMemorySize, User) #define ILibWebServer_Create2(Chain, MaxConnections, PortNumber, OnSession, ExtraMemorySize, User) ILibWebServer_CreateEx2(Chain, MaxConnections, PortNumber, INADDR_ANY, OnSession, ExtraMemorySize, User)
ILibAsyncServerSocket_ServerModule ILibWebServer_GetServerSocketModule(ILibWebServer_ServerToken server);
void ILibWebServer_StopListener(ILibWebServer_ServerToken server); void ILibWebServer_StopListener(ILibWebServer_ServerToken server);
void ILibWebServer_RestartListener(ILibWebServer_ServerToken server); void ILibWebServer_RestartListener(ILibWebServer_ServerToken server);