|
@@ -1,4 +1,4 @@
|
|
-/* Copyright (c) 2015 the Civetweb developers
|
|
|
|
|
|
+/* Copyright (c) 2015-2016 the Civetweb developers
|
|
*
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
@@ -103,6 +103,10 @@ wait_not_null(void *volatile *data)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#if defined(__MINGW32__) || defined(__GNUC__)
|
|
|
|
+#pragma GCC diagnostic push
|
|
|
|
+#pragma GCC diagnostic ignored "-Wunreachable-code-return"
|
|
|
|
+#endif
|
|
#ifdef __clang__
|
|
#ifdef __clang__
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wunreachable-code"
|
|
#pragma clang diagnostic ignored "-Wunreachable-code"
|
|
@@ -115,8 +119,12 @@ wait_not_null(void *volatile *data)
|
|
#ifdef __clang__
|
|
#ifdef __clang__
|
|
#pragma clang diagnostic pop
|
|
#pragma clang diagnostic pop
|
|
#endif
|
|
#endif
|
|
|
|
+#if defined(__MINGW32__) || defined(__GNUC__)
|
|
|
|
+#pragma GCC diagnostic pop
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
START_TEST(test_the_test_environment)
|
|
START_TEST(test_the_test_environment)
|
|
{
|
|
{
|
|
char wd[300];
|
|
char wd[300];
|
|
@@ -187,6 +195,7 @@ test_thread_func_t(void *param)
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
START_TEST(test_threading)
|
|
START_TEST(test_threading)
|
|
{
|
|
{
|
|
int ok;
|
|
int ok;
|
|
@@ -218,6 +227,7 @@ log_msg_func(const struct mg_connection *conn, const char *message)
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
START_TEST(test_mg_start_stop_http_server)
|
|
START_TEST(test_mg_start_stop_http_server)
|
|
{
|
|
{
|
|
struct mg_context *ctx;
|
|
struct mg_context *ctx;
|
|
@@ -249,6 +259,7 @@ START_TEST(test_mg_start_stop_http_server)
|
|
callbacks.log_message = log_msg_func;
|
|
callbacks.log_message = log_msg_func;
|
|
|
|
|
|
ctx = mg_start(&callbacks, (void *)errmsg, OPTIONS);
|
|
ctx = mg_start(&callbacks, (void *)errmsg, OPTIONS);
|
|
|
|
+ mark_point();
|
|
test_sleep(1);
|
|
test_sleep(1);
|
|
ck_assert_str_eq(errmsg, "");
|
|
ck_assert_str_eq(errmsg, "");
|
|
ck_assert(ctx != NULL);
|
|
ck_assert(ctx != NULL);
|
|
@@ -261,6 +272,7 @@ START_TEST(test_mg_start_stop_http_server)
|
|
ck_assert_int_eq(ssl[1], 0);
|
|
ck_assert_int_eq(ssl[1], 0);
|
|
|
|
|
|
test_sleep(1);
|
|
test_sleep(1);
|
|
|
|
+ mark_point();
|
|
|
|
|
|
memset(client_err, 0, sizeof(client_err));
|
|
memset(client_err, 0, sizeof(client_err));
|
|
client_conn =
|
|
client_conn =
|
|
@@ -286,7 +298,9 @@ START_TEST(test_mg_start_stop_http_server)
|
|
#endif
|
|
#endif
|
|
mg_close_connection(client_conn);
|
|
mg_close_connection(client_conn);
|
|
|
|
|
|
|
|
+ mark_point();
|
|
test_sleep(1);
|
|
test_sleep(1);
|
|
|
|
+ mark_point();
|
|
|
|
|
|
mg_stop(ctx);
|
|
mg_stop(ctx);
|
|
}
|
|
}
|
|
@@ -338,6 +352,7 @@ START_TEST(test_mg_start_stop_https_server)
|
|
callbacks.log_message = log_msg_func;
|
|
callbacks.log_message = log_msg_func;
|
|
|
|
|
|
ctx = mg_start(&callbacks, (void *)errmsg, OPTIONS);
|
|
ctx = mg_start(&callbacks, (void *)errmsg, OPTIONS);
|
|
|
|
+ mark_point();
|
|
test_sleep(1);
|
|
test_sleep(1);
|
|
ck_assert_str_eq(errmsg, "");
|
|
ck_assert_str_eq(errmsg, "");
|
|
ck_assert(ctx != NULL);
|
|
ck_assert(ctx != NULL);
|
|
@@ -352,6 +367,7 @@ START_TEST(test_mg_start_stop_https_server)
|
|
ck_assert_int_eq(ssl[2], 0);
|
|
ck_assert_int_eq(ssl[2], 0);
|
|
|
|
|
|
test_sleep(1);
|
|
test_sleep(1);
|
|
|
|
+ mark_point();
|
|
|
|
|
|
memset(client_err, 0, sizeof(client_err));
|
|
memset(client_err, 0, sizeof(client_err));
|
|
client_conn =
|
|
client_conn =
|
|
@@ -377,7 +393,9 @@ START_TEST(test_mg_start_stop_https_server)
|
|
#endif
|
|
#endif
|
|
mg_close_connection(client_conn);
|
|
mg_close_connection(client_conn);
|
|
|
|
|
|
|
|
+ mark_point();
|
|
test_sleep(1);
|
|
test_sleep(1);
|
|
|
|
+ mark_point();
|
|
|
|
|
|
mg_stop(ctx);
|
|
mg_stop(ctx);
|
|
#endif
|
|
#endif
|
|
@@ -444,6 +462,7 @@ START_TEST(test_mg_server_and_client_tls)
|
|
callbacks.log_message = log_msg_func;
|
|
callbacks.log_message = log_msg_func;
|
|
|
|
|
|
ctx = mg_start(&callbacks, (void *)errmsg, OPTIONS);
|
|
ctx = mg_start(&callbacks, (void *)errmsg, OPTIONS);
|
|
|
|
+ mark_point();
|
|
test_sleep(1);
|
|
test_sleep(1);
|
|
ck_assert_str_eq(errmsg, "");
|
|
ck_assert_str_eq(errmsg, "");
|
|
ck_assert(ctx != NULL);
|
|
ck_assert(ctx != NULL);
|
|
@@ -464,6 +483,7 @@ START_TEST(test_mg_server_and_client_tls)
|
|
ck_assert_int_eq(ports[2].is_redirect, 0);
|
|
ck_assert_int_eq(ports[2].is_redirect, 0);
|
|
|
|
|
|
test_sleep(1);
|
|
test_sleep(1);
|
|
|
|
+ mark_point();
|
|
|
|
|
|
memset(client_err, 0, sizeof(client_err));
|
|
memset(client_err, 0, sizeof(client_err));
|
|
client_conn =
|
|
client_conn =
|
|
@@ -504,7 +524,9 @@ START_TEST(test_mg_server_and_client_tls)
|
|
|
|
|
|
/* TODO: A client API using a client certificate is missing */
|
|
/* TODO: A client API using a client certificate is missing */
|
|
|
|
|
|
|
|
+ mark_point();
|
|
test_sleep(1);
|
|
test_sleep(1);
|
|
|
|
+ mark_point();
|
|
|
|
|
|
mg_stop(ctx);
|
|
mg_stop(ctx);
|
|
#endif
|
|
#endif
|
|
@@ -565,6 +587,7 @@ static const char *websocket_goodbye_msg = "websocket bye\n";
|
|
static const size_t websocket_goodbye_msg_len =
|
|
static const size_t websocket_goodbye_msg_len =
|
|
14 /* strlen(websocket_goodbye_msg) */;
|
|
14 /* strlen(websocket_goodbye_msg) */;
|
|
|
|
|
|
|
|
+
|
|
static int
|
|
static int
|
|
websock_server_connect(const struct mg_connection *conn, void *udata)
|
|
websock_server_connect(const struct mg_connection *conn, void *udata)
|
|
{
|
|
{
|
|
@@ -576,6 +599,7 @@ websock_server_connect(const struct mg_connection *conn, void *udata)
|
|
return 0; /* return 0 to accept every connection */
|
|
return 0; /* return 0 to accept every connection */
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
static void
|
|
static void
|
|
websock_server_ready(struct mg_connection *conn, void *udata)
|
|
websock_server_ready(struct mg_connection *conn, void *udata)
|
|
{
|
|
{
|
|
@@ -593,6 +617,7 @@ websock_server_ready(struct mg_connection *conn, void *udata)
|
|
printf("Server: Websocket ready X\n");
|
|
printf("Server: Websocket ready X\n");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
static int
|
|
static int
|
|
websock_server_data(struct mg_connection *conn,
|
|
websock_server_data(struct mg_connection *conn,
|
|
int bits,
|
|
int bits,
|
|
@@ -626,6 +651,11 @@ websock_server_data(struct mg_connection *conn,
|
|
mg_websocket_write(conn, WEBSOCKET_OPCODE_TEXT, "ok - 3", 6);
|
|
mg_websocket_write(conn, WEBSOCKET_OPCODE_TEXT, "ok - 3", 6);
|
|
mg_unlock_connection(conn);
|
|
mg_unlock_connection(conn);
|
|
} else {
|
|
} else {
|
|
|
|
+
|
|
|
|
+#if defined(__MINGW32__) || defined(__GNUC__)
|
|
|
|
+#pragma GCC diagnostic push
|
|
|
|
+#pragma GCC diagnostic ignored "-Wunreachable-code-return"
|
|
|
|
+#endif
|
|
#ifdef __clang__
|
|
#ifdef __clang__
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wunreachable-code"
|
|
#pragma clang diagnostic ignored "-Wunreachable-code"
|
|
@@ -639,6 +669,9 @@ websock_server_data(struct mg_connection *conn,
|
|
#ifdef __clang__
|
|
#ifdef __clang__
|
|
#pragma clang diagnostic pop
|
|
#pragma clang diagnostic pop
|
|
#endif
|
|
#endif
|
|
|
|
+#if defined(__MINGW32__) || defined(__GNUC__)
|
|
|
|
+#pragma GCC diagnostic pop
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
|
|
return 1; /* return 1 to keep the connetion open */
|
|
return 1; /* return 1 to keep the connetion open */
|
|
@@ -656,6 +689,7 @@ websock_server_close(const struct mg_connection *conn, void *udata)
|
|
* closed */
|
|
* closed */
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
/****************************************************************************/
|
|
/****************************************************************************/
|
|
/* WEBSOCKET CLIENT */
|
|
/* WEBSOCKET CLIENT */
|
|
/****************************************************************************/
|
|
/****************************************************************************/
|
|
@@ -665,6 +699,7 @@ struct tclient_data {
|
|
int closed;
|
|
int closed;
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+
|
|
static int
|
|
static int
|
|
websocket_client_data_handler(struct mg_connection *conn,
|
|
websocket_client_data_handler(struct mg_connection *conn,
|
|
int flags,
|
|
int flags,
|
|
@@ -693,6 +728,7 @@ websocket_client_data_handler(struct mg_connection *conn,
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
static void
|
|
static void
|
|
websocket_client_close_handler(const struct mg_connection *conn,
|
|
websocket_client_close_handler(const struct mg_connection *conn,
|
|
void *user_data)
|
|
void *user_data)
|
|
@@ -710,6 +746,7 @@ websocket_client_close_handler(const struct mg_connection *conn,
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
+
|
|
START_TEST(test_request_handlers)
|
|
START_TEST(test_request_handlers)
|
|
{
|
|
{
|
|
char ebuf[100];
|
|
char ebuf[100];
|
|
@@ -865,8 +902,13 @@ START_TEST(test_request_handlers)
|
|
ck_assert(ri != NULL);
|
|
ck_assert(ri != NULL);
|
|
ck_assert_str_eq(ri->uri, "200");
|
|
ck_assert_str_eq(ri->uri, "200");
|
|
i = mg_read(client_conn, buf, sizeof(buf));
|
|
i = mg_read(client_conn, buf, sizeof(buf));
|
|
|
|
+ if ((i>=0) && ((size_t)i<sizeof(buf))) {
|
|
|
|
+ buf[i] = 0;
|
|
|
|
+ } else {
|
|
|
|
+ ck_abort_msg("ERROR: test_request_handlers: read returned %i (>=0, <%i)", (int)i, (int)sizeof(buf));
|
|
|
|
+ }
|
|
ck_assert((int)i < (int)sizeof(buf));
|
|
ck_assert((int)i < (int)sizeof(buf));
|
|
- ck_assert(i > 0);
|
|
|
|
|
|
+ ck_assert(i > 0);
|
|
ck_assert_int_eq(i, (int)strlen(expected));
|
|
ck_assert_int_eq(i, (int)strlen(expected));
|
|
buf[i] = 0;
|
|
buf[i] = 0;
|
|
ck_assert_str_eq(buf, expected);
|
|
ck_assert_str_eq(buf, expected);
|
|
@@ -1209,6 +1251,7 @@ START_TEST(test_request_handlers)
|
|
"data1",
|
|
"data1",
|
|
5);
|
|
5);
|
|
|
|
|
|
|
|
+ mark_point();
|
|
wait_not_null(
|
|
wait_not_null(
|
|
&(ws_client1_data
|
|
&(ws_client1_data
|
|
.data)); /* Wait for the websocket acknowledge message */
|
|
.data)); /* Wait for the websocket acknowledge message */
|
|
@@ -1271,6 +1314,7 @@ START_TEST(test_request_handlers)
|
|
"data2",
|
|
"data2",
|
|
5);
|
|
5);
|
|
|
|
|
|
|
|
+ mark_point();
|
|
wait_not_null(
|
|
wait_not_null(
|
|
&(ws_client1_data
|
|
&(ws_client1_data
|
|
.data)); /* Wait for the websocket acknowledge message */
|
|
.data)); /* Wait for the websocket acknowledge message */
|
|
@@ -1287,6 +1331,7 @@ START_TEST(test_request_handlers)
|
|
|
|
|
|
mg_websocket_client_write(ws_client1_conn, WEBSOCKET_OPCODE_TEXT, "bye", 3);
|
|
mg_websocket_client_write(ws_client1_conn, WEBSOCKET_OPCODE_TEXT, "bye", 3);
|
|
|
|
|
|
|
|
+ mark_point();
|
|
wait_not_null(
|
|
wait_not_null(
|
|
&(ws_client1_data.data)); /* Wait for the websocket goodbye message */
|
|
&(ws_client1_data.data)); /* Wait for the websocket goodbye message */
|
|
ck_assert(ws_client1_data.closed == 0);
|
|
ck_assert(ws_client1_data.closed == 0);
|
|
@@ -1304,6 +1349,7 @@ START_TEST(test_request_handlers)
|
|
|
|
|
|
mg_close_connection(ws_client1_conn);
|
|
mg_close_connection(ws_client1_conn);
|
|
|
|
|
|
|
|
+ mark_point();
|
|
test_sleep(3); /* Won't get any message */
|
|
test_sleep(3); /* Won't get any message */
|
|
ck_assert(ws_client1_data.closed == 1);
|
|
ck_assert(ws_client1_data.closed == 1);
|
|
ck_assert(ws_client2_data.closed == 0);
|
|
ck_assert(ws_client2_data.closed == 0);
|
|
@@ -1314,6 +1360,7 @@ START_TEST(test_request_handlers)
|
|
|
|
|
|
mg_websocket_client_write(ws_client2_conn, WEBSOCKET_OPCODE_TEXT, "bye", 3);
|
|
mg_websocket_client_write(ws_client2_conn, WEBSOCKET_OPCODE_TEXT, "bye", 3);
|
|
|
|
|
|
|
|
+ mark_point();
|
|
wait_not_null(
|
|
wait_not_null(
|
|
&(ws_client2_data.data)); /* Wait for the websocket goodbye message */
|
|
&(ws_client2_data.data)); /* Wait for the websocket goodbye message */
|
|
ck_assert(ws_client1_data.closed == 1);
|
|
ck_assert(ws_client1_data.closed == 1);
|
|
@@ -1331,6 +1378,7 @@ START_TEST(test_request_handlers)
|
|
|
|
|
|
mg_close_connection(ws_client2_conn);
|
|
mg_close_connection(ws_client2_conn);
|
|
|
|
|
|
|
|
+ mark_point();
|
|
test_sleep(3); /* Won't get any message */
|
|
test_sleep(3); /* Won't get any message */
|
|
ck_assert(ws_client1_data.closed == 1);
|
|
ck_assert(ws_client1_data.closed == 1);
|
|
ck_assert(ws_client2_data.closed == 1);
|
|
ck_assert(ws_client2_data.closed == 1);
|
|
@@ -1381,11 +1429,13 @@ START_TEST(test_request_handlers)
|
|
/* Close the server */
|
|
/* Close the server */
|
|
g_ctx = NULL;
|
|
g_ctx = NULL;
|
|
mg_stop(ctx);
|
|
mg_stop(ctx);
|
|
|
|
+ mark_point();
|
|
|
|
|
|
#ifdef USE_WEBSOCKET
|
|
#ifdef USE_WEBSOCKET
|
|
for (i = 0; i < 100; i++) {
|
|
for (i = 0; i < 100; i++) {
|
|
test_sleep(1);
|
|
test_sleep(1);
|
|
if (ws_client3_data.closed != 0) {
|
|
if (ws_client3_data.closed != 0) {
|
|
|
|
+ mark_point();
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1435,6 +1485,7 @@ make_public_server_suite(void)
|
|
return suite;
|
|
return suite;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
#ifdef REPLACE_CHECK_FOR_LOCAL_DEBUGGING
|
|
#ifdef REPLACE_CHECK_FOR_LOCAL_DEBUGGING
|
|
/* Used to debug test cases without using the check framework */
|
|
/* Used to debug test cases without using the check framework */
|
|
|
|
|
|
@@ -1515,3 +1566,4 @@ suite_create(const char *name)
|
|
void tcase_set_timeout(TCase *tc, double timeout){};
|
|
void tcase_set_timeout(TCase *tc, double timeout){};
|
|
|
|
|
|
#endif
|
|
#endif
|
|
|
|
+
|