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:
285
microscript/ILibDuktape_ChildProcess.c
Normal file
285
microscript/ILibDuktape_ChildProcess.c
Normal 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
|
||||
9
microscript/ILibDuktape_ChildProcess.h
Normal file
9
microscript/ILibDuktape_ChildProcess.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef __ILIBDUKTAPE_CHILDPROCESS__
|
||||
#define __ILIBDUKTAPE_CHILDPROCESS__
|
||||
|
||||
#include "duktape.h"
|
||||
|
||||
void ILibDuktape_ChildProcess_Init(duk_context *ctx);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -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);
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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); }
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user