Reimplement http -> https redirects. Remove request phases. With just a little extra storage, it wasn't needed.

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4723 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
2024-01-02 15:02:47 +00:00
parent d7c0ffaac4
commit 9ef909c9a1
4 changed files with 93 additions and 8 deletions

View File

@ -21,6 +21,11 @@
static JSClassID _httpd_class_id;
static JSClassID _httpd_request_class_id;
typedef struct _http_user_data_t
{
char redirect[1024];
} http_user_data_t;
typedef struct _http_handler_data_t
{
JSContext* context;
@ -217,13 +222,42 @@ static void _httpd_callback_internal(tf_http_request_t* request, bool is_websock
}
}
static bool _httpd_redirect(tf_http_request_t* request)
{
if (request->is_tls)
{
return false;
}
http_user_data_t* user_data = tf_http_get_user_data(request->http);
if (!user_data || !*user_data->redirect)
{
return false;
}
char redirect[1024];
snprintf(redirect, sizeof(redirect), "%s%s", user_data->redirect, request->path);
tf_http_respond(request, 303, (const char*[]) { "Location", redirect }, 1, NULL, 0);
return true;
}
static void _httpd_callback(tf_http_request_t* request)
{
if (_httpd_redirect(request))
{
return;
}
_httpd_callback_internal(request, false);
}
static void _httpd_websocket_callback(tf_http_request_t* request)
{
if (_httpd_redirect(request))
{
return;
}
const char* header_connection = tf_http_request_get_header(request, "connection");
const char* header_upgrade = tf_http_request_get_header(request, "upgrade");
const char* header_sec_websocket_key = tf_http_request_get_header(request, "sec-websocket-key");
@ -297,6 +331,28 @@ static JSValue _httpd_start(JSContext* context, JSValueConst this_val, int argc,
return JS_NewInt32(context, assigned_port);
}
static void _httpd_free_user_data(void* user_data)
{
tf_free(user_data);
}
static JSValue _httpd_set_http_redirect(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
{
tf_http_t* http = JS_GetOpaque(this_val, _httpd_class_id);
http_user_data_t* user_data = tf_http_get_user_data(http);
if (!user_data)
{
user_data = tf_malloc(sizeof(http_user_data_t));
memset(user_data, 0, sizeof(http_user_data_t));
tf_http_set_user_data(http, user_data, _httpd_free_user_data);
}
const char* redirect = JS_ToCString(context, argv[0]);
snprintf(user_data->redirect, sizeof(user_data->redirect), "%s", redirect ? redirect : "");
JS_FreeCString(context, redirect);
return JS_UNDEFINED;
}
void _httpd_finalizer(JSRuntime* runtime, JSValue value)
{
tf_http_t* http = JS_GetOpaque(value, _httpd_class_id);
@ -343,6 +399,7 @@ void tf_httpd_register(JSContext* 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", 2));
JS_SetPropertyStr(context, httpd, "set_http_redirect", JS_NewCFunction(context, _httpd_set_http_redirect, "set_http_redirect", 1));
JS_SetPropertyStr(context, global, "httpd", httpd);
JS_FreeValue(context, global);
}