Tryingn to button down websocket lifetime issues.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4795 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		
							
								
								
									
										10
									
								
								src/http.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/http.c
									
									
									
									
									
								
							| @@ -158,6 +158,15 @@ static void _http_connection_destroy(tf_http_connection_t* connection, const cha | ||||
| { | ||||
| 	connection->is_shutting_down = true; | ||||
|  | ||||
| 	if (connection->request && connection->request->on_close) | ||||
| 	{ | ||||
| 		tf_http_close_callback* on_close = connection->request->on_close; | ||||
| 		connection->request->on_close = NULL; | ||||
| 		tf_trace_begin(connection->http->trace, connection->trace_name ? connection->trace_name : "websocket"); | ||||
| 		on_close(connection->request); | ||||
| 		tf_trace_end(connection->http->trace); | ||||
| 	} | ||||
|  | ||||
| 	if (connection->tcp.data && !uv_is_closing((uv_handle_t*)&connection->tcp)) | ||||
| 	{ | ||||
| 		uv_close((uv_handle_t*)&connection->tcp, _http_connection_on_close); | ||||
| @@ -896,6 +905,7 @@ void tf_http_request_release(tf_http_request_t* request) | ||||
| 	} | ||||
| 	if (--request->ref_count == 0) | ||||
| 	{ | ||||
| 		request->connection->request = NULL; | ||||
| 		tf_free(request); | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -11,6 +11,7 @@ typedef struct _tf_trace_t tf_trace_t; | ||||
| typedef struct uv_loop_s uv_loop_t; | ||||
|  | ||||
| typedef void (tf_http_message_callback)(tf_http_request_t* request, int op_code, const void* data, size_t size); | ||||
| typedef void (tf_http_close_callback)(tf_http_request_t* request); | ||||
|  | ||||
| typedef struct _tf_http_request_t | ||||
| { | ||||
| @@ -25,6 +26,7 @@ typedef struct _tf_http_request_t | ||||
| 	struct phr_header* headers; | ||||
| 	int headers_count; | ||||
| 	tf_http_message_callback* on_message; | ||||
| 	tf_http_close_callback* on_close; | ||||
| 	void* context; | ||||
| 	void* user_data; | ||||
| 	int ref_count; | ||||
|   | ||||
| @@ -163,12 +163,23 @@ static JSValue _httpd_response_send(JSContext* context, JSValueConst this_val, i | ||||
| 	return JS_UNDEFINED; | ||||
| } | ||||
|  | ||||
| static void _httpd_close_callback(tf_http_request_t* request) | ||||
| { | ||||
| 	JSContext* context = request->context; | ||||
| 	JSValue response_object = JS_MKPTR(JS_TAG_OBJECT, request->user_data); | ||||
| 	JSValue on_close = JS_GetPropertyStr(context, response_object, "onClose"); | ||||
| 	JSValue response = JS_Call(context, on_close, JS_UNDEFINED, 0, NULL); | ||||
| 	tf_util_report_error(context, response); | ||||
| 	JS_FreeValue(context, response); | ||||
| 	JS_FreeValue(context, on_close); | ||||
| 	tf_http_request_release(request); | ||||
| } | ||||
|  | ||||
| static void _httpd_message_callback(tf_http_request_t* request, int op_code, const void* data, size_t size) | ||||
| { | ||||
| 	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, op_code)); | ||||
| 	JS_SetPropertyStr(context, event, "data", JS_NewStringLen(context, data, size)); | ||||
| @@ -307,12 +318,14 @@ static JSValue _httpd_websocket_upgrade(JSContext* context, JSValueConst this_va | ||||
| 		tf_http_respond(request, 101, headers, headers_count, NULL, 0); | ||||
|  | ||||
| 		request->on_message = _httpd_message_callback; | ||||
| 		request->on_close = _httpd_close_callback; | ||||
| 		request->context = context; | ||||
| 		request->user_data = JS_VALUE_GET_PTR(JS_DupValue(context, this_val)); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		tf_http_respond(request, 400, NULL, 0, NULL, 0); | ||||
| 		tf_http_request_release(request); | ||||
| 	} | ||||
|  | ||||
| 	return JS_UNDEFINED; | ||||
| @@ -324,6 +337,7 @@ static JSValue _httpd_endpoint_all(JSContext* context, JSValueConst this_val, in | ||||
| 	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]) }; | ||||
| 	/* TODO: This leaks the callback. */ | ||||
| 	tf_http_add_handler(http, pattern, _httpd_callback, data); | ||||
| 	JS_FreeCString(context, pattern); | ||||
| 	return JS_UNDEFINED; | ||||
| @@ -334,6 +348,7 @@ static JSValue _httpd_endpoint_start(JSContext* context, JSValueConst this_val, | ||||
| 	tf_http_t* http = JS_GetOpaque(this_val, _httpd_class_id); | ||||
| 	int port = 0; | ||||
| 	JS_ToInt32(context, &port, argv[0]); | ||||
| 	/* TODO: This leaks the TLS context. */ | ||||
| 	tf_tls_context_t* tls = tf_tls_context_get(JS_DupValue(context, argv[1])); | ||||
| 	int assigned_port = tf_http_listen(http, port, tls); | ||||
| 	return JS_NewInt32(context, assigned_port); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user