forked from cory/tildefriends
		
	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:
		
							
								
								
									
										13
									
								
								src/http.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								src/http.c
									
									
									
									
									
								
							| @@ -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); | ||||||
|   | |||||||
| @@ -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; | ||||||
|   | |||||||
| @@ -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) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user