diff --git a/core/core.js b/core/core.js index 88ad4d36..54bb9689 100644 --- a/core/core.js +++ b/core/core.js @@ -988,12 +988,6 @@ loadSettings().then(function() { return staticFileHandler(request, response, null, request.uri); } else if (match = /^(.*)(\/(?:save|delete)?)$/.exec(request.uri)) { return blobHandler(request, response, match[1], match[2]); - } else if (match = /^\/disconnections$/.exec(request.uri)) { - return stringResponse(response, JSON.stringify(disconnectionsDebug(), null, 2)); - } else if (match = /^\/debug$/.exec(request.uri)) { - return stringResponse(response, JSON.stringify(getDebug(), null, 2)); - } else if (match = /^\/hitches$/.exec(request.uri)) { - return stringResponse(response, JSON.stringify(getHitches(), null, 2)); } else if ((match = /^\/.well-known\/(.*)/.exec(request.uri)) && request.uri.indexOf("..") == -1) { return wellKnownHandler(request, response, match[1]); } else { diff --git a/src/httpd.js.c b/src/httpd.js.c index 9bf7dc6a..72ee8bb7 100644 --- a/src/httpd.js.c +++ b/src/httpd.js.c @@ -427,6 +427,69 @@ static void _httpd_endpoint_mem(tf_http_request_t* request) tf_trace_end(trace); } +static void _httpd_endpoint_disconnections(tf_http_request_t* request) +{ + if (_httpd_redirect(request)) + { + return; + } + + tf_task_t* task = request->user_data; + tf_trace_t* trace = tf_task_get_trace(task); + tf_trace_begin(trace, __func__); + char* response = tf_task_get_disconnections(task); + const char* headers[] = + { + "Content-Type", "application/json; charset=utf-8", + "Access-Control-Allow-Origin", "*", + }; + tf_http_respond(request, 200, headers, tf_countof(headers) / 2, response, response ? strlen(response) : 0); + tf_free(response); + tf_trace_end(trace); +} + +static void _httpd_endpoint_hitches(tf_http_request_t* request) +{ + if (_httpd_redirect(request)) + { + return; + } + + tf_task_t* task = request->user_data; + tf_trace_t* trace = tf_task_get_trace(task); + tf_trace_begin(trace, __func__); + char* response = tf_task_get_hitches(task); + const char* headers[] = + { + "Content-Type", "application/json; charset=utf-8", + "Access-Control-Allow-Origin", "*", + }; + tf_http_respond(request, 200, headers, tf_countof(headers) / 2, response, response ? strlen(response) : 0); + tf_free(response); + tf_trace_end(trace); +} + +static void _httpd_endpoint_debug(tf_http_request_t* request) +{ + if (_httpd_redirect(request)) + { + return; + } + + tf_task_t* task = request->user_data; + tf_trace_t* trace = tf_task_get_trace(task); + tf_trace_begin(trace, __func__); + char* response = tf_task_get_debug(task); + const char* headers[] = + { + "Content-Type", "application/json; charset=utf-8", + "Access-Control-Allow-Origin", "*", + }; + tf_http_respond(request, 200, headers, tf_countof(headers) / 2, response, response ? strlen(response) : 0); + tf_free(response); + tf_trace_end(trace); +} + void tf_httpd_register(JSContext* context) { JS_NewClassID(&_httpd_class_id); @@ -457,8 +520,11 @@ void tf_httpd_register(JSContext* context) tf_http_t* http = tf_http_create(loop); JS_SetOpaque(httpd, http); - tf_http_add_handler(http, "/trace", _httpd_endpoint_trace, task); + tf_http_add_handler(http, "/debug", _httpd_endpoint_debug, task); + tf_http_add_handler(http, "/disconnections", _httpd_endpoint_disconnections, task); + tf_http_add_handler(http, "/hitches", _httpd_endpoint_hitches, task); tf_http_add_handler(http, "/mem", _httpd_endpoint_mem, task); + tf_http_add_handler(http, "/trace", _httpd_endpoint_trace, task); JS_SetPropertyStr(context, httpd, "handlers", JS_NewObject(context)); JS_SetPropertyStr(context, httpd, "all", JS_NewCFunction(context, _httpd_all, "all", 2)); diff --git a/src/mem.c b/src/mem.c index 5ca3ad6c..4ee559bb 100644 --- a/src/mem.c +++ b/src/mem.c @@ -205,7 +205,7 @@ tf_mem_allocation_t* tf_mem_summarize_allocations(int* out_count) } *out_count = summary.count; tf_mem_allocation_t* result = tf_malloc(sizeof(tf_mem_allocation_t) * summary.count); - if (result) + if (result && summary.count) { memcpy(result, summary.allocations, sizeof(tf_mem_allocation_t) * summary.count); } diff --git a/src/task.c b/src/task.c index 0c1e531c..59dc84a3 100644 --- a/src/task.c +++ b/src/task.c @@ -862,14 +862,13 @@ static void _tf_backtrace_error(void* data, const char* message, int error) JS_SetPropertyUint32(bt->context, bt->array, bt->count++, entry); } -static JSValue _tf_task_getDebug(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +char* tf_task_get_debug(tf_task_t* task) { - tf_task_t* task = JS_GetContextOpaque(context); tf_trace_begin(task->_trace, __func__); - JSValue result = JS_NewObject(context); - + JSContext* context = task->_context; + JSValue object = JS_NewObject(context); JSValue promises = JS_NewArray(context); - JS_SetPropertyStr(context, result, "promises", promises); + JS_SetPropertyStr(context, object, "promises", promises); int j = 0; for (int i = 0; i < task->_promise_stack_count; i++) { @@ -901,35 +900,56 @@ static JSValue _tf_task_getDebug(JSContext* context, JSValueConst this_val, int JS_SetPropertyUint32(context, promises, j++, entry); } } + JSValue json = JS_JSONStringify(context, object, JS_NULL, JS_NewInt32(context, 2)); + const char* string = JS_ToCString(context, json); + char* result = tf_strdup(string); + JS_FreeCString(context, string); + JS_FreeValue(context, json); + JS_FreeValue(context, object); tf_trace_end(task->_trace); return result; } -static JSValue _tf_task_getHitches(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +char* tf_task_get_hitches(tf_task_t* task) { - tf_task_t* task = JS_GetContextOpaque(context); + JSContext* context = task->_context; tf_trace_begin(task->_trace, __func__); - JSValue result = JS_NewObject(context); + JSValue object = JS_NewObject(context); for (int i = 0; i < (int)_countof(task->hitches); i++) { if (*task->hitches[i].name) { - JS_SetPropertyStr(context, result, task->hitches[i].name, JS_NewFloat64(context, task->hitches[i].duration_ns / 1e9)); + JS_SetPropertyStr(context, object, task->hitches[i].name, JS_NewFloat64(context, task->hitches[i].duration_ns / 1e9)); } } + JSValue json = JS_JSONStringify(context, object, JS_NULL, JS_NewInt32(context, 2)); + const char* string = JS_ToCString(context, json); + char* result = tf_strdup(string); + JS_FreeCString(context, string); + JS_FreeValue(context, json); + JS_FreeValue(context, object); tf_trace_end(task->_trace); return result; } -static JSValue _tf_task_disconnectionsDebug(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +char* tf_task_get_disconnections(tf_task_t* task) { - tf_task_t* task = JS_GetContextOpaque(context); + JSContext* context = task->_context; tf_trace_begin(task->_trace, __func__); - JSValue result = tf_ssb_get_disconnection_debug(task->_ssb, context); + JSValue object = tf_ssb_get_disconnection_debug(task->_ssb, context); + JSValue json = JS_JSONStringify(context, object, JS_NULL, JS_NewInt32(context, 2)); + const char* string = JS_ToCString(context, json); + char* result = tf_strdup(string); + JS_FreeCString(context, string); + JS_FreeValue(context, json); + JS_FreeValue(context, object); tf_trace_end(task->_trace); return result; } +char* tf_task_get_debug(tf_task_t* task); +char* tf_task_get_hitches(tf_task_t* task); + static JSValue _tf_task_getFile(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { tf_task_t* task = JS_GetContextOpaque(context); @@ -1704,10 +1724,6 @@ void tf_task_activate(tf_task_t* task) } JS_SetPropertyStr(context, global, "getStats", JS_NewCFunction(context, _tf_task_getStats, "getStats", 0)); - - JS_SetPropertyStr(context, global, "getDebug", JS_NewCFunction(context, _tf_task_getDebug, "getDebug", 0)); - JS_SetPropertyStr(context, global, "getHitches", JS_NewCFunction(context, _tf_task_getHitches, "getHitches", 0)); - JS_SetPropertyStr(context, global, "disconnectionsDebug", JS_NewCFunction(context, _tf_task_disconnectionsDebug, "disconnectionsDebug", 0)); } else { diff --git a/src/task.h b/src/task.h index bd99afde..f3f7a79e 100644 --- a/src/task.h +++ b/src/task.h @@ -75,3 +75,7 @@ JSValue tf_try_get_typed_array_buffer(JSContext *ctx, JSValueConst obj, size_t * uint8_t *tf_try_get_array_buffer(JSContext *ctx, size_t *psize, JSValueConst obj); bool tf_task_send_error_to_parent(tf_task_t* task, JSValue error); + +char* tf_task_get_disconnections(tf_task_t* task); +char* tf_task_get_debug(tf_task_t* task); +char* tf_task_get_hitches(tf_task_t* task);