From d1a2556fba82dbf8db00a47e0301ea4fcd76abef Mon Sep 17 00:00:00 2001 From: Alex Hultman Date: Fri, 5 Jun 2020 16:49:26 +0200 Subject: [PATCH] Merge userData with wsObject --- examples/Upgrade.js | 2 +- src/AppWrapper.h | 31 ++++++++++++++++++++----------- src/HttpResponseWrapper.h | 16 ++++------------ 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/examples/Upgrade.js b/examples/Upgrade.js index c37dc64f..a66b148a 100644 --- a/examples/Upgrade.js +++ b/examples/Upgrade.js @@ -22,7 +22,7 @@ const app = uWS./*SSL*/App({ context); }, open: (ws) => { - console.log('A WebSocket connected with URL: ' + ws.userData.url); + console.log('A WebSocket connected with URL: ' + ws.url); }, message: (ws, message, isBinary) => { /* Ok is false if backpressure was built up, wait for drain */ diff --git a/src/AppWrapper.h b/src/AppWrapper.h index 1dce0517..f567be89 100644 --- a/src/AppWrapper.h +++ b/src/AppWrapper.h @@ -102,22 +102,31 @@ void uWS_App_ws(const FunctionCallbackInfo &args) { Isolate *isolate = perContextData->isolate; HandleScope hs(isolate); - printf("Open event called!\n"); - - /* Retrieve temporary userData object */ - PerSocketData *perSocketData = (PerSocketData *) ws->getUserData(); - - // if socketPf is nullptr we have nothing to copy - Local userData = Local::New(isolate, *(perSocketData->socketPf)); - /* Create a new websocket object */ Local wsObject = perContextData->wsTemplate[getAppTypeIndex()].Get(isolate)->Clone(); wsObject->SetAlignedPointerInInternalField(0, ws); - /* Copy entires from userData */ - wsObject->Set(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "userData"), userData); + /* Retrieve temporary userData object */ + PerSocketData *perSocketData = (PerSocketData *) ws->getUserData(); - /* Attach a new V8 object with pointer to us, to us */ + /* Copy entires from userData, only if we have it set */ + if (perSocketData->socketPf) { + /* socketPf points to a stack allocated UniquePersistent, or nullptr, at this point */ + Local userData = Local::New(isolate, *(perSocketData->socketPf)); + + /* Merge userData and wsObject; this code is exceedingly horrible */ + Local keys; + if (userData->GetOwnPropertyNames(isolate->GetCurrentContext()).ToLocal(&keys)) { + for (int i = 0; i < keys->Length(); i++) { + wsObject->Set(isolate->GetCurrentContext(), + keys->Get(isolate->GetCurrentContext(), i).ToLocalChecked(), + userData->Get(isolate->GetCurrentContext(), keys->Get(isolate->GetCurrentContext(), i).ToLocalChecked()).ToLocalChecked() + ); + } + } + } + + /* Attach a new V8 object with pointer to us, to it */ perSocketData->socketPf = new UniquePersistent; perSocketData->socketPf->Reset(isolate, wsObject); diff --git a/src/HttpResponseWrapper.h b/src/HttpResponseWrapper.h index 2f917393..26c1d67a 100644 --- a/src/HttpResponseWrapper.h +++ b/src/HttpResponseWrapper.h @@ -248,26 +248,17 @@ struct HttpResponseWrapper { } } + /* Takes UserData, secKey, secProtocol, secExtensions, context. Returns nothing */ template static void res_upgrade(const FunctionCallbackInfo &args) { Isolate *isolate = args.GetIsolate(); auto *res = getHttpResponse(args); if (res) { - - printf("Calling upgrade!\n"); - + /* We require exactly 5 arguments */ if (args.Length() != 5) { return; } - /* We are being passed userData (wsObject) */ - //Local wsObject = args[0]; - //Local secWebSocketKey = args[1]; - //Local secWebSocketProtocol = args[2]; - //Local secWebSocketExtensions = args[3]; - //Local context = args[4]; - - NativeString secWebSocketKey(args.GetIsolate(), args[1]); if (secWebSocketKey.isInvalid(args)) { return; @@ -287,10 +278,11 @@ struct HttpResponseWrapper { invalidateResObject(args); + /* This releases on return */ UniquePersistent userData; userData.Reset(isolate, Local::Cast(args[0])); - printf("Upgrading now!\n"); + /* Immediately calls open handler */ res->template upgrade({ .socketPf = &userData }, secWebSocketKey.getString(), secWebSocketProtocol.getString(),