1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-20 02:03:15 +00:00

MeshAgent for MeshCentral2 Beta2 with improved crypto.

This commit is contained in:
Ylian Saint-Hilaire
2017-10-25 21:08:41 -07:00
parent 0a7e84849d
commit 34e09c2304
53 changed files with 1778 additions and 551 deletions

View File

@@ -42,6 +42,7 @@ typedef void(*ILibDuktape_DuplexStream_PauseResumeHandler)(ILibDuktape_DuplexStr
#define ILibDuktape_DuplexStream_Ready(duplexStream) ILibDuktape_WritableStream_Ready((duplexStream)->writableStream)
#define ILibDuktape_DuplexStream_WriteData(duplexStream, buffer, bufferLen) ILibDuktape_readableStream_WriteData((duplexStream)->readableStream, buffer, bufferLen)
#define ILibDuktape_DuplexStream_WriteDataEx(duplexStream, streamReserved, buffer, bufferLen) ILibDuktape_readableStream_WriteDataEx((duplexStream)->readableStream, streamReserved, buffer, bufferLen)
#define ILibDuktape_DuplexStream_WriteEnd(duplexStream) ILibDuktape_readableStream_WriteEnd((duplexStream)->readableStream)
#define ILibDuktape_DuplexStream_Closed(duplexStream) ILibDuktape_readableStream_Closed((duplexStream)->readableStream)

View File

@@ -19,6 +19,7 @@ ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx);
ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_GetEmitter(duk_context *ctx, duk_idx_t i);
ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_GetEmitter_fromThis(duk_context *ctx);
#define ILibDuktape_EventEmitter_GetEmitter_fromCurrent(ctx) ILibDuktape_EventEmitter_GetEmitter(ctx, -1)
ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_GetEmitter_fromObject(duk_context *ctx, void *objHeapptr);
void ILibDuktape_EventEmitter_Init(duk_context *ctx);
void ILibDuktape_EventEmitter_RemoveAll(ILibDuktape_EventEmitter *emitter); // Removes all event handlers/dispatchers

View File

@@ -397,6 +397,8 @@ void ILibDuktape_Process_UncaughtExceptionEx(duk_context *ctx, char *format, ...
void *j = ILibDuktape_GetProcessObject(ctx);
ILibDuktape_EventEmitter *emitter;
if (strcmp(errmsg, "Process.exit() forced script termination") == 0) { return; }
duk_push_heapptr(ctx, j); // [process]
emitter = ILibDuktape_EventEmitter_GetEmitter_fromCurrent(ctx);
duk_pop(ctx); // ...

View File

@@ -40,7 +40,7 @@ ILibHashtable ILibDuktape_NetworkMonitor_CreateTable(duk_context *ctx)
while (duk_next(ctx, -1, 1))
{
// [networkInterfaces][enum][adapter][array]
int count = duk_get_length(ctx, -1);
int count = (int)duk_get_length(ctx, -1);
for (i = 0; i < count; ++i)
{
duk_get_prop_index(ctx, -1, i); // [networkInterfaces][enum][adapter][array][obj]
@@ -48,7 +48,7 @@ ILibHashtable ILibDuktape_NetworkMonitor_CreateTable(duk_context *ctx)
{
duk_get_prop_string(ctx, -1, "address");// [networkInterfaces][enum][adapter][array][obj][address]
buffer = (char*)duk_get_lstring(ctx, -1, &bufferLen);
ILibHashtable_Put(retVal, NULL, buffer, bufferLen, (void*)0x01);
ILibHashtable_Put(retVal, NULL, buffer, (int)bufferLen, (void*)0x01);
duk_pop(ctx); // [networkInterfaces][enum][adapter][array][obj]
}
duk_pop(ctx); // [networkInterfaces][enum][adapter][array]

View File

@@ -114,6 +114,18 @@ duk_ret_t ILibDuktape_Polyfills_Buffer_from(duk_context *ctx)
}
return 1;
}
duk_ret_t ILibDuktape_Polyfills_Buffer_readInt32BE(duk_context *ctx)
{
int offset = duk_require_int(ctx, 0);
char *buffer;
duk_size_t bufferLen;
duk_push_this(ctx);
buffer = Duktape_GetBuffer(ctx, -1, &bufferLen);
duk_push_int(ctx, ntohl(((int*)(buffer + offset))[0]));
return(1);
}
void ILibDuktape_Polyfills_Buffer(duk_context *ctx)
{
// Polyfill 'Buffer.slice'
@@ -122,6 +134,8 @@ void ILibDuktape_Polyfills_Buffer(duk_context *ctx)
duk_get_prop_string(ctx, -1, "prototype"); // [g][Duktape][Buffer][prototype]
duk_push_c_function(ctx, ILibDuktape_Pollyfills_Buffer_slice, DUK_VARARGS); // [g][Duktape][Buffer][prototype][func]
duk_put_prop_string(ctx, -2, "slice"); // [g][Duktape][Buffer][prototype]
duk_push_c_function(ctx, ILibDuktape_Polyfills_Buffer_readInt32BE, DUK_VARARGS);
duk_put_prop_string(ctx, -2, "readInt32BE");
duk_pop_3(ctx); // [g]
// Polyfill 'Buffer.toString()
@@ -159,7 +173,27 @@ duk_ret_t ILibDuktape_Polyfills_String_startsWith(duk_context *ctx)
return 1;
}
duk_ret_t ILibDuktape_Polyfills_String_endsWith(duk_context *ctx)
{
duk_size_t tokenLen;
char *token = Duktape_GetBuffer(ctx, 0, &tokenLen);
char *buffer;
duk_size_t bufferLen;
duk_push_this(ctx);
buffer = Duktape_GetBuffer(ctx, -1, &bufferLen);
if (ILibString_EndsWith(buffer, (int)bufferLen, token, (int)tokenLen) != 0)
{
duk_push_true(ctx);
}
else
{
duk_push_false(ctx);
}
return 1;
}
void ILibDuktape_Polyfills_String(duk_context *ctx)
{
// Polyfill 'String.startsWith'
@@ -167,6 +201,8 @@ void ILibDuktape_Polyfills_String(duk_context *ctx)
duk_get_prop_string(ctx, -1, "prototype"); // [string][proto]
duk_push_c_function(ctx, ILibDuktape_Polyfills_String_startsWith, DUK_VARARGS); // [string][proto][func]
duk_put_prop_string(ctx, -2, "startsWith"); // [string][proto]
duk_push_c_function(ctx, ILibDuktape_Polyfills_String_endsWith, DUK_VARARGS); // [string][proto][func]
duk_put_prop_string(ctx, -2, "endsWith"); // [string][proto]
duk_pop_2(ctx);
}
duk_ret_t ILibDuktape_Polyfills_Console_log(duk_context *ctx)
@@ -189,6 +225,32 @@ duk_ret_t ILibDuktape_Polyfills_Console_log(duk_context *ctx)
printf("\n");
return 0;
}
duk_ret_t ILibDuktape_Polyfills_Console_enableWebLog(duk_context *ctx)
{
#ifdef _REMOTELOGGING
void *chain = Duktape_GetChain(ctx);
int port = duk_require_int(ctx, 0);
duk_size_t pLen;
if (duk_peval_string(ctx, "process.argv0") != 0) { return(ILibDuktape_Error(ctx, "console.enableWebLog(): Couldn't fetch argv0")); }
char *p = (char*)duk_get_lstring(ctx, -1, &pLen);
if (ILibString_EndsWith(p, (int)pLen, ".js", 3) != 0)
{
memcpy_s(ILibScratchPad2, sizeof(ILibScratchPad2), p, pLen - 3);
sprintf_s(ILibScratchPad2 + (pLen - 3), sizeof(ILibScratchPad2) - 3, ".wlg");
}
else if (ILibString_EndsWith(p, (int)pLen, ".exe", 3) != 0)
{
memcpy_s(ILibScratchPad2, sizeof(ILibScratchPad2), p, pLen - 4);
sprintf_s(ILibScratchPad2 + (pLen - 3), sizeof(ILibScratchPad2) - 4, ".wlg");
}
else
{
sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s.wlg", p);
}
ILibStartDefaultLoggerEx(chain, (unsigned short)port, ILibScratchPad2);
#endif
return (0);
}
void ILibDuktape_Polyfills_Console(duk_context *ctx)
{
// Polyfill console.log()
@@ -204,6 +266,9 @@ void ILibDuktape_Polyfills_Console(duk_context *ctx)
}
duk_push_c_function(ctx, ILibDuktape_Polyfills_Console_log, DUK_VARARGS); // [g][console][log]
duk_put_prop_string(ctx, -2, "log"); // [g][console]
ILibDuktape_CreateInstanceMethod(ctx, "enableWebLog", ILibDuktape_Polyfills_Console_enableWebLog, 1);
duk_pop(ctx); // [g]
}
duk_ret_t ILibDuktape_ntohl(duk_context *ctx)
@@ -391,7 +456,7 @@ duk_ret_t ILibDuktape_Polyfills_addModule(duk_context *ctx)
char *module = (char*)Duktape_GetBuffer(ctx, 1, &moduleLen);
char *moduleName = (char*)duk_require_string(ctx, 0);
if (ILibDuktape_ModSearch_AddModule(ctx, moduleName, module, moduleLen) != 0)
if (ILibDuktape_ModSearch_AddModule(ctx, moduleName, module, (int)moduleLen) != 0)
{
return(ILibDuktape_Error(ctx, "Cannot add module: %s", moduleName));
}

View File

