1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2026-02-22 04:13:41 +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

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_AddSink(ILibDuktape_EventEmitter *emitter, char *eventName, ILibDuktape_EventEmitter_Handler handler); // Add Native Event Handler
int ILibDuktape_EventEmitter_AddOnce(ILibDuktape_EventEmitter *emitter, char *eventName, void *heapptr); // Add native event handler 'once'
int ILibDuktape_EventEmitter_AddOnceEx(ILibDuktape_EventEmitter *emitter, char *eventName, duk_c_function func, duk_idx_t funcArgs);
int ILibDuktape_EventEmitter_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
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_Process_ExitCode "\xFF_ExitCode"
#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, ...)
{
char dest[4096];
@@ -444,27 +458,15 @@ void ILibDuktape_Process_UncaughtException(duk_context *ctx)
char* Duktape_GetContextGuidHex(duk_context *ctx)
{
char *retVal = NULL;
char *guid;
duk_size_t guidLength;
int i;
duk_push_heap_stash(ctx); // [stash]
if (duk_has_prop_string(ctx, -1, CONTEXT_GUID_BUFFER))
duk_push_heap_stash(ctx); // [stash]
if (duk_has_prop_string(ctx, -1, "\xFF_ScriptContainerSettings_DB"))
{
duk_get_prop_string(ctx, -1, CONTEXT_GUID_BUFFER); // [stash][str]
guid = (char*)Duktape_GetBuffer(ctx, -1, &guidLength);
for (i = (int)guidLength-1; i > 1 && guid[i] == 0; --i)
{
}
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_get_prop_string(ctx, -1, "\xFF_ScriptContainerSettings_DB"); // [stash][db]
if (duk_get_pointer(ctx, -1) != NULL) { retVal = "0"; }
duk_pop(ctx); // [stash]
}
duk_pop(ctx); // ...
duk_pop(ctx); // ...
return retVal;
}
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_Helper_AddHeapFinalizer(duk_context *ctx, ILibDuktape_HelperEvent handler, void *user);
void ILibDuktape_Push_ObjectStash(duk_context *ctx);
#endif

View File

@@ -81,7 +81,17 @@ duk_ret_t ILibDuktape_Polyfills_Buffer_from(duk_context *ctx)
char *buffer;
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_throw(ctx);
@@ -97,14 +107,14 @@ duk_ret_t ILibDuktape_Polyfills_Buffer_from(duk_context *ctx)
duk_push_fixed_buffer(ctx, ILibBase64DecodeLength((int)strlength));
buffer = Duktape_GetBuffer(ctx, -1, NULL);
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)
{
duk_push_fixed_buffer(ctx, strlength / 2);
buffer = Duktape_GetBuffer(ctx, -1, NULL);
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
{
@@ -219,7 +229,25 @@ duk_ret_t ILibDuktape_Polyfills_Console_log(duk_context *ctx)
else
{
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");

View File

@@ -386,10 +386,13 @@ int ILibDuktape_readableStream_WriteDataEx(ILibDuktape_readableStream *stream, i
else
{
// 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_buffer = buffer;
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);
}
}

View File

@@ -57,7 +57,11 @@ limitations under the License.
#include "ILibDuktape_SHA256.h"
#include "ILibDuktape_EncryptionStream.h"
#include "ILibDuktape_ChildProcess.h"
#ifdef _POSIX
extern char **environ;
#endif
#define SCRIPT_ENGINE_PIPE_BUFFER_SIZE 65535
#define ILibDuktape_ScriptContainer_MasterPtr "\xFF_ScriptContainer_MasterPtr"
#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);
}
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:
void ILibDuktape_ScriptContainer_Process_ExitCallback(void *obj)
{
@@ -247,6 +303,49 @@ duk_ret_t ILibDuktape_ScriptContainer_Process_Argv(duk_context *ctx)
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)
{
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_object(ctx); // [g][process]
ILibDuktape_CreateEventWithGetter(ctx, "env", ILibDuktape_ScriptContainer_Process_env);
#if defined(WIN32) // [g][process][platform]
duk_push_string(ctx, "win32");
#elif defined(__APPLE__)
@@ -263,6 +364,19 @@ void ILibDuktape_ScriptContainer_Process_Init(duk_context *ctx, char **argList)
#endif
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)
{
duk_push_array(ctx); // [g][process][array]
@@ -691,7 +805,7 @@ duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx(SCRIPT_ENG
ILibDuktape_DGram_Init(ctx); // Datagram Sockets
}
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); }

