From 5bba5776b37d0aaf663965c2d5541ccde7f9ebcf Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Sat, 12 Apr 2025 09:43:55 -0400 Subject: [PATCH] core: Get rid of the httpd JS object. Potential progress on #108. --- src/httpd.js.c | 35 +++++++++++++---------------------- src/httpd.js.h | 14 ++++++++++++++ src/task.c | 11 +++++------ 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/httpd.js.c b/src/httpd.js.c index 3c38385f..f4a6d84d 100644 --- a/src/httpd.js.c +++ b/src/httpd.js.c @@ -47,7 +47,6 @@ static const char* _make_set_session_cookie_header(tf_http_request_t* request, c const char** _form_data_decode(const char* data, int length); const char* _form_data_get(const char** form_data, const char* key); -static JSClassID _httpd_class_id; static JSClassID _httpd_request_class_id; typedef struct _http_user_data_t @@ -538,12 +537,6 @@ static const char* _ext_to_content_type(const char* ext, bool use_fallback) return use_fallback ? "application/binary" : NULL; } -static void _httpd_finalizer(JSRuntime* runtime, JSValue value) -{ - tf_http_t* http = JS_GetOpaque(value, _httpd_class_id); - tf_http_destroy(http); -} - static void _httpd_request_finalizer(JSRuntime* runtime, JSValue value) { tf_http_request_t* request = JS_GetOpaque(value, _httpd_request_class_id); @@ -2362,16 +2355,7 @@ static const char* _httpd_read_file(tf_task_t* task, const char* path) void tf_httpd_register(JSContext* context) { - JS_NewClassID(&_httpd_class_id); JS_NewClassID(&_httpd_request_class_id); - JSClassDef httpd_def = { - .class_name = "Httpd", - .finalizer = &_httpd_finalizer, - }; - if (JS_NewClass(JS_GetRuntime(context), _httpd_class_id, &httpd_def) != 0) - { - fprintf(stderr, "Failed to register Httpd.\n"); - } JSClassDef request_def = { .class_name = "Request", .finalizer = &_httpd_request_finalizer, @@ -2382,14 +2366,19 @@ void tf_httpd_register(JSContext* context) } JSValue global = JS_GetGlobalObject(context); - JSValue httpd = JS_NewObjectClass(context, _httpd_class_id); + JSValue httpd = JS_NewObject(context); + JS_SetPropertyStr(context, httpd, "auth_query", JS_NewCFunction(context, _httpd_auth_query, "auth_query", 1)); + JS_SetPropertyStr(context, global, "httpd", httpd); + JS_FreeValue(context, global); +} +tf_http_t* tf_httpd_create(JSContext* context) +{ tf_task_t* task = tf_task_get(context); tf_ssb_t* ssb = tf_task_get_ssb(task); uv_loop_t* loop = tf_task_get_loop(task); tf_http_t* http = tf_http_create(loop); tf_http_set_trace(http, tf_task_get_trace(task)); - JS_SetOpaque(httpd, http); int64_t http_port = 0; int64_t https_port = 0; @@ -2454,10 +2443,6 @@ void tf_httpd_register(JSContext* context) tf_http_add_handler(http, "/app/socket", _httpd_endpoint_app_socket, NULL, task); - JS_SetPropertyStr(context, httpd, "auth_query", JS_NewCFunction(context, _httpd_auth_query, "auth_query", 1)); - JS_SetPropertyStr(context, global, "httpd", httpd); - JS_FreeValue(context, global); - if (http_port > 0 || *out_http_port_file) { httpd_listener_t* listener = tf_malloc(sizeof(httpd_listener_t)); @@ -2502,4 +2487,10 @@ void tf_httpd_register(JSContext* context) tf_free((char*)private_key); } } + return http; +} + +void tf_httpd_destroy(tf_http_t* http) +{ + tf_http_destroy(http); } diff --git a/src/httpd.js.h b/src/httpd.js.h index f9d1d51d..2fd83546 100644 --- a/src/httpd.js.h +++ b/src/httpd.js.h @@ -13,6 +13,8 @@ #include "quickjs.h" +typedef struct _tf_http_t tf_http_t; + /** ** Register the HTTP script interface. Also registers a number of built-in ** request handlers. An ongoing project is to move the JS request handlers @@ -21,4 +23,16 @@ */ void tf_httpd_register(JSContext* context); +/** +** Create the HTTP server instance. +** @param context The JS context. +*/ +tf_http_t* tf_httpd_create(JSContext* context); + +/** +** Destroy the HTTP server instance. +** @param http The HTTP server instance. +*/ +void tf_httpd_destroy(tf_http_t* http); + /** @} */ diff --git a/src/task.c b/src/task.c index 4a20af47..14e05edf 100644 --- a/src/task.c +++ b/src/task.c @@ -128,6 +128,7 @@ typedef struct _tf_task_t sqlite3* _db; tf_ssb_t* _ssb; + tf_http_t* _http; tf_trace_t* _trace; @@ -1756,6 +1757,7 @@ void tf_task_activate(tf_task_t* task) JS_SetPropertyStr(context, global, "getStats", JS_NewCFunction(context, _tf_task_getStats, "getStats", 0)); tf_httpd_register(context); + task->_http = tf_httpd_create(context); } else { @@ -1868,13 +1870,10 @@ void tf_task_destroy(tf_task_t* task) { tf_ssb_destroy(task->_ssb); } - - /* This ensures the HTTP handlers get cleaned up. */ - if (task->_trusted) + if (task->_http) { - JSValue global = JS_GetGlobalObject(task->_context); - JS_SetPropertyStr(task->_context, global, "httpd", JS_UNDEFINED); - JS_FreeValue(task->_context, global); + tf_httpd_destroy(task->_http); + task->_http = NULL; } JS_FreeContext(task->_context);