diff --git a/src/http.c b/src/http.c index c84009db..774de2bb 100644 --- a/src/http.c +++ b/src/http.c @@ -41,6 +41,7 @@ typedef struct _tf_http_connection_t int flags; tf_http_callback_t* callback; + tf_http_request_t* request; void* user_data; bool is_websocket; @@ -133,6 +134,7 @@ static void _http_connection_destroy(tf_http_connection_t* connection) { if (connection->tcp.data) { + tf_printf("CLOSE %p\n", connection); uv_close((uv_handle_t*)&connection->tcp, _http_connection_on_close); } 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) { - 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; 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, .user_data = connection->user_data, }; + connection->request = request; tf_http_request_ref(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) { + tf_printf("WRITE connection=%p\n", connection); uv_write_t* write = tf_malloc(sizeof(uv_write_t) + size); *write = (uv_write_t) { .data = connection }; memcpy(write + 1, data, size); diff --git a/src/http.h b/src/http.h index 71b1fe4b..fd5270ad 100644 --- a/src/http.h +++ b/src/http.h @@ -5,6 +5,7 @@ typedef struct uv_loop_s uv_loop_t; typedef struct _tf_http_t tf_http_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 { @@ -12,6 +13,8 @@ typedef enum _tf_http_callback_phase_t k_http_callback_phase_request_done, } 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 { tf_http_callback_phase_t phase; @@ -24,6 +27,8 @@ typedef struct _tf_http_request_t size_t content_length; struct phr_header* headers; int headers_count; + tf_http_message_callback* on_message; + void* context; void* user_data; int ref_count; } tf_http_request_t; diff --git a/src/httpd.js.c b/src/httpd.js.c index 3ebbe27d..3f23c24a 100644 --- a/src/httpd.js.c +++ b/src/httpd.js.c @@ -116,14 +116,14 @@ static JSValue _httpd_response_send(JSContext* context, JSValueConst this_val, i if (length < 126) { copy[1] = length; - header += 2; + header += 1; } else if (length < (1 << 16)) { copy[1] = 126; copy[2] = (length >> 8) & 0xff; copy[3] = (length >> 0) & 0xff; - header += 4; + header += 3; } else { @@ -138,19 +138,34 @@ static JSValue _httpd_response_send(JSContext* context, JSValueConst this_val, i copy[7] = (low >> 16) & 0xff; copy[8] = (low >> 8) & 0xff; copy[9] = (low >> 0) & 0xff; - header += 10; + header += 9; } 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_free(copy); JS_FreeCString(context, message); 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) { -#if 0 if (request->flags & k_tf_http_handler_flag_websocket) { 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); } } -#endif http_handler_data_t* data = request->user_data; 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); tf_util_report_error(context, response); JS_FreeValue(context, request_object); - JS_FreeValue(context, response_object); + //JS_FreeValue(context, response_object); 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)