View File

@@ -140,6 +140,7 @@ typedef struct 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);
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_EventEmitter.h"
#include "microstack/ILibCrypto.h"
#include "microstack/ILibRemoteLogging.h"
#define HTTP_SERVER_PTR "\xFF_ServerPtr"
#define HTTP_WEBCLIENT_MGR "_RequestManagerPtr"
@@ -52,13 +53,20 @@ limitations under the License.
#define HTTP_STREAM_WRAPPER_BUFSIZE 4096
#define HTTP_CLIENTREQUEST_PARAMETER "\xFF_http_clientRequest_parameter"
#define CLIENTREQUEST_HTTP "\xFF_clientRequest_HTTP"
#define CLIENTREQUEST_SOCKET_WCDO "\xFF_clientRequest_SOCKET_WCDO"
#define HTTP_INCOMINGMSG_WebStateObject "\xFF_incomingMessage_WebStateObject"
#define DIGEST_USERNAME "\xFF_DigestUsername"
#define DIGEST_PASSWORD "\xFF_DigestPassword"
#define DIGEST_WCDO "\xFF_DIGEST_WCDO"
#define HTTP_DIGEST "\xFF_HTTP_DIGEST"
#define DIGEST_CLIENT_REQUEST "\xFF_DIGEST_CLIENT_REQUEST"
#define HTTP_CLIENTREQUEST_DATAPTR "\xFF_CLIENTREQUEST_DATAPTR"
#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);
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 *OnReceive;
void *OnContinue;
void *OnSocket;
#ifndef MICROSTACK_NOTLS
int rejectUnauthorized;
void *checkServerIdentity;
@@ -954,6 +963,33 @@ duk_ret_t ILibDuktape_http_server_tlsSettings_Finalizer(duk_context *ctx)
{
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)
{
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_put_prop_string(ctx, -2, "listen"); // [http][server]
ILibDuktape_CreateInstanceMethod(ctx, "_address", ILibDuktape_http_server_address, 0);
return 1;
}
@@ -1096,15 +1133,13 @@ void ILibDuktape_http_request_OnResponse(ILibWebClient_StateObject WebStateObjec
{
if (ctx != NULL)
{
duk_push_heapptr(ctx, ptrs->OnReceive); // [func]
duk_push_heapptr(ctx, ptrs->clientRequest); // [func][this]
duk_del_prop_string(ctx, -1, HTTP_REQUEST_TOKEN_PTR); // (Prevents crash in Request Finalizer)
duk_push_null(ctx); // [func][this][null]
if (duk_pcall_method(ctx, 1) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(ctx);
}
duk_pop(ctx); // ...
duk_push_heapptr(ctx, ptrs->clientRequest); // [clientRequest]
duk_get_prop_string(ctx, -1, "emit"); // [clientRequest][emit]
duk_swap_top(ctx, -2); // [emit][this]
duk_push_string(ctx, "error"); // [emit][this][error]
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(): "); }
duk_pop(ctx); // ...
}
return;
}
@@ -1147,6 +1182,7 @@ void ILibDuktape_http_request_OnResponse(ILibWebClient_StateObject WebStateObjec
{
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_USER_PTR);
ILibDuktape_EventEmitter_RemoveAll(ILibDuktape_EventEmitter_GetEmitter(ctx, -1));
duk_pop(ctx); // ...
}
@@ -1479,8 +1515,27 @@ void ILibDuktape_http_webSocket_onSendOk(ILibWebClient_StateObject sender, void
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)
{
union { int i; void*p; }u;
ILibHTTPPacket *packet;
char *host;
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);
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
{
@@ -1589,7 +1648,6 @@ duk_ret_t ILibDuktape_http_request(duk_context *ctx)
if (isWebSocket != 0)
{
union { int i; void*p; }u;
int len;
char value[32];
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);
}
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"))
{
duk_get_prop_string(ctx, 0, "headers");
@@ -1750,10 +1815,66 @@ duk_ret_t ILibDuktape_http_request_no_op(duk_context *ctx)
{
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)
{
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 &&
((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]);
}
if (isWebSocket == 0)
{
ILibWebClient_RequestToken_ConnectionHandler_Set(token, ILibDuktape_http_request_connect, ILibDuktape_http_request_disconnect);
}
duk_push_object(ctx); // [obj]
duk_push_pointer(ctx, user);
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, "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])->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]
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);
}
@@ -2469,15 +2606,81 @@ duk_ret_t ILibDuktape_httpDigest_clientRequest_propagateEvent(duk_context *ctx)
}
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)
{
ILibHTTPPacket *packet;
ILibWebClient_StateObject wcdo;
char *username, *password;
int tmpLen = 0;
char *uri = NULL;
void *digestClientPtr;
void *paramPtr = NULL;
void *cr_self;
duk_push_current_function(ctx);
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)
{
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, "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);
wcdo = (ILibWebClient_StateObject)duk_get_pointer(ctx, -1);
int freePath = 0;
char *method, *path;
char result1[33];
char result2[33];
char result3[33];
void* table = ILibWebClient_Digest_GenerateTable(wcdo);
char* realm = (char*)ILibGetEntry(table, "realm", 5);
char* nonce = (char*)ILibGetEntry(table, "nonce", 5);
char* opaque = (char*)ILibGetEntry(table, "opaque", 6);
ILibDestroyHashTree(table);
duk_size_t methodLen, pathLen;
int authLen;
char *method, *path, *auth;
void *ReservedMemory = ILibMemory_AllocateA(8000);
ILibHTTPPacket *pk = ILibCreateEmptyPacketEx(ReservedMemory);
pk->Version = "1.1";
pk->VersionLength = 3;
duk_push_this(ctx); // [clientRequest]
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;
uri = (char*)duk_get_string(ctx, -1);
ILibParseUri(uri, &tmpHost, &tmpPort, &path, NULL);
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s:%s", (method = "GET"), path);
util_md5hex(ILibScratchPad2, tmpLen, result2);
ILibSetDirective(pk, "GET", 3, path, -1);
free(tmpHost);
freePath = 1;
free(path);
}
else
{
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s:%s", (method = Duktape_GetStringPropertyValue(ctx, -1, "method", "GET")), (path = Duktape_GetStringPropertyValue(ctx, -1, "path", "/")));
util_md5hex(ILibScratchPad2, tmpLen, result2);
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);
paramPtr = duk_get_heapptr(ctx, -1);
}
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s:%s:%s", username, realm, password);
util_md5hex(ILibScratchPad2, tmpLen, result1);
ILibWebClient_GenerateAuthenticationHeader(wcdo, pk, username, password);
auth = ILibGetHeaderLineEx(pk, "Authorization", 13, &authLen);
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s:%s:%s", result1, nonce, result2);
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, path, opaque, result3);
duk_push_this(ctx); // [clientReqeust]
duk_get_prop_string(ctx, -1, CLIENTREQUEST_HTTP); // [clientReqeust][http]
duk_push_this(ctx); // [clientReqeust]
duk_get_prop_string(ctx, -1, CLIENTREQUEST_HTTP); // [clientReqeust][http]
if (freePath != 0) { free(path); }
if (paramPtr == NULL)
{
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_swap_top(ctx, -2); // [clientRequest][request][this]
duk_push_heapptr(ctx, paramPtr); // [clientRequest][request][this][options]
duk_del_prop_string(ctx, -1, "timeout");
}
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_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, "headers"); // [clientReqeust][get][this][options]
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_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"); }
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_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));
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_heapptr(ctx, digestClientPtr); // [clientReqeust][onDrain][digestClientRequest]
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));
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_swap_top(ctx, -2); // [digestClientRequest][clientRequest]
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);
}
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;
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))
{
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_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))
{
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_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)
{
int nargs = duk_get_top(ctx);
void *clientRequest = NULL;
ILibDuktape_EventEmitter *emitter;
ILibDuktape_EventEmitter *crEmitter;
char *username = NULL;
char *password = NULL;
duk_push_current_function(ctx); // [func]
duk_get_prop_string(ctx, -1, "isGet"); // [func][isGet]
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]
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_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); }
// [clientRequest]
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_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_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]
@@ -2764,7 +3119,11 @@ duk_ret_t ILibDuktape_httpDigest_http_request(duk_context *ctx)
ILibDuktape_EventEmitter_CreateEventEx(emitter, "error");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "upgrade");
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);
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]
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_dup(ctx, -2); // [digestClientRequest][onDrain][digestClientRequest]
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/ILibCrypto.h"
#include "microstack/ILibAsyncServerSocket.h"
#include "microstack/ILibRemoteLogging.h"
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_put_prop_string(ctx, -2, "address");
return 1;
}
@@ -918,6 +920,29 @@ duk_ret_t ILibDuktape_net_server_Finalizer(duk_context *ctx)
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)
{
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_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);
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;
}
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 retVal = 1;