From f77d07014a86de218ec6b53d29409133a58a70b3 Mon Sep 17 00:00:00 2001 From: Alex Hultman Date: Mon, 17 Aug 2020 03:57:37 +0200 Subject: [PATCH] addServerName, removeServerName, ServerName.js --- examples/ServerName.js | 26 +++++++++++++ src/AppWrapper.h | 86 +++++++++++++++++++++++++++++++++++------- uWebSockets | 2 +- 3 files changed, 99 insertions(+), 15 deletions(-) create mode 100644 examples/ServerName.js diff --git a/examples/ServerName.js b/examples/ServerName.js new file mode 100644 index 0000000..15fa0c9 --- /dev/null +++ b/examples/ServerName.js @@ -0,0 +1,26 @@ +/* Minimal SSL example using ServerNameIndication */ + +const uWS = require('../dist/uws.js'); +const port = 9001; + +const app = uWS.SSLApp({ + key_file_name: 'misc/key.pem', + cert_file_name: 'misc/cert.pem', + passphrase: '1234' +}).addServerName("localhost", { + key_file_name: 'misc/key.pem', + cert_file_name: 'misc/cert.pem', + passphrase: '1234' +}).removeServerName("localhost").addServerName("localhost", { + key_file_name: 'misc/key.pem', + cert_file_name: 'misc/cert.pem', + passphrase: '1234' +}).get('/*', (res, req) => { + res.end('Hello World!'); +}).listen(port, (token) => { + if (token) { + console.log('Listening to port ' + port); + } else { + console.log('Failed to listen to port ' + port); + } +}); diff --git a/src/AppWrapper.h b/src/AppWrapper.h index cc4a346..61f776b 100644 --- a/src/AppWrapper.h +++ b/src/AppWrapper.h @@ -312,24 +312,20 @@ void uWS_App_publish(const FunctionCallbackInfo &args) { app->publish(topic.getString(), message.getString(), BooleanValue(isolate, args[2]) ? uWS::OpCode::BINARY : uWS::OpCode::TEXT, BooleanValue(isolate, args[3])); } -template -void uWS_App(const FunctionCallbackInfo &args) { - +/* This one modified per-thread static strings temporarily */ +std::pair readOptionsObject(const FunctionCallbackInfo &args, int index) { Isolate *isolate = args.GetIsolate(); - Local appTemplate = FunctionTemplate::New(isolate); - appTemplate->SetClassName(String::NewFromUtf8(isolate, std::is_same::value ? "uWS.SSLApp" : "uWS.App", NewStringType::kNormal).ToLocalChecked()); - /* Read the options object if any */ us_socket_context_options_t options = {}; - std::string keyFileName, certFileName, passphrase, dhParamsFileName, caFileName; - if (args.Length() == 1) { + thread_local std::string keyFileName, certFileName, passphrase, dhParamsFileName, caFileName; + if (args.Length() > index) { - Local optionsObject = Local::Cast(args[0]); + Local optionsObject = Local::Cast(args[index]); /* Key file name */ NativeString keyFileNameValue(isolate, optionsObject->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "key_file_name", NewStringType::kNormal).ToLocalChecked()).ToLocalChecked()); if (keyFileNameValue.isInvalid(args)) { - return; + return {}; } if (keyFileNameValue.getString().length()) { keyFileName = keyFileNameValue.getString(); @@ -339,7 +335,7 @@ void uWS_App(const FunctionCallbackInfo &args) { /* Cert file name */ NativeString certFileNameValue(isolate, optionsObject->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "cert_file_name", NewStringType::kNormal).ToLocalChecked()).ToLocalChecked()); if (certFileNameValue.isInvalid(args)) { - return; + return {}; } if (certFileNameValue.getString().length()) { certFileName = certFileNameValue.getString(); @@ -349,7 +345,7 @@ void uWS_App(const FunctionCallbackInfo &args) { /* Passphrase */ NativeString passphraseValue(isolate, optionsObject->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "passphrase", NewStringType::kNormal).ToLocalChecked()).ToLocalChecked()); if (passphraseValue.isInvalid(args)) { - return; + return {}; } if (passphraseValue.getString().length()) { passphrase = passphraseValue.getString(); @@ -359,7 +355,7 @@ void uWS_App(const FunctionCallbackInfo &args) { /* DH params file name */ NativeString dhParamsFileNameValue(isolate, optionsObject->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "dh_params_file_name", NewStringType::kNormal).ToLocalChecked()).ToLocalChecked()); if (dhParamsFileNameValue.isInvalid(args)) { - return; + return {}; } if (dhParamsFileNameValue.getString().length()) { dhParamsFileName = dhParamsFileNameValue.getString(); @@ -369,7 +365,7 @@ void uWS_App(const FunctionCallbackInfo &args) { /* CA file name */ NativeString caFileNameValue(isolate, optionsObject->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "ca_file_name", NewStringType::kNormal).ToLocalChecked()).ToLocalChecked()); if (caFileNameValue.isInvalid(args)) { - return; + return {}; } if (caFileNameValue.getString().length()) { caFileName = caFileNameValue.getString(); @@ -380,6 +376,64 @@ void uWS_App(const FunctionCallbackInfo &args) { options.ssl_prefer_low_memory_usage = BooleanValue(isolate, optionsObject->Get(isolate->GetCurrentContext(), String::NewFromUtf8(isolate, "ssl_prefer_low_memory_usage", NewStringType::kNormal).ToLocalChecked()).ToLocalChecked()); } + return {options, true}; +} + +template +void uWS_App_addServerName(const FunctionCallbackInfo &args) { + APP *app = (APP *) args.Holder()->GetAlignedPointerFromInternalField(0); + + Isolate *isolate = args.GetIsolate(); + NativeString hostnamePatternValue(isolate, args[0]); + if (hostnamePatternValue.isInvalid(args)) { + return; + } + std::string hostnamePattern; + if (hostnamePatternValue.getString().length()) { + hostnamePattern = hostnamePatternValue.getString(); + } + + auto [options, valid] = readOptionsObject(args, 1); + if (!valid) { + return; + } + + app->addServerName(hostnamePattern.c_str(), options); + + args.GetReturnValue().Set(args.Holder()); +} + +template +void uWS_App_removeServerName(const FunctionCallbackInfo &args) { + APP *app = (APP *) args.Holder()->GetAlignedPointerFromInternalField(0); + + Isolate *isolate = args.GetIsolate(); + NativeString hostnamePatternValue(isolate, args[0]); + if (hostnamePatternValue.isInvalid(args)) { + return; + } + std::string hostnamePattern; + if (hostnamePatternValue.getString().length()) { + hostnamePattern = hostnamePatternValue.getString(); + } + + app->removeServerName(hostnamePattern.c_str()); + + args.GetReturnValue().Set(args.Holder()); +} + +template +void uWS_App(const FunctionCallbackInfo &args) { + + Isolate *isolate = args.GetIsolate(); + Local appTemplate = FunctionTemplate::New(isolate); + appTemplate->SetClassName(String::NewFromUtf8(isolate, std::is_same::value ? "uWS.SSLApp" : "uWS.App", NewStringType::kNormal).ToLocalChecked()); + + auto [options, valid] = readOptionsObject(args, 0); + if (!valid) { + return; + } + /* uSockets copies strings here */ APP *app = new APP(options); @@ -439,6 +493,10 @@ void uWS_App(const FunctionCallbackInfo &args) { appTemplate->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "listen", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, uWS_App_listen, args.Data())); appTemplate->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "publish", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, uWS_App_publish, args.Data())); + /* SNI */ + appTemplate->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "addServerName", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, uWS_App_addServerName, args.Data())); + appTemplate->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "removeServerName", NewStringType::kNormal).ToLocalChecked(), FunctionTemplate::New(isolate, uWS_App_removeServerName, args.Data())); + Local localApp = appTemplate->GetFunction(isolate->GetCurrentContext()).ToLocalChecked()->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); localApp->SetAlignedPointerInInternalField(0, app); diff --git a/uWebSockets b/uWebSockets index 4fcfe49..77aced0 160000 --- a/uWebSockets +++ b/uWebSockets @@ -1 +1 @@ -Subproject commit 4fcfe49bcce574c0aca7ab6409f81a725bf8f88c +Subproject commit 77aced05f8ed262287583299bd86641f40d87cb5