forked from cory/tildefriends
Make the http test complete successfully.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4680 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
parent
7b3a9e0f63
commit
03e4b37c04
56
src/http.c
56
src/http.c
@ -44,9 +44,12 @@ typedef struct _tf_http_t
|
|||||||
tf_http_handler_t* handlers;
|
tf_http_handler_t* handlers;
|
||||||
int handlers_count;
|
int handlers_count;
|
||||||
|
|
||||||
|
int pending_closes;
|
||||||
uv_loop_t* loop;
|
uv_loop_t* loop;
|
||||||
} tf_http_t;
|
} tf_http_t;
|
||||||
|
|
||||||
|
static void _http_connection_destroy(tf_http_connection_t* connection);
|
||||||
|
|
||||||
tf_http_t* tf_http_create(uv_loop_t* loop)
|
tf_http_t* tf_http_create(uv_loop_t* loop)
|
||||||
{
|
{
|
||||||
tf_http_t* http = tf_malloc(sizeof(tf_http_t));
|
tf_http_t* http = tf_malloc(sizeof(tf_http_t));
|
||||||
@ -82,6 +85,33 @@ static void _http_on_write(uv_write_t* write, int status)
|
|||||||
tf_free(write);
|
tf_free(write);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _http_connection_on_close(uv_handle_t* handle)
|
||||||
|
{
|
||||||
|
tf_http_connection_t* connection = handle->data;
|
||||||
|
handle->data = NULL;
|
||||||
|
_http_connection_destroy(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _http_connection_destroy(tf_http_connection_t* connection)
|
||||||
|
{
|
||||||
|
if (connection->tcp.data)
|
||||||
|
{
|
||||||
|
uv_close((uv_handle_t*)&connection->tcp, _http_connection_on_close);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tf_http_t* http = connection->http;
|
||||||
|
for (int i = 0; i < http->connections_count; i++)
|
||||||
|
{
|
||||||
|
if (http->connections[i] == connection)
|
||||||
|
{
|
||||||
|
http->connections[i] = http->connections[--http->connections_count];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tf_free(connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _http_on_read(uv_stream_t* stream, ssize_t read_size, const uv_buf_t* buffer)
|
void _http_on_read(uv_stream_t* stream, ssize_t read_size, const uv_buf_t* buffer)
|
||||||
{
|
{
|
||||||
tf_http_connection_t* connection = stream->data;
|
tf_http_connection_t* connection = stream->data;
|
||||||
@ -129,6 +159,10 @@ void _http_on_read(uv_stream_t* stream, ssize_t read_size, const uv_buf_t* buffe
|
|||||||
tf_printf("phr_parse_request: %d\n", parse_result);
|
tf_printf("phr_parse_request: %d\n", parse_result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_http_connection_destroy(connection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _http_on_connection(uv_stream_t* stream, int status)
|
static void _http_on_connection(uv_stream_t* stream, int status)
|
||||||
@ -218,8 +252,28 @@ void tf_http_add_handler(tf_http_t* http, const char* pattern, tf_http_callback_
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _http_free_on_close(uv_handle_t* handle)
|
||||||
|
{
|
||||||
|
handle->data = NULL;
|
||||||
|
tf_free(handle);
|
||||||
|
}
|
||||||
|
|
||||||
void tf_http_destroy(tf_http_t* http)
|
void tf_http_destroy(tf_http_t* http)
|
||||||
{
|
{
|
||||||
|
for (int i = 0; i < http->listeners_count; i++)
|
||||||
|
{
|
||||||
|
uv_close((uv_handle_t*)http->listeners[i], _http_free_on_close);
|
||||||
|
}
|
||||||
|
tf_free(http->listeners);
|
||||||
|
http->listeners = NULL;
|
||||||
|
http->listeners_count = 0;
|
||||||
|
|
||||||
|
tf_free(http->handlers);
|
||||||
|
http->handlers_count = 0;
|
||||||
|
|
||||||
|
tf_free(http->connections);
|
||||||
|
http->connections_count = 0;
|
||||||
|
|
||||||
tf_free(http);
|
tf_free(http);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,7 +292,7 @@ static void _http_on_shutdown(uv_shutdown_t* request, int status)
|
|||||||
tf_free(request);
|
tf_free(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tf_http_respond(tf_http_request_t* request, int status, const char** headers, int headers_count, 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)
|
||||||
{
|
{
|
||||||
const char* status_text = _http_status_text(status);
|
const char* status_text = _http_status_text(status);
|
||||||
/* HTTP/1.x 200 OK\r\n */
|
/* HTTP/1.x 200 OK\r\n */
|
||||||
|
@ -28,5 +28,5 @@ typedef void (tf_http_callback_t)(tf_http_request_t* request);
|
|||||||
tf_http_t* tf_http_create(uv_loop_t* loop);
|
tf_http_t* tf_http_create(uv_loop_t* loop);
|
||||||
void tf_http_listen(tf_http_t* http, int port);
|
void tf_http_listen(tf_http_t* http, int port);
|
||||||
void tf_http_add_handler(tf_http_t* http, const char* pattern, tf_http_callback_t* callback, void* user_data);
|
void tf_http_add_handler(tf_http_t* http, const char* pattern, tf_http_callback_t* callback, void* user_data);
|
||||||
void tf_http_respond(tf_http_request_t* request, int status, const char** headers, int headers_count, 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);
|
||||||
void tf_http_destroy(tf_http_t* http);
|
void tf_http_destroy(tf_http_t* http);
|
||||||
|
31
src/tests.c
31
src/tests.c
@ -670,24 +670,40 @@ static void _test_b64(const tf_test_options_t* options)
|
|||||||
unlink("out/test.js");
|
unlink("out/test.js");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _test_http_t
|
||||||
|
{
|
||||||
|
uv_loop_t* loop;
|
||||||
|
uv_async_t async;
|
||||||
|
bool done;
|
||||||
|
} test_http_t;
|
||||||
|
|
||||||
|
static void _test_http_async(uv_async_t* async)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static void _test_http_thread(void* data)
|
static void _test_http_thread(void* data)
|
||||||
{
|
{
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
|
test_http_t* test = data;
|
||||||
int r = system("curl -v http://localhost:23456/");
|
int r = system("curl -v http://localhost:23456/");
|
||||||
*(int*)data = WEXITSTATUS(r);
|
|
||||||
assert(WEXITSTATUS(r) == 0);
|
assert(WEXITSTATUS(r) == 0);
|
||||||
tf_printf("curl returned %d\n", WEXITSTATUS(r));
|
tf_printf("curl returned %d\n", WEXITSTATUS(r));
|
||||||
|
|
||||||
|
test->done = true;
|
||||||
|
|
||||||
|
/* All to wake up the loop. */
|
||||||
|
uv_async_send(&test->async);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _test_http_handler(tf_http_request_t* request)
|
static void _test_http_handler(tf_http_request_t* request)
|
||||||
{
|
{
|
||||||
tf_printf("HANDLER %d\n", request->phase);
|
|
||||||
const char* headers[] =
|
const char* headers[] =
|
||||||
{
|
{
|
||||||
"Connection", "close",
|
"Connection", "close",
|
||||||
};
|
};
|
||||||
tf_http_respond(request, 200, headers, 1, "Hello, world!", strlen("Hello, world!"));
|
const char* k_payload = "Hello, world!\n";
|
||||||
|
tf_http_respond(request, 200, headers, 1, k_payload, strlen(k_payload));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _test_http(const tf_test_options_t* options)
|
static void _test_http(const tf_test_options_t* options)
|
||||||
@ -698,16 +714,19 @@ static void _test_http(const tf_test_options_t* options)
|
|||||||
tf_http_add_handler(http, NULL, _test_http_handler, NULL);
|
tf_http_add_handler(http, NULL, _test_http_handler, NULL);
|
||||||
tf_http_listen(http, 23456);
|
tf_http_listen(http, 23456);
|
||||||
|
|
||||||
int result = -1;
|
test_http_t test = { .loop = &loop };
|
||||||
|
uv_async_init(&loop, &test.async, _test_http_async);
|
||||||
uv_thread_t thread = { 0 };
|
uv_thread_t thread = { 0 };
|
||||||
uv_thread_create(&thread, _test_http_thread, &result);
|
uv_thread_create(&thread, _test_http_thread, &test);
|
||||||
while (result == -1)
|
while (!test.done)
|
||||||
{
|
{
|
||||||
uv_run(&loop, UV_RUN_ONCE);
|
uv_run(&loop, UV_RUN_ONCE);
|
||||||
}
|
}
|
||||||
|
uv_close((uv_handle_t*)&test.async, NULL);
|
||||||
tf_printf("Done running.\n");
|
tf_printf("Done running.\n");
|
||||||
|
|
||||||
tf_http_destroy(http);
|
tf_http_destroy(http);
|
||||||
|
uv_run(&loop, UV_RUN_DEFAULT);
|
||||||
uv_loop_close(&loop);
|
uv_loop_close(&loop);
|
||||||
|
|
||||||
uv_thread_join(&thread);
|
uv_thread_join(&thread);
|
||||||
|
Loading…
Reference in New Issue
Block a user