Skip to content

Commit c25e9e3

Browse files
committed
Wrap cache a bit
1 parent 54f6830 commit c25e9e3

File tree

4 files changed

+98
-26
lines changed

4 files changed

+98
-26
lines changed

src/AppWrapper.h

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -810,9 +810,69 @@ void uWS_App(const FunctionCallbackInfo<Value> &args) {
810810

811811
appTemplate->InstanceTemplate()->SetInternalFieldCount(1);
812812

813+
813814
/* All the http methods */
814815
appTemplate->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "get", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, [](auto &args) {
815-
uWS_App_get<APP>(&APP::get, args);
816+
817+
/* Add non-cached variants */
818+
if constexpr (std::is_same<APP, uWS::App>::value) {
819+
820+
if (args.Length() == 3) {
821+
/* Use cached variant */
822+
std::cout << "Registering cached get handler" << std::endl;
823+
824+
825+
APP *app = (APP *) args.Holder()->GetAlignedPointerFromInternalField(0);
826+
827+
/* Pattern */
828+
NativeString pattern(args.GetIsolate(), args[0]);
829+
if (pattern.isInvalid(args)) {
830+
return;
831+
}
832+
833+
/* Handler */
834+
Callback checkedCallback(args.GetIsolate(), args[1]);
835+
if (checkedCallback.isInvalid(args)) {
836+
return;
837+
}
838+
UniquePersistent<Function> cb = checkedCallback.getFunction();
839+
840+
/* This function requires perContextData */
841+
PerContextData *perContextData = (PerContextData *) Local<External>::Cast(args.Data())->Value();
842+
843+
app->get(std::string(pattern.getString()), [cb = std::move(cb), perContextData](auto *res, auto *req) {
844+
Isolate *isolate = perContextData->isolate;
845+
HandleScope hs(isolate);
846+
847+
848+
// this needs to be cachedresponse wrapper (for both cached tcp and cached SSL?)
849+
Local<Object> resObject = perContextData->resTemplate[/*getAppTypeIndex<APP>()*/3].Get(isolate)->Clone();
850+
resObject->SetAlignedPointerInInternalField(0, res);
851+
852+
Local<Object> reqObject = perContextData->reqTemplate[std::is_same<APP, uWS::H3App>::value].Get(isolate)->Clone();
853+
reqObject->SetAlignedPointerInInternalField(0, req);
854+
855+
Local<Value> argv[] = {resObject, reqObject};
856+
CallJS(isolate, cb.Get(isolate), 2, argv);
857+
858+
/* Properly invalidate req */
859+
reqObject->SetAlignedPointerInInternalField(0, nullptr);
860+
861+
/* µWS itself will terminate if not responded and not attached
862+
* onAborted handler, so we can assume it's done */
863+
}, 13);
864+
865+
args.GetReturnValue().Set(args.Holder());
866+
867+
868+
} else {
869+
uWS_App_get<APP>(&uWS::TemplatedApp<false, uWS::CachingApp<false>>::get, args);
870+
}
871+
872+
} else if constexpr (std::is_same<APP, uWS::SSLApp>::value) {
873+
uWS_App_get<APP>(&uWS::TemplatedApp<true, uWS::CachingApp<true>>::get, args);
874+
}
875+
816876
}, args.Data()));
817877

