1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-10 21:33:38 +00:00
Files
MeshAgent/microscript/ILibWebClient_Duktape.c
2017-10-12 14:28:03 -07:00

577 lines
21 KiB
C

/*
Copyright 2006 - 2017 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
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
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
limitations under the License.
*/
#include "ILibWebClient_Duktape.h"
#include "microstack/ILibParsers.h"
#include "microstack/ILibWebClient.h"
#include "ILibDuktape_Helpers.h"
#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(_MINCORE)
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#endif
extern duk_idx_t ILibWebServer_DukTape_Push_PacketHeader(duk_context *ctx, ILibHTTPPacket *packet);
typedef struct ILibWebClient_DukTape_WebSocketCallbacks
{
void *OnMessage;
void *OnClose;
void *OnSendOK;
}ILibWebClient_DukTape_WebSocketCallbacks;
duk_idx_t ILibWebClient_DukTape_Push_WebRequestManager(duk_context *ctx, void* wcm);
duk_ret_t ILibWebClient_DukTape_RequestToken_Cancel(duk_context *ctx)
{
void *token;
duk_push_this(ctx);
duk_get_prop_string(ctx, -1, "TokenPtr");
token = duk_to_pointer(ctx, -1);
ILibWebClient_CancelRequest(token); //ToDo: Check to see if we should delete from stash here, or from somewhere else
return 0;
}
duk_idx_t ILibWebClient_DukTape_Push_RequestToken(duk_context *ctx, ILibWebClient_RequestToken token)
{
char *key = Duktape_GetStashKey(token);
duk_push_heap_stash(ctx);
if (duk_has_prop_string(ctx, -1, key) != 0)
{
duk_get_prop_string(ctx, -1, key); // [stash][obj]
duk_swap_top(ctx, -2); // [obj][stash]
duk_pop(ctx); // [obj]
return(duk_get_top_index(ctx));
}
duk_push_object(ctx); // [stash][obj]
duk_push_pointer(ctx, token); // [stash][obj][ptr]
duk_put_prop_string(ctx, -2, "TokenPtr"); // [stash][obj]
duk_push_c_function(ctx, ILibWebClient_DukTape_RequestToken_Cancel, 0); // [stash][obj][func]
duk_put_prop_string(ctx, -2, "Cancel"); // [stash][obj]
duk_dup(ctx, -1); // [stash][obj1][obj2]
duk_put_prop_string(ctx, -3, key); // [stash][obj2]
duk_swap_top(ctx, -2); // [obj2][stash]
duk_pop(ctx); // [obj2]
return(duk_get_top_index(ctx));
}
duk_ret_t ILibWebClient_DukTape_StateObject_Resume(duk_context *ctx)
{
return 0;
}
duk_ret_t ILibWebClient_DukTape_StateObject_Digest_NeedAuthenticate(duk_context *ctx)
{
ILibWebClient_StateObject wcdo;
duk_push_this(ctx);
duk_get_prop_string(ctx, -1, "StatePtr");
wcdo = (ILibWebClient_StateObject)duk_to_pointer(ctx, -1);
duk_push_int(ctx, ILibWebClient_Digest_NeedAuthenticate(wcdo));
return 1;
}
duk_ret_t ILibWebClient_DukTape_StateObject_Digest_GetRealm(duk_context *ctx)
{
char *realm;
ILibWebClient_StateObject wcdo;
duk_push_this(ctx);
duk_get_prop_string(ctx, -1, "StatePtr");
wcdo = (ILibWebClient_StateObject)duk_to_pointer(ctx, -1);
realm = ILibWebClient_Digest_GetRealm(wcdo);
duk_push_string(ctx, realm != NULL ? realm : "");
return 1;
}
duk_ret_t ILibWebClient_DukTape_StateObject_Digest_AddAuthenticationHeader(duk_context *ctx)
{
ILibWebClient_StateObject wcdo;
char *username;
char *password;
ILibHTTPPacket *packet;
duk_push_this(ctx);
duk_get_prop_string(ctx, -1, "StatePtr");
wcdo = (ILibWebClient_StateObject)duk_to_pointer(ctx, -1);
duk_get_prop_string(ctx, 0, "PacketPtr");
packet = (ILibHTTPPacket*)duk_to_pointer(ctx, -1);
username = (char*)duk_require_string(ctx, 1);
password = (char*)duk_require_string(ctx, 2);
ILibWebClient_GenerateAuthenticationHeader(wcdo, packet, username, password);
return 0;
}
duk_idx_t ILibWebClient_DukTape_WebClient_WebSocket_Send(duk_context *ctx)
{
int bufferType = duk_require_int(ctx, 0);
char *buffer = Duktape_GetBuffer(ctx, 1, NULL);
int bufferLen = duk_require_int(ctx, 2);
int fragmentFlags = duk_require_int(ctx, 3);
ILibWebClient_StateObject wcdo;
ILibAsyncSocket_SendStatus retVal;
duk_push_this(ctx);
duk_get_prop_string(ctx, -1, "StatePtr");
wcdo = (ILibWebClient_StateObject)duk_to_pointer(ctx, -1);
retVal = ILibWebClient_WebSocket_Send(wcdo, bufferType, buffer, bufferLen, ILibAsyncSocket_MemoryOwnership_USER, fragmentFlags);
duk_push_int(ctx, retVal);
return 1;
}
duk_idx_t ILibWebClient_DukTape_Push_StateObject(duk_context *ctx, ILibWebClient_StateObject WebStateObject)
{
char* key = Duktape_GetStashKey(WebStateObject);
duk_push_heap_stash(ctx); // [stash]
if (duk_has_prop_string(ctx, -1, key) != 0)
{
duk_get_prop_string(ctx, -1, key); // [stash][obj]
duk_swap_top(ctx, -2); // [obj][stash]
duk_pop(ctx); // [obj]
return(duk_get_top_index(ctx));
}
duk_push_object(ctx); // [stash][obj]
duk_push_pointer(ctx, WebStateObject); // [stash][obj][ptr]
duk_put_prop_string(ctx, -2, "StatePtr"); // [stash][obj]
duk_push_external_buffer(ctx); // [stash][obj][buffer]
duk_put_prop_string(ctx, -2, "BufferPtr"); // [stash][obj]
duk_push_c_function(ctx, ILibWebClient_DukTape_StateObject_Resume, 0); // [stash][obj][func]
duk_put_prop_string(ctx, -2, "Resume"); // [stash][obj]
duk_push_c_function(ctx, ILibWebClient_DukTape_StateObject_Digest_NeedAuthenticate, 0); // [stash][obj][func]
duk_put_prop_string(ctx, -2, "Digest_NeedAuthenticate"); // [stash][obj]
duk_push_c_function(ctx, ILibWebClient_DukTape_StateObject_Digest_GetRealm, 0); // [stash][obj][func]
duk_put_prop_string(ctx, -2, "Digest_GetRealm"); // [stash][obj]
duk_push_c_function(ctx, ILibWebClient_DukTape_StateObject_Digest_AddAuthenticationHeader, 3); // [stash][obj][func]
duk_put_prop_string(ctx, -2, "Digest_AddAuthenticationHeader"); // [stash][obj]
duk_push_c_function(ctx, ILibWebClient_DukTape_WebClient_WebSocket_Send, 4); // [stash][obj][func]
duk_put_prop_string(ctx, -2, "WebSocket_Send"); // [stash][obj]
duk_dup(ctx, -1); // [stash][obj][obj]
duk_put_prop_string(ctx, -3, key); // [stash][obj]
duk_swap_top(ctx, -2); // [obj][stash]
duk_pop(ctx); // [obj]
return(duk_get_top_index(ctx));
}
void ILibWebClient_DukTape_OnResponse(ILibWebClient_StateObject WebStateObject, int InterruptFlag, struct packetheader *header, char *bodyBuffer, int *beginPointer, int endPointer, ILibWebClient_ReceiveStatus recvStatus, void *user1, void *user2, int *PAUSE)
{
duk_context *ctx = (duk_context*)user1;
void *OnResp = user2;
int retVal;
duk_push_heapptr(ctx, OnResp); // [Func]
ILibWebClient_DukTape_Push_StateObject(ctx, WebStateObject); // [Func][state]
duk_push_int(ctx, InterruptFlag); // [Func][state][Interrupt]
ILibWebServer_DukTape_Push_PacketHeader(ctx, header); // [Func][state][Interrupt][header]
duk_get_prop_string(ctx, -3, "BufferPtr"); // [Func][state][Interrupt][header][buffer]
duk_config_buffer(ctx, -1, bodyBuffer + *beginPointer, endPointer - *beginPointer);
duk_push_int(ctx, endPointer - *beginPointer); // [Func][state][Interrupt][header][buffer][len]
duk_push_int(ctx, recvStatus); // [Func][state][Interrupt][header][buffer][len][status]
if (duk_pcall(ctx, 6) == 0)
{
if (duk_get_type(ctx, -1) == DUK_TYPE_UNDEFINED)
{
retVal = duk_to_int(ctx, -1);
if (retVal < 0)
{
*PAUSE = 1;
}
else
{
*beginPointer = retVal;
}
}
else
{
*beginPointer = endPointer;
}
}
else
{
ILibDuktape_Process_UncaughtException(ctx);
}
duk_pop(ctx);
if (recvStatus == ILibWebClient_ReceiveStatus_Complete)
{
// Done, so we can clear our reference in the heap stash
ILibWebClient_RequestToken token = ILibWebClient_GetRequestToken_FromStateObject(WebStateObject);
duk_push_heap_stash(ctx);
duk_del_prop_string(ctx, -1, Duktape_GetStashKey(WebStateObject));
if (token != NULL)
{
duk_del_prop_string(ctx, -1, Duktape_GetStashKey(token));
}
duk_pop(ctx);
}
}
duk_idx_t ILibWebClient_DukTape_PipelineRequest(duk_context *ctx)
{
int args = duk_get_top(ctx);
ILibHTTPPacket *packet;
char *addr;
int port;
struct sockaddr_in6* dest;
void *wcm;
ILibWebClient_OnResponse OnResp = NULL;
ILibWebClient_RequestToken token;
if (args < 3) { duk_push_string(ctx, "Too few arguments"); duk_throw(ctx); return(DUK_RET_ERROR); }
if (duk_get_prop_string(ctx, 1, "PacketPtr") == 0) { duk_push_string(ctx, "Invalid Argument[packet]"); duk_throw(ctx); return(DUK_RET_ERROR); }
packet = (ILibHTTPPacket*)duk_to_pointer(ctx, -1);
if (duk_get_prop_string(ctx, 0, "IPAddress") == 0) { duk_push_string(ctx, "Invalid Argument[RemoteEndpoint]"); duk_throw(ctx); return(DUK_RET_ERROR); }
addr = (char*)duk_to_string(ctx, -1);
if (duk_get_prop_string(ctx, 0, "Port") == 0) { duk_push_string(ctx, "Invalid Argument[RemoteEndpoint]"); duk_throw(ctx); return(DUK_RET_ERROR); }
port = duk_to_int(ctx, -1);
dest = Duktape_IPAddress4_FromString(addr, (unsigned short)port);
OnResp = duk_require_heapptr(ctx, 2);
duk_push_this(ctx);
duk_get_prop_string(ctx, -1, "ManagerPtr");
wcm = duk_to_pointer(ctx, -1);
duk_pop(ctx);
duk_dup(ctx, 2);
duk_put_prop_string(ctx, -2, "OnResponsePtr");
token = ILibWebClient_PipelineRequest(wcm, (struct sockaddr*)dest, packet, ILibWebClient_DukTape_OnResponse, ctx, OnResp);
ILibWebClient_DukTape_Push_RequestToken(ctx, token);
return 1;
}
duk_idx_t ILibWebClient_DukTape_Push_WebRequestManager(duk_context *ctx, void* wcm)
{
char* key = Duktape_GetStashKey(wcm);
duk_push_heap_stash(ctx);
if (duk_has_prop_string(ctx, -1, key))
{
duk_get_prop_string(ctx, -1, key);
}
else
{
duk_push_object(ctx);
duk_push_pointer(ctx, wcm);
duk_put_prop_string(ctx, -2, "ManagerPtr");
duk_push_c_function(ctx, ILibWebClient_DukTape_PipelineRequest, DUK_VARARGS);
duk_push_pointer(ctx, wcm);
duk_put_prop_string(ctx, -2, "ManagerPtr");
duk_put_prop_string(ctx, -2, "PipelineRequest");
}
duk_swap_top(ctx, -2); // Swap Stash and Object, so stash is on top
duk_pop(ctx); // Pop Stash off stack, leaving the object at top
return(duk_get_top_index(ctx));
}
duk_ret_t ILibWebClient_DukTape_Create(duk_context *ctx)
{
int poolSize = duk_require_int(ctx, 0);
void *chain;
ILibWebClient_RequestManager wcm;
duk_push_current_function(ctx);
duk_get_prop_string(ctx, -1, "chain");
chain = duk_to_pointer(ctx, -1);
duk_pop_2(ctx); // Pop Chain & Function
wcm = ILibCreateWebClient(poolSize, chain);
ILibWebClient_DukTape_Push_WebRequestManager(ctx, wcm);
return 1;
}
duk_ret_t ILibWebClient_DukTape_WebSocket_Finalizer(duk_context *ctx)
{
return 0;
}
duk_ret_t ILibWebClient_DukTape_WebSocket_Ptr_Setter(duk_context *ctx)
{
if (!duk_is_null(ctx, 0) && !duk_is_undefined(ctx, 0))
{
duk_push_this(ctx); // [wsock]
duk_push_current_function(ctx); // [wsock][func]
duk_get_prop_string(ctx, -1, "SetterKey"); // [wsock][func][key]
duk_swap_top(ctx, -2); // [wsock][key][func]
duk_pop(ctx); // [wsock][key]
duk_dup(ctx, 0); // [wsock][key][Ptr]
duk_put_prop(ctx, -3); // [wsock]
}
return 0;
}
void ILibWebClient_DukTape_WebSocket_OnResponse(ILibWebClient_StateObject WebStateObject, int InterruptFlag, struct packetheader *header, char *bodyBuffer, int *beginPointer, int endPointer, ILibWebClient_ReceiveStatus recvStatus, void *user1, void *user2, int *PAUSE)
{
duk_context *ctx = (duk_context*)user1;
if (header == NULL || (header->StatusCode != 101 && recvStatus == ILibWebClient_ReceiveStatus_Complete))
{
duk_push_heapptr(ctx, user2); // [wsock]
if (duk_has_prop_string(ctx, -1, "OnErrorPtr"))
{
duk_get_prop_string(ctx, -1, "OnErrorPtr"); // [wsock][OnError]
duk_swap_top(ctx, -2); // [OnError][this]
if (duk_pcall_method(ctx, 0) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(ctx);
}
duk_pop(ctx);
return;
}
duk_pop(ctx); // ...
return;
}
else if (header->StatusCode == 101)
{
ILibWebClient_DukTape_WebSocketCallbacks *callbacks = (ILibWebClient_DukTape_WebSocketCallbacks*)ILibMemory_GetExtraMemory(ILibWebClient_GetRequestToken_FromStateObject(WebStateObject), ILibMemory_WebClient_RequestToken_CONTAINERSIZE);
if (recvStatus == ILibWebClient_ReceiveStatus_Connection_Established)
{
memset(callbacks, 0, sizeof(ILibWebClient_DukTape_WebSocketCallbacks));
duk_push_heapptr(ctx, user2); // [wsock]
if (duk_has_prop_string(ctx, -1, "OnOpenPtr"))
{
duk_get_prop_string(ctx, -1, "OnMessagePtr"); // [wsock][OnMessage]
callbacks->OnMessage = duk_to_pointer(ctx, -1);
duk_pop(ctx); // [wsock]
duk_get_prop_string(ctx, -1, "OnSendOKPtr"); // [wsock][OnSendOK]
callbacks->OnSendOK = duk_to_pointer(ctx, -1);
duk_pop(ctx); // [wsock]
duk_push_pointer(ctx, WebStateObject); // [wsock][wcdo]
duk_put_prop_string(ctx, -2, "wcdo"); // [wsock]
duk_get_prop_string(ctx, -1, "OnOpenPtr"); // [wsock][OnOpen]
duk_swap_top(ctx, -2); // [OnOpen][this]
if (duk_pcall_method(ctx, 0) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(ctx);
}
}
duk_pop(ctx); // ...
}
else
{
if (callbacks->OnMessage != NULL)
{
duk_push_heapptr(ctx, callbacks->OnMessage); // [func]
duk_push_heapptr(ctx, user2); // [func][this]
duk_get_prop_string(ctx, -1, "buffer"); // [func][this][buffer]
duk_config_buffer(ctx, -1, bodyBuffer + *beginPointer, endPointer - *beginPointer);
duk_push_int(ctx, recvStatus); // [func][this][buffer][fragmentFlag]
if (duk_pcall_method(ctx, 2) == 0) // [retVal]
{
if (duk_is_number(ctx, -1))
{
*beginPointer = duk_to_int(ctx, -1);
}
else
{
*beginPointer = endPointer;
}
}
else
{
ILibDuktape_Process_UncaughtException(ctx);
}
duk_pop(ctx);
}
}
}
}
void ILibWebClient_DukTape_WebSocket_OnSendOK(ILibWebClient_StateObject wcdo, void* user1, void* user2)
{
duk_context *ctx = (duk_context*)user1;
ILibWebClient_DukTape_WebSocketCallbacks *callbacks = (ILibWebClient_DukTape_WebSocketCallbacks*)ILibMemory_GetExtraMemory(ILibWebClient_GetRequestToken_FromStateObject(wcdo), ILibMemory_WebClient_RequestToken_CONTAINERSIZE);
if (callbacks->OnSendOK != NULL)
{
duk_push_heapptr(ctx, callbacks->OnSendOK); // [func]
duk_push_heapptr(ctx, user2); // [func][this]
if (duk_pcall_method(ctx, 0) != 0) // [retVal]
{
ILibDuktape_Process_UncaughtException(ctx);
}
duk_pop(ctx); // ...
}
}
duk_ret_t ILibWebClient_DukTape_W3CWebSocket_Send(duk_context *ctx)
{
char *buffer;
duk_size_t bufferLen;
ILibWebClient_WebSocket_FragmentFlags fragmentFlag = ILibWebClient_WebSocket_FragmentFlag_Complete;
ILibWebClient_WebSocket_DataTypes bufferType = duk_is_string(ctx, 0) ? ILibWebClient_WebSocket_DataType_TEXT : ILibWebClient_WebSocket_DataType_BINARY;
ILibAsyncSocket_SendStatus status;
int nargs = duk_get_top(ctx);
if (nargs < 1) { duk_push_string(ctx, "Too Few Arguments"); duk_throw(ctx); return(DUK_RET_ERROR); }
if (nargs > 1) { fragmentFlag = (ILibWebClient_WebSocket_FragmentFlags)duk_require_int(ctx, 1); }
if (duk_is_string(ctx, 0))
{
buffer = (char*)duk_get_lstring(ctx, 0, &bufferLen);
}
else
{
buffer = Duktape_GetBuffer(ctx, 0, &bufferLen);
}
duk_push_this(ctx); // [wsock]
duk_get_prop_string(ctx, -1, "wcdo"); // [wsock][wcdo]
status = ILibWebClient_WebSocket_Send(duk_to_pointer(ctx, -1), bufferType, buffer, (int)bufferLen, ILibAsyncSocket_MemoryOwnership_USER, fragmentFlag);
duk_push_int(ctx, status);
return 1;
}
duk_ret_t ILibWebClient_DukTape_WebSocketContructor(duk_context *ctx)
{
if (!duk_is_string(ctx, 0)) { return(ILibDuktape_Error(ctx, "WebSocketConstructor(): Invalid Uri")); }
duk_size_t uriLen;
char *uri = (char*)duk_get_lstring(ctx, 0, &uriLen);
char *host;
char *path;
unsigned short port;
ILibHTTPPacket *packet;
int len;
int reassemblySize = 4096;
int poolSize = 5;
void *chain;
ILibWebClient_RequestManager *wcm;
ILibWebClient_RequestToken token;
struct sockaddr_in6* dest;
if (!duk_is_constructor_call(ctx))
{
return DUK_RET_TYPE_ERROR;
}
if (duk_get_top(ctx) > 1)
{
if (duk_has_prop_string(ctx, 1, "MaxBufferSize"))
{
duk_get_prop_string(ctx, 1, "MaxBufferSize");
reassemblySize = duk_to_int(ctx, -1);
duk_pop(ctx);
}
if (duk_has_prop_string(ctx, 1, "PoolSize"))
{
duk_get_prop_string(ctx, 1, "PoolSize");
poolSize = duk_to_int(ctx, -1);
duk_pop(ctx);
}
}
duk_push_current_function(ctx); // [func]
duk_get_prop_string(ctx, -1, "chain"); // [func][chain]
chain = duk_to_pointer(ctx, -1);
duk_push_this(ctx); // [func][chain][wsock]
duk_swap_top(ctx, -2); // [func][wsock][chain]
duk_put_prop_string(ctx, -2, "chain"); // [func][wsock]
ILibParseUri(uri, &host, &port, &path, NULL);
packet = ILibCreateEmptyPacket();
ILibSetVersion(packet, "1.1", 3);
ILibSetDirective(packet, "GET", 3, path, (int)strnlen_s(path, (int)uriLen));
len = sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "%s:%u", host, port);
ILibAddHeaderLine(packet, "Host", 4, ILibScratchPad, len);
ILibWebClient_AddWebSocketRequestHeaders(packet, reassemblySize, ILibWebClient_DukTape_WebSocket_OnSendOK);
duk_push_heap_stash(ctx); // [heapstash]
if (duk_has_prop_string(ctx, -1, "WSockClient"))
{
duk_get_prop_string(ctx, -1, "WSockClient"); // [heapstash][wcm]
wcm = (ILibWebClient_RequestManager)duk_to_pointer(ctx, -1);
duk_pop_2(ctx); // ...
}
else
{
wcm = ILibCreateWebClient(poolSize, chain);
duk_push_pointer(ctx, wcm); // [heapstash][wcm]
duk_put_prop_string(ctx, -2, "WSockClient"); // [heapstash]
}
duk_pop(ctx); // [func][wsock]
duk_push_c_function(ctx, ILibWebClient_DukTape_WebSocket_Finalizer, 1); // [func][wsock][fin]
duk_set_finalizer(ctx, -2); // [func][wsock]
duk_push_external_buffer(ctx); // [func][wsock][buffer]
duk_put_prop_string(ctx, -2, "buffer"); // [func][wsock]
duk_push_string(ctx, "onopen"); // [func][wsock][key]
duk_push_c_function(ctx, ILibWebClient_DukTape_WebSocket_Ptr_Setter, 1); // [func][wsock][key][func]
duk_push_string(ctx, "OnOpenPtr"); // [func][wsock][key][func][str]
duk_put_prop_string(ctx, -2, "SetterKey"); // [func][wsock][key][func]
duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_SETTER); // [func][wsock]
duk_push_string(ctx, "onmessage"); // [func][wsock][key]
duk_push_c_function(ctx, ILibWebClient_DukTape_WebSocket_Ptr_Setter, 1); // [func][wsock][key][func]
duk_push_string(ctx, "OnMessagePtr"); // [func][wsock][key][func][str]
duk_put_prop_string(ctx, -2, "SetterKey"); // [func][wsock][key][func]
duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_SETTER); // [func][wsock]
duk_push_string(ctx, "onerror"); // [func][wsock][key]
duk_push_c_function(ctx, ILibWebClient_DukTape_WebSocket_Ptr_Setter, 1); // [func][wsock][key][func]
duk_push_string(ctx, "OnErrorPtr"); // [func][wsock][key][func][str]
duk_put_prop_string(ctx, -2, "SetterKey"); // [func][wsock][key][func]
duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_SETTER); // [func][wsock]
duk_push_string(ctx, "onclose"); // [func][wsock][key]
duk_push_c_function(ctx, ILibWebClient_DukTape_WebSocket_Ptr_Setter, 1); // [func][wsock][key][func]
duk_push_string(ctx, "OnClosePtr"); // [func][wsock][key][func][str]
duk_put_prop_string(ctx, -2, "SetterKey"); // [func][wsock][key][func]
duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_SETTER); // [func][wsock]
duk_push_string(ctx, "onsendok"); // [func][wsock][key]
duk_push_c_function(ctx, ILibWebClient_DukTape_WebSocket_Ptr_Setter, 1); // [func][wsock][key][func]
duk_push_string(ctx, "OnSendOKPtr"); // [func][wsock][key][func][str]
duk_put_prop_string(ctx, -2, "SetterKey"); // [func][wsock][key][func]
duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_SETTER); // [func][wsock]
duk_push_c_function(ctx, ILibWebClient_DukTape_W3CWebSocket_Send, DUK_VARARGS); // [func][wsock][func]
duk_put_prop_string(ctx, -2, "Send"); // [func][wsock]
dest = Duktape_IPAddress4_FromString(host, port);
token = ILibWebClient_PipelineRequest(wcm, (struct sockaddr*)dest, packet, ILibWebClient_DukTape_WebSocket_OnResponse, ctx, duk_get_heapptr(ctx, -1));
duk_push_pointer(ctx, token); // [func][wsock][token]
duk_put_prop_string(ctx, -2, "RequestTokenPtr");// [func][wsock]
return 0;
}
void ILibWebClient_DukTape_Init(duk_context * ctx, void * chain)
{
duk_push_global_object(ctx);
duk_push_c_function(ctx, ILibWebClient_DukTape_Create, 1); // [global][func]
duk_push_pointer(ctx, chain); // [global][func][chain]
duk_put_prop_string(ctx, -2, "chain"); // [global][func]
duk_put_prop_string(ctx, -2, "ILibWebClient_Create"); // [global]
duk_push_c_function(ctx, ILibWebClient_DukTape_WebSocketContructor, DUK_VARARGS); // [global][func]
duk_push_pointer(ctx, chain); // [global][func][chain]
duk_put_prop_string(ctx, -2, "chain"); // [global][func]
duk_put_prop_string(ctx, -2, "WebSocket"); // [global]
Duktape_CreateEnum(ctx, "WebSocket_Status", (char*[]) { "COMPLETE_FRAGMENT", "END", "PARTIAL_FRAGMENT", "LAST_PARTIAL_FRAGMENT" }, (int[]) { 0, 1, 10, 11 }, 4);
duk_pop(ctx);
}