Bugs galore, but this is sending and receiving some websocket messages.

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4697 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
Cory McWilliams 2023-12-25 23:39:16 +00:00
parent ccebf831e7
commit cd43bf9dfa
3 changed files with 41 additions and 8 deletions

View File

@ -41,6 +41,7 @@ typedef struct _tf_http_connection_t
int flags; int flags;
tf_http_callback_t* callback; tf_http_callback_t* callback;
tf_http_request_t* request;
void* user_data; void* user_data;
bool is_websocket; bool is_websocket;
@ -133,6 +134,7 @@ static void _http_connection_destroy(tf_http_connection_t* connection)
{ {
if (connection->tcp.data) if (connection->tcp.data)
{ {
tf_printf("CLOSE %p\n", connection);
uv_close((uv_handle_t*)&connection->tcp, _http_connection_on_close); uv_close((uv_handle_t*)&connection->tcp, _http_connection_on_close);
} }
else if (connection->ref_count == 0) else if (connection->ref_count == 0)
@ -233,7 +235,14 @@ static void _http_add_body_bytes(tf_http_connection_t* connection, const void* d
} }
if (fin) if (fin)
{ {
tf_printf("MESSAGE %d [%.*s]\n", opcode, (int)length, p + mask_start + 4); if (connection->request->on_message)
{
connection->request->on_message(connection->request, p + mask_start + 4, length);
}
else
{
tf_printf("MESSAGE %d [%.*s]\n", opcode, (int)length, p + mask_start + 4);
}
} }
size_t total_length = end; size_t total_length = end;
memmove(connection->body, (char*)connection->body + total_length, connection->body_length - total_length); memmove(connection->body, (char*)connection->body + total_length, connection->body_length - total_length);
@ -271,6 +280,7 @@ static void _http_add_body_bytes(tf_http_connection_t* connection, const void* d
.headers_count = connection->headers_length, .headers_count = connection->headers_length,
.user_data = connection->user_data, .user_data = connection->user_data,
}; };
connection->request = request;
tf_http_request_ref(request); tf_http_request_ref(request);
connection->callback(request); connection->callback(request);
@ -523,6 +533,7 @@ static void _http_on_shutdown(uv_shutdown_t* request, int status)
static void _http_write(tf_http_connection_t* connection, const void* data, size_t size) static void _http_write(tf_http_connection_t* connection, const void* data, size_t size)
{ {
tf_printf("WRITE connection=%p\n", connection);
uv_write_t* write = tf_malloc(sizeof(uv_write_t) + size); uv_write_t* write = tf_malloc(sizeof(uv_write_t) + size);
*write = (uv_write_t) { .data = connection }; *write = (uv_write_t) { .data = connection };
memcpy(write + 1, data, size); memcpy(write + 1, data, size);

View File

@ -5,6 +5,7 @@
typedef struct uv_loop_s uv_loop_t; typedef struct uv_loop_s uv_loop_t;
typedef struct _tf_http_t tf_http_t; typedef struct _tf_http_t tf_http_t;
typedef struct _tf_http_connection_t tf_http_connection_t; typedef struct _tf_http_connection_t tf_http_connection_t;
typedef struct _tf_http_request_t tf_http_request_t;
typedef enum _tf_http_callback_phase_t typedef enum _tf_http_callback_phase_t
{ {
@ -12,6 +13,8 @@ typedef enum _tf_http_callback_phase_t
k_http_callback_phase_request_done, k_http_callback_phase_request_done,
} tf_http_callback_phase_t; } tf_http_callback_phase_t;
typedef void (tf_http_message_callback)(tf_http_request_t* request, const void* data, size_t size);
typedef struct _tf_http_request_t typedef struct _tf_http_request_t
{ {
tf_http_callback_phase_t phase; tf_http_callback_phase_t phase;
@ -24,6 +27,8 @@ typedef struct _tf_http_request_t
size_t content_length; size_t content_length;
struct phr_header* headers; struct phr_header* headers;
int headers_count; int headers_count;
tf_http_message_callback* on_message;
void* context;
void* user_data; void* user_data;
int ref_count; int ref_count;
} tf_http_request_t; } tf_http_request_t;

View File

@ -116,14 +116,14 @@ static JSValue _httpd_response_send(JSContext* context, JSValueConst this_val, i
if (length < 126) if (length < 126)
{ {
copy[1] = length; copy[1] = length;
header += 2; header += 1;
} }
else if (length < (1 << 16)) else if (length < (1 << 16))
{ {
copy[1] = 126; copy[1] = 126;
copy[2] = (length >> 8) & 0xff; copy[2] = (length >> 8) & 0xff;
copy[3] = (length >> 0) & 0xff; copy[3] = (length >> 0) & 0xff;
header += 4; header += 3;
} }
else else
{ {
@ -138,19 +138,34 @@ static JSValue _httpd_response_send(JSContext* context, JSValueConst this_val, i
copy[7] = (low >> 16) & 0xff; copy[7] = (low >> 16) & 0xff;
copy[8] = (low >> 8) & 0xff; copy[8] = (low >> 8) & 0xff;
copy[9] = (low >> 0) & 0xff; copy[9] = (low >> 0) & 0xff;
header += 10; header += 9;
} }
memcpy(copy + header, message, length); memcpy(copy + header, message, length);
tf_printf("SEND [%.*s]\n", (int)length, message); tf_printf("SEND %d\n", (int)length);
tf_http_request_send(request, copy, header + length); tf_http_request_send(request, copy, header + length);
tf_free(copy); tf_free(copy);
JS_FreeCString(context, message); JS_FreeCString(context, message);
return JS_UNDEFINED; return JS_UNDEFINED;
} }
static void _httpd_message_callback(tf_http_request_t* request, const void* data, size_t size)
{
tf_printf("message [%.*s]\n", (int)size, (const char*)data);
JSContext* context = request->context;
JSValue response_object = JS_MKPTR(JS_TAG_OBJECT, request->user_data);
JSValue on_message = JS_GetPropertyStr(context, response_object, "onMessage");
JSValue event = JS_NewObject(context);
JS_SetPropertyStr(context, event, "opCode", JS_NewInt32(context, 0x1));
JS_SetPropertyStr(context, event, "data", JS_NewStringLen(context, data, size)); //tf_util_new_uint8_array(context, data, size);
JSValue response = JS_Call(context, on_message, JS_UNDEFINED, 1, &event);
tf_util_report_error(context, response);
JS_FreeValue(context, event);
JS_FreeValue(context, on_message);
}
static void _httpd_callback(tf_http_request_t* request) static void _httpd_callback(tf_http_request_t* request)
{ {
#if 0
if (request->flags & k_tf_http_handler_flag_websocket) if (request->flags & k_tf_http_handler_flag_websocket)
{ {
const char* header_connection = tf_http_request_get_header(request, "connection"); const char* header_connection = tf_http_request_get_header(request, "connection");
@ -186,7 +201,6 @@ static void _httpd_callback(tf_http_request_t* request)
tf_http_respond(request, 101, headers, send_version ? k_headers_count : (k_headers_count - 1), NULL, 0); tf_http_respond(request, 101, headers, send_version ? k_headers_count : (k_headers_count - 1), NULL, 0);
} }
} }
#endif
http_handler_data_t* data = request->user_data; http_handler_data_t* data = request->user_data;
JSContext* context = data->context; JSContext* context = data->context;
@ -226,8 +240,11 @@ static void _httpd_callback(tf_http_request_t* request)
JSValue response = JS_Call(context, data->callback, JS_UNDEFINED, 2, args); JSValue response = JS_Call(context, data->callback, JS_UNDEFINED, 2, args);
tf_util_report_error(context, response); tf_util_report_error(context, response);
JS_FreeValue(context, request_object); JS_FreeValue(context, request_object);
JS_FreeValue(context, response_object); //JS_FreeValue(context, response_object);
JS_FreeValue(context, response); JS_FreeValue(context, response);
request->on_message = _httpd_message_callback;
request->context = context;
request->user_data = JS_VALUE_GET_PTR(response_object);
} }
static JSValue _httpd_all(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) static JSValue _httpd_all(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)