818878
appTemplate->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "post", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, [](auto &args) {

src/HttpResponseWrapper.h

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ using namespace v8;
2323

2424
thread_local int insideCorkCallback = 0;
2525

26+
/* PROTOCOL is 0 = TCP, 1 = TLS, 2 = QUIC, 3 = CACHE */
27+
2628
struct HttpResponseWrapper {
2729

2830
static void assumeCorked() {
@@ -34,15 +36,17 @@ struct HttpResponseWrapper {
3436
template <int PROTOCOL>
3537
static inline constexpr decltype(auto) getHttpResponse(const FunctionCallbackInfo<Value> &args) {
3638
Isolate *isolate = args.GetIsolate();
37-
auto *res = (uWS::HttpResponse<PROTOCOL != 0> *) args.Holder()->GetAlignedPointerFromInternalField(0);
39+
void *res = args.Holder()->GetAlignedPointerFromInternalField(0);
3840
if (!res) {
3941
args.GetReturnValue().Set(isolate->ThrowException(v8::Exception::Error(String::NewFromUtf8(isolate, "uWS.HttpResponse must not be accessed after uWS.HttpResponse.onAborted callback, or after a successful response. See documentation for uWS.HttpResponse and consult the user manual.", NewStringType::kNormal).ToLocalChecked())));
4042
}
4143

4244
if constexpr (PROTOCOL == 2) {
4345
return (uWS::Http3Response *) res;
46+
} else if constexpr (PROTOCOL == 3) {
47+
return (uWS::CachingHttpResponse *) res;
4448
} else {
45-
return res;
49+
return (uWS::HttpResponse<PROTOCOL != 0> *) res;
4650
}
4751
}
4852

@@ -417,7 +421,7 @@ struct HttpResponseWrapper {
417421
}
418422
}
419423

420-
/* 0 = TCP, 1 = TLS, 2 = QUIC */
424+
/* 0 = TCP, 1 = TLS, 2 = QUIC, 3 = CACHE */
421425
template <int SSL>
422426
static Local<Object> init(Isolate *isolate) {
423427
Local<FunctionTemplate> resTemplateLocal = FunctionTemplate::New(isolate);
@@ -427,32 +431,39 @@ struct HttpResponseWrapper {
427431
resTemplateLocal->SetClassName(String::NewFromUtf8(isolate, "uWS.HttpResponse", NewStringType::kNormal).ToLocalChecked());
428432
} else if (SSL == 2) {
429433
resTemplateLocal->SetClassName(String::NewFromUtf8(isolate, "uWS.Http3Response", NewStringType::kNormal).ToLocalChecked());
434+
} else if (SSL == 3) {
435+
resTemplateLocal->SetClassName(String::NewFromUtf8(isolate, "uWS.CachedHttpResponse", NewStringType::kNormal).ToLocalChecked());
430436
}
431437
resTemplateLocal->InstanceTemplate()->SetInternalFieldCount(1);
432438

433439
/* Register our functions */
434-
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "writeStatus", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_writeStatus<SSL>));
435440
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "end", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_end<SSL>));
436-
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "endWithoutBody", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_endWithoutBody<SSL>));
437-
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "tryEnd", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_tryEnd<SSL>));
438-
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "write", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_write<SSL>));
439-
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "writeHeader", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_writeHeader<SSL>));
440-
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "close", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_close<SSL>));
441-
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "onWritable", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_onWritable<SSL>));
442-
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "onAborted", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_onAborted<SSL>));
443-
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "onData", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_onData<SSL>));
444-
445-
if constexpr (SSL != 2) {
446-
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getWriteOffset", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_getWriteOffset<SSL>));
447-
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getRemoteAddress", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_getRemoteAddress<SSL>));
448-
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "cork", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_cork<SSL>));
449-
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "collect", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_cork<SSL>));
450-
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "upgrade", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_upgrade<SSL>));
451-
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getRemoteAddressAsText", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_getRemoteAddressAsText<SSL>));
452-
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getProxiedRemoteAddress", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_getProxiedRemoteAddress<SSL>));
453-
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getProxiedRemoteAddressAsText", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_getProxiedRemoteAddressAsText<SSL>));
454-
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "pause", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_pause<SSL>));
455-
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "resume", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_resume<SSL>));
441+
442+
/* Cache has almost nothing wrapped yet */
443+
if constexpr (SSL != 3) {
444+
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "writeStatus", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_writeStatus<SSL>));
445+
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "endWithoutBody", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_endWithoutBody<SSL>));
446+
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "tryEnd", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_tryEnd<SSL>));
447+
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "write", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_write<SSL>));
448+
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "writeHeader", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_writeHeader<SSL>));
449+
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "close", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_close<SSL>));
450+
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "onWritable", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_onWritable<SSL>));
451+
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "onAborted", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_onAborted<SSL>));
452+
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "onData", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_onData<SSL>));
453+
454+
/* QUIC has a lot of functions unimplemented */
455+
if constexpr (SSL != 2) {
456+
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getWriteOffset", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_getWriteOffset<SSL>));
457+
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getRemoteAddress", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_getRemoteAddress<SSL>));
458+
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "cork", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_cork<SSL>));
459+
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "collect", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_cork<SSL>));
460+
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "upgrade", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_upgrade<SSL>));
461+
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getRemoteAddressAsText", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_getRemoteAddressAsText<SSL>));
462+
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getProxiedRemoteAddress", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_getProxiedRemoteAddress<SSL>));
463+
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getProxiedRemoteAddressAsText", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_getProxiedRemoteAddressAsText<SSL>));
464+
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "pause", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_pause<SSL>));
465+
resTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "resume", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, res_resume<SSL>));
466+
}
456467
}
457468

458469
/* Create our template */

src/Utilities.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ struct PerSocketData {
5353
struct PerContextData {
5454
Isolate *isolate;
5555
UniquePersistent<Object> reqTemplate[2]; // 0 = non-SSL/SSL, 1 = Http3
56-
UniquePersistent<Object> resTemplate[3]; // 0 = non-SSL, 1 = SSL, 2 = Http3
56+
UniquePersistent<Object> resTemplate[4]; // 0 = non-SSL, 1 = SSL, 2 = Http3
5757
UniquePersistent<Object> wsTemplate[2];
5858

5959
/* We hold all apps until free */

src/addon.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ PerContextData *Main(Local<Object> exports) {
382382
perContextData->resTemplate[0].Reset(isolate, HttpResponseWrapper::init<0>(isolate));
383383
perContextData->resTemplate[1].Reset(isolate, HttpResponseWrapper::init<1>(isolate));
384384
perContextData->resTemplate[2].Reset(isolate, HttpResponseWrapper::init<2>(isolate));
385+
perContextData->resTemplate[3].Reset(isolate, HttpResponseWrapper::init<3>(isolate));
385386
perContextData->wsTemplate[0].Reset(isolate, WebSocketWrapper::init<0>(isolate));
386387
perContextData->wsTemplate[1].Reset(isolate, WebSocketWrapper::init<1>(isolate));
387388

0 commit comments

Comments
 (0)