1
0
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:
Bryan Roe
2021-05-20 11:36:40 -07:00
parent 2b1d5916bb
commit 486f8eaa39
4 changed files with 450 additions and 136 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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
{

View File

@@ -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);
}