forked from cory/tildefriends
Stop leaking the TLS context.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4802 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
parent
14a4117aff
commit
7f0643f9c0
22
src/http.c
22
src/http.c
@ -77,6 +77,8 @@ typedef struct _tf_http_listener_t
|
|||||||
tf_http_t* http;
|
tf_http_t* http;
|
||||||
tf_tls_context_t* tls;
|
tf_tls_context_t* tls;
|
||||||
uv_tcp_t tcp;
|
uv_tcp_t tcp;
|
||||||
|
tf_http_cleanup_t* cleanup;
|
||||||
|
void* user_data;
|
||||||
} tf_http_listener_t;
|
} tf_http_listener_t;
|
||||||
|
|
||||||
typedef struct _tf_http_t
|
typedef struct _tf_http_t
|
||||||
@ -606,10 +608,17 @@ static void _http_on_connection(uv_stream_t* stream, int status)
|
|||||||
http->connections[http->connections_count++] = connection;
|
http->connections[http->connections_count++] = connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tf_http_listen(tf_http_t* http, int port, tf_tls_context_t* tls)
|
int tf_http_listen(tf_http_t* http, int port, tf_tls_context_t* tls, tf_http_cleanup_t* cleanup, void* user_data)
|
||||||
{
|
{
|
||||||
tf_http_listener_t* listener = tf_malloc(sizeof(tf_http_listener_t));
|
tf_http_listener_t* listener = tf_malloc(sizeof(tf_http_listener_t));
|
||||||
*listener = (tf_http_listener_t) { .http = http, .tls = tls, .tcp = { .data = listener } };
|
*listener = (tf_http_listener_t)
|
||||||
|
{
|
||||||
|
.http = http,
|
||||||
|
.tls = tls,
|
||||||
|
.tcp = { .data = listener },
|
||||||
|
.cleanup = cleanup,
|
||||||
|
.user_data = user_data,
|
||||||
|
};
|
||||||
int r = uv_tcp_init(http->loop, &listener->tcp);
|
int r = uv_tcp_init(http->loop, &listener->tcp);
|
||||||
if (r)
|
if (r)
|
||||||
{
|
{
|
||||||
@ -651,7 +660,7 @@ int tf_http_listen(tf_http_t* http, int port, tf_tls_context_t* tls)
|
|||||||
|
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
{
|
{
|
||||||
http->listeners = tf_realloc(http->listeners, sizeof(tf_http_listener_t*) * (http->listeners_count + 1));
|
http->listeners = tf_resize_vec(http->listeners, sizeof(tf_http_listener_t*) * (http->listeners_count + 1));
|
||||||
http->listeners[http->listeners_count++] = listener;
|
http->listeners[http->listeners_count++] = listener;
|
||||||
}
|
}
|
||||||
return assigned_port;
|
return assigned_port;
|
||||||
@ -680,7 +689,12 @@ void tf_http_destroy(tf_http_t* http)
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < http->listeners_count; i++)
|
for (int i = 0; i < http->listeners_count; i++)
|
||||||
{
|
{
|
||||||
uv_close((uv_handle_t*)&http->listeners[i]->tcp, _http_free_listener_on_close);
|
tf_http_listener_t* listener = http->listeners[i];
|
||||||
|
if (listener->cleanup)
|
||||||
|
{
|
||||||
|
listener->cleanup(listener->user_data);
|
||||||
|
}
|
||||||
|
uv_close((uv_handle_t*)&listener->tcp, _http_free_listener_on_close);
|
||||||
}
|
}
|
||||||
tf_free(http->listeners);
|
tf_free(http->listeners);
|
||||||
http->listeners = NULL;
|
http->listeners = NULL;
|
||||||
|
@ -37,7 +37,7 @@ typedef void (tf_http_cleanup_t)(void* user_data);
|
|||||||
|
|
||||||
tf_http_t* tf_http_create(uv_loop_t* loop);
|
tf_http_t* tf_http_create(uv_loop_t* loop);
|
||||||
void tf_http_set_trace(tf_http_t* http, tf_trace_t* trace);
|
void tf_http_set_trace(tf_http_t* http, tf_trace_t* trace);
|
||||||
int tf_http_listen(tf_http_t* http, int port, tf_tls_context_t* tls);
|
int tf_http_listen(tf_http_t* http, int port, tf_tls_context_t* tls, tf_http_cleanup_t* cleanup, void* user_data);
|
||||||
void tf_http_add_handler(tf_http_t* http, const char* pattern, tf_http_callback_t* callback, tf_http_cleanup_t* cleanup, void* user_data);
|
void tf_http_add_handler(tf_http_t* http, const char* pattern, tf_http_callback_t* callback, tf_http_cleanup_t* cleanup, void* user_data);
|
||||||
void tf_http_respond(tf_http_request_t* request, int status, const char** headers, int headers_count, const void* body, size_t content_length);
|
void tf_http_respond(tf_http_request_t* request, int status, const char** headers, int headers_count, const void* body, size_t content_length);
|
||||||
size_t tf_http_get_body(const tf_http_request_t* request, const void** out_data);
|
size_t tf_http_get_body(const tf_http_request_t* request, const void** out_data);
|
||||||
|
@ -347,20 +347,34 @@ static JSValue _httpd_endpoint_all(JSContext* context, JSValueConst this_val, in
|
|||||||
const char* pattern = JS_ToCString(context, argv[0]);
|
const char* pattern = JS_ToCString(context, argv[0]);
|
||||||
http_handler_data_t* data = tf_malloc(sizeof(http_handler_data_t));
|
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]) };
|
*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, _httpd_cleanup_callback, data);
|
tf_http_add_handler(http, pattern, _httpd_callback, _httpd_cleanup_callback, data);
|
||||||
JS_FreeCString(context, pattern);
|
JS_FreeCString(context, pattern);
|
||||||
return JS_UNDEFINED;
|
return JS_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _httpd_listener_t
|
||||||
|
{
|
||||||
|
JSContext* context;
|
||||||
|
JSValue tls;
|
||||||
|
} httpd_listener_t;
|
||||||
|
|
||||||
|
static void _httpd_listener_cleanup(void* user_data)
|
||||||
|
{
|
||||||
|
httpd_listener_t* listener = user_data;
|
||||||
|
JS_FreeValue(listener->context, listener->tls);
|
||||||
|
tf_free(listener);
|
||||||
|
}
|
||||||
|
|
||||||
static JSValue _httpd_endpoint_start(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
static JSValue _httpd_endpoint_start(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||||
{
|
{
|
||||||
tf_http_t* http = JS_GetOpaque(this_val, _httpd_class_id);
|
tf_http_t* http = JS_GetOpaque(this_val, _httpd_class_id);
|
||||||
int port = 0;
|
int port = 0;
|
||||||
JS_ToInt32(context, &port, argv[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]));
|
httpd_listener_t* listener = tf_malloc(sizeof(httpd_listener_t));
|
||||||
int assigned_port = tf_http_listen(http, port, tls);
|
*listener = (httpd_listener_t) { .context = context, .tls = JS_DupValue(context, argv[1]) };
|
||||||
|
tf_tls_context_t* tls = tf_tls_context_get(listener->tls);
|
||||||
|
int assigned_port = tf_http_listen(http, port, tls, _httpd_listener_cleanup, listener);
|
||||||
return JS_NewInt32(context, assigned_port);
|
return JS_NewInt32(context, assigned_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -739,7 +739,7 @@ static void _test_http(const tf_test_options_t* options)
|
|||||||
tf_http_t* http = tf_http_create(&loop);
|
tf_http_t* http = tf_http_create(&loop);
|
||||||
tf_http_add_handler(http, "/hello", _test_http_handler, NULL, NULL);
|
tf_http_add_handler(http, "/hello", _test_http_handler, NULL, NULL);
|
||||||
tf_http_add_handler(http, "/post", _test_http_handler_post, NULL, NULL);
|
tf_http_add_handler(http, "/post", _test_http_handler_post, NULL, NULL);
|
||||||
tf_http_listen(http, 23456, NULL);
|
tf_http_listen(http, 23456, NULL, NULL, NULL);
|
||||||
|
|
||||||
test_http_t test = { .loop = &loop };
|
test_http_t test = { .loop = &loop };
|
||||||
uv_async_init(&loop, &test.async, _test_http_async);
|
uv_async_init(&loop, &test.async, _test_http_async);
|
||||||
|
Loading…
Reference in New Issue
Block a user