From f9940fc436e897cb209d0f62f9f8138003e88a84 Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Thu, 21 Dec 2023 00:56:16 +0000 Subject: [PATCH] Add a runtime switch between httpd implementions. One of which is totally not hooked up yet. git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4685 ed5197a5-7fde-0310-b194-c3ffbd925b24 --- core/core.js | 8 ++-- core/httpd.js | 119 +++++++++++++++++++++++++------------------------ src/httpd.js.c | 32 +++++++++++++ src/httpd.js.h | 5 +++ src/task.c | 2 + 5 files changed, 105 insertions(+), 61 deletions(-) create mode 100644 src/httpd.js.c create mode 100644 src/httpd.js.h diff --git a/core/core.js b/core/core.js index 3523909b..801f8b5c 100644 --- a/core/core.js +++ b/core/core.js @@ -952,8 +952,9 @@ function stringResponse(response, data) { } loadSettings().then(function() { - httpd.all("/login", auth.handler); - httpd.all("", function(request, response) { + let httpd_impl = (tildefriends.args.httpdc ? httpdc : httpd); + httpd_impl.all("/login", auth.handler); + httpd_impl.all("", function(request, response) { let match; if (request.uri === "/" || request.uri === "") { try { @@ -1003,7 +1004,8 @@ loadSettings().then(function() { return response.end(data); } }); - httpd.registerSocketHandler("/app/socket", app.socket); + httpd_impl.registerSocketHandler("/app/socket", app.socket); + httpd_impl.start(); }).catch(function(error) { print('Failed to load settings.'); printError({print: print}, error); diff --git a/core/httpd.js b/core/httpd.js index 467f0e36..3e97e5d1 100644 --- a/core/httpd.js +++ b/core/httpd.js @@ -521,73 +521,76 @@ function handleConnection(client) { let kBacklog = 8; let kHost = platform() == 'haiku' ? 'localhost' : '::'; -let socket = new Socket(); -socket.bind(kHost, tildefriends.http_port).then(function(port) { - print("bound to", port); - print("checking", tildefriends.args.out_http_port_file); - if (tildefriends.args.out_http_port_file) { - print("going to write the file"); - File.writeFile(tildefriends.args.out_http_port_file, port.toString() + '\n').then(function(r) { - print("wrote port file", tildefriends.args.out_http_port_file, r); - }).catch(function() { - print("failed to write port file"); - }); - } - let listenResult = socket.listen(kBacklog, async function() { - try { - let client = await socket.accept(); - client.noDelay = true; - handleConnection(client); - } catch (error) { - logError("[" + new Date() + "] accept error " + error); +function start() { + print('ACTUAL START'); + let socket = new Socket(); + socket.bind(kHost, tildefriends.http_port).then(function(port) { + print("bound to", port); + print("checking", tildefriends.args.out_http_port_file); + if (tildefriends.args.out_http_port_file) { + print("going to write the file"); + File.writeFile(tildefriends.args.out_http_port_file, port.toString() + '\n').then(function(r) { + print("wrote port file", tildefriends.args.out_http_port_file, r); + }).catch(function() { + print("failed to write port file"); + }); } - }); -}).catch(function(error) { - logError("[" + new Date() + "] bind error " + error); -}); - -if (tildefriends.https_port) { - let tls = {}; - let secureSocket = new Socket(); - secureSocket.bind(kHost, tildefriends.https_port).then(function() { - return secureSocket.listen(kBacklog, async function() { + let listenResult = socket.listen(kBacklog, async function() { try { - let client = await secureSocket.accept(); + let client = await socket.accept(); client.noDelay = true; - client.tls = true; - const kCertificatePath = "data/httpd/certificate.pem"; - const kPrivateKeyPath = "data/httpd/privatekey.pem"; - - let stat = await Promise.all([ - await File.stat(kCertificatePath), - await File.stat(kPrivateKeyPath), - ]); - if (!tls.context || - tls.certStat.mtime != stat[0].mtime || - tls.certStat.size != stat[0].size || - tls.keyStat.mtime != stat[1].mtime || - tls.keyStat.size != stat[1].size) { - print("Reloading " + kCertificatePath + " and " + kPrivateKeyPath); - let privateKey = utf8Decode(await File.readFile(kPrivateKeyPath)); - let certificate = utf8Decode(await File.readFile(kCertificatePath)); - - tls.context = new TlsContext(); - tls.context.setPrivateKey(privateKey); - tls.context.setCertificate(certificate); - tls.certStat = stat[0]; - tls.keyStat = stat[1]; - } - - let result = client.startTls(tls.context); handleConnection(client); - return result; } catch (error) { - logError("[" + new Date() + "] " + error); + logError("[" + new Date() + "] accept error " + error); } }); }).catch(function(error) { logError("[" + new Date() + "] bind error " + error); }); + + if (tildefriends.https_port) { + let tls = {}; + let secureSocket = new Socket(); + secureSocket.bind(kHost, tildefriends.https_port).then(function() { + return secureSocket.listen(kBacklog, async function() { + try { + let client = await secureSocket.accept(); + client.noDelay = true; + client.tls = true; + const kCertificatePath = "data/httpd/certificate.pem"; + const kPrivateKeyPath = "data/httpd/privatekey.pem"; + + let stat = await Promise.all([ + await File.stat(kCertificatePath), + await File.stat(kPrivateKeyPath), + ]); + if (!tls.context || + tls.certStat.mtime != stat[0].mtime || + tls.certStat.size != stat[0].size || + tls.keyStat.mtime != stat[1].mtime || + tls.keyStat.size != stat[1].size) { + print("Reloading " + kCertificatePath + " and " + kPrivateKeyPath); + let privateKey = utf8Decode(await File.readFile(kPrivateKeyPath)); + let certificate = utf8Decode(await File.readFile(kCertificatePath)); + + tls.context = new TlsContext(); + tls.context.setPrivateKey(privateKey); + tls.context.setCertificate(certificate); + tls.certStat = stat[0]; + tls.keyStat = stat[1]; + } + + let result = client.startTls(tls.context); + handleConnection(client); + return result; + } catch (error) { + logError("[" + new Date() + "] " + error); + } + }); + }).catch(function(error) { + logError("[" + new Date() + "] bind error " + error); + }); + } } -export { all, registerSocketHandler }; +export { all, start, registerSocketHandler }; diff --git a/src/httpd.js.c b/src/httpd.js.c new file mode 100644 index 00000000..fe3a7900 --- /dev/null +++ b/src/httpd.js.c @@ -0,0 +1,32 @@ +#include "httpd.js.h" + +#include "log.h" + +static JSValue _httpd_all(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ + tf_printf("HTTPD_ALL UNIMPLEMENTED\n"); + return JS_UNDEFINED; +} + +static JSValue _httpd_register_socket_handler(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ + tf_printf("HTTPD_REGISTER_SOCKET_HANDLER UNIMPLEMENTED\n"); + return JS_UNDEFINED; +} + +static JSValue _httpd_start(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ + tf_printf("HTTPD_START UNIMPLEMENTED\n"); + return JS_UNDEFINED; +} + +void tf_httpd_register(JSContext* context) +{ + JSValue global = JS_GetGlobalObject(context); + JSValue httpd = JS_NewObject(context); + JS_SetPropertyStr(context, httpd, "all", JS_NewCFunction(context, _httpd_all, "all", 2)); + JS_SetPropertyStr(context, httpd, "registerSocketHandler", JS_NewCFunction(context, _httpd_register_socket_handler, "register_socket_handler", 2)); + JS_SetPropertyStr(context, httpd, "start", JS_NewCFunction(context, _httpd_start, "start", 0)); + JS_SetPropertyStr(context, global, "httpdc", httpd); + JS_FreeValue(context, global); +} diff --git a/src/httpd.js.h b/src/httpd.js.h new file mode 100644 index 00000000..04cc2ad7 --- /dev/null +++ b/src/httpd.js.h @@ -0,0 +1,5 @@ +#pragma once + +#include "quickjs.h" + +void tf_httpd_register(JSContext* context); diff --git a/src/task.c b/src/task.c index e45bec40..4081793e 100644 --- a/src/task.c +++ b/src/task.c @@ -3,6 +3,7 @@ #include "bcrypt.js.h" #include "database.js.h" #include "file.js.h" +#include "httpd.js.h" #include "log.h" #include "mem.h" #include "packetstream.h" @@ -1731,6 +1732,7 @@ void tf_task_activate(tf_task_t* task) JS_SetPropertyStr(context, global, "TlsContext", tf_tls_context_register(context)); tf_file_register(context); tf_database_register(context); + tf_httpd_register(context); task->_ssb = tf_ssb_create(&task->_loop, task->_context, task->_db_path); tf_ssb_set_trace(task->_ssb, task->_trace);