#include "httpd.js.h" #include "http.h" #include "log.h" #include "mem.h" #include "task.h" #include "util.js.h" static JSClassID _httpd_class_id; typedef struct _http_handler_data_t { JSContext* context; JSValue callback; } http_handler_data_t; static void _httpd_callback(tf_http_request_t* request) { tf_printf("httpd_callback!\n"); http_handler_data_t* data = request->user_data; JSValue response = JS_Call(data->context, data->callback, JS_UNDEFINED, 0, NULL); tf_printf("%d %d\n", JS_IsUndefined(response), JS_IsException(response)); tf_util_report_error(data->context, response); JS_FreeValue(data->context, response); } static JSValue _httpd_all(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { tf_http_t* http = JS_GetOpaque(this_val, _httpd_class_id); const char* pattern = JS_ToCString(context, argv[0]); http_handler_data_t* data = tf_malloc(sizeof(http_handler_data_t)); *data = (http_handler_data_t) { .context = context, .callback = JS_DupValue(context, argv[1]) }; tf_http_add_handler(http, pattern, _httpd_callback, data); tf_printf("HTTPD_ALL: %s\n", pattern); JS_FreeCString(context, pattern); 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_http_t* http = JS_GetOpaque(this_val, _httpd_class_id); tf_http_listen(http, 12345); return JS_UNDEFINED; } void _httpd_finalizer(JSRuntime* runtime, JSValue value) { tf_http_t* http = JS_GetOpaque(value, _httpd_class_id); tf_http_destroy(http); } void tf_httpd_register(JSContext* context) { JS_NewClassID(&_httpd_class_id); JSClassDef def = { .class_name = "Httpd", .finalizer = &_httpd_finalizer, }; if (JS_NewClass(JS_GetRuntime(context), _httpd_class_id, &def) != 0) { fprintf(stderr, "Failed to register Httpd.\n"); } JSValue global = JS_GetGlobalObject(context); JSValue httpd = JS_NewObjectClass(context, _httpd_class_id); tf_task_t* task = tf_task_get(context); uv_loop_t* loop = tf_task_get_loop(task); tf_http_t* http = tf_http_create(loop); JS_SetOpaque(httpd, http); JS_SetPropertyStr(context, httpd, "handlers", 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); }