@@ -54,15 +54,17 @@ public:
\brief The ReadableStream.pipe() method attaches a WritableStream to the readable, causing it to switch automatically into flowing mode and push all of its data to the attached WritableStream.
*
* Flow control of data will be automatically managed so that the destination WritableStream is not overwhelmed by a faster ReadableStream.
\param destination[in] The WritableStream to attach to the ReadableStream.
\param destination \<WritableStream\> The WritableStream to attach to the ReadableStream.
\param options <Object> Optional parameters:\n
<b>dataTypeSkip</b> If set to 1, String values will only emit 'data' events instead of being piped to the WritableStream
*/
void pipe(WritableStream destination);
void pipe(destination[, options]);
/*!
\brief The ReadableStream.unpipe() method detaches a WritableStream previously attached using the ReadableStream.pipe() method.
*
\param destination[in] If specified, the WritableStream to detach. If not specified, all streams will be dettached.
\param destination \<WritableStream\> If specified, the WritableStream to detach. If not specified, all streams will be dettached.
*/
void unpipe(WritableStream destination);
void unpipe(destination);
/*!
@@ -98,12 +100,14 @@ typedef struct ILibDuktape_readableStream_bufferedData
{
struct ILibDuktape_readableStream_bufferedData *Next;
int bufferLen;
int Reserved;
char buffer[];
}ILibDuktape_readableStream_bufferedData;
void ILibDuktape_readableStream_WriteData_buffer(ILibDuktape_readableStream *stream, char *buffer, int bufferLen)
void ILibDuktape_readableStream_WriteData_buffer(ILibDuktape_readableStream *stream, int streamReserved, char *buffer, int bufferLen)
{
ILibDuktape_readableStream_bufferedData *buffered = (ILibDuktape_readableStream_bufferedData*)ILibMemory_Allocate(bufferLen + sizeof(ILibDuktape_readableStream_bufferedData), 0, NULL, NULL);
buffered->Reserved = streamReserved;
buffered->bufferLen = bufferLen;
memcpy_s(buffered->buffer, bufferLen, buffer, bufferLen);
@@ -134,8 +138,15 @@ void ILibDuktape_readableStream_WriteData_OnData_ChainThread(void *chain, void *
stream->paused = 0;
duk_push_heapptr(stream->ctx, stream->OnData); // [func]
duk_push_heapptr(stream->ctx, stream->object); // [func][this]
duk_push_heapptr(stream->ctx, stream->extBuffer); // [func][this][buffer]
duk_config_buffer(stream->ctx, -1, stream->extBuffer_buffer, stream->extBuffer_bufferLen);
if (stream->extBuffer_Reserved == 0)
{
duk_push_heapptr(stream->ctx, stream->extBuffer); // [func][this][buffer]
duk_config_buffer(stream->ctx, -1, stream->extBuffer_buffer, stream->extBuffer_bufferLen);
}
else
{
duk_push_lstring(stream->ctx, stream->extBuffer_buffer, stream->extBuffer_bufferLen);
}
if (duk_pcall_method(stream->ctx, 1) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(stream->ctx);
@@ -256,7 +267,7 @@ void ILibDuktape_readableStream_WriteData_ChainThread(void *chain, void *user)
}
}
int ILibDuktape_readableStream_WriteData(ILibDuktape_readableStream *stream, char* buffer, int bufferLen)
int ILibDuktape_readableStream_WriteDataEx(ILibDuktape_readableStream *stream, int streamReserved, char* buffer, int bufferLen)
{
ILibDuktape_readableStream_nextWriteablePipe *w;
int nonNativeCount = 0;
@@ -264,42 +275,46 @@ int ILibDuktape_readableStream_WriteData(ILibDuktape_readableStream *stream, cha
if (stream->paused != 0)
{
ILibDuktape_readableStream_WriteData_buffer(stream, buffer, bufferLen);
ILibDuktape_readableStream_WriteData_buffer(stream, streamReserved, buffer, bufferLen);
return(stream->paused);
}
sem_wait(&(stream->pipeLock));
w = stream->nextWriteable;
while (w != NULL)
if (stream->bypassValue == 0 || stream->bypassValue != streamReserved)
{
if (w->nativeWritable == 0) { ++nonNativeCount; }
else { ++nativeCount; }
w = w->next;
}
w = stream->nextWriteable;
if (w != NULL)
{
if (nonNativeCount > 0)
sem_wait(&(stream->pipeLock));
w = stream->nextWriteable;
while (w != NULL)
{
// There are piped Pure JavaScript objects... We must context switch to Microstack Thread
stream->extBuffer_buffer = buffer;
stream->extBuffer_bufferLen = bufferLen;
sem_post(&(stream->pipeLock));
if (stream->PauseHandler != NULL) { stream->paused = 1; stream->PauseHandler(stream, stream->user); }
ILibChain_RunOnMicrostackThread(stream->chain, ILibDuktape_readableStream_WriteData_ChainThread, stream);
return(stream->paused);
if (w->nativeWritable == 0) { ++nonNativeCount; }
else { ++nativeCount; }
w = w->next;
}
else
w = stream->nextWriteable;
if (w != NULL)
{
// All piped objects are native, so we can blast out a send
stream->pipe_pendingCount = nativeCount;
while (w != NULL)
if (nonNativeCount > 0)
{
if (w->nativeWritable != NULL)
// There are piped Pure JavaScript objects... We must context switch to Microstack Thread
stream->extBuffer_Reserved = streamReserved;
stream->extBuffer_buffer = buffer;
stream->extBuffer_bufferLen = bufferLen;
sem_post(&(stream->pipeLock));
if (stream->PauseHandler != NULL) { stream->paused = 1; stream->PauseHandler(stream, stream->user); }
ILibChain_RunOnMicrostackThread(stream->chain, ILibDuktape_readableStream_WriteData_ChainThread, stream);
return(stream->paused);
}
else
{
// All piped objects are native, so we can blast out a send
stream->pipe_pendingCount = nativeCount;
while (w != NULL)
{
ILibDuktape_WritableStream *ws = (ILibDuktape_WritableStream*)w->nativeWritable;
switch (ws->WriteSink(ws, buffer, bufferLen, ws->WriteSink_User))
if (w->nativeWritable != NULL)
{
ILibDuktape_WritableStream *ws = (ILibDuktape_WritableStream*)w->nativeWritable;
ws->Reserved = streamReserved;
switch (ws->WriteSink(ws, buffer, bufferLen, ws->WriteSink_User))
{
case ILibTransport_DoneState_INCOMPLETE:
ws->OnWriteFlushEx = ILibDuktape_readableStream_WriteData_Flush;
ws->OnWriteFlushEx_User = stream;
@@ -324,28 +339,28 @@ int ILibDuktape_readableStream_WriteData(ILibDuktape_readableStream *stream, cha
--stream->pipe_pendingCount;
#endif
break;
}
}
w = w->next;
}
if (stream->pipe_pendingCount == 0)
{
sem_post(&(stream->pipeLock));
return(stream->paused);
}
else
{
sem_post(&(stream->pipeLock));
if (stream->PauseHandler != NULL) { stream->paused = 1; stream->PauseHandler(stream, stream->user); }
return(stream->paused);
}
w = w->next;
}
if (stream->pipe_pendingCount == 0)
{
sem_post(&(stream->pipeLock));
return(stream->paused);
}
else
{
sem_post(&(stream->pipeLock));
if (stream->PauseHandler != NULL) { stream->paused = 1; stream->PauseHandler(stream, stream->user); }
return(stream->paused);
}
}
else
{
sem_post(&(stream->pipeLock));
}
}
else
{
sem_post(&(stream->pipeLock));
}
if (stream->OnData != NULL)
{
@@ -353,8 +368,15 @@ int ILibDuktape_readableStream_WriteData(ILibDuktape_readableStream *stream, cha
{
duk_push_heapptr(stream->ctx, stream->OnData); // [func]
duk_push_heapptr(stream->ctx, stream->object); // [func][this]
duk_push_heapptr(stream->ctx, stream->extBuffer); // [func][this][buffer]
duk_config_buffer(stream->ctx, -1, buffer, bufferLen);
if (streamReserved == 0)
{
duk_push_heapptr(stream->ctx, stream->extBuffer); // [func][this][buffer]
duk_config_buffer(stream->ctx, -1, buffer, bufferLen);
}
else
{
duk_push_lstring(stream->ctx, buffer, bufferLen); // [func][this][string]
}
if (duk_pcall_method(stream->ctx, 1) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(stream->ctx);
@@ -365,6 +387,7 @@ int ILibDuktape_readableStream_WriteData(ILibDuktape_readableStream *stream, cha
{
// 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); }
stream->extBuffer_Reserved = streamReserved;
stream->extBuffer_buffer = buffer;
stream->extBuffer_bufferLen = bufferLen;
ILibChain_RunOnMicrostackThread(stream->chain, ILibDuktape_readableStream_WriteData_OnData_ChainThread, stream);
@@ -375,7 +398,7 @@ int ILibDuktape_readableStream_WriteData(ILibDuktape_readableStream *stream, cha
// If we get here, it means we are writing data, but nobody is going to be receiving it...
// So we need to buffer the data, so when we are resumed later, we can retry
ILibDuktape_readableStream_WriteData_buffer(stream, buffer, bufferLen);
ILibDuktape_readableStream_WriteData_buffer(stream, streamReserved, buffer, bufferLen);
}
else if (stream->OnEnd != NULL)
{
@@ -477,8 +500,7 @@ int ILibDuktape_readableStream_resume_flush(ILibDuktape_readableStream *rs)
while ((buffered = rs->paused_data))
{
rs->paused_data = buffered->Next;
if (ILibDuktape_readableStream_WriteData(rs, buffered->buffer, buffered->bufferLen) != 0)
if (ILibDuktape_readableStream_WriteDataEx(rs, buffered->Reserved, buffered->buffer, buffered->bufferLen) != 0)
{
// Send did not complete, so lets exit out, and we'll continue next time.
free(buffered);
@@ -515,12 +537,18 @@ duk_ret_t ILibDuktape_readableStream_pipe(duk_context *ctx)
{
ILibDuktape_readableStream *rstream;
ILibDuktape_readableStream_nextWriteablePipe *w;
int nargs = duk_get_top(ctx);
duk_push_this(ctx); // [readable]
duk_get_prop_string(ctx, -1, ILibDuktape_readableStream_RSPTRS); // [readable][ptrs]
rstream = (ILibDuktape_readableStream*)Duktape_GetBuffer(ctx, -1, NULL);
duk_pop(ctx); // [readable]
if (nargs > 1 && duk_is_object(ctx, 1))
{
rstream->bypassValue = Duktape_GetIntPropertyValue(ctx, 1, "dataTypeSkip", 0);
}
duk_push_object(ctx); // [readable][nextWriteable]
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_readableStream_nextWriteablePipe)); // [readable][nextWriteable][ptrBuffer]
w = (ILibDuktape_readableStream_nextWriteablePipe*)Duktape_GetBuffer(ctx, -1, NULL);

View File

@@ -42,7 +42,7 @@ typedef struct ILibDuktape_readableStream
void *OnEnd;
void *extBuffer;
char *extBuffer_buffer;
int extBuffer_bufferLen;
int extBuffer_bufferLen, extBuffer_Reserved;
void *user;
ILibDuktape_readableStream_nextWriteablePipe *nextWriteable;
@@ -54,7 +54,7 @@ typedef struct ILibDuktape_readableStream
#else
int pipe_pendingCount; // No Atomic Built-ins... Use a Mutex
#endif
int bypassValue;
int paused;
void *paused_data;
ILibDuktape_readableStream_PauseResumeHandler PauseHandler;
@@ -65,8 +65,10 @@ typedef struct ILibDuktape_readableStream
ILibDuktape_readableStream* ILibDuktape_InitReadableStream(duk_context *ctx, ILibDuktape_readableStream_PauseResumeHandler OnPause, ILibDuktape_readableStream_PauseResumeHandler OnResume, void *user);
#define ILibDuktape_ReadableStream_Init(ctx, OnPause, OnResume, user) ILibDuktape_InitReadableStream(ctx, OnPause, OnResume, user)
#define ILibDuktape_readableStream_SetPauseResumeHandlers(stream, PauseFunc, ResumeFunc, userObj) ((ILibDuktape_readableStream*)stream)->PauseHandler = PauseFunc; ((ILibDuktape_readableStream*)stream)->ResumeHandler = ResumeFunc; ((ILibDuktape_readableStream*)stream)->user = userObj;
int ILibDuktape_readableStream_WriteData(ILibDuktape_readableStream *stream, char* buffer, int bufferLen);
int ILibDuktape_readableStream_WriteDataEx(ILibDuktape_readableStream *stream, int streamReserved, char* buffer, int bufferLen);
int ILibDuktape_readableStream_WriteEnd(ILibDuktape_readableStream *stream);
#define ILibDuktape_readableStream_WriteData(stream, buffer, bufferLen) ILibDuktape_readableStream_WriteDataEx(stream, 0, buffer, bufferLen)
void ILibDuktape_readableStream_Closed(ILibDuktape_readableStream *stream);
#endif

View File

@@ -8,6 +8,7 @@
#define ILibDuktape_MD5_PTR "\xFF_MD5PTR"
#define ILibDuktape_SHA256_PTR "\xFF_SHA256PTR"
#define ILibDuktape_SHA512_PTR "\xFF_SHA512PTR"
#define ILibDuktape_SHA256_SIGNER_PTR "\xFF_SHA256_SIGNER_PTR"
#define ILibDuktape_SHA256_SIGNER_CERT "\xFF_SHA256_SIGNER_CERT"
#define ILibDuktape_SHA256_SIGNER_CERT_ALLOC "\xFF_SHA256_SIGNER_CERT_ALLOC"
@@ -25,6 +26,16 @@ typedef struct ILibDuktape_SHA256_Data
char buffer[33];
SHA256_CTX shctx;
}ILibDuktape_SHA256_Data;
typedef struct ILibDuktape_SHA512_Data
{
duk_context *ctx;
void *object;
void *OnHash;
void *OnHashString;
char buffer[65];
SHA512_CTX shctx;
}ILibDuktape_SHA512_Data;
typedef struct ILibDuktape_MD5_Data
{
duk_context *ctx;
@@ -51,6 +62,10 @@ duk_ret_t ILibDuktape_SHA256_Finalizer(duk_context *ctx)
{
return 0;
}
duk_ret_t ILibDuktape_SHA384_Finalizer(duk_context *ctx)
{
return 0;
}
ILibTransport_DoneState ILibDuktape_SHA256_Write(struct ILibDuktape_WritableStream *stream, char *buffer, int bufferLen, void *user)
{
ILibDuktape_SHA256_Data *data = (ILibDuktape_SHA256_Data*)user;
@@ -58,6 +73,13 @@ ILibTransport_DoneState ILibDuktape_SHA256_Write(struct ILibDuktape_WritableStre
SHA256_Update(&(data->shctx), buffer, bufferLen);
return(ILibTransport_DoneState_COMPLETE);
}
ILibTransport_DoneState ILibDuktape_SHA384_Write(struct ILibDuktape_WritableStream *stream, char *buffer, int bufferLen, void *user)
{
ILibDuktape_SHA512_Data *data = (ILibDuktape_SHA512_Data*)user;
SHA384_Update(&(data->shctx), buffer, bufferLen);
return(ILibTransport_DoneState_COMPLETE);
}
void ILibDuktape_SHA256_End(struct ILibDuktape_WritableStream *stream, void *user)
{
@@ -89,6 +111,36 @@ void ILibDuktape_SHA256_End(struct ILibDuktape_WritableStream *stream, void *use
duk_pop(data->ctx); // ...
}
}
void ILibDuktape_SHA384_End(struct ILibDuktape_WritableStream *stream, void *user)
{
ILibDuktape_SHA512_Data *data = (ILibDuktape_SHA512_Data*)user;
data->buffer[48] = 0;
SHA384_Final((unsigned char*)data->buffer, &(data->shctx));
if (data->ctx != NULL && data->OnHash != NULL)
{
duk_push_heapptr(data->ctx, data->OnHash); // [func]
duk_push_heapptr(data->ctx, data->object); // [func][this]
duk_push_external_buffer(data->ctx); // [func][this][hash]
duk_config_buffer(data->ctx, -1, data->buffer, 48);
if (duk_pcall_method(data->ctx, 1) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(data->ctx);
}
duk_pop(data->ctx); // ...
}
if (data->ctx != NULL && data->OnHashString != NULL)
{
duk_push_heapptr(data->ctx, data->OnHashString); // [func]
duk_push_heapptr(data->ctx, data->object); // [func][this]
duk_push_string(data->ctx, util_tohex(data->buffer, 48, ILibScratchPad)); // [func][this][hashString]
if (duk_pcall_method(data->ctx, 1) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(data->ctx);
}
duk_pop(data->ctx); // ...
}
}
duk_ret_t ILibDuktape_SHA256_SIGNER_Finalizer(duk_context *ctx)
{
ILibDuktape_SHA256_Signer_Data *data;
@@ -268,7 +320,35 @@ duk_ret_t ILibDuktape_SHA256_syncHash(duk_context *ctx)
}
return(1);
}
duk_ret_t ILibDuktape_SHA384_syncHash(duk_context *ctx)
{
ILibDuktape_SHA512_Data *data;
duk_size_t bufferLen;
char *buffer = Duktape_GetBuffer(ctx, 0, &bufferLen);
duk_push_this(ctx); // [sha]
duk_get_prop_string(ctx, -1, ILibDuktape_SHA512_PTR);
data = (ILibDuktape_SHA512_Data*)Duktape_GetBuffer(ctx, -1, NULL);
SHA384_Init(&(data->shctx));
SHA384_Update(&(data->shctx), buffer, bufferLen);
SHA384_Final((unsigned char*)data->buffer, &(data->shctx));
data->buffer[48] = 0;
duk_push_current_function(ctx);
duk_get_prop_string(ctx, -1, "strRet");
if (duk_get_boolean(ctx, -1) == 0)
{
duk_push_external_buffer(ctx);
duk_config_buffer(ctx, -1, data->buffer, 48);
}
else
{
util_tohex(data->buffer, 48, ILibScratchPad);
duk_push_string(ctx, ILibScratchPad);
}
return(1);
}
ILibTransport_DoneState ILibDuktape_MD5_Write(struct ILibDuktape_WritableStream *stream, char *buffer, int bufferLen, void *user)
{
@@ -388,11 +468,43 @@ duk_ret_t ILibDuktape_SHA256_Create(duk_context *ctx)
return(1);
}
duk_ret_t ILibDuktape_SHA384_Create(duk_context *ctx)
{
ILibDuktape_SHA512_Data *data;
ILibDuktape_EventEmitter *emitter;
duk_push_object(ctx); // [sha]
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_SHA512_Data)); // [sha][buffer]
data = (ILibDuktape_SHA512_Data*)Duktape_GetBuffer(ctx, -1, NULL);
duk_put_prop_string(ctx, -2, ILibDuktape_SHA512_PTR); // [sha]
emitter = ILibDuktape_EventEmitter_Create(ctx);
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_SHA384_Finalizer);
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 0, "syncHash", ILibDuktape_SHA384_syncHash, 1);
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 1, "syncHashString", ILibDuktape_SHA384_syncHash, 1);
ILibDuktape_EventEmitter_CreateEvent(emitter, "hash", &(data->OnHash));
ILibDuktape_EventEmitter_CreateEvent(emitter, "hashString", &(data->OnHashString));
data->ctx = ctx;
data->object = duk_get_heapptr(ctx, -1);
SHA384_Init(&(data->shctx));
ILibDuktape_WritableStream_Init(ctx, ILibDuktape_SHA384_Write, ILibDuktape_SHA384_End, data);
return(1);
}
void ILibDuktape_SHA256_PUSH(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [sha]
ILibDuktape_CreateInstanceMethod(ctx, "create", ILibDuktape_SHA256_Create, 0);
}
void ILibDuktape_SHA384_PUSH(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [sha]
ILibDuktape_CreateInstanceMethod(ctx, "create", ILibDuktape_SHA384_Create, 0);
}
void ILibDuktape_MD5_PUSH(duk_context *ctx, void *chain)
{
duk_push_object(ctx); // [md5]
@@ -404,6 +516,7 @@ void ILibDuktape_SHA256_Init(duk_context * ctx)
#ifndef MICROSTACK_NOTLS
ILibDuktape_ModSearch_AddHandler(ctx, "SHA256Stream_Signer", ILibDuktape_SHA256_SIGNER_PUSH);
ILibDuktape_ModSearch_AddHandler(ctx, "SHA256Stream_Verifier", ILibDuktape_SHA256_VERIFY_PUSH);
ILibDuktape_ModSearch_AddHandler(ctx, "SHA384Stream", ILibDuktape_SHA384_PUSH);
ILibDuktape_ModSearch_AddHandler(ctx, "SHA256Stream", ILibDuktape_SHA256_PUSH);
ILibDuktape_ModSearch_AddHandler(ctx, "MD5Stream", ILibDuktape_MD5_PUSH);
#endif

View File

@@ -211,8 +211,7 @@ duk_ret_t ILibDuktape_ScriptContainer_Process_Exit(duk_context *ctx)
tmp = (void**)ILibMemory_Allocate(sizeof(void*), 0, NULL, NULL);
tmp[0] = ctx;
ILibLifeTime_Add(ILibGetBaseTimer(Duktape_GetChain(ctx)), tmp, 0, ILibDuktape_ScriptContainer_Process_ExitCallback, NULL);
return 0;
return(ILibDuktape_Error(ctx, "Process.exit() forced script termination"));
}
@@ -339,7 +338,7 @@ SCRIPT_ENGINE_SETTINGS *ILibDuktape_ScriptContainer_GetSettings(duk_context *ctx
duk_get_prop_string(ctx, -1, "process"); // [g][process]
duk_get_prop_string(ctx, -1, ILibDuktape_ScriptContainer_Process_ArgArray); // [g][process][array]
int i, count = duk_get_length(ctx, -1);
int i, count = (int)duk_get_length(ctx, -1);
for (i = 0; i < count; ++i)
{
duk_get_prop_index(ctx, -1, i); // [g][process][array][index]
@@ -369,7 +368,7 @@ duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx2(SCRIPT_EN
void *ILibDuktape_ScriptContainer_Engine_malloc(void *udata, duk_size_t size)
{
return(ILibMemory_Allocate(size, 0, NULL, NULL));
return(ILibMemory_Allocate((int)size, 0, NULL, NULL));
}
void *ILibDuktape_ScriptContainer_Engine_realloc(void *udata, void *ptr, duk_size_t size)
{
@@ -837,7 +836,7 @@ void ILibDuktape_ScriptContainer_Slave_ProcessCommands(ILibDuktape_ScriptContain
char *moduleName = Duktape_GetStringPropertyValue(slave->ctx, -1, "name", NULL);
char *module = Duktape_GetStringPropertyValueEx(slave->ctx, -1, "module", NULL, &moduleLen);
ILibDuktape_ModSearch_AddModule(slave->ctx, moduleName, module, moduleLen);
ILibDuktape_ModSearch_AddModule(slave->ctx, moduleName, module, (int)moduleLen);
ILibRemoteLogging_printf(ILibChainGetLogger(slave->chain), ILibRemoteLogging_Modules_Microstack_Generic | ILibRemoteLogging_Modules_ConsolePrint, ILibRemoteLogging_Flags_VerbosityLevel_1, "MeshAgent_Slave: Added module %s", moduleName);
break;
@@ -850,7 +849,7 @@ void ILibDuktape_ScriptContainer_Slave_ProcessCommands(ILibDuktape_ScriptContain
if (duk_has_prop_string(codec, -1, "argv"))
{
duk_get_prop_string(codec, -1, "argv"); // [json][argv]
int i, argLen = duk_get_length(codec, -1);
int i, argLen = (int)duk_get_length(codec, -1);
if (argLen > 0)
{
if ((argLen + 1) * sizeof(void*) > sizeof(ILibScratchPad))
@@ -922,7 +921,7 @@ void ILibDuktape_ScriptContainer_Slave_ProcessCommands(ILibDuktape_ScriptContain
{
// Execute String
execData = (char*)Duktape_GetStringPropertyValueEx(slave->ctx, -1, "string", NULL, &execDataLen);
if (ILibDuktape_ScriptContainer_CompileJavaScript(slave->ctx, execData, execDataLen) == 0 && ILibDuktape_ScriptContainer_ExecuteByteCode(slave->ctx) == 0)
if (ILibDuktape_ScriptContainer_CompileJavaScript(slave->ctx, execData, (int)execDataLen) == 0 && ILibDuktape_ScriptContainer_ExecuteByteCode(slave->ctx) == 0)
{
// Success
duk_push_object(slave->ctx); // [json][retJSON]
@@ -964,7 +963,7 @@ void ILibDuktape_ScriptContainer_Slave_ProcessCommands(ILibDuktape_ScriptContain
{
// Execute Path
execData = (char*)Duktape_GetStringPropertyValueEx(slave->ctx, -1, "path", NULL, &execDataLen);
if (ILibDuktape_ScriptContainer_CompileJavaScript_FromFile(slave->ctx, execData, execDataLen) == 0 && ILibDuktape_ScriptContainer_ExecuteByteCode(slave->ctx))
if (ILibDuktape_ScriptContainer_CompileJavaScript_FromFile(slave->ctx, execData, (int)execDataLen) == 0 && ILibDuktape_ScriptContainer_ExecuteByteCode(slave->ctx))
{
// SUCCESS
duk_push_object(slave->ctx); // [json][retJSON]
@@ -1224,10 +1223,10 @@ duk_ret_t ILibDuktape_ScriptContainer_ExecuteString(duk_context *ctx)
duk_json_encode(ctx, -1);
buffer = (char*)duk_get_lstring(ctx, -1, &bufferLen);
((int*)header)[0] = bufferLen + 4;
((int*)header)[0] = (int)bufferLen + 4;
ILibProcessPipe_Process_WriteStdIn(master->child, header, 4, ILibTransport_MemoryOwnership_USER);
ILibProcessPipe_Process_WriteStdIn(master->child, buffer, bufferLen, ILibTransport_MemoryOwnership_USER);
ILibProcessPipe_Process_WriteStdIn(master->child, buffer, (int)bufferLen, ILibTransport_MemoryOwnership_USER);
return(0);
}
@@ -1490,7 +1489,7 @@ duk_ret_t ILibDuktape_ScriptContainer_Create(duk_context *ctx)
duk_swap_top(ctx, -2); // [json][container]
((int*)header)[0] = bufferLen + 4;
((int*)header)[0] = (int)bufferLen + 4;
ILibProcessPipe_Process_AddHandlers(master->child, SCRIPT_ENGINE_PIPE_BUFFER_SIZE, ILibDuktape_ScriptContainer_ExitSink, ILibDuktape_ScriptContainer_StdOutSink, ILibDuktape_ScriptContainer_StdErrSink, ILibDuktape_ScriptContainer_SendOkSink, master);
ILibProcessPipe_Process_WriteStdIn(master->child, header, sizeof(header), ILibTransport_MemoryOwnership_USER);
ILibProcessPipe_Process_WriteStdIn(master->child, buffer, (int)bufferLen, ILibTransport_MemoryOwnership_USER);

View File

@@ -157,6 +157,8 @@ duk_ret_t ILibDuktape_WritableStream_Write(duk_context *ctx)
char *buffer = Duktape_GetBuffer(ctx, 0, &bufferLen);
int cbIndex = 0;
stream->Reserved = duk_is_string(ctx, 0) ? 1 : 0;
for (cbIndex = 1; cbIndex < nargs; ++cbIndex)
{
if (duk_is_function(ctx, cbIndex)) { break; }

View File

@@ -44,6 +44,7 @@ typedef struct ILibDuktape_WritableStream
ILibDuktape_WritableStream_EndHandler EndSink;
ILibDuktape_WritableStream_PipeHandler PipeSink;
void *WriteSink_User;
int Reserved;
} ILibDuktape_WritableStream;
#define ILibDuktape_WritableStream_WSPTRS "\xFF_WritableStream_PTRS"

View File

@@ -125,11 +125,11 @@ char* ILibDuktape_fs_fixLinuxPath(char *path)
int len = end;
if (end > (sizeof(ILibDuktape_fs_linuxPath)-1)) { return(NULL); }
if (path[0] == '/') { start = 1; } else { ++len; }
//if (path[0] == '/') { start = 1; } else { ++len; }
if (path[end - 1] == '*') { --end; --len; }
ILibDuktape_fs_linuxPath[0] = '/';
memcpy_s(ILibDuktape_fs_linuxPath + 1, sizeof(ILibDuktape_fs_linuxPath) - 1, path + start, end);
memcpy_s(ILibDuktape_fs_linuxPath, sizeof(ILibDuktape_fs_linuxPath), path + start, end);
ILibDuktape_fs_linuxPath[len] = 0; // Klocwork is being retarded, as it is too stupid to notice the size check at the top of this func
return(ILibDuktape_fs_linuxPath);
}
@@ -1319,7 +1319,7 @@ public:
Array<String> readdirSync(path[, options]);
/*!
\brief Returns a new WritableStream
\param path \<String]>
\param path \<String\>
\param options <Object> has the following defaults:\n
<b>flags</b> \<String\> 'w'\n
<b>encoding</b> \<String\> 'utf8'\n

View File

@@ -36,6 +36,7 @@ limitations under the License.
#include "ILibDuktape_EventEmitter.h"
#include "microstack/ILibCrypto.h"
#define HTTP_SERVER_PTR "\xFF_ServerPtr"
#define HTTP_WEBCLIENT_MGR "_RequestManagerPtr"
#define NativeSessionPtr "\xFF_SessionPtr"
#define SessionPtrJS "\xFF_SessionPtr_JS"
@@ -43,6 +44,7 @@ limitations under the License.
#define TLS_CERT "\xFF_cert"
#define TLS_CERT_NON_LEAF "\xFF_cert_nonleaf"
#define HTTP_DEFAULT_PROTO_KEY "\xFF_defaultProto"
#define HTTP_REQUEST_USER_PTR "\xFF_request_user_ptr"
#define HTTP_REQUEST_TOKEN_PTR "_TokenPtr"
#define HTTP_SOCKET_PTRS "\xFF_socket_ptrs"
#define HTTP_SOCKET_BUFFERPTR "\xFF_socket_bufferptr"
@@ -56,6 +58,7 @@ limitations under the License.
#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"
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);
@@ -80,18 +83,20 @@ typedef struct ILibDuktape_http_requestClient_callbacks
void *readableStream;
void *requestStream;
void *OnReceive;
void *OnContinue;
#ifndef MICROSTACK_NOTLS
int rejectUnauthorized;
void *checkServerIdentity;
#endif
}ILibDuktape_http_requestClient_callbacks;
typedef struct ILibDuktape_http_server_session_ptrs
typedef struct ILibDuktape_http_server_ptrs
{
void *ctx;
void *serverObject;
void *OnResponse;
void *OnUpgrade;
void *OnCheckContinue;
void *OnConnect;
}ILibDuktape_http_server_ptrs;
typedef struct ILibDuktape_http_session_ptrs
@@ -99,6 +104,12 @@ typedef struct ILibDuktape_http_session_ptrs
ILibDuktape_readableStream *req;
ILibDuktape_WritableStream *res;
}ILibDuktape_http_session_ptrs;
typedef struct ILibDuktape_http_server_websocket_ptrs
{
ILibDuktape_EventEmitter *emitter;
ILibDuktape_DuplexStream *ds;
ILibWebServer_Session *session;
}ILibDuktape_http_server_websocket_ptrs;
typedef struct ILibDuktape_WebSocket_Pointers
{
@@ -208,7 +219,7 @@ duk_ret_t ILibDuktape_http_serverresponse_end(duk_context *ctx)
int nargs = duk_get_top(ctx);
duk_push_this(ctx); // [res]
duk_get_prop_string(ctx, -1, "SessionPtr"); // [res][session]
duk_get_prop_string(ctx, -1, NativeSessionPtr); // [res][session]
session = (ILibWebServer_Session*)duk_to_pointer(ctx, -1); // [res][session]
duk_pop(ctx); // [res]
duk_get_prop_string(ctx, -1, "PacketPtr"); // [res][packet]
@@ -274,7 +285,7 @@ duk_ret_t ILibDuktape_http_serverresponse_writeHead(duk_context *ctx)
duk_get_prop_string(ctx, -1, "PacketPtr"); // [response][packet]
packet = (ILibHTTPPacket*)duk_to_pointer(ctx, -1);
duk_del_prop_string(ctx, -2, "PacketPtr");
duk_get_prop_string(ctx, -2, "SessionPtr"); // [response][packet][session]
duk_get_prop_string(ctx, -2, NativeSessionPtr); // [response][packet][session]
session = (ILibWebServer_Session*)duk_to_pointer(ctx, -1);
if (nargs < 1) { duk_push_string(ctx, "Missing Status Code"); duk_throw(ctx); return(DUK_RET_ERROR); }
@@ -344,6 +355,15 @@ duk_ret_t ILibDuktape_http_server_ServerResponse_Finalizer(duk_context *ctx)
}
return 0;
}
duk_ret_t ILibDuktape_http_server_ServerResponse_writeContinue(duk_context *ctx)
{
duk_push_this(ctx);
duk_get_prop_string(ctx, -1, NativeSessionPtr);
ILibWebServer_Session *session = (ILibWebServer_Session*)duk_get_pointer(ctx, -1);
ILibWebServer_Send_Raw(session, "HTTP/1.1 100 Continue\r\n\r\n", 25, ILibAsyncSocket_MemoryOwnership_STATIC, ILibWebServer_DoneFlag_NotDone);
return(0);
}
ILibDuktape_WritableStream* ILibDuktape_http_server_PUSH_ServerResponse(duk_context *ctx, ILibWebServer_Session *session)
{
ILibHTTPPacket *packet = ILibCreateEmptyPacket();
@@ -351,7 +371,7 @@ ILibDuktape_WritableStream* ILibDuktape_http_server_PUSH_ServerResponse(duk_cont
duk_push_object(ctx); // [obj]
duk_push_pointer(ctx, session); // [obj][session]
duk_put_prop_string(ctx, -2, "SessionPtr"); // [obj]
duk_put_prop_string(ctx, -2, NativeSessionPtr); // [obj]
duk_push_pointer(ctx, packet); // [obj][packet]
duk_put_prop_string(ctx, -2, "PacketPtr"); // [obj]
duk_push_int(ctx, 500); // [obj][statusCode]
@@ -368,6 +388,8 @@ ILibDuktape_WritableStream* ILibDuktape_http_server_PUSH_ServerResponse(duk_cont
duk_push_c_function(ctx, ILibDuktape_http_serverresponse_writeHead, DUK_VARARGS); // [obj][func]
duk_put_prop_string(ctx, -2, "writeHead"); // [obj]
ILibDuktape_CreateInstanceMethod(ctx, "writeContinue", ILibDuktape_http_server_ServerResponse_writeContinue, 0);
return ILibDuktape_WritableStream_Init(ctx, ILibDuktape_http_server_WriteResponse, ILibDuktape_http_server_EndResponse, session);
}
@@ -456,8 +478,8 @@ void ILibDuktape_http_server_NativeSession_PUSH(duk_context *ctx, ILibWebServer_
ILibDuktape_CreateInstanceMethod(ctx, "Digest_SendUnauthorized", ILibDuktape_http_server_NativeSession_Digest_SendUnAuthorized, 2);
ILibDuktape_CreateInstanceMethod(ctx, "Digest_GetUsername", ILibDuktape_http_server_NativeSession_Digest_GetUsername, 0);
ILibDuktape_CreateInstanceMethod(ctx, "Digest_ValidatePassword", ILibDuktape_http_server_NativeSession_Digest_ValidatePassword, 1);
ILibDuktape_CreateInstanceMethod(ctx, "WebSocket_GetDataType", ILibDuktape_http_server_NativeSession_WebSocket_GetDataType, 0);
ILibDuktape_CreateInstanceMethod(ctx, "WebSocket_Upgrade", ILibDuktape_http_server_NativeSession_WebSocket_Upgrade, DUK_VARARGS);
//ILibDuktape_CreateInstanceMethod(ctx, "WebSocket_GetDataType", ILibDuktape_http_server_NativeSession_WebSocket_GetDataType, 0);
//ILibDuktape_CreateInstanceMethod(ctx, "WebSocket_Upgrade", ILibDuktape_http_server_NativeSession_WebSocket_Upgrade, DUK_VARARGS);
}
@@ -564,7 +586,10 @@ void ILibDuktape_http_server_PUSH_IncomingMessage(duk_context *ctx, ILibHTTPPack
{
duk_push_pointer(ctx, session); // [obj][session]
duk_put_prop_string(ctx, -2, NativeSessionPtr); // [obj]
ILibDuktape_CreateEventWithGetter(ctx, "NativeSession", ILibDuktape_http_server_NativeSession_Getter);
ILibDuktape_CreateInstanceMethod(ctx, "Digest_IsAuthenticated", ILibDuktape_http_server_NativeSession_Digest_IsAuthenticated, 1);
ILibDuktape_CreateInstanceMethod(ctx, "Digest_SendUnauthorized", ILibDuktape_http_server_NativeSession_Digest_SendUnAuthorized, 2);
ILibDuktape_CreateInstanceMethod(ctx, "Digest_GetUsername", ILibDuktape_http_server_NativeSession_Digest_GetUsername, 0);
ILibDuktape_CreateInstanceMethod(ctx, "Digest_ValidatePassword", ILibDuktape_http_server_NativeSession_Digest_ValidatePassword, 1);
}
if (packet != NULL && packet->Directive != NULL)
{
@@ -612,13 +637,118 @@ void ILibDuktape_http_server_Resume(ILibDuktape_readableStream *sender, void *us
{
ILibWebServer_Resume((ILibWebServer_Session*)user);
}
ILibTransport_DoneState ILibDuktape_http_server_webSocket_WriteHandler(ILibDuktape_DuplexStream *stream, char *buffer, int bufferLen, void *user)
{
return((ILibTransport_DoneState)ILibWebServer_WebSocket_Send(((ILibDuktape_http_server_websocket_ptrs*)user)->session, buffer, bufferLen, stream->writableStream->Reserved == 0 ? ILibWebServer_WebSocket_DataType_BINARY : ILibWebServer_WebSocket_DataType_TEXT, ILibAsyncSocket_MemoryOwnership_USER, ILibWebServer_WebSocket_FragmentFlag_Complete));
}
void ILibDuktape_http_server_webSocket_EndHandler(ILibDuktape_DuplexStream *stream, void *user)
{
ILibWebServer_WebSocket_Close(((ILibDuktape_http_server_websocket_ptrs*)user)->session);
}
void ILibDuktape_http_server_webSocket_PauseHandler(ILibDuktape_DuplexStream *sender, void *user)
{
ILibWebServer_Pause(((ILibDuktape_http_server_websocket_ptrs*)user)->session);
}
void ILibDuktape_http_server_webSocket_ResumeHandler(ILibDuktape_DuplexStream *sender, void *user)
{
ILibWebServer_Resume(((ILibDuktape_http_server_websocket_ptrs*)user)->session);
}
void ILibDuktape_http_server_webSocket_OnReceive(struct ILibWebServer_Session *sender, int InterruptFlag, struct packetheader *header, char *bodyBuffer, int *beginPointer, int endPointer, ILibWebServer_DoneFlag done)
{
ILibDuktape_http_server_websocket_ptrs *ptrs = (ILibDuktape_http_server_websocket_ptrs*)((void**)sender->Reserved_Transport.ChainLink.ExtraMemoryPtr)[0];
*beginPointer = endPointer;
if (done == ILibWebServer_DoneFlag_Done)
{
ILibDuktape_DuplexStream_WriteEnd(ptrs->ds);
sender->OnDisconnect = NULL;
}
else
{
ILibDuktape_DuplexStream_WriteDataEx(ptrs->ds, ILibWebServer_WebSocket_GetDataType(sender) == ILibWebServer_WebSocket_DataType_TEXT ? 1 : 0, bodyBuffer, endPointer);
}
}
void ILibDuktape_http_server_webSocket_OnDisconnect(struct ILibWebServer_Session *sender)
{
ILibDuktape_http_server_websocket_ptrs *ptrs = (ILibDuktape_http_server_websocket_ptrs*)((void**)sender->Reserved_Transport.ChainLink.ExtraMemoryPtr)[0];
ILibDuktape_DuplexStream_WriteEnd(ptrs->ds);
sender->OnDisconnect = NULL;
duk_push_heapptr(ptrs->emitter->ctx, ptrs->emitter->object);
duk_del_prop_string(ptrs->emitter->ctx, -1, NativeSessionPtr);
duk_pop(ptrs->emitter->ctx);
}
void ILibDuktape_http_server_webSocket_OnSendOK(struct ILibWebServer_Session *sender)
{
ILibDuktape_http_server_websocket_ptrs *ptrs = (ILibDuktape_http_server_websocket_ptrs*)((void**)sender->Reserved_Transport.ChainLink.ExtraMemoryPtr)[0];
ILibDuktape_DuplexStream_Ready(ptrs->ds);
}
void ILibDuktape_http_server_IntermediateSocket_Finalizer(duk_context *ctx, void *obj)
{
duk_push_heapptr(ctx, obj);
if (duk_has_prop_string(ctx, -1, NativeSessionPtr))
{
duk_get_prop_string(ctx, -1, NativeSessionPtr);
ILibWebServer_Session *session = (ILibWebServer_Session*)duk_get_pointer(ctx, -1);
session->OnDisconnect = NULL;
session->OnReceive = NULL;
session->OnSendOK = NULL;
ILibWebServer_DisconnectSession(session);
}
}
duk_ret_t ILibDuktape_http_server_IntermediateSocket_upgradeWebSocket(duk_context *ctx)
{
ILibWebServer_Session *session;
int bufferSize = duk_get_top(ctx) == 0 ? 65535 : duk_require_int(ctx, 0);
duk_push_this(ctx); // [socket]
duk_get_prop_string(ctx, -1, NativeSessionPtr); // [socket][ptr]
session = (ILibWebServer_Session*)duk_get_pointer(ctx, -1);
duk_pop(ctx); // [socket]
if (ILibWebServer_UpgradeWebSocket(session, bufferSize) != 0) { return(ILibDuktape_Error(ctx, "upgradeWebSocket(): Invalid State")); }
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_http_server_websocket_ptrs)); // [socket][buffer]
ILibDuktape_http_server_websocket_ptrs *ptrs = (ILibDuktape_http_server_websocket_ptrs*)Duktape_GetBuffer(ctx, -1, NULL);
memset(ptrs, 0, sizeof(ILibDuktape_http_server_websocket_ptrs));
duk_put_prop_string(ctx, -2, HTTP_SOCKET_PTRS); // [socket]
ILibDuktape_CreateIndependentFinalizer(ctx, ILibDuktape_http_server_IntermediateSocket_Finalizer);
((void**)session->Reserved_Transport.ChainLink.ExtraMemoryPtr)[0] = ptrs;
ptrs->session = session;
ptrs->emitter = ILibDuktape_EventEmitter_Create(ctx);
ptrs->ds = ILibDuktape_DuplexStream_Init(ctx, ILibDuktape_http_server_webSocket_WriteHandler, ILibDuktape_http_server_webSocket_EndHandler, ILibDuktape_http_server_webSocket_PauseHandler, ILibDuktape_http_server_webSocket_ResumeHandler, ptrs);
// Redirect these events, because it's now a websocket
session->OnDisconnect = ILibDuktape_http_server_webSocket_OnDisconnect;
session->OnReceive = ILibDuktape_http_server_webSocket_OnReceive;
session->OnSendOK = ILibDuktape_http_server_webSocket_OnSendOK;
return(1);
}
duk_ret_t ILibDuktape_http_server_IntermediateSocket_end(duk_context *ctx)
{
duk_push_this(ctx);
duk_get_prop_string(ctx, -1, NativeSessionPtr);
ILibWebServer_DisconnectSession((ILibWebServer_Session*)duk_get_pointer(ctx, -1));
return(0);
}
void ILibDuktape_http_server_PUSH_IntermediateSocket(duk_context *ctx, ILibWebServer_Session *session)
{
duk_push_object(ctx); // [sock]
duk_push_pointer(ctx, session); // [sock][session]
duk_put_prop_string(ctx, -2, NativeSessionPtr); // [sock]
ILibDuktape_CreateInstanceMethod(ctx, "upgradeWebSocket", ILibDuktape_http_server_IntermediateSocket_upgradeWebSocket, DUK_VARARGS);
ILibDuktape_CreateProperty_InstanceMethod(ctx, "end", ILibDuktape_http_server_IntermediateSocket_end, 0);
}
void ILibDuktape_http_server_OnReceive(struct ILibWebServer_Session *sender, int InterruptFlag, struct packetheader *header, char *bodyBuffer, int *beginPointer, int endPointer, ILibWebServer_DoneFlag done)
{
ILibDuktape_http_server_ptrs* serverPtrs = (ILibDuktape_http_server_ptrs*)sender->ParentExtraMemory;
ILibDuktape_http_session_ptrs *sessionPtrs = (ILibDuktape_http_session_ptrs*)sender->Reserved_Transport.ChainLink.ExtraMemoryPtr;
char *headerVal;
int headerValLen;
int r = 0;
if (ILibGetHeaderLineEx(header, "upgrade", 7, NULL) != NULL)
@@ -630,34 +760,60 @@ void ILibDuktape_http_server_OnReceive(struct ILibWebServer_Session *sender, int
ILibDuktape_http_server_PUSH_IncomingMessage(serverPtrs->ctx, header, sender); // [func][this][incoming]
ILibDuktape_http_server_PUSH_IntermediateSocket(serverPtrs->ctx, sender); // [func][this][incoming][socket]
duk_push_null(serverPtrs->ctx); // [func][this][incoming][socket][head]
if (duk_pcall_method(serverPtrs->ctx, 3) != 0) { ILibDuktape_Process_UncaughtExceptionEx(serverPtrs->ctx, "Server.OnUpgrade(): "); }
duk_pop(serverPtrs->ctx); // ...
//ILibDuktape_EventEmitter_RemoveAllListeners();
}
}
// The very first time, Server.request event will be emitted
if (sessionPtrs->req == NULL && serverPtrs->OnResponse != NULL)
return;
}
if ((headerVal = ILibGetHeaderLineEx(header, "expect", 6, &headerValLen)) != NULL)
{
duk_push_heapptr(serverPtrs->ctx, serverPtrs->OnResponse); // [func]
ILibDuktape_http_server_PUSH_IncomingMessage(serverPtrs->ctx, header, sender); // [func][req]
sessionPtrs->req = ILibDuktape_InitReadableStream(serverPtrs->ctx, NULL, NULL, NULL);
ILibDuktape_readableStream_SetPauseResumeHandlers(sessionPtrs->req, ILibDuktape_http_server_Pause, ILibDuktape_http_server_Resume, sender);
duk_push_heap_stash(serverPtrs->ctx); // [func][req][stash]
duk_dup(serverPtrs->ctx, -2); // [func][req][stash][req]
duk_put_prop_string(serverPtrs->ctx, -2, Duktape_GetStashKey(sessionPtrs->req->object)); // [func][req][stash]
duk_pop(serverPtrs->ctx); // [func][req]
sessionPtrs->res = ILibDuktape_http_server_PUSH_ServerResponse(serverPtrs->ctx, sender); // [func][req][res]
if (duk_pcall(serverPtrs->ctx, 2) != 0) // [retVal]
if (ILibString_StartsWith(headerVal, headerValLen, "100-", 4))
{
ILibDuktape_Process_UncaughtException(serverPtrs->ctx);
}
duk_pop(serverPtrs->ctx); // ...
}
if (serverPtrs->OnCheckContinue != NULL)
{
duk_push_heapptr(serverPtrs->ctx, serverPtrs->OnCheckContinue); // [func]
duk_push_heapptr(serverPtrs->ctx, serverPtrs->serverObject); // [func][this]
ILibDuktape_http_server_PUSH_IncomingMessage(serverPtrs->ctx, header, sender); // [func][this][incoming]
sessionPtrs->req = ILibDuktape_InitReadableStream(serverPtrs->ctx, NULL, NULL, NULL);
ILibDuktape_readableStream_SetPauseResumeHandlers(sessionPtrs->req, ILibDuktape_http_server_Pause, ILibDuktape_http_server_Resume, sender);
sessionPtrs->res = ILibDuktape_http_server_PUSH_ServerResponse(serverPtrs->ctx, sender);// [func][this][incoming][res]
if (duk_pcall_method(serverPtrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(serverPtrs->ctx, "httpServer.onCheckContinue(): "); }
duk_pop(serverPtrs->ctx); // ...
}
else
{
// Noboddy is listening for checkContinue, so we must send a 100-Continue manually
ILibWebServer_Send_Raw(sender, "HTTP/1.1 Continue\r\n\r\n", 25, ILibAsyncSocket_MemoryOwnership_STATIC, ILibWebServer_DoneFlag_NotDone);
}
ILibDeleteHeaderLine(header, "expect", 6);
}
}
else
{
// The very first time, Server.request event will be emitted
if (sessionPtrs->req == NULL && serverPtrs->OnResponse != NULL)
{
duk_push_heapptr(serverPtrs->ctx, serverPtrs->OnResponse); // [func]
ILibDuktape_http_server_PUSH_IncomingMessage(serverPtrs->ctx, header, sender); // [func][req]
sessionPtrs->req = ILibDuktape_InitReadableStream(serverPtrs->ctx, NULL, NULL, NULL);
ILibDuktape_readableStream_SetPauseResumeHandlers(sessionPtrs->req, ILibDuktape_http_server_Pause, ILibDuktape_http_server_Resume, sender);
duk_push_heap_stash(serverPtrs->ctx); // [func][req][stash]
duk_dup(serverPtrs->ctx, -2); // [func][req][stash][req]
duk_put_prop_string(serverPtrs->ctx, -2, Duktape_GetStashKey(sessionPtrs->req->object)); // [func][req][stash]
duk_pop(serverPtrs->ctx); // [func][req]
sessionPtrs->res = ILibDuktape_http_server_PUSH_ServerResponse(serverPtrs->ctx, sender); // [func][req][res]
if (duk_pcall(serverPtrs->ctx, 2) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(serverPtrs->ctx);
}
duk_pop(serverPtrs->ctx); // ...
}
}
// Now we just write to the ReadableStream
if (sessionPtrs->req != NULL)
{
@@ -727,6 +883,20 @@ int ILibDuktape_http_server_clientVerify(ILibWebServer_ServerToken sender, int p
return retVal;
}
#endif
duk_ret_t ILibDuktape_http_server_finalizer(duk_context *ctx)
{
duk_get_prop_string(ctx, 0, HTTP_SERVER_PTR);
ILibWebServer_ServerToken server = (ILibWebServer_ServerToken)duk_get_pointer(ctx, -1);
void *chain = Duktape_GetChain(ctx);
if (ILibIsChainBeingDestroyed(chain) == 0)
{
// SafeRemove Server here...
ILibChain_SafeRemove(chain, server);
}
return(0);
}
duk_ret_t ILibDuktape_http_server_listen(duk_context *ctx)
{
int nargs = duk_get_top(ctx);
@@ -735,7 +905,6 @@ duk_ret_t ILibDuktape_http_server_listen(duk_context *ctx)
int maxConnections = nargs > 2 ? duk_require_int(ctx, 2) : 5;
void *chain;
ILibWebServer_ServerToken server;
char *key;
ILibDuktape_EventEmitter *emitter = ILibDuktape_EventEmitter_GetEmitter_fromThis(ctx);
duk_push_this(ctx); // [server]
@@ -750,6 +919,7 @@ duk_ret_t ILibDuktape_http_server_listen(duk_context *ctx)
ILibDuktape_EventEmitter_AddEventHeapptr(emitter, "request", &(((ILibDuktape_http_server_ptrs*)((ILibChain_Link*)server)->ExtraMemoryPtr)->OnResponse));
ILibDuktape_EventEmitter_AddEventHeapptr(emitter, "connect", &(((ILibDuktape_http_server_ptrs*)((ILibChain_Link*)server)->ExtraMemoryPtr)->OnConnect));
ILibDuktape_EventEmitter_AddEventHeapptr(emitter, "upgrade", &(((ILibDuktape_http_server_ptrs*)((ILibChain_Link*)server)->ExtraMemoryPtr)->OnUpgrade));
ILibDuktape_EventEmitter_AddEventHeapptr(emitter, "checkContinue", &(((ILibDuktape_http_server_ptrs*)((ILibChain_Link*)server)->ExtraMemoryPtr)->OnCheckContinue));
#ifndef MICROSTACK_NOTLS
if (duk_has_prop_string(ctx, -1, TLSPTR))
@@ -774,13 +944,8 @@ duk_ret_t ILibDuktape_http_server_listen(duk_context *ctx)
#endif
duk_push_pointer(ctx, server); // [server][serverPtr]
duk_put_prop_string(ctx, -2, "ServerPtr"); // [server]
key = Duktape_GetStashKey(server);
duk_push_heap_stash(ctx); // [server][stash]
duk_swap_top(ctx, -2); // [stash][server]
duk_put_prop_string(ctx, -2, key); // [stash]
duk_put_prop_string(ctx, -2, HTTP_SERVER_PTR); // [server]
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_http_server_finalizer);
return 0;
}
@@ -808,6 +973,7 @@ duk_ret_t ILibDuktape_http_createServer(duk_context *ctx)
ILibDuktape_EventEmitter_CreateEventEx(emitter, "listening");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "upgrade");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "connect");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "checkContinue");
for (i = 0; i < nargs; ++i)
{
@@ -943,26 +1109,35 @@ void ILibDuktape_http_request_OnResponse(ILibWebClient_StateObject WebStateObjec
return;
}
ILibDuktape_http_server_PUSH_IncomingMessage(ctx, header, NULL); // [iMsg]
duk_push_pointer(ctx, WebStateObject);
duk_put_prop_string(ctx, -2, HTTP_INCOMINGMSG_WebStateObject);
ptrs->readableStream = ILibDuktape_InitReadableStream(ctx, NULL, NULL, NULL);
ILibDuktape_readableStream_SetPauseResumeHandlers(ptrs->readableStream, ILibDuktape_http_request_Pause, ILibDuktape_http_request_Resume, WebStateObject);
duk_push_heapptr(ctx, ptrs->clientRequest); // [iMsg][clientRequest]
duk_swap_top(ctx, -2); // [clientRequest][iMsg]
duk_dup(ctx, -1); // [clientRequest][iMsg][iMsg]
duk_put_prop_string(ctx, -3, "_iMsgPtr"); // [clientRequest][iMsg]
duk_swap_top(ctx, -2); // [iMsg][clientRequest]
duk_push_heapptr(ctx, ptrs->OnReceive); // [iMsg][clientRequest][func]
duk_swap(ctx, -3, -1); // [func][clientRequest/this][iMsg]
if (duk_pcall_method(ctx, 1) != 0) // [retVal]
if ((header->StatusCode == 100 && ptrs->OnContinue != NULL) || ptrs->OnReceive != NULL)
{
ILibDuktape_Process_UncaughtException(ctx);
}
duk_pop(ctx); // ...
ILibDuktape_http_server_PUSH_IncomingMessage(ctx, header, NULL); // [iMsg]
duk_push_pointer(ctx, WebStateObject);
duk_put_prop_string(ctx, -2, HTTP_INCOMINGMSG_WebStateObject);
ptrs->readableStream = ILibDuktape_InitReadableStream(ctx, NULL, NULL, NULL);
ILibDuktape_readableStream_SetPauseResumeHandlers(ptrs->readableStream, ILibDuktape_http_request_Pause, ILibDuktape_http_request_Resume, WebStateObject);
duk_push_heapptr(ctx, ptrs->clientRequest); // [iMsg][clientRequest]
duk_swap_top(ctx, -2); // [clientRequest][iMsg]
duk_dup(ctx, -1); // [clientRequest][iMsg][iMsg]
duk_put_prop_string(ctx, -3, "_iMsgPtr"); // [clientRequest][iMsg]
duk_swap_top(ctx, -2); // [iMsg][clientRequest]
if (header->StatusCode == 100 && ptrs->OnContinue != NULL)
{
duk_push_heapptr(ctx, ptrs->OnContinue); // [iMsg][clientRequest][func]
}
else
{
duk_push_heapptr(ctx, ptrs->OnReceive); // [iMsg][clientRequest][func]
}
duk_swap(ctx, -3, -1); // [func][clientRequest/this][iMsg]
if (duk_pcall_method(ctx, 1) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(ctx);
}
duk_pop(ctx); // ...
}
if (endPointer > 0) { r += ILibDuktape_readableStream_WriteData(ptrs->readableStream, bodyBuffer + *beginPointer, endPointer - *beginPointer); }
if (r == 0 && recvStatus == ILibWebClient_ReceiveStatus_Complete) { r += ILibDuktape_readableStream_WriteEnd(ptrs->readableStream); }
}
@@ -1137,6 +1312,10 @@ void ILibDuktape_http_request_WebSocket_OnResponse(ILibWebClient_StateObject Web
ILibDuktape_WebSocket_Pointers *ptrs = (ILibDuktape_WebSocket_Pointers*)user2;
if (ctx == NULL || ptrs == NULL) { return; }
duk_push_heapptr(ctx, ptrs->clientRequest_ptr);
duk_del_prop_string(ctx, -1, HTTP_REQUEST_TOKEN_PTR);
void **user = ILibWebClient_RequestToken_GetUserObjects(ILibWebClient_GetRequestToken_FromStateObject(WebStateObject));
duk_pop(ctx);
if (header != NULL && header->StatusCode != 101)
{
@@ -1152,6 +1331,7 @@ void ILibDuktape_http_request_WebSocket_OnResponse(ILibWebClient_StateObject Web
duk_pop(ctx); // ...
*beginPointer = endPointer;
user[1] = NULL;
return;
}
@@ -1208,6 +1388,7 @@ void ILibDuktape_http_request_WebSocket_OnResponse(ILibWebClient_StateObject Web
duk_pop(ctx); //[clientRequest]
}
duk_del_prop_string(ctx, -1, HTTP_REQUEST_TOKEN_PTR);
duk_del_prop_string(ctx, -1, HTTP_REQUEST_USER_PTR);
duk_pop(ctx);
if (ptrs->socket_ptr != NULL)
@@ -1223,6 +1404,7 @@ void ILibDuktape_http_request_WebSocket_OnResponse(ILibWebClient_StateObject Web
ILibDuktape_EventEmitter_RemoveAll(ILibDuktape_EventEmitter_GetEmitter(ctx, -1));
duk_pop(ctx);
}
user[1] = NULL;
}
}
void ILibDuktape_http_request_OnSendOK(ILibWebClient_StateObject sender, void *user1, void *user2)
@@ -1313,7 +1495,6 @@ duk_ret_t ILibDuktape_http_request(duk_context *ctx)
char *path, *method;
duk_size_t pathLen, methodLen;
char *proto = Duktape_GetStringPropertyValue(ctx, 0, "protocol", ILibDuktape_http_getDefaultProto(ctx));
#ifndef MICROSTACK_NOTLS
ILibWebClient_RequestToken_HTTPS protocol = (strncmp(proto, "https:", 6) == 0 || strncmp(proto, "wss:", 4) == 0) ? ILibWebClient_RequestToken_USE_HTTPS : ILibWebClient_RequestToken_USE_HTTP;
@@ -1531,6 +1712,14 @@ duk_ret_t ILibDuktape_http_request_finalizer(duk_context *ctx)
ILibWebClient_RequestToken token;
void **user;
if (duk_has_prop_string(ctx, 0, HTTP_REQUEST_USER_PTR))
{
duk_get_prop_string(ctx, 0, HTTP_REQUEST_USER_PTR);
user = (void**)duk_get_pointer(ctx, -1);
user[1] = NULL;
}
if (duk_has_prop_string(ctx, 0, HTTP_CLIENTREQUEST_DATAPTR))
{
duk_get_prop_string(ctx, 0, HTTP_CLIENTREQUEST_DATAPTR);
@@ -1554,6 +1743,7 @@ duk_ret_t ILibDuktape_http_request_finalizer(duk_context *ctx)
ILibWebClient_CancelRequest(token);
}
}
return 0;
}
duk_ret_t ILibDuktape_http_request_no_op(duk_context *ctx)
@@ -1563,7 +1753,7 @@ duk_ret_t ILibDuktape_http_request_no_op(duk_context *ctx)
void* ILibDuktape_http_request_PUSH_clientRequest(duk_context *ctx, ILibWebClient_RequestToken token, int isWebSocket)
{
ILibDuktape_EventEmitter *emitter = NULL;
void **user = ILibWebClient_RequestToken_GetUserObjects(token);
void **user = ILibWebClient_RequestToken_GetUserObjects_Tail(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)
@@ -1573,6 +1763,9 @@ void* ILibDuktape_http_request_PUSH_clientRequest(duk_context *ctx, ILibWebClien
}
duk_push_object(ctx); // [obj]
duk_push_pointer(ctx, user);
duk_put_prop_string(ctx, -2, HTTP_REQUEST_USER_PTR);
duk_push_pointer(ctx, token); // [obj][token]
duk_put_prop_string(ctx, -2, HTTP_REQUEST_TOKEN_PTR); // [obj]
duk_push_fixed_buffer(ctx, isWebSocket == 0 ? sizeof(ILibDuktape_http_requestClient_callbacks) : sizeof(ILibDuktape_WebSocket_Pointers));
@@ -1589,11 +1782,13 @@ void* ILibDuktape_http_request_PUSH_clientRequest(duk_context *ctx, ILibWebClien
if (((ILibDuktape_http_request_dataType*)user[1])->STRUCT_TYPE == ILibDuktape_http_request_dataType_request)
{
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_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);
}
else
{
ILibDuktape_EventEmitter_CreateEventEx(emitter, "response");
((ILibDuktape_WebSocket_Pointers*)user[1])->ctx = ctx;
((ILibDuktape_WebSocket_Pointers*)user[1])->clientRequest_ptr = duk_get_heapptr(ctx, -1);
ILibDuktape_CreateInstanceMethod(ctx, "end", ILibDuktape_http_request_no_op, 0);
@@ -2221,23 +2416,6 @@ void ILibDuktape_https_PUSH(duk_context *ctx, void *chain)
ILibDuktape_http_PUSH_EX(ctx, chain, 1);
}
duk_ret_t ILibDuktape_httpDigest_clientRequest_onUpgrade(duk_context *ctx)
{
int i, nargs = duk_get_top(ctx);
duk_push_current_function(ctx); // [func]
duk_get_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST); // [func][digestClientRequest]
duk_get_prop_string(ctx, -1, "emit"); // [func][digestClientRequest][emit]
duk_swap_top(ctx, -2); // [func][emit][this]
duk_push_string(ctx, "upgrade"); // [func][emit][this][upgrade]
for (i = 0; i < nargs; ++i)
{
duk_dup(ctx, i); // [func][emit][this][upgrade][params]
}
if (duk_pcall_method(ctx, 1 + nargs) != 0) { duk_throw(ctx); return(DUK_RET_ERROR); }
return(0);
}
duk_ret_t ILibDuktape_httpDigest_clientRequest_response2(duk_context *ctx)
{
ILibHTTPPacket *packet;
@@ -2258,6 +2436,38 @@ duk_ret_t ILibDuktape_httpDigest_clientRequest_response2(duk_context *ctx)
return(0);
}
duk_ret_t ILibDuktape_httpDigest_clientRequest_onDrain(duk_context *ctx)
{
duk_push_this(ctx); // [clientRequest]
if (duk_has_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST))
{
duk_get_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST); // [clientRequest][digestClientRequest]
if (duk_has_prop_string(ctx, -1, ILibDuktape_WritableStream_WSPTRS))
{
duk_get_prop_string(ctx, -1, ILibDuktape_WritableStream_WSPTRS);
ILibDuktape_WritableStream_Ready((ILibDuktape_WritableStream*)Duktape_GetBuffer(ctx, -1, NULL));
}
}
return(0);
}
duk_ret_t ILibDuktape_httpDigest_clientRequest_propagateEvent(duk_context *ctx)
{
int i, nargs = duk_get_top(ctx);
duk_push_current_function(ctx); // [func]
duk_get_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST); // [func][digestClientRequest]
duk_get_prop_string(ctx, -1, "emit"); // [func][digestClientRequest][emit]
duk_swap_top(ctx, -2); // [func][emit][this]
duk_get_prop_string(ctx, -3, CLIENTREQUEST_EVENT_NAME); // [func][emit][this][eventName]
for (i = 0; i < nargs; ++i)
{
duk_dup(ctx, i); // [func][emit][this][eventName][params]
}
if (duk_pcall_method(ctx, 1 + nargs) != 0) { duk_throw(ctx); return(DUK_RET_ERROR); }
return(0);
}
extern void* ILibWebClient_Digest_GenerateTable(ILibWebClient_StateObject state);
duk_ret_t ILibDuktape_httpDigest_clientRequest_response(duk_context *ctx)
{
@@ -2269,8 +2479,8 @@ duk_ret_t ILibDuktape_httpDigest_clientRequest_response(duk_context *ctx)
void *digestClientPtr;
void *paramPtr = NULL;
duk_push_current_function(ctx);
duk_get_prop_string(ctx, -1, "digestClientRequest");
duk_push_current_function(ctx);
duk_get_prop_string(ctx, -1, "digestClientRequest");
digestClientPtr = duk_get_heapptr(ctx, -1);
duk_get_prop_string(ctx, -1, "digest");
duk_get_prop_string(ctx, -1, DIGEST_USERNAME);
@@ -2283,6 +2493,17 @@ 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))
{
duk_get_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST); // [digestClientRequest][clientRequest]
duk_get_prop_string(ctx, -1, "end"); // [digestClientRequest][clientRequest][end]
duk_dup(ctx, -2); // [digestClientRequest][clientRequest][end][this]
if (duk_pcall_method(ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http-digest.onResponse(): "); }
duk_pop_2(ctx); // [digestClientRequest]
}
duk_pop(ctx); // ...
// UnAuthorized, need to retry request with Authorization Headers
duk_get_prop_string(ctx, 0, HTTP_INCOMINGMSG_WebStateObject);
wcdo = (ILibWebClient_StateObject)duk_get_pointer(ctx, -1);
@@ -2364,10 +2585,42 @@ duk_ret_t ILibDuktape_httpDigest_clientRequest_response(duk_context *ctx)
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_c_function(ctx, ILibDuktape_httpDigest_clientRequest_onUpgrade, 3); // [clientReqeust][OnUpgrade]
duk_push_heapptr(ctx, digestClientPtr); // [clientReqeust][OnUpgrade][digestClientRequest]
duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [clientReqeust][OnUpgrade]
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, "upgrade"); // [clientReqeust][EventDispatcher][eventName]
duk_put_prop_string(ctx, -2, CLIENTREQUEST_EVENT_NAME); // [clientReqeust][EventDispatcher]
ILibDuktape_EventEmitter_AddOnce(ILibDuktape_EventEmitter_GetEmitter(ctx, -2), "upgrade", 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, "error"); // [clientReqeust][EventDispatcher][eventName]
duk_put_prop_string(ctx, -2, CLIENTREQUEST_EVENT_NAME); // [clientReqeust][EventDispatcher]
ILibDuktape_EventEmitter_AddOnce(ILibDuktape_EventEmitter_GetEmitter(ctx, -2), "error", 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, "continue"); // [clientReqeust][EventDispatcher][eventName]
duk_put_prop_string(ctx, -2, CLIENTREQUEST_EVENT_NAME); // [clientReqeust][EventDispatcher]
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_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]
duk_push_heapptr(ctx, digestClientPtr); // [clientRequest][digestClientRequest]
duk_swap_top(ctx, -2); // [digestClientRequest][clientRequest]
duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [digestClientRequest]
}
return(0);
@@ -2397,17 +2650,78 @@ duk_ret_t ILibDuktape_httpDigest_digestRequest_end(duk_context *ctx)
int nargs = duk_get_top(ctx);
int i;
duk_push_this(ctx); // [digestClientRequest]
duk_get_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST); // [digestClientRequest][clientRequest]
duk_get_prop_string(ctx, -1, "end"); // [digestClientRequest][clientRequest][end]
duk_swap_top(ctx, -2); // [digestClientRequest][end][this]
for (i = 0; i < nargs; ++i)
if (duk_has_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST))
{
duk_dup(ctx, i); // [digestClientRequest][end][this][params...]
duk_get_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST); // [digestClientRequest][clientRequest]
duk_get_prop_string(ctx, -1, "end"); // [digestClientRequest][clientRequest][end]
duk_swap_top(ctx, -2); // [digestClientRequest][end][this]
for (i = 0; i < nargs; ++i)
{
duk_dup(ctx, i); // [digestClientRequest][end][this][params...]
}
if (duk_pcall_method(ctx, nargs) != 0) { duk_throw(ctx); return(DUK_RET_ERROR); }
duk_push_this(ctx);
duk_del_prop_string(ctx, -1, "DIGEST_CLIENT_REQUEST");
}
if (duk_pcall_method(ctx, nargs) != 0) { duk_throw(ctx); return(DUK_RET_ERROR); }
return(0);
}
ILibTransport_DoneState ILibDuktape_httpDigest_http_request_WriteHandler(struct ILibDuktape_WritableStream *stream, char *buffer, int bufferLen, void *user)
{
ILibTransport_DoneState retVal = ILibTransport_DoneState_ERROR;
duk_context *ctx = stream->ctx;
duk_push_heapptr(ctx, stream->obj); // [digestClientRequest]
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, "write"); // [digestClientRequest][clientRequest][write]
duk_swap_top(ctx, -2); // [digestClientRequest][write][this]
if (stream->Reserved == 0)
{
duk_push_external_buffer(ctx);
duk_config_buffer(ctx, -1, buffer, (duk_size_t)bufferLen);
}
else
{
duk_push_lstring(ctx, buffer, (duk_size_t)bufferLen);
}
if (duk_pcall_method(ctx, 1) != 0)
{
ILibDuktape_Process_UncaughtExceptionEx(ctx, "http-digest.clientRequest.write(): ");
retVal = ILibTransport_DoneState_ERROR;
}
else
{
retVal = duk_get_boolean(ctx, -1) ? ILibTransport_DoneState_COMPLETE : ILibTransport_DoneState_INCOMPLETE;
}
duk_pop(ctx); // [digestClientRequest]
}
duk_pop(ctx); // ...
return(retVal);
}
void ILibDuktape_httpDigest_http_request_DoneHandler(struct ILibDuktape_WritableStream *stream, void *user)
{
duk_context *ctx = stream->ctx;
duk_push_heapptr(ctx, stream->obj); // [digestClientRequest]
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, "end"); // [digestClientRequest][clientRequest][end]
duk_swap_top(ctx, -2); // [digestClientRequest][end][this]
if (duk_pcall_method(ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http-digest.clientRequest.end(): "); }
duk_pop(ctx); // [digestClientRequest]
duk_del_prop_string(ctx, -1, "DIGEST_CLIENT_REQUEST");
}
duk_pop(ctx); // ...
}
duk_ret_t ILibDuktape_httpDigest_http_request(duk_context *ctx)
{
int nargs = duk_get_top(ctx);
@@ -2449,7 +2763,9 @@ duk_ret_t ILibDuktape_httpDigest_http_request(duk_context *ctx)
ILibDuktape_EventEmitter_CreateEventEx(emitter, "response");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "error");
ILibDuktape_EventEmitter_CreateEventEx(emitter, "upgrade");
ILibDuktape_CreateInstanceMethod(ctx, "end", ILibDuktape_httpDigest_digestRequest_end, DUK_VARARGS);
ILibDuktape_EventEmitter_CreateEventEx(emitter, "continue");
ILibDuktape_WritableStream_Init(ctx, ILibDuktape_httpDigest_http_request_WriteHandler, ILibDuktape_httpDigest_http_request_DoneHandler, NULL);
if (nargs > 1 && duk_is_function(ctx, 1))
{
@@ -2462,12 +2778,36 @@ duk_ret_t ILibDuktape_httpDigest_http_request(duk_context *ctx)
if (duk_pcall_method(ctx, 2) != 0) { duk_throw(ctx); return(DUK_RET_ERROR); }
// [clientRequest]
duk_push_heapptr(emitter->ctx, emitter->object); // [digestClientRequest]
duk_push_c_function(ctx, ILibDuktape_httpDigest_clientRequest_onUpgrade, 3); // [digestClientRequest][OnUpgrade]
duk_dup(ctx, -2); // [digestClientRequest][OnUpgrade][digestClientRequest]
duk_put_prop_string(ctx, -2, DIGEST_CLIENT_REQUEST); // [digestClientRequest][OnUpgrade]
ILibDuktape_EventEmitter_AddOnce(crEmitter, "upgrade", duk_get_heapptr(ctx, -1));
duk_pop(ctx); // [digestClientRequest]
duk_push_heapptr(emitter->ctx, emitter->object); // [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, "upgrade"); // [digestClientRequest][EventDispatcher][eventName]
duk_put_prop_string(ctx, -2, CLIENTREQUEST_EVENT_NAME); // [digestClientRequest][EventDispatcher]
ILibDuktape_EventEmitter_AddOnce(crEmitter, "upgrade", 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, "error"); // [digestClientRequest][EventDispatcher][eventName]
duk_put_prop_string(ctx, -2, CLIENTREQUEST_EVENT_NAME); // [digestClientRequest][EventDispatcher]
ILibDuktape_EventEmitter_AddOnce(crEmitter, "error", 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, "continue"); // [digestClientRequest][EventDispatcher][eventName]
duk_put_prop_string(ctx, -2, CLIENTREQUEST_EVENT_NAME); // [digestClientRequest][EventDispatcher]
ILibDuktape_EventEmitter_AddOnce(crEmitter, "continue", 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]
ILibDuktape_EventEmitter_AddOn(crEmitter, "drain", duk_get_heapptr(ctx, -1)); // [digestClientRequest][onDrain]
duk_pop(ctx); // [digestClientRequest]
return(1);
}

View File

@@ -17,8 +17,6 @@
#define ILibDuktape_EventEmitter_Hook ((void*)0xEEEE)
#define ILibDuktape_EventEmitter_GlobalListenerCount "\xFF_EventEmitter_GlobalListenerCount"
void ILibDuktape_EventEmitter_ClearListenersSink(void *chain, void *eventList);
#ifdef __DOXY__
@@ -94,7 +92,14 @@ public:
};
#endif
ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_GetEmitter_fromObject(duk_context *ctx, void *objHeapptr)
{
ILibDuktape_EventEmitter *retVal = NULL;
duk_push_heapptr(ctx, objHeapptr); // [obj]
retVal = ILibDuktape_EventEmitter_GetEmitter(ctx, -1);
duk_pop(ctx); // ...
return(retVal);
}
void ILibDuktape_EventEmitter_FinalizerEx(ILibHashtable sender, void *Key1, char* Key2, int Key2Len, void *Data, void *user)
{
ILibDuktape_EventEmitter *data = (ILibDuktape_EventEmitter*)user;
@@ -166,8 +171,9 @@ duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
int nargs = duk_get_top(ctx);
ILibDuktape_EventEmitter *data;
void *node, *nextNode, *func, *dispatcher;
int i, count;
int i, j, count;
void **hptr;
void **emitList;
duk_push_this(ctx);
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_TempObject); // [this][tmp]
@@ -183,17 +189,19 @@ duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
dispatcher = ILibHashtable_Get(data->eventTable, ILibDuktape_EventEmitter_SetterFunc, name, (int)nameLen);
if (dispatcher == NULL) { return ILibDuktape_Error(ctx, "EventEmitter.emit(): Internal Error with event '%s'", name); }
// Copy the list, so we can enumerate with local memory, so the list can be manipulated while we are dispatching
#ifdef WIN32
emitList = (void**)_alloca(((unsigned int)ILibLinkedList_GetCount(eventList) + 1) * sizeof(void*));
#else
emitList = (void**)alloca(((unsigned int)ILibLinkedList_GetCount(eventList) + 1) * sizeof(void*));
#endif
node = ILibLinkedList_GetNode_Head(eventList);
i = 0;
while (node != NULL)
{
nextNode = ILibLinkedList_GetNextNode(node);
func = ILibLinkedList_GetDataFromNode(node);
duk_push_heapptr(ctx, func); // [func]
duk_push_heapptr(ctx, self); // [func][this]
for (i = 1; i < nargs; ++i)
{
duk_dup(ctx, i); // [func][this][...args...]
}
emitList[i++] = ILibLinkedList_GetDataFromNode(node);
if (((int*)ILibLinkedList_GetExtendedMemory(node))[0] == 1)
{
@@ -201,15 +209,11 @@ duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
ILibLinkedList_Remove(node);
data->totalListeners[0]--;
}
if (duk_pcall_method(ctx, nargs-1) != 0)
{
return(ILibDuktape_Error(ctx, "EventEmitter.emit(): Event dispatch for '%s' threw an exception: %s", name, duk_safe_to_string(ctx, -1)));
}
duk_pop(ctx); // ...
node = nextNode;
}
emitList[i] = NULL;
// If no more listeners, we can set the hptr to NULL
if (ILibLinkedList_GetCount(eventList) == 0)
{
duk_push_heapptr(ctx, dispatcher); // [dispatcher]
@@ -224,6 +228,24 @@ duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
}
duk_pop_2(ctx); // ...
}
// Now that we have all the housekeeping stuff out of the way, we can actually dispatch our events
i = 0;
while ((func = emitList[i++]) != NULL)
{
duk_push_heapptr(ctx, func); // [func]
duk_push_heapptr(ctx, self); // [func][this]
for (j = 1; j < nargs; ++j)
{
duk_dup(ctx, j); // [func][this][...args...]
}
if (duk_pcall_method(ctx, nargs - 1) != 0)
{
return(ILibDuktape_Error(ctx, "EventEmitter.emit(): Event dispatch for '%s' threw an exception: %s", name, duk_safe_to_string(ctx, -1)));
}
duk_pop(ctx); // ...
}
return 0;
}
int ILibDuktape_EventEmitter_AddOnce(ILibDuktape_EventEmitter *emitter, char *eventName, void *heapptr)
@@ -272,7 +294,10 @@ duk_ret_t ILibDuktape_EventEmitter_on(duk_context *ctx)
data = (ILibDuktape_EventEmitter*)Duktape_GetBuffer(ctx, -1, NULL);
eventList = ILibHashtable_Get(data->eventTable, NULL, propName, (int)propNameLen);
if (eventList == NULL) { return(ILibDuktape_Error(ctx, "EventEmitter.on(): Event '%s' not found", propName)); }
if (eventList == NULL)
{
return(ILibDuktape_Error(ctx, "EventEmitter.on(): Event '%s' not found", propName));
}
dispatcher = ILibHashtable_Get(data->eventTable, ILibDuktape_EventEmitter_SetterFunc, propName, (int)propNameLen);
if (dispatcher == NULL) { return(ILibDuktape_Error(ctx, "EventEmitter.on(): Internal error with Event '%s'", propName)); }
@@ -371,8 +396,7 @@ duk_ret_t ILibDuktape_EventEmitter_removeAllListeners(duk_context *ctx)
duk_pop(ctx); // [dispatcher][hptrList]
}
//Use this callback, just in case we were called from an event dispatch. Don't want to clear it during a dispatch, cause we'll crash
ILibChain_RunOnMicrostackThreadEx(Duktape_GetChain(ctx), ILibDuktape_EventEmitter_ClearListenersSink, eventList);
ILibLinkedList_Clear(eventList);
emitter->totalListeners[0] = 0;
}
return(0);
@@ -429,15 +453,12 @@ ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx)
return retVal;
}
void ILibDuktape_EventEmitter_ClearListenersSink(void *chain, void *eventList)
{
ILibLinkedList_Clear(eventList);
}
void ILibDuktape_EventEmitter_AddHook(ILibDuktape_EventEmitter *emitter, char *eventName, ILibDuktape_EventEmitter_HookHandler handler)
{
if (ILibHashtable_Get(emitter->eventTable, ILibDuktape_EventEmitter_Hook, eventName, strnlen_s(eventName, 255)) == NULL && handler != NULL)
if (ILibHashtable_Get(emitter->eventTable, ILibDuktape_EventEmitter_Hook, eventName, (int)strnlen_s(eventName, 255)) == NULL && handler != NULL)
{
ILibHashtable_Put(emitter->eventTable, ILibDuktape_EventEmitter_Hook, eventName, strnlen_s(eventName, 255), handler);
ILibHashtable_Put(emitter->eventTable, ILibDuktape_EventEmitter_Hook, eventName, (int)strnlen_s(eventName, 255), handler);
}
}
duk_ret_t ILibDuktape_EventEmitter_SetEvent(duk_context *ctx)
@@ -479,8 +500,7 @@ duk_ret_t ILibDuktape_EventEmitter_SetEvent(duk_context *ctx)
duk_pop(ctx); // [dispatcher][hptrList]
}
//Use this callback, just in case we were called from an event dispatch. Don't want to clear it during a dispatch
ILibChain_RunOnMicrostackThread(Duktape_GetChain(ctx), ILibDuktape_EventEmitter_ClearListenersSink, eventList);
ILibLinkedList_Clear(eventList);
}
else
{
@@ -629,7 +649,7 @@ void ILibDuktape_EventEmitter_RemoveEventHeapptr(ILibDuktape_EventEmitter *emitt
if (heapptr != NULL)
{
duk_get_prop_string(emitter->ctx, -1, ILibDuktape_EventEmitter_HPTR_LIST); // [dispatcher][hptrList]
count = duk_get_length(emitter->ctx, -1);
count = (int)duk_get_length(emitter->ctx, -1);
for (i = 0; i < count; ++i)
{
duk_get_prop_index(emitter->ctx, -1, i); // [dispatcher][hptrList][hptr]