diff --git a/examples/HelloWorld.js b/examples/HelloWorld.js index 269bde6..f738711 100644 --- a/examples/HelloWorld.js +++ b/examples/HelloWorld.js @@ -7,8 +7,10 @@ const app = uWS./*SSL*/App({ key_file_name: '/home/alexhultman/key.pem', cert_file_name: '/home/alexhultman/cert.pem', passphrase: '1234' +}).get('/static/:param', (res, req) => { + res.end('Hello, your url is ' + req.getUrl() + ". The param1 is " + req.getParameter(0)); }).get('/hello', (res, req) => { - res.end('Hejdå!'); + res.end('Hej, du är på url: ' + req.getUrl()); }).ws('/*', { compression: 0, maxPayloadLength: 16 * 1024 * 1024, diff --git a/src/AppWrapper.h b/src/AppWrapper.h index 4a32864..de3e409 100644 --- a/src/AppWrapper.h +++ b/src/AppWrapper.h @@ -145,7 +145,7 @@ void uWS_App_get(const FunctionCallbackInfo &args) { Local resObject = getResInstance(); resObject->SetAlignedPointerInInternalField(0, res); - Local reqObject = Local::New(isolate, reqTemplate)->Clone(); + Local reqObject = HttpRequestWrapper::getReqInstance();//Local::New(isolate, reqTemplate)->Clone(); reqObject->SetAlignedPointerInInternalField(0, req); Local argv[] = {resObject, reqObject}; diff --git a/src/HttpRequestWrapper.h b/src/HttpRequestWrapper.h index 9518b0f..8eaa8cb 100644 --- a/src/HttpRequestWrapper.h +++ b/src/HttpRequestWrapper.h @@ -1,34 +1,70 @@ -// req.getParam(int) -// req.getUrl() -// req.onAbort ? - -/* Helping QtCreator */ +#include "App.h" #include #include "Utilities.h" using namespace v8; -/* The only thing this req needs is getHeader and similar, getParameter, getUrl and so on */ -Persistent reqTemplate; +/* This one is the same for SSL and non-SSL */ +struct HttpRequestWrapper { + static Persistent reqTemplate; -void req_getHeader(const FunctionCallbackInfo &args) { - NativeString data(args.GetIsolate(), args[0]); - char *buf = data.getData(); int length = data.getLength(); + // todo: refuse all function calls if we are not inside correct callback - std::string_view header = ((uWS::HttpRequest *) args.Holder()->GetAlignedPointerFromInternalField(0))->getHeader(std::string_view(buf, length)); + static inline uWS::HttpRequest *getHttpRequest(const FunctionCallbackInfo &args) { + return ((uWS::HttpRequest *) args.Holder()->GetAlignedPointerFromInternalField(0)); + } - args.GetReturnValue().Set(String::NewFromUtf8(isolate, header.data(), v8::String::kNormalString, header.length())); -} + // req.onAbort ? -void initReqTemplate() { - /*reqTemplateLocal->PrototypeTemplate()->SetAccessor(String::NewFromUtf8(isolate, "url"), Request::url); - reqTemplateLocal->PrototypeTemplate()->SetAccessor(String::NewFromUtf8(isolate, "method"), Request::method);*/ + /* Takes int, returns string (must be in bounds) */ + static void req_getParameter(const FunctionCallbackInfo &args) { + int index = args[0]->Uint32Value(); + std::string_view parameter = getHttpRequest(args)->getParameter(index); - // Request template (do we need to clone this?) - Local reqTemplateLocal = FunctionTemplate::New(isolate); - reqTemplateLocal->SetClassName(String::NewFromUtf8(isolate, "uWS.HttpRequest")); - reqTemplateLocal->InstanceTemplate()->SetInternalFieldCount(1); - reqTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getHeader"), FunctionTemplate::New(isolate, req_getHeader)); + args.GetReturnValue().Set(String::NewFromUtf8(isolate, parameter.data(), v8::String::kNormalString, parameter.length())); + } - Local reqObjectLocal = reqTemplateLocal->GetFunction()->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); - reqTemplate.Reset(isolate, reqObjectLocal); -} + /* Takes nothing, returns string */ + static void req_getUrl(const FunctionCallbackInfo &args) { + std::string_view url = getHttpRequest(args)->getUrl(); + + args.GetReturnValue().Set(String::NewFromUtf8(isolate, url.data(), v8::String::kNormalString, url.length())); + } + + /* Takes String, returns String */ + static void req_getHeader(const FunctionCallbackInfo &args) { + NativeString data(args.GetIsolate(), args[0]); + char *buf = data.getData(); int length = data.getLength(); + + std::string_view header = getHttpRequest(args)->getHeader(std::string_view(buf, length)); + + args.GetReturnValue().Set(String::NewFromUtf8(isolate, header.data(), v8::String::kNormalString, header.length())); + } + + static void initReqTemplate() { + /* The only thing this req needs is getHeader and similar, getParameter, getUrl and so on */ + + /*reqTemplateLocal->PrototypeTemplate()->SetAccessor(String::NewFromUtf8(isolate, "url"), Request::url); + reqTemplateLocal->PrototypeTemplate()->SetAccessor(String::NewFromUtf8(isolate, "method"), Request::method);*/ + + /* We do clone every request object, we could share them, they are illegal to use outside the function anyways */ + Local reqTemplateLocal = FunctionTemplate::New(isolate); + reqTemplateLocal->SetClassName(String::NewFromUtf8(isolate, "uWS.HttpRequest")); + reqTemplateLocal->InstanceTemplate()->SetInternalFieldCount(1); + + /* Register our functions */ + reqTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getHeader"), FunctionTemplate::New(isolate, req_getHeader)); + reqTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getParameter"), FunctionTemplate::New(isolate, req_getParameter)); + reqTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getUrl"), FunctionTemplate::New(isolate, req_getUrl)); + + /* Create the template */ + Local reqObjectLocal = reqTemplateLocal->GetFunction()->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); + reqTemplate.Reset(isolate, reqObjectLocal); + } + + //template + static Local getReqInstance() { + return Local::New(isolate, reqTemplate)->Clone(); + } +}; + +Persistent HttpRequestWrapper::reqTemplate; diff --git a/src/addon.cpp b/src/addon.cpp index f6c959f..a95511f 100644 --- a/src/addon.cpp +++ b/src/addon.cpp @@ -84,7 +84,7 @@ void Main(Local exports) { initResTemplate<1>(); /* Init a shared request object */ - initReqTemplate(); + HttpRequestWrapper::initReqTemplate(); } /* This is required when building as a Node.js addon */