WebSocket request/response header dance. Feels like the loop is getting close to closed, but I want to refactor everything.

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4692 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
2023-12-24 17:43:33 +00:00
parent 196ab66e14
commit 1621f1753a
5 changed files with 90 additions and 13 deletions

View File

@ -9,6 +9,9 @@
#include "picohttpparser.h"
#include <stdlib.h>
#include <string.h>
#include <openssl/sha.h>
#if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(_WIN32)
#include <alloca.h>
@ -99,6 +102,43 @@ static JSValue _httpd_response_end(JSContext* context, JSValueConst this_val, in
static void _httpd_callback(tf_http_request_t* request)
{
if (request->flags & k_tf_http_handler_flag_websocket)
{
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");
tf_printf("\n%s\n%s\n%s\n\n", header_connection, header_upgrade, header_sec_websocket_key);
if (header_connection &&
header_upgrade &&
header_sec_websocket_key &&
strstr(header_connection, "Upgrade") &&
strcasecmp(header_upgrade, "websocket") == 0)
{
static const char* k_magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
size_t key_length = strlen(header_sec_websocket_key);
size_t size = key_length + 36;
uint8_t* key_magic = alloca(size);
memcpy(key_magic, header_sec_websocket_key, key_length);
memcpy(key_magic + key_length, k_magic, 36);
uint8_t digest[20];
SHA1(key_magic, size, digest);
char key[41] = { 0 };
tf_base64_encode(digest, sizeof(digest), key, sizeof(key));
tf_printf("ACCEPT %s\n", key);
enum { k_headers_count = 4 };
const char* headers[k_headers_count * 2] =
{
"Upgrade", "websocket",
"Connection", "upgrade",
"Sec-WebSocket-Accept", key,
"Sec-WebSocket-Version", "13",
};
tf_http_respond(request, 101, headers, k_headers_count, NULL, 0);
return;
}
}
http_handler_data_t* data = request->user_data;
JSContext* context = data->context;
JSValue request_object = JS_NewObject(context);
@ -146,15 +186,19 @@ static JSValue _httpd_all(JSContext* context, JSValueConst this_val, int argc, J
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_http_add_handler(http, pattern, k_tf_http_handler_flag_none, _httpd_callback, data);
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");
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, k_tf_http_handler_flag_websocket, _httpd_callback, data);
JS_FreeCString(context, pattern);
return JS_UNDEFINED;
}