diff --git a/src/http.c b/src/http.c index 92fccc83..a240d84a 100644 --- a/src/http.c +++ b/src/http.c @@ -974,9 +974,42 @@ static void _http_write(tf_http_connection_t* connection, const void* data, size } } -void tf_http_request_send(tf_http_request_t* request, const void* data, size_t size) +void tf_http_request_websocket_send(tf_http_request_t* request, int op_code, const void* data, size_t size) { - _http_write(request->connection, data, size); + uint8_t* copy = tf_malloc(size + 16); + bool fin = true; + size_t header = 1; + copy[0] = (fin ? (1 << 7) : 0) | (op_code & 0xf); + if (size < 126) + { + copy[1] = size; + header += 1; + } + else if (size < (1 << 16)) + { + copy[1] = 126; + copy[2] = (size >> 8) & 0xff; + copy[3] = (size >> 0) & 0xff; + header += 3; + } + else + { + uint32_t high = (size >> 32) & 0xffffffff; + uint32_t low = (size >> 0) & 0xffffffff; + copy[1] = 127; + copy[2] = (high >> 24) & 0xff; + copy[3] = (high >> 16) & 0xff; + copy[4] = (high >> 8) & 0xff; + copy[5] = (high >> 0) & 0xff; + copy[6] = (low >> 24) & 0xff; + copy[7] = (low >> 16) & 0xff; + copy[8] = (low >> 8) & 0xff; + copy[9] = (low >> 0) & 0xff; + header += 9; + } + memcpy(copy + header, data, size); + _http_write(request->connection, copy, header + size); + tf_free(copy); } void tf_http_respond(tf_http_request_t* request, int status, const char** headers, int headers_count, const void* body, size_t content_length) diff --git a/src/http.h b/src/http.h index 6eaba0be..32c15eaa 100644 --- a/src/http.h +++ b/src/http.h @@ -209,10 +209,11 @@ const char* tf_http_get_cookie(const char* cookie_header, const char* name); ** Send a websocket message. ** @param request The HTTP request which was previously updated to a websocket ** session with tf_http_request_websocket_upgrade(). +** @param op_code Websocket op code. ** @param data The message data. ** @param size The size of data. */ -void tf_http_request_send(tf_http_request_t* request, const void* data, size_t size); +void tf_http_request_websocket_send(tf_http_request_t* request, int op_code, const void* data, size_t size); /** ** Upgrade an HTTP request to a websocket session. diff --git a/src/httpd.js.c b/src/httpd.js.c index 7773947d..f084cdd2 100644 --- a/src/httpd.js.c +++ b/src/httpd.js.c @@ -152,44 +152,9 @@ static JSValue _httpd_response_send(JSContext* context, JSValueConst this_val, i tf_http_request_t* request = JS_GetOpaque(this_val, _httpd_request_class_id); int opcode = 0x1; JS_ToInt32(context, &opcode, argv[1]); - uint64_t length = 0; - size_t length_size = 0; - const char* message = JS_ToCStringLen(context, &length_size, argv[0]); - length = length_size; - uint8_t* copy = tf_malloc(length + 16); - bool fin = true; - size_t header = 1; - copy[0] = (fin ? (1 << 7) : 0) | (opcode & 0xf); - if (length < 126) - { - copy[1] = length; - header += 1; - } - else if (length < (1 << 16)) - { - copy[1] = 126; - copy[2] = (length >> 8) & 0xff; - copy[3] = (length >> 0) & 0xff; - header += 3; - } - else - { - uint32_t high = (length >> 32) & 0xffffffff; - uint32_t low = (length >> 0) & 0xffffffff; - copy[1] = 127; - copy[2] = (high >> 24) & 0xff; - copy[3] = (high >> 16) & 0xff; - copy[4] = (high >> 8) & 0xff; - copy[5] = (high >> 0) & 0xff; - copy[6] = (low >> 24) & 0xff; - copy[7] = (low >> 16) & 0xff; - copy[8] = (low >> 8) & 0xff; - copy[9] = (low >> 0) & 0xff; - header += 9; - } - memcpy(copy + header, message, length); - tf_http_request_send(request, copy, header + length); - tf_free(copy); + size_t length = 0; + const char* message = JS_ToCStringLen(context, &length, argv[0]); + tf_http_request_websocket_send(request, opcode, message, length); JS_FreeCString(context, message); return JS_UNDEFINED; }