2019-01-14 10:45:25 +00:00
|
|
|
#include "App.h"
|
|
|
|
#include <v8.h>
|
|
|
|
#include "Utilities.h"
|
|
|
|
using namespace v8;
|
|
|
|
|
2019-01-18 15:33:56 +00:00
|
|
|
// todo: also check for use after free here!
|
2019-01-17 07:22:43 +00:00
|
|
|
// todo: probably isCorked, cork should be exposed?
|
|
|
|
|
2019-01-14 10:54:37 +00:00
|
|
|
struct WebSocketWrapper {
|
|
|
|
static Persistent<Object> wsTemplate[2];
|
2019-01-14 10:34:20 +00:00
|
|
|
|
2019-01-14 11:16:24 +00:00
|
|
|
template <bool SSL>
|
|
|
|
static inline uWS::WebSocket<SSL, true> *getWebSocket(const FunctionCallbackInfo<Value> &args) {
|
|
|
|
return ((uWS::WebSocket<SSL, true> *) args.Holder()->GetAlignedPointerFromInternalField(0));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Takes code, message, returns undefined */
|
|
|
|
template <bool SSL>
|
|
|
|
static void uWS_WebSocket_close(const FunctionCallbackInfo<Value> &args) {
|
|
|
|
int code = 0;
|
|
|
|
if (args.Length() >= 1) {
|
|
|
|
code = args[0]->Uint32Value();
|
|
|
|
}
|
|
|
|
|
2019-01-18 15:33:56 +00:00
|
|
|
NativeString message(args.GetIsolate(), args[1]);
|
|
|
|
if (message.isInvalid(args)) {
|
|
|
|
return;
|
2019-01-14 11:16:24 +00:00
|
|
|
}
|
|
|
|
|
2019-01-18 15:33:56 +00:00
|
|
|
getWebSocket<SSL>(args)->close(code, message.getString());
|
2019-01-14 11:16:24 +00:00
|
|
|
}
|
2019-01-14 10:34:20 +00:00
|
|
|
|
2019-01-14 11:16:24 +00:00
|
|
|
/* Takes nothing, returns integer */
|
|
|
|
template <bool SSL>
|
|
|
|
static void uWS_WebSocket_getBufferedAmount(const FunctionCallbackInfo<Value> &args) {
|
|
|
|
int bufferedAmount = getWebSocket<SSL>(args)->getBufferedAmount();
|
|
|
|
args.GetReturnValue().Set(Integer::New(isolate, bufferedAmount));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Takes message, isBinary. Returns true on success, false otherwise */
|
2019-01-14 10:54:37 +00:00
|
|
|
template <bool SSL>
|
|
|
|
static void uWS_WebSocket_send(const FunctionCallbackInfo<Value> &args) {
|
2019-01-18 15:33:56 +00:00
|
|
|
NativeString message(args.GetIsolate(), args[0]);
|
|
|
|
if (message.isInvalid(args)) {
|
|
|
|
return;
|
|
|
|
}
|
2019-01-14 10:34:20 +00:00
|
|
|
|
2019-01-14 11:16:24 +00:00
|
|
|
bool isBinary = args[1]->BooleanValue();
|
2019-01-14 10:34:20 +00:00
|
|
|
|
2019-01-18 15:33:56 +00:00
|
|
|
bool ok = getWebSocket<SSL>(args)->send(message.getString(), isBinary ? uWS::OpCode::BINARY : uWS::OpCode::TEXT);
|
2019-01-14 10:34:20 +00:00
|
|
|
|
2019-01-14 10:54:37 +00:00
|
|
|
args.GetReturnValue().Set(Boolean::New(isolate, ok));
|
|
|
|
}
|
2019-01-14 10:34:20 +00:00
|
|
|
|
2019-01-14 10:54:37 +00:00
|
|
|
template <bool SSL>
|
|
|
|
static void initWsTemplate() {
|
|
|
|
Local<FunctionTemplate> wsTemplateLocal = FunctionTemplate::New(isolate);
|
|
|
|
if (SSL) {
|
|
|
|
wsTemplateLocal->SetClassName(String::NewFromUtf8(isolate, "uWS.SSLWebSocket"));
|
|
|
|
} else {
|
|
|
|
wsTemplateLocal->SetClassName(String::NewFromUtf8(isolate, "uWS.WebSocket"));
|
|
|
|
}
|
|
|
|
wsTemplateLocal->InstanceTemplate()->SetInternalFieldCount(1);
|
2019-01-14 11:16:24 +00:00
|
|
|
|
|
|
|
/* Register our functions */
|
2019-01-14 10:54:37 +00:00
|
|
|
wsTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "send"), FunctionTemplate::New(isolate, uWS_WebSocket_send<SSL>));
|
2019-01-14 11:16:24 +00:00
|
|
|
wsTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "close"), FunctionTemplate::New(isolate, uWS_WebSocket_close<SSL>));
|
|
|
|
wsTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getBufferedAmount"), FunctionTemplate::New(isolate, uWS_WebSocket_getBufferedAmount<SSL>));
|
2019-01-14 10:54:37 +00:00
|
|
|
|
2019-01-14 11:16:24 +00:00
|
|
|
/* Create the template */
|
2019-01-14 10:54:37 +00:00
|
|
|
Local<Object> wsObjectLocal = wsTemplateLocal->GetFunction()->NewInstance(isolate->GetCurrentContext()).ToLocalChecked();
|
|
|
|
wsTemplate[SSL].Reset(isolate, wsObjectLocal);
|
2019-01-14 10:34:20 +00:00
|
|
|
}
|
|
|
|
|
2019-01-14 11:16:24 +00:00
|
|
|
/* This is where we output an instance */
|
2019-01-14 10:54:37 +00:00
|
|
|
template <class APP>
|
|
|
|
static Local<Object> getWsInstance() {
|
|
|
|
return Local<Object>::New(isolate, wsTemplate[std::is_same<APP, uWS::SSLApp>::value])->Clone();
|
|
|
|
}
|
|
|
|
};
|
2019-01-14 10:34:20 +00:00
|
|
|
|
2019-01-14 11:16:24 +00:00
|
|
|
/* Fix this, should be nicer */
|
2019-01-14 10:54:37 +00:00
|
|
|
Persistent<Object> WebSocketWrapper::wsTemplate[2];
|