mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-06 00:13:33 +00:00
1. Fixed Compiler Warnings
2. Updated GC behavior for HTTP
This commit is contained in:
@@ -77,6 +77,7 @@ int ILibDuktape_EventEmitter_AddOnEx(duk_context *ctx, duk_idx_t idx, char *even
|
||||
void ILibDuktape_EventEmitter_AddHook(ILibDuktape_EventEmitter *emitter, char *eventName, ILibDuktape_EventEmitter_HookHandler handler);
|
||||
void ILibDuktape_EventEmitter_ClearHook(ILibDuktape_EventEmitter *emitter, char *eventName);
|
||||
|
||||
int ILibDuktape_EventEmitter_ForwardEventEx(duk_context *ctx, duk_idx_t sourceIdx, duk_idx_t targetIdx, char *eventName);
|
||||
void ILibDuktape_EventEmitter_ForwardEvent(duk_context *ctx, duk_idx_t eventSourceIndex, char *sourceEventName, duk_idx_t eventTargetIndex, char *targetEventName);
|
||||
void ILibDuktape_EventEmitter_DeleteForwardEvent(duk_context *ctx, duk_idx_t eventSourceIndex, char *sourceEventName);
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
Unless required by applicable law or agreed to in writing, software2
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
@@ -38,6 +38,7 @@ struct ILibWebClientDataObject;
|
||||
extern int ILibWebServer_WebSocket_CreateHeader(char* header, unsigned short FLAGS, unsigned short OPCODE, int payloadLength);
|
||||
extern void ILibWebClient_ResetWCDO(struct ILibWebClientDataObject *wcdo);
|
||||
extern int ILibDeflate(char *buffer, size_t bufferLen, char *compressed, size_t *compressedLen, uint32_t *crc);
|
||||
void ILibDuktape_RemoveObjFromTable(duk_context *ctx, duk_idx_t tableIdx, char *key, void *obj);
|
||||
|
||||
#define ILibDuktape_Agent_SocketJustCreated "\xFF_Agent_SocketJustCreated"
|
||||
#define ILibDuktape_ClientRequest "\xFF_CR"
|
||||
@@ -59,14 +60,13 @@ extern int ILibDeflate(char *buffer, size_t bufferLen, char *compressed, size_t
|
||||
#define ILibDuktape_HTTP2PipedWritable "\xFF_HTTP2PipedWritable"
|
||||
#define ILibDuktape_HTTPStream2Data "\xFF_HTTPStream2Data"
|
||||
#define ILibDuktape_HTTPStream2HTTP "\xFF_HTTPStream2HTTP"
|
||||
#define ILibDuktape_HTTPStream2IMSG "\xFF_HTTPStream2IMSG"
|
||||
//#define ILibDuktape_HTTPStream2IMSG "\xFF_HTTPStream2IMSG"
|
||||
#define ILibDuktape_HTTPStream2Socket "\xFF_HTTPStream2Socket"
|
||||
#define ILibDuktape_IMSG2HttpStream "\xFF_IMSG2HttpStream"
|
||||
#define ILibDuktape_IMSG2Ptr "\xFF_IMSG2Ptr"
|
||||
#define ILibDuktape_IMSG2SR "\xFF_IMSG2ServerResponse"
|
||||
#define ILibDuktape_NS2HttpServer "\xFF_Http_NetServer2HttpServer"
|
||||
#define ILibDuktape_Options2ClientRequest "\xFF_Options2ClientRequest"
|
||||
#define ILibDuktape_PipedReadable "\xFF_PipedReadable"
|
||||
#define ILibDuktape_Socket2AgentStash "\xFF_Socket2AgentStash"
|
||||
#define ILibDuktape_Socket2Agent "\xFF_Socket2Agent"
|
||||
#define ILibDuktape_Socket2AgentKey "\xFF_Socket2AgentKey"
|
||||
@@ -627,8 +627,23 @@ duk_ret_t ILibDuktape_HttpStream_http_onUpgrade(duk_context *ctx)
|
||||
duk_push_null(ctx); // [HTTPStream][websocket][emit][this][upgrade][imsg][WS_DEC][null]
|
||||
duk_call_method(ctx, 4); duk_pop(ctx); // [HTTPStream][websocket]
|
||||
|
||||
if (duk_has_prop_string(ctx, -1, ILibDuktape_WS2CR))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_WS2CR); // [HTTPStream][websocket][request]
|
||||
duk_prepare_method_call(ctx, -1, "removeAllListeners"); // [HTTPStream][websocket][request][removeAll][this]
|
||||
duk_call_method(ctx, 0); duk_pop_2(ctx); // [HTTPStream][websocket]
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_findAgentRequestSink(duk_context *ctx)
|
||||
{
|
||||
duk_push_current_function(ctx); // [func]
|
||||
duk_dup(ctx, 0); // [func][elem]
|
||||
duk_get_prop_string(ctx, -2, "request");// [func][elem][request]
|
||||
duk_push_boolean(ctx, duk_equals(ctx, -2, -1));
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_http_endResponseSink(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx); // [imsg]
|
||||
@@ -648,16 +663,28 @@ duk_ret_t ILibDuktape_HttpStream_http_endResponseSink(duk_context *ctx)
|
||||
|
||||
duk_get_prop_string(ctx, -1, "socket"); // [imsg][httpstream][CR][socket]
|
||||
duk_insert(ctx, -4); // [socket][imsg][httpstream][CR]
|
||||
duk_push_undefined(ctx); // [socket][imsg][httpstream][CR][undefined]
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "socket"); // [socket][imsg][httpstream][CR]
|
||||
|
||||
ILibDuktape_DeleteReadOnlyProperty(ctx, -1, "socket");
|
||||
ILibDuktape_DeleteReadOnlyProperty(ctx, -2, ILibDuktape_HTTPStream2Socket);
|
||||
ILibDuktape_DeleteReadOnlyProperty(ctx, -4, ILibDuktape_Socket2HttpStream);
|
||||
duk_del_prop_string(ctx, -2, ILibDuktape_HTTP2PipedReadable);
|
||||
|
||||
duk_prepare_method_call(ctx, -1, "removeAllListeners"); // [socket][imsg][httpstream][CR][remove][this]
|
||||
duk_pcall_method(ctx, 0); duk_pop(ctx); // [socket][imsg][httpstream][CR]
|
||||
|
||||
if (Duktape_GetBooleanProperty(ctx, -2, "connectionCloseSpecified", 0) != 0)
|
||||
{
|
||||
// We cant persist this connection, so close the socket.
|
||||
// Agent is already listening for the 'close' event, so it'll cleanup automatically
|
||||
duk_prepare_method_call(ctx, -2, "unpipe"); // [socket][imsg][httpstream][CR][unpipe][this]
|
||||
duk_pcall_method(ctx, 0); duk_pop(ctx); // [socket][imsg][httpstream][CR]
|
||||
duk_prepare_method_call(ctx, -4, "unpipe"); // [socket][imsg][httpstream][CR][unpipe][this]
|
||||
duk_pcall_method(ctx, 0); duk_pop(ctx); // [socket][imsg][httpstream][CR]
|
||||
|
||||
duk_dup(ctx, -4); // [socket][imsg][httpstream][CR][socket]
|
||||
duk_get_prop_string(ctx, -1, "end"); // [socket][imsg][httpstream][CR][socket][end]
|
||||
duk_swap_top(ctx, -2); // [socket][imsg][httpstream][CR][end][this]
|
||||
duk_call_method(ctx, 0);
|
||||
duk_call_method(ctx, 0); duk_pop(ctx); // [socket][imsg][httpstream][CR]
|
||||
return(0);
|
||||
}
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_CR2Agent); // [socket][imsg][httpstream][CR][Agent]
|
||||
@@ -756,15 +783,14 @@ duk_ret_t ILibDuktape_HttpStream_http_SocketResponseReceived(duk_context *ctx)
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_Socket2CR); // [httpStream][socket][CR]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_CR2Options); // [httpStream][socket][CR][Options]
|
||||
duk_del_prop_string(ctx, -1, ILibDuktape_Options2ClientRequest);
|
||||
|
||||
duk_pop_2(ctx); // [httpStream][socket]
|
||||
duk_del_prop_string(ctx, -1, ILibDuktape_Socket2CR);
|
||||
|
||||
duk_get_prop_string(ctx, -1, "removeListener"); // [httpStream][socket][removeListener]
|
||||
duk_swap_top(ctx, -2); // [httpStream][removeListener][this]
|
||||
duk_push_string(ctx, "close"); // [httpStream][removeListener][this][close]
|
||||
duk_get_prop_string(ctx, -2, ILibDuktape_Socket2DiedListener); // [httpStream][removeListener][this][close][listener]
|
||||
duk_call_method(ctx, 2);
|
||||
//duk_get_prop_string(ctx, -1, "removeListener"); // [httpStream][socket][removeListener]
|
||||
//duk_swap_top(ctx, -2); // [httpStream][removeListener][this]
|
||||
//duk_push_string(ctx, "close"); // [httpStream][removeListener][this][close]
|
||||
//duk_get_prop_string(ctx, -2, ILibDuktape_Socket2DiedListener); // [httpStream][removeListener][this][close][listener]
|
||||
//duk_call_method(ctx, 2);
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_http_OnSocketClosed(duk_context *ctx)
|
||||
@@ -772,6 +798,9 @@ duk_ret_t ILibDuktape_HttpStream_http_OnSocketClosed(duk_context *ctx)
|
||||
duk_push_this(ctx); // [socket]
|
||||
if (duk_has_prop_string(ctx, -1, ILibDuktape_Socket2HttpStream))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_Socket2HttpStream);
|
||||
printf(" REMOVING reference to HttpStream: %s\n", Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_EventEmitter_FinalizerDebugMessage, ""));
|
||||
duk_pop(ctx);
|
||||
duk_del_prop_string(ctx, -1, ILibDuktape_Socket2HttpStream);
|
||||
}
|
||||
duk_pop(ctx); // ...
|
||||
@@ -783,10 +812,10 @@ duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
|
||||
void *httpStream;
|
||||
|
||||
duk_dup(ctx, 0); // [socket]
|
||||
duk_push_string(ctx, "client"); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_FinalizerDebugMessage);
|
||||
duk_push_c_function(ctx, ILibDuktape_HttpStream_http_SocketDiedPrematurely, DUK_VARARGS);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Socket2DiedListener); // [socket]
|
||||
duk_push_this(ctx); // [socket][clientRequest]
|
||||
|
||||
if (Duktape_GetBooleanProperty(ctx, -1, ILibDuktape_CR_AbortCalled, 0))
|
||||
{
|
||||
// We were aborted, so instead of continuing, lets just put the socket back, so someone else can use it
|
||||
@@ -814,7 +843,6 @@ duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
|
||||
duk_call_method(ctx, 2); duk_pop(ctx); // [socket][clientRequest]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Socket2CR); // [socket]
|
||||
duk_push_this(ctx); // [socket][clientRequest]
|
||||
|
||||
if (duk_has_prop_string(ctx, -2, ILibDuktape_Socket2HttpStream))
|
||||
{
|
||||
// HTTP and/or TLS was already setup previously
|
||||
@@ -850,8 +878,9 @@ duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
|
||||
|
||||
ILibDuktape_EventEmitter_ForwardEvent(ctx, -1, "response", -2, "response");
|
||||
ILibDuktape_EventEmitter_ForwardEvent(ctx, -1, "continue", -2, "continue");
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "upgrade", ILibDuktape_HttpStream_http_onUpgrade);
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "response", ILibDuktape_HttpStream_http_responseSink);
|
||||
|
||||
ILibDuktape_EventEmitter_AddOn_Infrastructure(ctx, -1, "upgrade", ILibDuktape_HttpStream_http_onUpgrade);
|
||||
ILibDuktape_EventEmitter_AddOn_Infrastructure(ctx, -1, "response", ILibDuktape_HttpStream_http_responseSink);
|
||||
|
||||
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_HTTP2PipedWritable); // [socket][clientRequest][HTTPStream][destination]
|
||||
@@ -880,6 +909,7 @@ duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
|
||||
}
|
||||
|
||||
httpStream = duk_get_heapptr(ctx, -1); // [socket][clientRequest][httpStream]
|
||||
duk_push_string(ctx, "client"); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_FinalizerDebugMessage);
|
||||
duk_dup(ctx, -3); // [socket][clientRequest][httpStream][socket]
|
||||
duk_dup(ctx, -2); // [socket][clientRequest][httpStream][socket][httpStream]
|
||||
if (strcmp(Duktape_GetStringPropertyValue(ctx, -2, ILibDuktape_OBJID, "net.socket"), "tls.socket") == 0) { ILibDuktape_WriteID(ctx, "https.httpStream"); }
|
||||
@@ -887,10 +917,10 @@ duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
|
||||
duk_pop(ctx); // [socket][clientRequest][httpStream]
|
||||
duk_dup(ctx, -2); // [socket][clientRequest][httpStream][clientRequest]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_HTTP2CR); // [socket][clientRequest][httpStream]
|
||||
ILibDuktape_EventEmitter_ForwardEvent(ctx, -1, "response", -2, "response");
|
||||
ILibDuktape_EventEmitter_ForwardEvent(ctx, -1, "continue", -2, "continue");
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "upgrade", ILibDuktape_HttpStream_http_onUpgrade);
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "response", ILibDuktape_HttpStream_http_responseSink);
|
||||
ILibDuktape_EventEmitter_ForwardEventEx(ctx, -1, -2, "response");
|
||||
ILibDuktape_EventEmitter_ForwardEventEx(ctx, -1, -2, "continue");
|
||||
ILibDuktape_EventEmitter_AddOn_Infrastructure(ctx, -1, "upgrade", ILibDuktape_HttpStream_http_onUpgrade);
|
||||
ILibDuktape_EventEmitter_AddOn_Infrastructure(ctx, -1, "response", ILibDuktape_HttpStream_http_responseSink);
|
||||
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -1, "write", ILibDuktape_HttpStream_http_SocketResponseReceived);
|
||||
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -3, "close", ILibDuktape_HttpStream_http_OnSocketClosed); // We need to detach HttpStream when socket closes
|
||||
|
||||
@@ -898,7 +928,7 @@ duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_CR2Options); // [socket][clientRequest][options]
|
||||
ILibDuktape_HttpStream_http_ConvertOptionToSend(ctx, duk_get_heapptr(ctx, -3), duk_get_heapptr(ctx, -1));
|
||||
duk_pop(ctx); // [socket][clientRequest]
|
||||
|
||||
|
||||
// ClientRequest => Socket
|
||||
duk_get_prop_string(ctx, -1, "pipe"); // [socket][clientRequest][pipe]
|
||||
duk_swap_top(ctx, -2); // [socket][pipe][this]
|
||||
@@ -913,7 +943,6 @@ duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
|
||||
duk_dup(ctx, -2); // [socket][httpStream][socket]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2Socket); // [socket][httpStream]
|
||||
duk_pop(ctx); // [socket]
|
||||
|
||||
// Socket => HttpStream
|
||||
duk_get_prop_string(ctx, -1, "pipe"); // [socket][pipe]
|
||||
duk_dup(ctx, -2); // [socket][pipe][this]
|
||||
@@ -923,6 +952,7 @@ duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
|
||||
|
||||
// HttpStream => Socket
|
||||
duk_push_heapptr(ctx, httpStream); // [socket][http]
|
||||
|
||||
duk_get_prop_string(ctx, -1, "pipe"); // [socket][http][pipe]
|
||||
duk_swap_top(ctx, -2); // [socket][pipe][this]
|
||||
duk_dup(ctx, -3); // [socket][pipe][this][socket]
|
||||
@@ -933,6 +963,7 @@ duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
|
||||
duk_ret_t ILibDuktape_HttpStream_http_OnConnectError(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx); // [socket]
|
||||
|
||||
if (duk_has_prop_string(ctx, -1, ILibDuktape_Socket2CR))
|
||||
{
|
||||
// Socket was created via 'createConnection' specified by the application
|
||||
@@ -1028,12 +1059,61 @@ duk_ret_t ILibDuktape_HttpStream_http_OnConnectError(duk_context *ctx)
|
||||
// }
|
||||
// return(0);
|
||||
//}
|
||||
duk_ret_t ILibDuktape_Agent_findConnection(duk_context *ctx)
|
||||
{
|
||||
duk_push_current_function(ctx); // [func]
|
||||
duk_get_prop_string(ctx, -1, "socket"); // [func][socket]
|
||||
duk_dup(ctx, 0); // [func][socket][socket]
|
||||
if (duk_equals(ctx, -2, -1))
|
||||
{
|
||||
duk_push_true(ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_false(ctx);
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Agent_connectionEnded(duk_context *ctx)
|
||||
{
|
||||
duk_idx_t top;
|
||||
duk_push_this(ctx); // [socket]
|
||||
duk_prepare_method_call(ctx, -1, "removeAllListeners"); // [socket][remove][this]
|
||||
duk_call_method(ctx, 0); duk_pop(ctx); // [socket]
|
||||
|
||||
char *key = (char*)Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_Socket2AgentKey, NULL);
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_Socket2Agent); // [socket][agent]
|
||||
top = duk_get_top(ctx);
|
||||
duk_get_prop_string(ctx, -1, "sockets"); // [socket][agent][table]
|
||||
duk_get_prop_string(ctx, -1, key); // [socket][agent][table][array]
|
||||
if (duk_is_array(ctx, -1))
|
||||
{
|
||||
duk_push_c_function(ctx, ILibDuktape_Agent_findConnection, DUK_VARARGS); //array][func]
|
||||
duk_prepare_method_call(ctx, -2, "findIndex"); // [socket][agent][table][array][func][findIndex][this]
|
||||
duk_dup(ctx, -3); // [socket][agent][table][array][func][findIndex][this][func]
|
||||
duk_push_this(ctx); // [socket][agent][table][array][func][findIndex][this][func][socket]
|
||||
duk_put_prop_string(ctx, -2, "socket"); // [socket][agent][table][array][func][findIndex][this][func]
|
||||
duk_call_method(ctx, 1); // [socket][agent][table][array][func][int]
|
||||
duk_del_prop_string(ctx, -2, "socket");
|
||||
if (duk_get_int(ctx, -1) >= 0)
|
||||
{
|
||||
duk_prepare_method_call(ctx, -3, "splice"); // [socket][agent][table][array][func][int][splice][this]
|
||||
duk_dup(ctx, -3); // [socket][agent][table][array][func][int][splice][this][index]
|
||||
duk_push_int(ctx, 1); // [socket][agent][table][array][func][int][splice][this][index][i]
|
||||
duk_call_method(ctx, 2); duk_pop(ctx); // [socket][agent][table][array][func][int]
|
||||
}
|
||||
}
|
||||
|
||||
duk_set_top(ctx, top); // [socket][agent]
|
||||
duk_get_prop_string(ctx, -1, "freeSockets"); // [socket][agent][table]
|
||||
ILibDuktape_RemoveObjFromTable(ctx, -1, key, duk_get_heapptr(ctx, -3));
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_http_OnConnect(duk_context *ctx)
|
||||
{
|
||||
duk_ret_t retVal = 0;
|
||||
duk_push_this(ctx); // [socket]
|
||||
|
||||
if (duk_has_prop_string(ctx, -1, ILibDuktape_Socket2CR))
|
||||
{
|
||||
// Socket was created with passed in createConnection
|
||||
@@ -1052,15 +1132,8 @@ duk_ret_t ILibDuktape_HttpStream_http_OnConnect(duk_context *ctx)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add socket to agent.Sockets
|
||||
char *key = (char*)Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_Socket2AgentKey, NULL);
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_Socket2Agent); // [socket][agent]
|
||||
duk_get_prop_string(ctx, -1, "sockets"); // [socket][agent][table]
|
||||
if (!duk_has_prop_string(ctx, -1, key)) { duk_push_array(ctx); duk_put_prop_string(ctx, -2, key); }
|
||||
duk_get_prop_string(ctx, -1, key); // [socket][agent][table][array]
|
||||
duk_dup(ctx, -4); // [socket][agent][table][array][socket]
|
||||
duk_array_push(ctx, -2); // [socket][agent][table][array]
|
||||
duk_pop_2(ctx); // [socket][agent]
|
||||
ILibDuktape_EventEmitter_AddOn_Infrastructure(ctx, -2, "end", ILibDuktape_Agent_connectionEnded);
|
||||
|
||||
duk_get_prop_string(ctx, -1, "keepSocketAlive"); // [socket][agent][keepSocketAlive]
|
||||
duk_swap_top(ctx, -2); // [socket][keepSocketAlive][this]
|
||||
@@ -1168,6 +1241,7 @@ duk_ret_t ILibDuktape_ClientRequest_Finalizer(duk_context *ctx)
|
||||
data->buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -1277,6 +1351,7 @@ duk_ret_t ILibDuktape_HttpStream_http_request(duk_context *ctx)
|
||||
|
||||
duk_dup(ctx, 0); // [options]
|
||||
duk_push_object(ctx); // [options][clientRequest]
|
||||
|
||||
duk_dup(ctx, -1); // [options][clientRequest][dup]
|
||||
duk_put_prop_string(ctx, -3, ILibDuktape_Options2ClientRequest);// [options][clientRequest]
|
||||
duk_remove(ctx, -2); // [clientRequest]
|
||||
@@ -1303,11 +1378,11 @@ duk_ret_t ILibDuktape_HttpStream_http_request(duk_context *ctx)
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "timeout");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "upgrade");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "error");
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "socket", ILibDuktape_HttpStream_http_OnSocketReady);
|
||||
|
||||
ILibDuktape_EventEmitter_AddOn_Infrastructure(ctx, -1, "socket", ILibDuktape_HttpStream_http_OnSocketReady);
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "~", ILibDuktape_ClientRequest_Finalizer);
|
||||
ILibDuktape_CreateProperty_InstanceMethod(ctx, "abort", ILibDuktape_HttpStream_http_request_abort, 0);
|
||||
|
||||
|
||||
if (nargs > 1 && duk_is_function(ctx, 1))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, "once"); // [clientRequest][once]
|
||||
@@ -1547,7 +1622,11 @@ duk_ret_t ILibDuktape_HttpStream_http_server_upgradeWebsocket(duk_context *ctx)
|
||||
SHA_CTX c;
|
||||
char shavalue[21];
|
||||
|
||||
duk_push_this(ctx); // [socket]
|
||||
duk_push_this(ctx); // [socket]
|
||||
duk_get_prop_string(ctx, -1, "Digest_writeUnauthorized"); // [socket][func]
|
||||
duk_del_prop_string(ctx, -1, "imsg");
|
||||
duk_pop(ctx); // [socket]
|
||||
|
||||
duk_push_current_function(ctx); // [socket][func]
|
||||
duk_get_prop_string(ctx, -2, "unpipe"); // [socket][func][unpipe]
|
||||
duk_dup(ctx, -3); // [socket][func][unpipe][this]
|
||||
@@ -1556,6 +1635,7 @@ duk_ret_t ILibDuktape_HttpStream_http_server_upgradeWebsocket(duk_context *ctx)
|
||||
duk_get_prop_string(ctx, -1, "imsg"); // [socket][func][imsg]
|
||||
duk_get_prop_string(ctx, -1, "headers"); // [socket][func][imsg][headers]
|
||||
duk_get_prop_string(ctx, -1, "Sec-WebSocket-Key"); // [socket][func][imsg][headers][key]
|
||||
duk_del_prop_string(ctx, -4, "imsg");
|
||||
|
||||
key = (char*)Duktape_GetBuffer(ctx, -1, &keyLen);
|
||||
keyResult = ILibString_Cat(key, (int)keyLen, wsguid, sizeof(wsguid));
|
||||
@@ -1648,17 +1728,6 @@ duk_ret_t ILibDuktape_HttpStream_http_server_onUpgrade(duk_context *ctx)
|
||||
duk_call_method(ctx, 4); duk_pop(ctx); // [HS]
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_http_server_onConnection_TLSConnect(duk_context *ctx)
|
||||
{
|
||||
//duk_get_prop_string(ctx, -1, ILibDuktape_NS2HttpServer); // [NS][HS]
|
||||
//duk_get_prop_string(ctx, -1, "emit"); // [NS][HS][emit]
|
||||
//duk_swap_top(ctx, -2); // [NS][emit][this]
|
||||
//duk_push_string(ctx, "connection"); // [NS][emit][this][connection]
|
||||
//duk_dup(ctx, 0); // [NS][emit][this][connection][socket]
|
||||
//if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.server.onConnection() => Error dispatching connection event "); }
|
||||
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_http_server_onConnectionTimeout(duk_context *ctx)
|
||||
{
|
||||
void *cb = NULL;
|
||||
@@ -1725,25 +1794,36 @@ duk_ret_t ILibDuktape_HttpStream_http_server_onConnection(duk_context *ctx)
|
||||
|
||||
// Pipe: Socket => HttpStream
|
||||
duk_dup(ctx, 0); // [NS][socket]
|
||||
duk_push_string(ctx, "server"); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_FinalizerDebugMessage);
|
||||
duk_get_prop_string(ctx, -1, "pipe"); // [NS][socket][pipe]
|
||||
duk_dup(ctx, -2); // [NS][socket][pipe][this]
|
||||
|
||||
duk_eval_string(ctx, "require('http').createStream(true);"); // [NS][socket][pipe][this][httpStream]
|
||||
duk_push_string(ctx, "server"); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_FinalizerDebugMessage);
|
||||
duk_get_prop_string(ctx, -5, ILibDuktape_NS2HttpServer); // [NS][socket][pipe][this][httpStream][httpServer]
|
||||
duk_dup(ctx, -1); // [NS][socket][pipe][this][httpStream][httpServer][dup]
|
||||
duk_put_prop_string(ctx, -3, ILibduktape_HttpStream2HttpServer); // [NS][socket][pipe][this][httpStream][httpServer]
|
||||
ILibDuktape_EventEmitter_ForwardEvent(ctx, -2, "checkContinue", -1, "checkContinue");
|
||||
ILibDuktape_EventEmitter_ForwardEvent(ctx, -2, "checkExpectation", -1, "checkExpectation");
|
||||
ILibDuktape_EventEmitter_ForwardEvent(ctx, -2, "clientError", -1, "clientError");
|
||||
ILibDuktape_EventEmitter_ForwardEventEx(ctx, -2, -1, "checkContinue");
|
||||
ILibDuktape_EventEmitter_ForwardEventEx(ctx, -2, -1, "checkExpectation");
|
||||
ILibDuktape_EventEmitter_ForwardEventEx(ctx, -2, -1, "clientError");
|
||||
//ILibDuktape_EventEmitter_ForwardEvent(ctx, -2, "close", -1, "close");
|
||||
ILibDuktape_EventEmitter_ForwardEvent(ctx, -2, "connect", -1, "connect");
|
||||
ILibDuktape_EventEmitter_ForwardEvent(ctx, -2, "request", -1, "request");
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -2, "parseError", ILibDuktape_HttpStream_http_parseError);
|
||||
ILibDuktape_EventEmitter_ForwardEventEx(ctx, -2, -1, "connect");
|
||||
ILibDuktape_EventEmitter_ForwardEventEx(ctx, -2, -1, "request");
|
||||
|
||||
//ILibDuktape_EventEmitter_ForwardEvent(ctx, -2, "connect", -1, "connect");
|
||||
//ILibDuktape_EventEmitter_ForwardEvent(ctx, -2, "request", -1, "request");
|
||||
ILibDuktape_EventEmitter_AddOn_Infrastructure(ctx, -2, "parseError", ILibDuktape_HttpStream_http_parseError);
|
||||
|
||||
|
||||
if (ILibDuktape_EventEmitter_HasListenersEx(ctx, -1, "upgrade") > 0)
|
||||
{
|
||||
ILibDuktape_EventEmitter_AddOn_Infrastructure(ctx, -2, "upgrade", ILibDuktape_HttpStream_http_server_onUpgrade);
|
||||
}
|
||||
|
||||
if (ILibDuktape_EventEmitter_HasListenersEx(ctx, -1, "upgrade") > 0) { ILibDuktape_EventEmitter_AddOnceEx3(ctx, -2, "upgrade", ILibDuktape_HttpStream_http_server_onUpgrade); }
|
||||
|
||||
duk_pop(ctx); // [NS][socket][pipe][this][httpStream]
|
||||
duk_call_method(ctx, 1); duk_pop_2(ctx); // [NS]
|
||||
duk_call_method(ctx, 1); duk_pop(ctx); // [NS][socket]
|
||||
|
||||
duk_pop(ctx); // [NS]
|
||||
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_NS2HttpServer); // [NS][HS]
|
||||
duk_get_prop_string(ctx, -1, "emit"); // [NS][HS][emit]
|
||||
@@ -2715,6 +2795,12 @@ duk_ret_t ILibDuktape_HttpStream_ServerResponse_writeContinue(duk_context *ctx)
|
||||
duk_call_method(ctx, 2);
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_ServerResponse_Finalizer(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx);
|
||||
duk_del_prop_string(ctx, -1, ILibDuktape_SR2HttpStream);
|
||||
return(0);
|
||||
}
|
||||
void ILibDuktape_HttpStream_ServerResponse_PUSH(duk_context *ctx, void* writeStream, ILibHTTPPacket *header, void *httpStream)
|
||||
{
|
||||
ILibDuktape_HttpStream_ServerResponse_State *state;
|
||||
@@ -2760,6 +2846,8 @@ void ILibDuktape_HttpStream_ServerResponse_PUSH(duk_context *ctx, void* writeStr
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "setHeader", ILibDuktape_HttpStream_ServerResponse_setHeader, 2);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "removeHeader", ILibDuktape_HttpStream_ServerResponse_removeHeader, 1);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "Digest_writeUnauthorized", ILibDuktape_HttpStream_ServerResponse_Digest_SendUnauthorized, DUK_VARARGS);
|
||||
|
||||
ILibDuktape_EventEmitter_AddOn_Infrastructure(ctx, -1, "~", ILibDuktape_HttpStream_ServerResponse_Finalizer);
|
||||
}
|
||||
|
||||
int ILibDuktape_Digest_IsCorrectRealmAndNonce(duk_context *ctx, void *IMSG, char* realm, int realmLen)
|
||||
@@ -2922,6 +3010,8 @@ duk_ret_t ILibDuktape_HttpStream_IncomingMessage_Digest_ValidatePassword(duk_con
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_IncomingMessage_finalizer(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx);
|
||||
duk_del_prop_string(ctx, -1, ILibDuktape_IMSG2HttpStream);
|
||||
return(0);
|
||||
}
|
||||
void ILibDuktape_HttpStream_AddHeaderDef(duk_context *ctx, struct packetheader *header)
|
||||
@@ -2958,9 +3048,26 @@ void ILibDuktape_HttpStream_AddHeaderDef(duk_context *ctx, struct packetheader *
|
||||
duk_put_prop_string(ctx, -2, "statusMessage"); // [message]
|
||||
}
|
||||
}
|
||||
|
||||
void ILibDuktape_HttpStream_IncomingMessage_PUSH(duk_context *ctx, ILibHTTPPacket *header, void *httpstream)
|
||||
{
|
||||
duk_push_object(ctx); // [message]
|
||||
if (header->Directive != NULL)
|
||||
{
|
||||
duk_push_lstring(ctx, header->Directive, header->DirectiveLength); // [message][METHOD]
|
||||
duk_push_lstring(ctx, header->DirectiveObj, header->DirectiveObjLength);// [message][METHOD][PATH]
|
||||
duk_push_sprintf(ctx, "%s %s", duk_get_string(ctx, -2), duk_get_string(ctx, -1)); //[METHOD][PATH][STRING]
|
||||
duk_put_prop_string(ctx, -4, ILibDuktape_EventEmitter_FinalizerDebugMessage);//sage][METHOD][PATH]
|
||||
duk_pop_2(ctx); // [message]
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_lstring(ctx, header->StatusData, header->StatusDataLength); // [message][STATUS]
|
||||
duk_push_sprintf(ctx, "%d %s", header->StatusCode, duk_get_string(ctx, -1));// [message][STATUS][STRING]
|
||||
duk_put_prop_string(ctx, -3, ILibDuktape_EventEmitter_FinalizerDebugMessage);//[message][STATUS]
|
||||
duk_pop(ctx); // [message]
|
||||
}
|
||||
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_HttpStream_IncomingMessage_finalizer);
|
||||
duk_push_heapptr(ctx, httpstream); // [message][httpStream]
|
||||
duk_dup(ctx, -1); // [message][httpStream][dup]
|
||||
@@ -3043,7 +3150,25 @@ duk_ret_t ILibDuktape_HttpStream_OnReceive_bodyStreamFinalized(duk_context *ctx)
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
void ILibDuktape_HttpStream_IMSG_EndSink2(duk_context *ctx, void ** args, int argsLen)
|
||||
{
|
||||
void *tmp = args[1];
|
||||
if (ILibMemory_CanaryOK(tmp))
|
||||
{
|
||||
duk_push_heapptr(ctx, args[0]); // [IMSG]
|
||||
duk_prepare_method_call(ctx, -1, "removeAllListeners"); // [IMSG][removeAll][this]
|
||||
duk_pcall_method(ctx, 0); // [IMSG][ret]
|
||||
duk_pop_2(ctx); // ...
|
||||
}
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_IMSG_EndSink(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx);
|
||||
void *t = Duktape_PushBuffer(ctx, 1); duk_put_prop_string(ctx, -2, "tmp");
|
||||
void *h = duk_get_heapptr(ctx, -1);
|
||||
ILibDuktape_Immediate(ctx, (void*[]) { h, t }, 2, ILibDuktape_HttpStream_IMSG_EndSink2);
|
||||
return(0);
|
||||
}
|
||||
void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject, int InterruptFlag, struct packetheader *header, char *bodyBuffer, int *beginPointer, int endPointer, ILibWebClient_ReceiveStatus recvStatus, void *user1, void *user2, int *PAUSE)
|
||||
{
|
||||
ILibDuktape_HttpStream_Data *data = (ILibDuktape_HttpStream_Data*)user1;
|
||||
@@ -3057,7 +3182,7 @@ void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject,
|
||||
if (recvStatus == ILibWebClient_ReceiveStatus_Complete)
|
||||
{
|
||||
ILibDuktape_readableStream_WriteEnd(data->bodyStream);
|
||||
data->bodyStream = NULL;
|
||||
if (ILibMemory_CanaryOK(data)) { data->bodyStream = NULL; }
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -3084,8 +3209,8 @@ void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject,
|
||||
duk_push_string(ctx, "connect"); // [emit][this][connect] // [emit][this][request]
|
||||
ILibDuktape_HttpStream_IncomingMessage_PUSH(ctx, header, data->DS->ParentObject); // [emit][this][connect][imsg] // [emit][this][request][imsg]
|
||||
data->bodyStream = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_HttpStream_IncomingMessage_PauseSink, ILibDuktape_HttpStream_IncomingMessage_ResumeSink, ILibDuktape_HttpStream_IncomingMessage_UnshiftBytes, data);
|
||||
duk_dup(ctx, -3); duk_dup(ctx, -2); // [emit][this][connect][imsg][this][imsg] // [emit][this][request][imsg][httpstream][imsg]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2IMSG); duk_pop(ctx); // [emit][this][connect][imsg]
|
||||
//duk_dup(ctx, -3); duk_dup(ctx, -2); // [emit][this][connect][imsg][this][imsg] // [emit][this][request][imsg][httpstream][imsg]
|
||||
//duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2IMSG); duk_pop(ctx); // [emit][this][connect][imsg]
|
||||
duk_get_prop_string(ctx, -3, ILibDuktape_HTTP2PipedReadable); // [emit][this][connect][imsg][socket]
|
||||
duk_prepare_method_call(ctx, -1, "unpipe"); // [unpipe][this]
|
||||
duk_pcall_method(ctx, 0); duk_pop(ctx);
|
||||
@@ -3159,8 +3284,13 @@ void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject,
|
||||
duk_push_string(ctx, "checkContinue"); // [emit][this][checkContinue]
|
||||
ILibDuktape_HttpStream_IncomingMessage_PUSH(ctx, header, data->DS->ParentObject); // [emit][this][checkContinue][imsg]
|
||||
data->bodyStream = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_HttpStream_IncomingMessage_PauseSink, ILibDuktape_HttpStream_IncomingMessage_ResumeSink, ILibDuktape_HttpStream_IncomingMessage_UnshiftBytes, data);
|
||||
duk_dup(ctx, -3); duk_dup(ctx, -2); // [emit][this][checkContinue][imsg][httpstream][imsg]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2IMSG); duk_pop(ctx); // [emit][this][checkContinue][imsg]
|
||||
//duk_dup(ctx, -3); duk_dup(ctx, -2); // [emit][this][checkContinue][imsg][httpstream][imsg]
|
||||
//duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2IMSG); duk_pop(ctx); // [emit][this][checkContinue][imsg]
|
||||
|
||||
// Setup an infrastructure event, to remove all subscribers when done
|
||||
duk_events_setup_on(ctx, -1, "end", ILibDuktape_HttpStream_IMSG_EndSink);
|
||||
duk_push_true(ctx); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_InfrastructureEvent);
|
||||
duk_pcall_method(ctx, 2); duk_pop(ctx);
|
||||
|
||||
ILibDuktape_HttpStream_ServerResponse_PUSH(ctx, data->DS->writableStream->pipedReadable, header, data->DS->ParentObject); // [emit][this][checkContinue][imsg][rsp]
|
||||
if (duk_pcall_method(ctx, 3) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.httpStream.onReceive->checkContinue(): "); } // [rsp][hadListener]
|
||||
@@ -3178,9 +3308,15 @@ void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject,
|
||||
duk_push_string(ctx, "request"); // [emit][this][request]
|
||||
ILibDuktape_HttpStream_IncomingMessage_PUSH(ctx, header, data->DS->ParentObject); // [emit][this][request][imsg]
|
||||
data->bodyStream = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_HttpStream_IncomingMessage_PauseSink, ILibDuktape_HttpStream_IncomingMessage_ResumeSink, ILibDuktape_HttpStream_IncomingMessage_UnshiftBytes, data);
|
||||
duk_dup(ctx, -3); duk_dup(ctx, -2); // [emit][this][request][imsg][httpstream][imsg]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2IMSG); duk_pop(ctx); // [emit][this][request][imsg]
|
||||
//duk_dup(ctx, -3); duk_dup(ctx, -2); // [emit][this][request][imsg][httpstream][imsg]
|
||||
//duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2IMSG); duk_pop(ctx); // [emit][this][request][imsg]
|
||||
|
||||
// Setup an infrastructure event, to remove all subscribers when done
|
||||
duk_events_setup_on(ctx, -1, "end", ILibDuktape_HttpStream_IMSG_EndSink);
|
||||
duk_push_true(ctx); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_InfrastructureEvent);
|
||||
duk_pcall_method(ctx, 2); duk_pop(ctx);
|
||||
|
||||
|
||||
ILibDuktape_HttpStream_ServerResponse_PUSH(ctx, data->DS->writableStream->pipedReadable, header, data->DS->ParentObject); // [emit][this][request][imsg][rsp]
|
||||
if (duk_pcall_method(ctx, 3) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.httpStream.onReceive->request(): "); }
|
||||
duk_pop(ctx); // ...
|
||||
@@ -3192,8 +3328,13 @@ void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject,
|
||||
duk_push_string(ctx, "request"); // [emit][this][request]
|
||||
ILibDuktape_HttpStream_IncomingMessage_PUSH(ctx, header, data->DS->ParentObject); // [emit][this][request][imsg]
|
||||
data->bodyStream = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_HttpStream_IncomingMessage_PauseSink, ILibDuktape_HttpStream_IncomingMessage_ResumeSink, ILibDuktape_HttpStream_IncomingMessage_UnshiftBytes, data);
|
||||
duk_dup(ctx, -3); duk_dup(ctx, -2); // [emit][this][request][imsg][httpstream][imsg]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2IMSG); duk_pop(ctx); // [emit][this][request][imsg]
|
||||
//duk_dup(ctx, -3); duk_dup(ctx, -2); // [emit][this][request][imsg][httpstream][imsg]
|
||||
//duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2IMSG); duk_pop(ctx); // [emit][this][request][imsg]
|
||||
|
||||
// Setup an infrastructure event, to remove all subscribers when done
|
||||
duk_events_setup_on(ctx, -1, "end", ILibDuktape_HttpStream_IMSG_EndSink);
|
||||
duk_push_true(ctx); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_InfrastructureEvent);
|
||||
duk_pcall_method(ctx, 2); duk_pop(ctx);
|
||||
|
||||
ILibDuktape_HttpStream_ServerResponse_PUSH(ctx, data->DS->writableStream->pipedReadable, header, data->DS->ParentObject); // [emit][this][request][imsg][rsp]
|
||||
|
||||
@@ -3251,10 +3392,14 @@ void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject,
|
||||
data->bodyStream = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_HttpStream_IncomingMessage_PauseSink, ILibDuktape_HttpStream_IncomingMessage_ResumeSink, ILibDuktape_HttpStream_IncomingMessage_UnshiftBytes, data);
|
||||
duk_push_pointer(ctx, data);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_IMSG2Ptr);
|
||||
duk_dup(ctx, -3); // [emit][this][response][imsg][httpstream]
|
||||
duk_dup(ctx, -2); // [emit][this][response][imsg][httpstream][imsg]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2IMSG); // [emit][this][response][imsg][httpstream]
|
||||
duk_pop(ctx); // [emit][this][response][imsg]
|
||||
duk_events_setup_on(ctx, -1, "end", ILibDuktape_HttpStream_IMSG_EndSink);
|
||||
duk_push_true(ctx); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_InfrastructureEvent);
|
||||
duk_pcall_method(ctx, 2); duk_pop(ctx);
|
||||
|
||||
//duk_dup(ctx, -3); // [emit][this][response][imsg][httpstream]
|
||||
//duk_dup(ctx, -2); // [emit][this][response][imsg][httpstream][imsg]
|
||||
//duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2IMSG); // [emit][this][response][imsg][httpstream]
|
||||
//duk_pop(ctx); // [emit][this][response][imsg]
|
||||
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "~", ILibDuktape_HttpStream_OnReceive_bodyStreamFinalized);
|
||||
|
||||
@@ -3344,7 +3489,7 @@ void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject,
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_Finalizer(duk_context *ctx)
|
||||
{
|
||||
duk_del_prop_string(ctx, 0, ILibDuktape_HTTPStream2IMSG);
|
||||
//duk_del_prop_string(ctx, 0, ILibDuktape_HTTPStream2IMSG);
|
||||
duk_get_prop_string(ctx, 0, ILibDuktape_HTTPStream2Data);
|
||||
ILibDuktape_HttpStream_Data *data = (ILibDuktape_HttpStream_Data*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
|
||||
@@ -3376,6 +3521,14 @@ duk_ret_t ILibDuktape_HttpStream_pipeEvent(duk_context *ctx)
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_HTTP2PipedReadable); // [httpStream]
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_unpipeEvent(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx); // [stream]
|
||||
duk_del_prop_string(ctx, -1, ILibDuktape_HTTP2PipedReadable);
|
||||
duk_prepare_method_call(ctx, -1, "removeAllListeners"); // [stream][remove]
|
||||
duk_call_method(ctx, 0);
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibduktape_HttpStream_create(duk_context *ctx)
|
||||
{
|
||||
int nargs = duk_get_top(ctx);
|
||||
@@ -3417,7 +3570,8 @@ duk_ret_t ILibduktape_HttpStream_create(duk_context *ctx)
|
||||
|
||||
data->chain = Duktape_GetChain(ctx);
|
||||
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "pipe", ILibDuktape_HttpStream_pipeEvent);
|
||||
ILibDuktape_EventEmitter_AddOn_Infrastructure(ctx, -1, "pipe", ILibDuktape_HttpStream_pipeEvent);
|
||||
ILibDuktape_EventEmitter_AddOn_Infrastructure(ctx, -1, "unpipe", ILibDuktape_HttpStream_unpipeEvent);
|
||||
|
||||
ILibDuktape_CreateEventWithGetter(ctx, "connectionCloseSpecified", ILibDuktape_HttpStream_connectionCloseSpecified);
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_HttpStream_Finalizer);
|
||||
@@ -3627,9 +3781,7 @@ duk_ret_t ILibDuktape_HttpStream_Agent_keepSocketAlive(duk_context *ctx)
|
||||
duk_get_prop_string(ctx, -7, "keepAliveMsecs"); // [AGent][table][push][this][socket][setTimeout][this][milliseconds]
|
||||
duk_push_c_function(ctx, ILibDuktape_HttpStream_Agent_keepSocketAlive_timeout, DUK_VARARGS); // [AGent][table][push][this][socket][setTimeout][this][milliseconds][callback]
|
||||
duk_call_method(ctx, 2); duk_pop(ctx); // [AGent][table][push][this][socket]
|
||||
|
||||
duk_call_method(ctx, 1); // [Agent][table][retVal]
|
||||
retVal = 1;
|
||||
duk_call_method(ctx, 1); // [Agent][table][retVal]
|
||||
}
|
||||
duk_push_int(ctx, retVal);
|
||||
return(1);
|
||||
@@ -3638,7 +3790,7 @@ void ILibDuktape_HttpStream_Agent_reuseSocketEx(duk_context *ctx, void ** args,
|
||||
{
|
||||
duk_push_this(ctx); // [immediate]
|
||||
duk_del_prop_string(ctx, -1, "CR");
|
||||
duk_del_prop_string(ctx, -2, "Socket");
|
||||
duk_del_prop_string(ctx, -1, "Socket");
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
duk_push_heapptr(ctx, args[1]); // [clientRequest]
|
||||
@@ -3661,13 +3813,7 @@ void ILibDuktape_HttpStream_Agent_reuseSocketEx(duk_context *ctx, void ** args,
|
||||
duk_ret_t ILibDuktape_HttpStream_Agent_reuseSocket(duk_context *ctx)
|
||||
{
|
||||
// Yield to the next loop, before we emit a 'socket' event, because emitting this event before anyone has the clientRequest object is pointless
|
||||
void *imm = ILibDuktape_Immediate(ctx, (void*[]) { duk_get_heapptr(ctx, 0), duk_get_heapptr(ctx, 1) }, 2, ILibDuktape_HttpStream_Agent_reuseSocketEx);
|
||||
duk_push_heapptr(ctx, imm); // [immediate]
|
||||
duk_dup(ctx, 1); // [immediate][ClientRequest]
|
||||
duk_put_prop_string(ctx, -2, "CR"); // [immediate]
|
||||
duk_dup(ctx, 0); // [immediate][Socket]
|
||||
duk_put_prop_string(ctx, -2, "Socket"); // [immediate]
|
||||
duk_pop(ctx);
|
||||
ILibDuktape_Immediate(ctx, (void*[]) { duk_get_heapptr(ctx, 0), duk_get_heapptr(ctx, 1) }, 2, ILibDuktape_HttpStream_Agent_reuseSocketEx);
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_Agent_createConnection_eventSink(duk_context *ctx)
|
||||
@@ -4249,11 +4395,12 @@ ILibTransport_DoneState ILibDuktape_httpStream_webSocket_EncodedWriteSink(ILibDu
|
||||
ILibDuktape_DuplexStream_WriteEnd(state->decodedStream);
|
||||
if (ILibIsRunningOnChainThread(state->chain) != 0 && state->encodedStream->writableStream->pipedReadable != NULL)
|
||||
{
|
||||
duk_context *ctx = state->ctx;
|
||||
duk_push_heapptr(state->ctx, state->encodedStream->writableStream->pipedReadable); // [stream]
|
||||
duk_get_prop_string(state->ctx, -1, "end"); // [stream][end]
|
||||
duk_swap_top(state->ctx, -2); // [end][this]
|
||||
if (duk_pcall_method(state->ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(state->ctx, "http.webSocketStream.write(): Error Dispatching 'end' "); }
|
||||
duk_pop(state->ctx); // ...
|
||||
if (duk_pcall_method(state->ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.webSocketStream.write(): Error Dispatching 'end' "); }
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
break;
|
||||
case WEBSOCKET_OPCODE_PING:
|
||||
@@ -4296,6 +4443,28 @@ void ILibDuktape_httpStream_webSocket_EncodedEndSink(ILibDuktape_DuplexStream *s
|
||||
{
|
||||
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)user;
|
||||
if (duk_ctx_shutting_down(state->ctx)) { return; }
|
||||
|
||||
duk_push_heapptr(state->ctx, state->ObjectPtr); // [websocket]
|
||||
duk_get_prop_string(state->ctx, -1, "decoded"); // [websocket][decoded]
|
||||
duk_del_prop_string(state->ctx, -1, ILibDuktape_WSDEC2WS);
|
||||
duk_prepare_method_call(state->ctx, -1, "unpipe"); // [websocket][decoded][pmc][this]
|
||||
duk_pcall_method(state->ctx, 0); duk_pop(state->ctx); // [websocket][decoded]
|
||||
duk_prepare_method_call(state->ctx, -1, "removeAllListeners"); // [websocket][decoded][removeAll][this]
|
||||
duk_pcall_method(state->ctx, 0); duk_pop(state->ctx); // [websocket][decoded]
|
||||
|
||||
duk_pop(state->ctx); // [websocket]
|
||||
duk_get_prop_string(state->ctx, -1, "encoded"); // [websocket][encoded]
|
||||
duk_prepare_method_call(state->ctx, -1, "removeAllListeners"); // [websocket][encoded][removeAll][this]
|
||||
duk_pcall_method(state->ctx, 0); duk_pop(state->ctx); // [websocket][encoded]
|
||||
|
||||
duk_del_prop_string(state->ctx, -1, ILibDuktape_WSENC2WS);
|
||||
duk_pop(state->ctx); // [websocket]
|
||||
|
||||
|
||||
ILibDuktape_DeleteReadOnlyProperty(state->ctx, -1, "decoded");
|
||||
ILibDuktape_DeleteReadOnlyProperty(state->ctx, -1, "encoded");
|
||||
duk_pop(state->ctx); // ...
|
||||
|
||||
if (!state->closed) { ILibDuktape_DuplexStream_WriteEnd(state->decodedStream); }
|
||||
}
|
||||
void ILibDuktape_httpStream_webSocket_EncodedPauseSink_Chain(void *chain, void *user)
|
||||
@@ -4509,6 +4678,7 @@ duk_ret_t ILibDuktape_httpStream_webSocketStream_sendPong(duk_context *ctx)
|
||||
ILibDuktape_httpStream_webSocket_WriteWebSocketPacket(state, WEBSOCKET_OPCODE_PONG, NULL, 0, ILibWebClient_WebSocket_FragmentFlag_Complete);
|
||||
return(0);
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_httpStream_webSocketStream_encodedPiped(duk_context *ctx)
|
||||
{
|
||||
// Someone Piped to the Encoded Stream
|
||||
@@ -4529,11 +4699,15 @@ duk_ret_t ILibDuktape_httpStream_webSocketStream_encodedPiped(duk_context *ctx)
|
||||
}
|
||||
duk_ret_t ILibDuktape_httpStream_webSocketStream_encoded_Finalizer(duk_context *ctx)
|
||||
{
|
||||
duk_get_prop_string(ctx, 0, ILibDuktape_WSENC2WS);
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_WebSocket_StatePtr);
|
||||
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
if (duk_has_prop_string(ctx, -1, ILibDuktape_WSENC2WS))
|
||||
{
|
||||
duk_get_prop_string(ctx, 0, ILibDuktape_WSENC2WS);
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_WebSocket_StatePtr);
|
||||
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
|
||||
state->encodedStream = NULL;
|
||||
}
|
||||
|
||||
state->encodedStream = NULL;
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -4717,7 +4891,6 @@ duk_ret_t ILibDuktape_httpStream_webSocketStream_new(duk_context *ctx)
|
||||
ILibDuktape_WriteID(ctx, "http.WebSocketStream");
|
||||
state = (ILibDuktape_WebSocket_State*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_WebSocket_State)); // [WebSocket][data]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_WebSocket_StatePtr); // [WebSocket]
|
||||
|
||||
state->ctx = ctx;
|
||||
state->ObjectPtr = duk_get_heapptr(ctx, -1);
|
||||
state->chain = Duktape_GetChain(ctx);
|
||||
@@ -4736,7 +4909,9 @@ duk_ret_t ILibDuktape_httpStream_webSocketStream_new(duk_context *ctx)
|
||||
duk_push_object(ctx); // [WebSocket][Encoded]
|
||||
ILibDuktape_WriteID(ctx, "http.WebSocketStream.encoded");
|
||||
state->encodedStream = ILibDuktape_DuplexStream_InitEx(ctx, ILibDuktape_httpStream_webSocket_EncodedWriteSink, ILibDuktape_httpStream_webSocket_EncodedEndSink, ILibDuktape_httpStream_webSocket_EncodedPauseSink, ILibDuktape_httpStream_webSocket_EncodedResumeSink, ILibDuktape_httpStream_webSocket_EncodedUnshiftSink, state);
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "pipe", ILibDuktape_httpStream_webSocketStream_encodedPiped);
|
||||
|
||||
ILibDuktape_EventEmitter_AddOn_Infrastructure(ctx, -1, "pipe", ILibDuktape_httpStream_webSocketStream_encodedPiped);
|
||||
|
||||
duk_dup(ctx, -2); // [WebSocket][Encoded][WebSocket]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_WSENC2WS); // [WebSocket][Encoded]
|
||||
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -1, "~", ILibDuktape_httpStream_webSocketStream_encoded_Finalizer);
|
||||
@@ -4764,7 +4939,6 @@ duk_ret_t ILibDuktape_httpStream_webSocketStream_new(duk_context *ctx)
|
||||
ILibDuktape_CreateEventWithGetter(ctx, "bytesSent_ratio", ILibDuktape_WebSocket_bytesSent_ratio);
|
||||
ILibDuktape_CreateEventWithGetter(ctx, "bytesReceived_ratio", ILibDuktape_WebSocket_bytesReceived_ratio);
|
||||
|
||||
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "decoded"); // [WebSocket]
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_httpStream_webSocketStream_finalizer);
|
||||
return(1);
|
||||
|
||||
@@ -208,7 +208,7 @@ void ILibDuktape_net_socket_OnConnect(ILibAsyncSocket_SocketModule socketModule,
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->object); // [socket]
|
||||
if (alpnLen != 0)
|
||||
{
|
||||
duk_push_lstring(ptrs->ctx, alpn, alpnLen);
|
||||
duk_push_lstring(ptrs->ctx, (char*)alpn, alpnLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -880,7 +880,7 @@ void ILibDuktape_net_server_OnConnect(ILibAsyncServerSocket_ServerModule AsyncSe
|
||||
SSL_SESSION_get0_alpn_selected(SSL_get_session(ILibAsyncServerSocket_GetSSL(ConnectionToken)), &alpn, &alpnLen);
|
||||
if (alpnLen != 0)
|
||||
{
|
||||
duk_push_lstring(ptr->ctx, alpn, alpnLen);
|
||||
duk_push_lstring(ptr->ctx, (char*)alpn, alpnLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -40,12 +40,6 @@ limitations under the License.
|
||||
#define ILibDuktape_EventEmitter_References "\xFF_EventReferences"
|
||||
extern void ILibDuktape_GenericMarshal_Variable_PUSH(duk_context *ctx, void *ptr, int size);
|
||||
|
||||
#ifdef ILIBEVENTEMITTER_REFHOLD
|
||||
int gEventEmitterReferenceHold = ILIBEVENTEMITTER_REFHOLD;
|
||||
#else
|
||||
int gEventEmitterReferenceHold = 0;
|
||||
#endif
|
||||
|
||||
typedef struct ILibDuktape_EventEmitter_EmitStruct
|
||||
{
|
||||
void *func;
|
||||
@@ -427,27 +421,6 @@ duk_ret_t ILibDuktape_EventEmitter_on(duk_context *ctx)
|
||||
duk_array_push(ctx, -2); // [object][table][array]
|
||||
}
|
||||
|
||||
if (gEventEmitterReferenceHold != 0)
|
||||
{
|
||||
duk_prepare_method_call(ctx, -3, "eventNames"); // [object][table][array][eventNames][this]
|
||||
duk_call_method(ctx, 0); // [object][table][array][names]
|
||||
|
||||
if (duk_get_length(ctx, -1) > 0)
|
||||
{
|
||||
duk_push_heap_stash(ctx); // [object][table][array][names][stash]
|
||||
if (!duk_has_prop_string(ctx, -1, ILibDuktape_EventEmitter_References))
|
||||
{
|
||||
duk_push_object(ctx); // [object][table][array][names][stash][refs]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_References); // [object][table][array][names][stash]
|
||||
}
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_References); // [object][table][array][names][stash][refs]
|
||||
duk_push_this(ctx); // [object][table][array][names][stash][refs][this]
|
||||
duk_put_prop_string(ctx, -2, Duktape_GetStashKey(duk_get_heapptr(ctx, -1))); //ect][table][array][names][stash][refs]
|
||||
duk_pop_2(ctx); // [object][table][array][names]
|
||||
}
|
||||
duk_pop(ctx); // [object][table][array]
|
||||
}
|
||||
|
||||
if (!(propNameLen == 11 && strncmp(propName, "newListener", 11) == 0) && !(propNameLen == 12 && strncmp(propName, "newListener2", 12) == 0))
|
||||
{
|
||||
// Only emit 'newListener2' when the event itself isn't 'newListener' or 'newListener2'
|
||||
@@ -504,8 +477,78 @@ duk_ret_t ILibDuktape_EventEmitter_removeListener(duk_context *ctx)
|
||||
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_EventEmitter_removeAllListeners_AllEvents_NonInfrastructure_find(duk_context *ctx)
|
||||
{
|
||||
duk_dup(ctx, 0); // [element]
|
||||
duk_get_prop_string(ctx, -1, "func"); // [element][func]
|
||||
if (Duktape_GetBooleanProperty(ctx, -1, ILibDuktape_EventEmitter_InfrastructureEvent, 0) == 0)
|
||||
{
|
||||
duk_push_true(ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_false(ctx);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_EventEmitter_removeAllListeners_AllEvents_NonInfrastructure(duk_context *ctx)
|
||||
{
|
||||
int i = -1;
|
||||
duk_push_this(ctx); // [emitter]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_EventTable); // [emitter][table]
|
||||
duk_enum(ctx, -1, DUK_ENUM_OWN_PROPERTIES_ONLY); // [emitter][table][enum]
|
||||
while (duk_next(ctx, -1, 1)) // [emitter][table][enum][name][array]
|
||||
{
|
||||
// Skip finalizers, as well as removeListener
|
||||
if (strcmp(duk_get_string(ctx, -2), "~") == 0 || strcmp(duk_get_string(ctx, -2), "removeListener") == 0) { duk_pop_2(ctx); continue; }
|
||||
do
|
||||
{
|
||||
duk_prepare_method_call(ctx, -1, "findIndex"); // [emitter][table][enum][name][array][findIndex][this]
|
||||
duk_push_c_function(ctx, ILibDuktape_EventEmitter_removeAllListeners_AllEvents_NonInfrastructure_find, DUK_VARARGS);//][func]
|
||||
duk_call_method(ctx, 1); // [emitter][table][enum][name][array][index]
|
||||
if ((i = duk_get_int(ctx, -1)) != -1)
|
||||
{
|
||||
duk_get_prop_index(ctx, -2, i); // [emitter][table][enum][name][array][index][element]
|
||||
duk_prepare_method_call(ctx, -3, "splice"); // [emitter][table][enum][name][array][index][element][splice][this]
|
||||
duk_push_int(ctx, i); // [emitter][table][enum][name][array][index][element][splice][this][start]
|
||||
duk_push_int(ctx, 1); // [emitter][table][enum][name][array][index][element][splice][this][start][1]
|
||||
duk_call_method(ctx, 2); duk_pop(ctx); // [emitter][table][enum][name][array][index][element]
|
||||
ILibDuktape_EventEmitter_emit_removeListener(ctx, duk_get_string(ctx, -4), -7, -1);
|
||||
duk_pop(ctx); // [emitter][table][enum][name][array][index]
|
||||
}
|
||||
duk_pop(ctx); // [emitter][table][enum][name][array]
|
||||
} while (i != -1);
|
||||
duk_pop_2(ctx); // [emitter][table][enum]
|
||||
}
|
||||
duk_pop(ctx); // [emitter][table]
|
||||
if (duk_has_prop_string(ctx, -1, "removeListener"))
|
||||
{
|
||||
i = -1;
|
||||
duk_get_prop_string(ctx, -1, "removeListener"); // [emitter][table][array]
|
||||
do
|
||||
{
|
||||
duk_prepare_method_call(ctx, -1, "findIndex"); // [emitter][table][array][findIndex][this]
|
||||
duk_push_c_function(ctx, ILibDuktape_EventEmitter_removeAllListeners_AllEvents_NonInfrastructure_find, DUK_VARARGS);//][func]
|
||||
duk_call_method(ctx, 1); // [emitter][table][array][index]
|
||||
if ((i = duk_get_int(ctx, -1)) != -1)
|
||||
{
|
||||
duk_get_prop_index(ctx, -2, i); // [emitter][table][array][index][element]
|
||||
duk_prepare_method_call(ctx, -3, "splice"); // [emitter][table][array][index][element][splice][this]
|
||||
duk_push_int(ctx, i); // [emitter][table][array][index][element][splice][this][start]
|
||||
duk_push_int(ctx, 1); // [emitter][table][array][index][element][splice][this][start][1]
|
||||
duk_call_method(ctx, 2); duk_pop(ctx); // [emitter][table][array][index][element]
|
||||
ILibDuktape_EventEmitter_emit_removeListener(ctx, "removeListener", -5, -1);
|
||||
duk_pop(ctx); // [emitter][table][array][index]
|
||||
}
|
||||
duk_pop(ctx); // [emitter][table][array]
|
||||
} while (i != -1);
|
||||
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_EventEmitter_removeAllListeners(duk_context *ctx)
|
||||
{
|
||||
if (duk_get_top(ctx) == 0) { return(ILibDuktape_EventEmitter_removeAllListeners_AllEvents_NonInfrastructure(ctx)); }
|
||||
char *eventName = (char*)duk_require_string(ctx, 0);
|
||||
|
||||
duk_push_this(ctx); // [object]
|
||||
@@ -715,23 +758,6 @@ duk_ret_t ILibDuktape_EventEmitter_listeners_tableinit(duk_context *ctx)
|
||||
duk_push_this(ctx); // [obj]
|
||||
ILibDuktape_EventEmitter *emitter = (ILibDuktape_EventEmitter*)Duktape_GetBufferProperty(ctx, -1, ILibDuktape_EventEmitter_Data);
|
||||
|
||||
if (isAdd == 0 && gEventEmitterReferenceHold != 0)
|
||||
{
|
||||
duk_prepare_method_call(ctx, -1, "eventNames"); // [obj][eventNames][this]
|
||||
duk_call_method(ctx, 0); // [obj][names]
|
||||
if (duk_get_length(ctx, -1) == 0)
|
||||
{
|
||||
duk_push_heap_stash(ctx); // [obj][names][stash]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_References); // [obj][names][stash][refs]
|
||||
if (!duk_is_null_or_undefined(ctx, -1))
|
||||
{
|
||||
duk_del_prop_string(ctx, -1, Duktape_GetStashKey(duk_get_heapptr(ctx, -4)));
|
||||
}
|
||||
duk_pop_2(ctx); // [obj][names]
|
||||
}
|
||||
duk_pop(ctx); // [obj]
|
||||
}
|
||||
|
||||
ILibSpinLock_Lock(&(emitter->listenerCountTableLock));
|
||||
duk_push_global_object(ctx); // [g]
|
||||
duk_get_prop_string(ctx, -1, "JSON"); // [g][JSON]
|
||||
@@ -1568,3 +1594,116 @@ int ILibDuktape_EventEmitter_AddOnEx(duk_context *ctx, duk_idx_t idx, char *even
|
||||
duk_pop(ctx); // ...
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_EventEmitter_ForwardEx_target_newListenerSink(duk_context *ctx)
|
||||
{
|
||||
duk_push_current_function(ctx); // [func]
|
||||
char *eventName = Duktape_GetStringPropertyValue(ctx, -1, "eventName", NULL);
|
||||
void **ptr = (void**)Duktape_GetPointerProperty(ctx, -1, "sourcePtr");
|
||||
char *hookedEvent = (char*)duk_require_string(ctx, 0);
|
||||
if (eventName == NULL || !ILibMemory_CanaryOK(ptr) || strcmp(eventName, hookedEvent) != 0) { return(0); }
|
||||
|
||||
duk_dup(ctx, 1); // [func]
|
||||
duk_prepare_method_call(ctx, -1, "bind"); // [func][bind][this]
|
||||
duk_push_this(ctx); // [func][bind][this][target]
|
||||
duk_call_method(ctx, 1); // [func][proxyFunc]
|
||||
duk_push_true(ctx); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_InfrastructureEvent);
|
||||
duk_push_pointer(ctx, ptr); duk_put_prop_string(ctx, -2, "sourcePtr");
|
||||
duk_dup(ctx, -1); // [func][proxyFunc][proxyFunc]
|
||||
duk_put_prop_string(ctx, -3, "proxyFunc"); // [func][proxyFunc]
|
||||
|
||||
|
||||
duk_push_heapptr(ctx, ptr[0]); // [func][proxyFunc][source]
|
||||
duk_prepare_method_call(ctx, -1, "on"); // [func][proxyFunc][source][on][this]
|
||||
duk_dup(ctx, 0); // [func][proxyFunc][source][on][this][eventName]
|
||||
duk_dup(ctx, -5); // [func][proxyFunc][source][on][this][eventName][func]
|
||||
duk_call_method(ctx, 2); // [func][proxyFunc][source][ret]
|
||||
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_EventEmitter_ForwardEx_target_removeListenerSink(duk_context *ctx)
|
||||
{
|
||||
duk_push_current_function(ctx); // [func]
|
||||
char *eventName = Duktape_GetStringPropertyValue(ctx, -1, "eventName", NULL);
|
||||
void **ptr = (void**)Duktape_GetPointerProperty(ctx, -1, "sourcePtr");
|
||||
char *hookedEvent = (char*)duk_require_string(ctx, 0);
|
||||
if (eventName == NULL || !ILibMemory_CanaryOK(ptr) || strcmp(eventName, hookedEvent) != 0 || !duk_has_prop_string(ctx, 1, "proxyFunc")) { return(0); }
|
||||
|
||||
duk_push_heapptr(ctx, ptr[0]); // [source]
|
||||
duk_prepare_method_call(ctx, -1, "removeListener"); // [source][removeListener][this]
|
||||
duk_dup(ctx, 0); // [source][removeListener][this][name]
|
||||
duk_get_prop_string(ctx, 1, "proxyFunc"); // [source][removeListener][this][name][func]
|
||||
duk_call_method(ctx, 2); // [source][ret]
|
||||
|
||||
duk_del_prop_string(ctx, 1, "proxyFunc");
|
||||
return(0);
|
||||
}
|
||||
int ILibDuktape_EventEmitter_ForwardEventEx(duk_context *ctx, duk_idx_t sourceIdx, duk_idx_t targetIdx, char *eventName)
|
||||
{
|
||||
int X = duk_get_top(ctx);
|
||||
void *source = duk_get_heapptr(ctx, sourceIdx);
|
||||
void *target = duk_get_heapptr(ctx, targetIdx);
|
||||
void **ptr;
|
||||
|
||||
duk_push_heapptr(ctx, source); // [source]
|
||||
if (!duk_has_prop_string(ctx, -1, "\xFF_ProxyEvent_WeakReference"))
|
||||
{
|
||||
ptr = (void**)Duktape_PushBuffer(ctx, sizeof(void*)); // [source][buffer]
|
||||
duk_put_prop_string(ctx, -2, "\xFF_ProxyEvent_WeakReference"); // [source]
|
||||
ptr[0] = source;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = Duktape_GetPointerProperty(ctx, -1, "\xFF_ProxyEvent_WeakReference");
|
||||
}
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
|
||||
// Check for pre-existing event listeners
|
||||
duk_prepare_method_call(ctx, targetIdx, "listeners"); // [listeners][this]
|
||||
duk_push_string(ctx, eventName); // [listeners][this][name]
|
||||
if (duk_pcall_method(ctx, 1) != 0) { duk_set_top(ctx, X); return(1); } // [array]
|
||||
while(duk_get_length(ctx, -1)>0)
|
||||
{
|
||||
duk_array_pop(ctx, -1); // [array][func]
|
||||
if (!duk_has_prop_string(ctx, -1, "proxyFunc"))
|
||||
{
|
||||
duk_prepare_method_call(ctx, -1, "bind"); // [array][func][bind][this]
|
||||
duk_push_heapptr(ctx, target); // [array][func][bind][this][target]
|
||||
if (duk_pcall_method(ctx, 1) != 0) { duk_set_top(ctx, X); return(1); } // [array][func][proxyFunc]
|
||||
duk_push_true(ctx); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_InfrastructureEvent);
|
||||
duk_push_pointer(ctx, ptr); duk_put_prop_string(ctx, -2, "sourcePtr");
|
||||
duk_put_prop_string(ctx, -2, "proxyFunc"); // [array][func]
|
||||
}
|
||||
duk_push_heapptr(ctx, source); // [array][func][source]
|
||||
duk_prepare_method_call(ctx, -1, "on"); // [array][func][source][on][this]
|
||||
duk_push_string(ctx, eventName); // [array][func][source][on][this][eventName]
|
||||
duk_get_prop_string(ctx, -5, "proxyFunc"); // [array][func][source][on][this][eventName][proxyFunc]
|
||||
if (duk_pcall_method(ctx, 2) != 0) { duk_set_top(ctx, X); return(1); } // [array][func][source][ret]
|
||||
duk_pop_n(ctx, 3); // [array]
|
||||
}
|
||||
|
||||
|
||||
// Hookup a 'newListener' hook, to attach new subscribers
|
||||
int ret = 0;
|
||||
duk_set_top(ctx, X);
|
||||
duk_events_setup_on(ctx, targetIdx, "newListener", ILibDuktape_EventEmitter_ForwardEx_target_newListenerSink); // [on][this][newListener][func]
|
||||
duk_push_string(ctx, eventName); duk_put_prop_string(ctx, -2, "eventName");
|
||||
duk_push_pointer(ctx, ptr); duk_put_prop_string(ctx, -2, "sourcePtr");
|
||||
duk_push_true(ctx); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_InfrastructureEvent);
|
||||
ret = duk_pcall_method(ctx, 2) == 0 ? 0 : 1;
|
||||
duk_set_top(ctx, X);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
// Hookup a 'removeListener' hook, to remove subscribers
|
||||
duk_events_setup_on(ctx, targetIdx, "removeListener", ILibDuktape_EventEmitter_ForwardEx_target_removeListenerSink); // [on][this][removeListener][func]
|
||||
duk_push_string(ctx, eventName); duk_put_prop_string(ctx, -2, "eventName");
|
||||
duk_push_pointer(ctx, ptr); duk_put_prop_string(ctx, -2, "sourcePtr");
|
||||
duk_push_true(ctx); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_InfrastructureEvent);
|
||||
ret = duk_pcall_method(ctx, 2) == 0 ? 0 : 1;
|
||||
duk_set_top(ctx, X);
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
Reference in New Issue
Block a user