From 103f6ff03c250f38f30322ea81c2d66739d6f10a Mon Sep 17 00:00:00 2001 From: Dries De Winter <32574669+driesdewinter@users.noreply.github.com> Date: Tue, 16 Jan 2024 20:38:26 +0100 Subject: [PATCH] Add binding for App.filter (#1010) --- docs/index.d.ts | 2 ++ src/AppWrapper.h | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/docs/index.d.ts b/docs/index.d.ts index 496316ed..6b3c4fe8 100644 --- a/docs/index.d.ts +++ b/docs/index.d.ts @@ -325,6 +325,8 @@ export interface TemplatedApp { removeServerName(hostname: string) : TemplatedApp; /** Registers a synchronous callback on missing server names. See /examples/ServerName.js. */ missingServerName(cb: (hostname: string) => void) : TemplatedApp; + /** Attaches a "filter" function to track socket connections / disconnections */ + filter(cb: (res: HttpResponse, count: Number) => void | Promise) : TemplatedApp; /** Closes all sockets including listen sockets. This will forcefully terminate all connections. */ close() : TemplatedApp; } diff --git a/src/AppWrapper.h b/src/AppWrapper.h index 1a05ce02..96d4447a 100644 --- a/src/AppWrapper.h +++ b/src/AppWrapper.h @@ -431,6 +431,34 @@ void uWS_App_listen(const FunctionCallbackInfo &args) { args.GetReturnValue().Set(args.Holder()); } +template +void uWS_App_filter(const FunctionCallbackInfo &args) { + APP *app = (APP *) args.Holder()->GetAlignedPointerFromInternalField(0); + + /* Handler */ + Callback checkedCallback(args.GetIsolate(), args[0]); + if (checkedCallback.isInvalid(args)) { + return; + } + UniquePersistent cb = checkedCallback.getFunction(); + + /* This function requires perContextData */ + PerContextData *perContextData = (PerContextData *) Local::Cast(args.Data())->Value(); + + app->filter([cb = std::move(cb), perContextData](auto *res, int count) { + Isolate *isolate = perContextData->isolate; + HandleScope hs(isolate); + + Local resObject = perContextData->resTemplate[getAppTypeIndex()].Get(isolate)->Clone(); + resObject->SetAlignedPointerInInternalField(0, res); + + Local argv[] = {resObject, Local::Cast(Integer::New(isolate, count))}; + CallJS(isolate, cb.Get(isolate), 2, argv); + }); + + args.GetReturnValue().Set(args.Holder()); +} + template void uWS_App_domain(const FunctionCallbackInfo &args) { APP *app = (APP *) args.Holder()->GetAlignedPointerFromInternalField(0); @@ -719,6 +747,7 @@ void uWS_App(const FunctionCallbackInfo &args) { appTemplate->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "close", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, uWS_App_close, args.Data())); appTemplate->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "listen_unix", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, uWS_App_listen_unix, args.Data())); + appTemplate->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "filter", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, uWS_App_filter, args.Data())); /* ws, listen */ appTemplate->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "ws", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, uWS_App_ws, args.Data()));