Make http.auth_query async and get its DB work off the main thread.
This commit is contained in:
		@@ -83,10 +83,10 @@ App.prototype.send = function (message) {
 | 
			
		||||
 * @param {*} response
 | 
			
		||||
 * @param {*} client
 | 
			
		||||
 */
 | 
			
		||||
function socket(request, response, client) {
 | 
			
		||||
async function socket(request, response, client) {
 | 
			
		||||
	let process;
 | 
			
		||||
	let options = {};
 | 
			
		||||
	let credentials = httpd.auth_query(request.headers);
 | 
			
		||||
	let credentials = await httpd.auth_query(request.headers);
 | 
			
		||||
 | 
			
		||||
	response.onClose = async function () {
 | 
			
		||||
		if (process && process.task) {
 | 
			
		||||
 
 | 
			
		||||
@@ -908,7 +908,7 @@ async function useAppHandler(
 | 
			
		||||
					},
 | 
			
		||||
					respond: do_resolve,
 | 
			
		||||
				},
 | 
			
		||||
				credentials: httpd.auth_query(headers),
 | 
			
		||||
				credentials: await httpd.auth_query(headers),
 | 
			
		||||
				packageOwner: packageOwner,
 | 
			
		||||
				packageName: packageName,
 | 
			
		||||
			}
 | 
			
		||||
@@ -1039,7 +1039,7 @@ async function blobHandler(request, response, blobId, uri) {
 | 
			
		||||
		if ((match = /^\/\~(\w+)\/(\w+)$/.exec(blobId))) {
 | 
			
		||||
			let user = match[1];
 | 
			
		||||
			let appName = match[2];
 | 
			
		||||
			let credentials = httpd.auth_query(request.headers);
 | 
			
		||||
			let credentials = await httpd.auth_query(request.headers);
 | 
			
		||||
			if (
 | 
			
		||||
				credentials &&
 | 
			
		||||
				credentials.session &&
 | 
			
		||||
@@ -1102,7 +1102,7 @@ async function blobHandler(request, response, blobId, uri) {
 | 
			
		||||
		if ((match = /^\/\~(\w+)\/(\w+)$/.exec(blobId))) {
 | 
			
		||||
			let user = match[1];
 | 
			
		||||
			let appName = match[2];
 | 
			
		||||
			let credentials = httpd.auth_query(request.headers);
 | 
			
		||||
			let credentials = await httpd.auth_query(request.headers);
 | 
			
		||||
			if (
 | 
			
		||||
				credentials &&
 | 
			
		||||
				credentials.session &&
 | 
			
		||||
 
 | 
			
		||||
@@ -154,8 +154,7 @@ static JSValue _database_get(JSContext* context, JSValueConst this_val, int argc
 | 
			
		||||
		size_t length;
 | 
			
		||||
		const char* key = JS_ToCStringLen(context, &length, argv[0]);
 | 
			
		||||
		database_get_t* work = tf_malloc(sizeof(database_get_t) + strlen(database->id) + 1 + length + 1);
 | 
			
		||||
		*work = (database_get_t)
 | 
			
		||||
		{
 | 
			
		||||
		*work = (database_get_t) {
 | 
			
		||||
			.id = (const char*)(work + 1),
 | 
			
		||||
			.key = (const char*)(work + 1) + strlen(database->id) + 1,
 | 
			
		||||
			.key_length = length,
 | 
			
		||||
@@ -226,8 +225,7 @@ static JSValue _database_set(JSContext* context, JSValueConst this_val, int argc
 | 
			
		||||
		const char* value = JS_ToCStringLen(context, &value_length, argv[1]);
 | 
			
		||||
 | 
			
		||||
		database_set_t* work = tf_malloc(sizeof(database_set_t) + strlen(database->id) + 1 + key_length + 1 + value_length + 1);
 | 
			
		||||
		*work = (database_set_t)
 | 
			
		||||
		{
 | 
			
		||||
		*work = (database_set_t) {
 | 
			
		||||
			.id = (const char*)(work + 1),
 | 
			
		||||
			.key = (const char*)(work + 1) + strlen(database->id) + 1,
 | 
			
		||||
			.value = (const char*)(work + 1) + strlen(database->id) + 1 + key_length + 1,
 | 
			
		||||
 
 | 
			
		||||
@@ -446,6 +446,55 @@ static JSValue _httpd_set_http_redirect(JSContext* context, JSValueConst this_va
 | 
			
		||||
	return JS_UNDEFINED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct _auth_query_work_t
 | 
			
		||||
{
 | 
			
		||||
	const char* settings;
 | 
			
		||||
	JSValue entry;
 | 
			
		||||
	JSValue result;
 | 
			
		||||
	JSValue promise[2];
 | 
			
		||||
} auth_query_work_t;
 | 
			
		||||
 | 
			
		||||
static void _httpd_auth_query_work(tf_ssb_t* ssb, void* user_data)
 | 
			
		||||
{
 | 
			
		||||
	auth_query_work_t* work = user_data;
 | 
			
		||||
	work->settings = tf_ssb_db_get_property(ssb, "core", "settings");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _httpd_auth_query_after_work(tf_ssb_t* ssb, int status, void* user_data)
 | 
			
		||||
{
 | 
			
		||||
	auth_query_work_t* work = user_data;
 | 
			
		||||
	JSContext* context = tf_ssb_get_context(ssb);
 | 
			
		||||
	JSValue name = JS_GetPropertyStr(context, work->entry, "name");
 | 
			
		||||
	const char* name_string = JS_ToCString(context, name);
 | 
			
		||||
	JSValue settings_value = work->settings ? JS_ParseJSON(context, work->settings, strlen(work->settings), NULL) : JS_UNDEFINED;
 | 
			
		||||
	JSValue out_permissions = JS_NewObject(context);
 | 
			
		||||
	JS_SetPropertyStr(context, work->result, "permissions", out_permissions);
 | 
			
		||||
	JSValue permissions = !JS_IsUndefined(settings_value) ? JS_GetPropertyStr(context, settings_value, "permissions") : JS_UNDEFINED;
 | 
			
		||||
	JSValue user_permissions = !JS_IsUndefined(permissions) ? JS_GetPropertyStr(context, permissions, name_string) : JS_UNDEFINED;
 | 
			
		||||
	int length = !JS_IsUndefined(user_permissions) ? tf_util_get_length(context, user_permissions) : 0;
 | 
			
		||||
	for (int i = 0; i < length; i++)
 | 
			
		||||
	{
 | 
			
		||||
		JSValue permission = JS_GetPropertyUint32(context, user_permissions, i);
 | 
			
		||||
		const char* permission_string = JS_ToCString(context, permission);
 | 
			
		||||
		JS_SetPropertyStr(context, out_permissions, permission_string, JS_TRUE);
 | 
			
		||||
		JS_FreeCString(context, permission_string);
 | 
			
		||||
		JS_FreeValue(context, permission);
 | 
			
		||||
	}
 | 
			
		||||
	JSValue error = JS_Call(context, work->promise[0], JS_UNDEFINED, 1, &work->result);
 | 
			
		||||
	JS_FreeValue(context, work->result);
 | 
			
		||||
	tf_util_report_error(context, error);
 | 
			
		||||
	JS_FreeValue(context, error);
 | 
			
		||||
	JS_FreeValue(context, work->promise[0]);
 | 
			
		||||
	JS_FreeValue(context, work->promise[1]);
 | 
			
		||||
	JS_FreeValue(context, user_permissions);
 | 
			
		||||
	JS_FreeValue(context, permissions);
 | 
			
		||||
	JS_FreeValue(context, settings_value);
 | 
			
		||||
	tf_free((void*)work->settings);
 | 
			
		||||
	JS_FreeCString(context, name_string);
 | 
			
		||||
	JS_FreeValue(context, name);
 | 
			
		||||
	tf_free(work);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static JSValue _httpd_auth_query(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
 | 
			
		||||
{
 | 
			
		||||
	tf_task_t* task = tf_task_get(context);
 | 
			
		||||
@@ -467,33 +516,16 @@ static JSValue _httpd_auth_query(JSContext* context, JSValueConst this_val, int
 | 
			
		||||
	JSValue result = JS_UNDEFINED;
 | 
			
		||||
	if (!JS_IsUndefined(entry))
 | 
			
		||||
	{
 | 
			
		||||
		result = JS_NewObject(context);
 | 
			
		||||
		JS_SetPropertyStr(context, result, "session", entry);
 | 
			
		||||
		JSValue out_permissions = JS_NewObject(context);
 | 
			
		||||
		JS_SetPropertyStr(context, result, "permissions", out_permissions);
 | 
			
		||||
		JSValue value = JS_NewObject(context);
 | 
			
		||||
		JS_SetPropertyStr(context, value, "session", entry);
 | 
			
		||||
 | 
			
		||||
		JSValue name = JS_GetPropertyStr(context, entry, "name");
 | 
			
		||||
		const char* name_string = JS_ToCString(context, name);
 | 
			
		||||
 | 
			
		||||
		const char* settings = tf_ssb_db_get_property(ssb, "core", "settings");
 | 
			
		||||
		JSValue settings_value = settings ? JS_ParseJSON(context, settings, strlen(settings), NULL) : JS_UNDEFINED;
 | 
			
		||||
		JSValue permissions = !JS_IsUndefined(settings_value) ? JS_GetPropertyStr(context, settings_value, "permissions") : JS_UNDEFINED;
 | 
			
		||||
		JSValue user_permissions = !JS_IsUndefined(permissions) ? JS_GetPropertyStr(context, permissions, name_string) : JS_UNDEFINED;
 | 
			
		||||
		int length = !JS_IsUndefined(user_permissions) ? tf_util_get_length(context, user_permissions) : 0;
 | 
			
		||||
		for (int i = 0; i < length; i++)
 | 
			
		||||
		{
 | 
			
		||||
			JSValue permission = JS_GetPropertyUint32(context, user_permissions, i);
 | 
			
		||||
			const char* permission_string = JS_ToCString(context, permission);
 | 
			
		||||
			JS_SetPropertyStr(context, out_permissions, permission_string, JS_TRUE);
 | 
			
		||||
			JS_FreeCString(context, permission_string);
 | 
			
		||||
			JS_FreeValue(context, permission);
 | 
			
		||||
		}
 | 
			
		||||
		JS_FreeValue(context, user_permissions);
 | 
			
		||||
		JS_FreeValue(context, permissions);
 | 
			
		||||
		JS_FreeValue(context, settings_value);
 | 
			
		||||
		tf_free((void*)settings);
 | 
			
		||||
		JS_FreeCString(context, name_string);
 | 
			
		||||
		JS_FreeValue(context, name);
 | 
			
		||||
		auth_query_work_t* work = tf_malloc(sizeof(auth_query_work_t));
 | 
			
		||||
		*work = (auth_query_work_t) {
 | 
			
		||||
			.entry = entry,
 | 
			
		||||
			.result = value,
 | 
			
		||||
		};
 | 
			
		||||
		result = JS_NewPromiseCapability(context, work->promise);
 | 
			
		||||
		tf_ssb_run_work(ssb, _httpd_auth_query_work, _httpd_auth_query_after_work, work);
 | 
			
		||||
	}
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
@@ -1315,7 +1347,6 @@ static void _httpd_endpoint_login_get_code_of_conduct_work(tf_ssb_t* ssb, void*
 | 
			
		||||
{
 | 
			
		||||
	login_request_t* login = user_data;
 | 
			
		||||
	login->settings = tf_ssb_db_get_property(ssb, "core", "settings");
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _httpd_endpoint_login_get_code_of_conduct_after_work(tf_ssb_t* ssb, int status, void* user_data)
 | 
			
		||||
 
 | 
			
		||||
@@ -280,8 +280,7 @@ static JSValue _tf_ssb_getIdentities(JSContext* context, JSValueConst this_val,
 | 
			
		||||
		size_t user_length = 0;
 | 
			
		||||
		const char* user = JS_ToCStringLen(context, &user_length, argv[0]);
 | 
			
		||||
		identities_visit_t* work = tf_malloc(sizeof(identities_visit_t) + user_length + 1);
 | 
			
		||||
		*work = (identities_visit_t)
 | 
			
		||||
		{
 | 
			
		||||
		*work = (identities_visit_t) {
 | 
			
		||||
			.context = context,
 | 
			
		||||
		};
 | 
			
		||||
		memcpy(work->user, user, user_length + 1);
 | 
			
		||||
@@ -331,8 +330,7 @@ static JSValue _tf_ssb_getAllIdentities(JSContext* context, JSValueConst this_va
 | 
			
		||||
	if (ssb)
 | 
			
		||||
	{
 | 
			
		||||
		identities_visit_t* work = tf_malloc(sizeof(identities_visit_t));
 | 
			
		||||
		*work = (identities_visit_t)
 | 
			
		||||
		{
 | 
			
		||||
		*work = (identities_visit_t) {
 | 
			
		||||
			.context = context,
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user