|
@@ -55,13 +55,13 @@ const char *locate_ssl_cert(void)
|
|
#else
|
|
#else
|
|
/* Appveyor */
|
|
/* Appveyor */
|
|
"..\\..\\..\\resources\\ssl_cert.pem"; /* TODO: the different paths
|
|
"..\\..\\..\\resources\\ssl_cert.pem"; /* TODO: the different paths
|
|
- * used in the different test
|
|
|
|
- * system is an unsolved
|
|
|
|
- * problem */
|
|
|
|
|
|
+ * used in the different test
|
|
|
|
+ * system is an unsolved
|
|
|
|
+ * problem */
|
|
#endif
|
|
#endif
|
|
#else
|
|
#else
|
|
#ifdef LOCAL_TEST
|
|
#ifdef LOCAL_TEST
|
|
- "../resources/ssl_cert.pem";
|
|
|
|
|
|
+ "../resources/ssl_cert.pem";
|
|
#else
|
|
#else
|
|
/* Travis */
|
|
/* Travis */
|
|
"../../resources/ssl_cert.pem"; // TODO: fix path in CI test environment
|
|
"../../resources/ssl_cert.pem"; // TODO: fix path in CI test environment
|
|
@@ -95,12 +95,12 @@ START_TEST(test_the_test_environment)
|
|
/* Check the pem file */
|
|
/* Check the pem file */
|
|
#ifdef _WIN32
|
|
#ifdef _WIN32
|
|
strcpy(buf, wd);
|
|
strcpy(buf, wd);
|
|
- strcat(buf, "\\");
|
|
|
|
|
|
+ strcat(buf, "\\");
|
|
strcat(buf, ssl_cert);
|
|
strcat(buf, ssl_cert);
|
|
f = fopen(buf, "rb");
|
|
f = fopen(buf, "rb");
|
|
#else
|
|
#else
|
|
strcpy(buf, wd);
|
|
strcpy(buf, wd);
|
|
- strcat(buf, "/");
|
|
|
|
|
|
+ strcat(buf, "/");
|
|
strcat(buf, ssl_cert);
|
|
strcat(buf, ssl_cert);
|
|
f = fopen(buf, "r");
|
|
f = fopen(buf, "r");
|
|
#endif
|
|
#endif
|
|
@@ -269,9 +269,9 @@ static int request_test_handler(struct mg_connection *conn, void *cbdata)
|
|
|
|
|
|
mg_set_user_connection_data(conn, (void *)6543);
|
|
mg_set_user_connection_data(conn, (void *)6543);
|
|
cud = mg_get_user_connection_data(conn);
|
|
cud = mg_get_user_connection_data(conn);
|
|
- ck_assert(cud == (void *)6543);
|
|
|
|
|
|
+ ck_assert_int_eq((int)cud, (int)6543);
|
|
|
|
|
|
- ck_assert(cbdata == (void *)7);
|
|
|
|
|
|
+ ck_assert_int_eq((int)cbdata, (int)7);
|
|
strcpy(chunk_data, "123456789A123456789B123456789C");
|
|
strcpy(chunk_data, "123456789A123456789B123456789C");
|
|
|
|
|
|
mg_printf(conn,
|
|
mg_printf(conn,
|
|
@@ -291,11 +291,130 @@ static int request_test_handler(struct mg_connection *conn, void *cbdata)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+#ifdef USE_WEBSOCKET
|
|
|
|
+/****************************************************************************/
|
|
|
|
+/* WEBSOCKET SERVER */
|
|
|
|
+/****************************************************************************/
|
|
|
|
+const char *websocket_welcome_msg = "websocket welcome\n";
|
|
|
|
+const size_t websocket_welcome_msg_len = 18 /* strlen(websocket_welcome_msg) */;
|
|
|
|
+const char *websocket_acknowledge_msg = "websocket msg ok\n";
|
|
|
|
+const size_t websocket_acknowledge_msg_len =
|
|
|
|
+ 17 /* strlen(websocket_acknowledge_msg) */;
|
|
|
|
+const char *websocket_goodbye_msg = "websocket bye\n";
|
|
|
|
+const size_t websocket_goodbye_msg_len = 14 /* strlen(websocket_goodbye_msg) */;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+int websock_server_connect(const struct mg_connection *conn, void *udata)
|
|
|
|
+{
|
|
|
|
+ ck_assert_int_eq((int)udata, 7531);
|
|
|
|
+ printf("Server: Websocket connected\n");
|
|
|
|
+ return 0; /* return 0 to accept every connection */
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void websock_server_ready(struct mg_connection *conn, void *udata)
|
|
|
|
+{
|
|
|
|
+ ck_assert_int_eq((int)udata, 7531);
|
|
|
|
+ printf("Server: Websocket ready\n");
|
|
|
|
+
|
|
|
|
+ /* Send websocket welcome message */
|
|
|
|
+ mg_lock_connection(conn);
|
|
|
|
+ mg_websocket_write(conn,
|
|
|
|
+ WEBSOCKET_OPCODE_TEXT,
|
|
|
|
+ websocket_welcome_msg,
|
|
|
|
+ websocket_welcome_msg_len);
|
|
|
|
+ mg_unlock_connection(conn);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int websock_server_data(struct mg_connection *conn,
|
|
|
|
+ int bits,
|
|
|
|
+ char *data,
|
|
|
|
+ size_t data_len,
|
|
|
|
+ void *udata)
|
|
|
|
+{
|
|
|
|
+ ck_assert_int_eq((int)udata, 7531);
|
|
|
|
+ printf("Server: Got %u bytes from the client\n", data_len);
|
|
|
|
+
|
|
|
|
+ if (data_len < 3 || 0 != memcmp(data, "bye", 3)) {
|
|
|
|
+ /* Send websocket acknowledge message */
|
|
|
|
+ mg_lock_connection(conn);
|
|
|
|
+ mg_websocket_write(conn,
|
|
|
|
+ WEBSOCKET_OPCODE_TEXT,
|
|
|
|
+ websocket_acknowledge_msg,
|
|
|
|
+ websocket_acknowledge_msg_len);
|
|
|
|
+ mg_unlock_connection(conn);
|
|
|
|
+ } else {
|
|
|
|
+ /* Send websocket acknowledge message */
|
|
|
|
+ mg_lock_connection(conn);
|
|
|
|
+ mg_websocket_write(conn,
|
|
|
|
+ WEBSOCKET_OPCODE_TEXT,
|
|
|
|
+ websocket_goodbye_msg,
|
|
|
|
+ websocket_goodbye_msg_len);
|
|
|
|
+ mg_unlock_connection(conn);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 1; /* return 1 to keep the connetion open */
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void websock_server_close(const struct mg_connection *conn, void *udata)
|
|
|
|
+{
|
|
|
|
+ ck_assert_int_eq((int)udata, 7531);
|
|
|
|
+ printf("Server: Close connection\n");
|
|
|
|
+
|
|
|
|
+ /* Can not send a websocket goodbye message here - the connection is already
|
|
|
|
+ * closed */
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/****************************************************************************/
|
|
|
|
+/* WEBSOCKET CLIENT */
|
|
|
|
+/****************************************************************************/
|
|
|
|
+struct tclient_data {
|
|
|
|
+ void *data;
|
|
|
|
+ size_t len;
|
|
|
|
+ int closed;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static int websocket_client_data_handler(struct mg_connection *conn,
|
|
|
|
+ int flags,
|
|
|
|
+ char *data,
|
|
|
|
+ size_t data_len,
|
|
|
|
+ void *user_data)
|
|
|
|
+{
|
|
|
|
+ struct mg_context *ctx = mg_get_context(conn);
|
|
|
|
+ struct tclient_data *pclient_data =
|
|
|
|
+ (struct tclient_data *)mg_get_user_data(ctx);
|
|
|
|
+ ck_assert(pclient_data != NULL);
|
|
|
|
+
|
|
|
|
+ printf("Client received data from server: ");
|
|
|
|
+ fwrite(data, 1, data_len, stdout);
|
|
|
|
+ printf("\n");
|
|
|
|
+
|
|
|
|
+ pclient_data->data = malloc(data_len);
|
|
|
|
+ ck_assert(pclient_data->data != NULL);
|
|
|
|
+ memcpy(pclient_data->data, data, data_len);
|
|
|
|
+ pclient_data->len = data_len;
|
|
|
|
+
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void websocket_client_close_handler(const struct mg_connection *conn,
|
|
|
|
+ void *user_data)
|
|
|
|
+{
|
|
|
|
+ struct mg_context *ctx = mg_get_context(conn);
|
|
|
|
+ struct tclient_data *pclient_data =
|
|
|
|
+ (struct tclient_data *)mg_get_user_data(ctx);
|
|
|
|
+ ck_assert(pclient_data != NULL);
|
|
|
|
+
|
|
|
|
+ printf("Client: Close handler\n");
|
|
|
|
+ pclient_data->closed++;
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+
|
|
START_TEST(test_request_handlers)
|
|
START_TEST(test_request_handlers)
|
|
{
|
|
{
|
|
char ebuf[100];
|
|
char ebuf[100];
|
|
struct mg_context *ctx;
|
|
struct mg_context *ctx;
|
|
- struct mg_connection *conn;
|
|
|
|
|
|
+ struct mg_connection *client_conn;
|
|
const struct mg_request_info *ri;
|
|
const struct mg_request_info *ri;
|
|
char uri[64];
|
|
char uri[64];
|
|
char buf[1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 8];
|
|
char buf[1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 8];
|
|
@@ -331,6 +450,16 @@ START_TEST(test_request_handlers)
|
|
int opt_idx = 0;
|
|
int opt_idx = 0;
|
|
const char *ssl_cert = locate_ssl_cert();
|
|
const char *ssl_cert = locate_ssl_cert();
|
|
|
|
|
|
|
|
+#ifdef USE_WEBSOCKET
|
|
|
|
+ struct tclient_data ws_client1_data = {NULL, 0, 0};
|
|
|
|
+ struct tclient_data ws_client2_data = {NULL, 0, 0};
|
|
|
|
+ struct tclient_data ws_client3_data = {NULL, 0, 0};
|
|
|
|
+ struct mg_connection *ws_client1_conn = NULL;
|
|
|
|
+ struct mg_connection *ws_client2_conn = NULL;
|
|
|
|
+ struct mg_connection *ws_client3_conn = NULL;
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+
|
|
memset((void *)OPTIONS, 0, sizeof(OPTIONS));
|
|
memset((void *)OPTIONS, 0, sizeof(OPTIONS));
|
|
OPTIONS[opt_idx++] = "listening_ports";
|
|
OPTIONS[opt_idx++] = "listening_ports";
|
|
OPTIONS[opt_idx++] = HTTP_PORT;
|
|
OPTIONS[opt_idx++] = HTTP_PORT;
|
|
@@ -381,124 +510,135 @@ START_TEST(test_request_handlers)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+#ifdef USE_WEBSOCKET
|
|
|
|
+ mg_set_websocket_handler(ctx,
|
|
|
|
+ "/websocket",
|
|
|
|
+ websock_server_connect,
|
|
|
|
+ websock_server_ready,
|
|
|
|
+ websock_server_data,
|
|
|
|
+ websock_server_close,
|
|
|
|
+ (void *)7531);
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+
|
|
/* Try to load non existing file */
|
|
/* Try to load non existing file */
|
|
- conn = mg_download("localhost",
|
|
|
|
- ipv4_port,
|
|
|
|
- 0,
|
|
|
|
- ebuf,
|
|
|
|
- sizeof(ebuf),
|
|
|
|
- "%s",
|
|
|
|
- "GET /file/not/found HTTP/1.0\r\n\r\n");
|
|
|
|
- ck_assert(conn != NULL);
|
|
|
|
- ri = mg_get_request_info(conn);
|
|
|
|
|
|
+ client_conn = mg_download("localhost",
|
|
|
|
+ ipv4_port,
|
|
|
|
+ 0,
|
|
|
|
+ ebuf,
|
|
|
|
+ sizeof(ebuf),
|
|
|
|
+ "%s",
|
|
|
|
+ "GET /file/not/found HTTP/1.0\r\n\r\n");
|
|
|
|
+ ck_assert(client_conn != NULL);
|
|
|
|
+ ri = mg_get_request_info(client_conn);
|
|
|
|
|
|
ck_assert(ri != NULL);
|
|
ck_assert(ri != NULL);
|
|
ck_assert_str_eq(ri->uri, "404");
|
|
ck_assert_str_eq(ri->uri, "404");
|
|
- mg_close_connection(conn);
|
|
|
|
|
|
+ mg_close_connection(client_conn);
|
|
|
|
|
|
|
|
|
|
/* Get data from callback */
|
|
/* Get data from callback */
|
|
- conn = mg_download(
|
|
|
|
|
|
+ client_conn = mg_download(
|
|
"localhost", ipv4_port, 0, ebuf, sizeof(ebuf), "%s", request);
|
|
"localhost", ipv4_port, 0, ebuf, sizeof(ebuf), "%s", request);
|
|
- ck_assert(conn != NULL);
|
|
|
|
- ri = mg_get_request_info(conn);
|
|
|
|
|
|
+ ck_assert(client_conn != NULL);
|
|
|
|
+ ri = mg_get_request_info(client_conn);
|
|
|
|
|
|
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(conn, buf, sizeof(buf));
|
|
|
|
|
|
+ i = mg_read(client_conn, buf, sizeof(buf));
|
|
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);
|
|
- mg_close_connection(conn);
|
|
|
|
|
|
+ mg_close_connection(client_conn);
|
|
|
|
|
|
|
|
|
|
/* Get data from callback using http://127.0.0.1 */
|
|
/* Get data from callback using http://127.0.0.1 */
|
|
- conn = mg_download(
|
|
|
|
|
|
+ client_conn = mg_download(
|
|
"127.0.0.1", ipv4_port, 0, ebuf, sizeof(ebuf), "%s", request);
|
|
"127.0.0.1", ipv4_port, 0, ebuf, sizeof(ebuf), "%s", request);
|
|
- ck_assert(conn != NULL);
|
|
|
|
- ri = mg_get_request_info(conn);
|
|
|
|
|
|
+ ck_assert(client_conn != NULL);
|
|
|
|
+ ri = mg_get_request_info(client_conn);
|
|
|
|
|
|
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(conn, buf, sizeof(buf));
|
|
|
|
|
|
+ i = mg_read(client_conn, buf, sizeof(buf));
|
|
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);
|
|
- mg_close_connection(conn);
|
|
|
|
|
|
+ mg_close_connection(client_conn);
|
|
|
|
|
|
|
|
|
|
#if defined(USE_IPV6)
|
|
#if defined(USE_IPV6)
|
|
/* Get data from callback using http://[::1] */
|
|
/* Get data from callback using http://[::1] */
|
|
- conn =
|
|
|
|
|
|
+ client_conn =
|
|
mg_download("[::1]", ipv6_port, 0, ebuf, sizeof(ebuf), "%s", request);
|
|
mg_download("[::1]", ipv6_port, 0, ebuf, sizeof(ebuf), "%s", request);
|
|
- ck_assert(conn != NULL);
|
|
|
|
- ri = mg_get_request_info(conn);
|
|
|
|
|
|
+ ck_assert(client_conn != NULL);
|
|
|
|
+ ri = mg_get_request_info(client_conn);
|
|
|
|
|
|
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(conn, buf, sizeof(buf));
|
|
|
|
|
|
+ i = mg_read(client_conn, buf, sizeof(buf));
|
|
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);
|
|
- mg_close_connection(conn);
|
|
|
|
|
|
+ mg_close_connection(client_conn);
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if !defined(NO_SSL)
|
|
#if !defined(NO_SSL)
|
|
/* Get data from callback using https://127.0.0.1 */
|
|
/* Get data from callback using https://127.0.0.1 */
|
|
- conn = mg_download(
|
|
|
|
|
|
+ client_conn = mg_download(
|
|
"127.0.0.1", ipv4s_port, 1, ebuf, sizeof(ebuf), "%s", request);
|
|
"127.0.0.1", ipv4s_port, 1, ebuf, sizeof(ebuf), "%s", request);
|
|
- ck_assert(conn != NULL);
|
|
|
|
- ri = mg_get_request_info(conn);
|
|
|
|
|
|
+ ck_assert(client_conn != NULL);
|
|
|
|
+ ri = mg_get_request_info(client_conn);
|
|
|
|
|
|
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(conn, buf, sizeof(buf));
|
|
|
|
|
|
+ i = mg_read(client_conn, buf, sizeof(buf));
|
|
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);
|
|
- mg_close_connection(conn);
|
|
|
|
|
|
+ mg_close_connection(client_conn);
|
|
|
|
|
|
/* Get redirect from callback using http://127.0.0.1 */
|
|
/* Get redirect from callback using http://127.0.0.1 */
|
|
- conn = mg_download(
|
|
|
|
|
|
+ client_conn = mg_download(
|
|
"127.0.0.1", ipv4r_port, 0, ebuf, sizeof(ebuf), "%s", request);
|
|
"127.0.0.1", ipv4r_port, 0, ebuf, sizeof(ebuf), "%s", request);
|
|
- ck_assert(conn != NULL);
|
|
|
|
- ri = mg_get_request_info(conn);
|
|
|
|
|
|
+ ck_assert(client_conn != NULL);
|
|
|
|
+ ri = mg_get_request_info(client_conn);
|
|
|
|
|
|
ck_assert(ri != NULL);
|
|
ck_assert(ri != NULL);
|
|
ck_assert_str_eq(ri->uri, "302");
|
|
ck_assert_str_eq(ri->uri, "302");
|
|
- i = mg_read(conn, buf, sizeof(buf));
|
|
|
|
|
|
+ i = mg_read(client_conn, buf, sizeof(buf));
|
|
ck_assert_int_eq(i, -1);
|
|
ck_assert_int_eq(i, -1);
|
|
- mg_close_connection(conn);
|
|
|
|
|
|
+ mg_close_connection(client_conn);
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if defined(USE_IPV6) && !defined(NO_SSL)
|
|
#if defined(USE_IPV6) && !defined(NO_SSL)
|
|
/* Get data from callback using https://[::1] */
|
|
/* Get data from callback using https://[::1] */
|
|
- conn =
|
|
|
|
|
|
+ client_conn =
|
|
mg_download("[::1]", ipv6s_port, 1, ebuf, sizeof(ebuf), "%s", request);
|
|
mg_download("[::1]", ipv6s_port, 1, ebuf, sizeof(ebuf), "%s", request);
|
|
- ck_assert(conn != NULL);
|
|
|
|
- ri = mg_get_request_info(conn);
|
|
|
|
|
|
+ ck_assert(client_conn != NULL);
|
|
|
|
+ ri = mg_get_request_info(client_conn);
|
|
|
|
|
|
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(conn, buf, sizeof(buf));
|
|
|
|
|
|
+ i = mg_read(client_conn, buf, sizeof(buf));
|
|
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);
|
|
- mg_close_connection(conn);
|
|
|
|
|
|
+ mg_close_connection(client_conn);
|
|
|
|
|
|
/* Get redirect from callback using http://127.0.0.1 */
|
|
/* Get redirect from callback using http://127.0.0.1 */
|
|
- conn =
|
|
|
|
|
|
+ client_conn =
|
|
mg_download("[::1]", ipv6r_port, 0, ebuf, sizeof(ebuf), "%s", request);
|
|
mg_download("[::1]", ipv6r_port, 0, ebuf, sizeof(ebuf), "%s", request);
|
|
- ck_assert(conn != NULL);
|
|
|
|
- ri = mg_get_request_info(conn);
|
|
|
|
|
|
+ ck_assert(client_conn != NULL);
|
|
|
|
+ ri = mg_get_request_info(client_conn);
|
|
|
|
|
|
ck_assert(ri != NULL);
|
|
ck_assert(ri != NULL);
|
|
ck_assert_str_eq(ri->uri, "302");
|
|
ck_assert_str_eq(ri->uri, "302");
|
|
- i = mg_read(conn, buf, sizeof(buf));
|
|
|
|
|
|
+ i = mg_read(client_conn, buf, sizeof(buf));
|
|
ck_assert_int_eq(i, -1);
|
|
ck_assert_int_eq(i, -1);
|
|
- mg_close_connection(conn);
|
|
|
|
|
|
+ mg_close_connection(client_conn);
|
|
#endif
|
|
#endif
|
|
|
|
|
|
/* It seems to be impossible to find out what the actual working
|
|
/* It seems to be impossible to find out what the actual working
|
|
@@ -515,15 +655,15 @@ START_TEST(test_request_handlers)
|
|
|
|
|
|
|
|
|
|
/* Get static data */
|
|
/* Get static data */
|
|
- conn = mg_download("localhost",
|
|
|
|
- ipv4_port,
|
|
|
|
- 0,
|
|
|
|
- ebuf,
|
|
|
|
- sizeof(ebuf),
|
|
|
|
- "%s",
|
|
|
|
- "GET /test.txt HTTP/1.0\r\n\r\n");
|
|
|
|
- ck_assert(conn != NULL);
|
|
|
|
- ri = mg_get_request_info(conn);
|
|
|
|
|
|
+ client_conn = mg_download("localhost",
|
|
|
|
+ ipv4_port,
|
|
|
|
+ 0,
|
|
|
|
+ ebuf,
|
|
|
|
+ sizeof(ebuf),
|
|
|
|
+ "%s",
|
|
|
|
+ "GET /test.txt HTTP/1.0\r\n\r\n");
|
|
|
|
+ ck_assert(client_conn != NULL);
|
|
|
|
+ ri = mg_get_request_info(client_conn);
|
|
|
|
|
|
ck_assert(ri != NULL);
|
|
ck_assert(ri != NULL);
|
|
|
|
|
|
@@ -531,74 +671,74 @@ START_TEST(test_request_handlers)
|
|
ck_assert_str_eq(ri->uri, "404");
|
|
ck_assert_str_eq(ri->uri, "404");
|
|
#else
|
|
#else
|
|
ck_assert_str_eq(ri->uri, "200");
|
|
ck_assert_str_eq(ri->uri, "200");
|
|
- i = mg_read(conn, buf, sizeof(buf));
|
|
|
|
|
|
+ i = mg_read(client_conn, buf, sizeof(buf));
|
|
ck_assert_int_eq(i, 17);
|
|
ck_assert_int_eq(i, 17);
|
|
if ((i >= 0) && (i < (int)sizeof(buf))) {
|
|
if ((i >= 0) && (i < (int)sizeof(buf))) {
|
|
buf[i] = 0;
|
|
buf[i] = 0;
|
|
}
|
|
}
|
|
ck_assert_str_eq(buf, "simple text file\n");
|
|
ck_assert_str_eq(buf, "simple text file\n");
|
|
#endif
|
|
#endif
|
|
- mg_close_connection(conn);
|
|
|
|
|
|
+ mg_close_connection(client_conn);
|
|
|
|
|
|
|
|
|
|
/* Get directory listing */
|
|
/* Get directory listing */
|
|
- conn = mg_download("localhost",
|
|
|
|
- ipv4_port,
|
|
|
|
- 0,
|
|
|
|
- ebuf,
|
|
|
|
- sizeof(ebuf),
|
|
|
|
- "%s",
|
|
|
|
- "GET / HTTP/1.0\r\n\r\n");
|
|
|
|
- ck_assert(conn != NULL);
|
|
|
|
- ri = mg_get_request_info(conn);
|
|
|
|
|
|
+ client_conn = mg_download("localhost",
|
|
|
|
+ ipv4_port,
|
|
|
|
+ 0,
|
|
|
|
+ ebuf,
|
|
|
|
+ sizeof(ebuf),
|
|
|
|
+ "%s",
|
|
|
|
+ "GET / HTTP/1.0\r\n\r\n");
|
|
|
|
+ ck_assert(client_conn != NULL);
|
|
|
|
+ ri = mg_get_request_info(client_conn);
|
|
|
|
|
|
ck_assert(ri != NULL);
|
|
ck_assert(ri != NULL);
|
|
#if defined(NO_FILES)
|
|
#if defined(NO_FILES)
|
|
ck_assert_str_eq(ri->uri, "404");
|
|
ck_assert_str_eq(ri->uri, "404");
|
|
#else
|
|
#else
|
|
ck_assert_str_eq(ri->uri, "200");
|
|
ck_assert_str_eq(ri->uri, "200");
|
|
- i = mg_read(conn, buf, sizeof(buf));
|
|
|
|
|
|
+ i = mg_read(client_conn, buf, sizeof(buf));
|
|
ck_assert(i > 6);
|
|
ck_assert(i > 6);
|
|
buf[6] = 0;
|
|
buf[6] = 0;
|
|
ck_assert_str_eq(buf, "<html>");
|
|
ck_assert_str_eq(buf, "<html>");
|
|
#endif
|
|
#endif
|
|
- mg_close_connection(conn);
|
|
|
|
|
|
+ mg_close_connection(client_conn);
|
|
|
|
|
|
|
|
|
|
/* POST to static file (will not work) */
|
|
/* POST to static file (will not work) */
|
|
- conn = mg_download("localhost",
|
|
|
|
- ipv4_port,
|
|
|
|
- 0,
|
|
|
|
- ebuf,
|
|
|
|
- sizeof(ebuf),
|
|
|
|
- "%s",
|
|
|
|
- "POST /test.txt HTTP/1.0\r\n\r\n");
|
|
|
|
- ck_assert(conn != NULL);
|
|
|
|
- ri = mg_get_request_info(conn);
|
|
|
|
|
|
+ client_conn = mg_download("localhost",
|
|
|
|
+ ipv4_port,
|
|
|
|
+ 0,
|
|
|
|
+ ebuf,
|
|
|
|
+ sizeof(ebuf),
|
|
|
|
+ "%s",
|
|
|
|
+ "POST /test.txt HTTP/1.0\r\n\r\n");
|
|
|
|
+ ck_assert(client_conn != NULL);
|
|
|
|
+ ri = mg_get_request_info(client_conn);
|
|
|
|
|
|
ck_assert(ri != NULL);
|
|
ck_assert(ri != NULL);
|
|
#if defined(NO_FILES)
|
|
#if defined(NO_FILES)
|
|
ck_assert_str_eq(ri->uri, "404");
|
|
ck_assert_str_eq(ri->uri, "404");
|
|
#else
|
|
#else
|
|
ck_assert_str_eq(ri->uri, "405");
|
|
ck_assert_str_eq(ri->uri, "405");
|
|
- i = mg_read(conn, buf, sizeof(buf));
|
|
|
|
|
|
+ i = mg_read(client_conn, buf, sizeof(buf));
|
|
ck_assert(i >= 29);
|
|
ck_assert(i >= 29);
|
|
buf[29] = 0;
|
|
buf[29] = 0;
|
|
ck_assert_str_eq(buf, "Error 405: Method Not Allowed");
|
|
ck_assert_str_eq(buf, "Error 405: Method Not Allowed");
|
|
#endif
|
|
#endif
|
|
- mg_close_connection(conn);
|
|
|
|
|
|
+ mg_close_connection(client_conn);
|
|
|
|
|
|
|
|
|
|
/* PUT to static file (will not work) */
|
|
/* PUT to static file (will not work) */
|
|
- conn = mg_download("localhost",
|
|
|
|
- ipv4_port,
|
|
|
|
- 0,
|
|
|
|
- ebuf,
|
|
|
|
- sizeof(ebuf),
|
|
|
|
- "%s",
|
|
|
|
- "PUT /test.txt HTTP/1.0\r\n\r\n");
|
|
|
|
- ck_assert(conn != NULL);
|
|
|
|
- ri = mg_get_request_info(conn);
|
|
|
|
|
|
+ client_conn = mg_download("localhost",
|
|
|
|
+ ipv4_port,
|
|
|
|
+ 0,
|
|
|
|
+ ebuf,
|
|
|
|
+ sizeof(ebuf),
|
|
|
|
+ "%s",
|
|
|
|
+ "PUT /test.txt HTTP/1.0\r\n\r\n");
|
|
|
|
+ ck_assert(client_conn != NULL);
|
|
|
|
+ ri = mg_get_request_info(client_conn);
|
|
|
|
|
|
ck_assert(ri != NULL);
|
|
ck_assert(ri != NULL);
|
|
#if defined(NO_FILES)
|
|
#if defined(NO_FILES)
|
|
@@ -606,16 +746,204 @@ START_TEST(test_request_handlers)
|
|
#else
|
|
#else
|
|
ck_assert_str_eq(ri->uri, "401"); /* not authorized */
|
|
ck_assert_str_eq(ri->uri, "401"); /* not authorized */
|
|
#endif
|
|
#endif
|
|
- mg_close_connection(conn);
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- /* TODO: Test websockets */
|
|
|
|
-
|
|
|
|
|
|
+ mg_close_connection(client_conn);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/* Websocket test */
|
|
|
|
+#ifdef USE_WEBSOCKET
|
|
|
|
+ /* Then connect a first client */
|
|
|
|
+ ws_client1_conn =
|
|
|
|
+ mg_connect_websocket_client("localhost",
|
|
|
|
+ ipv4_port,
|
|
|
|
+ 0,
|
|
|
|
+ ebuf,
|
|
|
|
+ sizeof(ebuf),
|
|
|
|
+ "/websocket",
|
|
|
|
+ NULL,
|
|
|
|
+ websocket_client_data_handler,
|
|
|
|
+ websocket_client_close_handler,
|
|
|
|
+ &ws_client1_data);
|
|
|
|
+
|
|
|
|
+ ck_assert(ws_client1_conn != NULL);
|
|
|
|
+
|
|
|
|
+ mg_Sleep(3); /* Should get the websocket welcome message */
|
|
|
|
+ ck_assert_int_eq(ws_client1_data.closed, 0);
|
|
|
|
+ ck_assert_int_eq(ws_client2_data.closed, 0);
|
|
|
|
+ ck_assert_int_eq(ws_client3_data.closed, 0);
|
|
|
|
+ ck_assert(ws_client2_data.data == NULL);
|
|
|
|
+ ck_assert_uint_eq(ws_client2_data.len, 0);
|
|
|
|
+ ck_assert(ws_client1_data.data != NULL);
|
|
|
|
+ ck_assert_uint_eq(ws_client1_data.len, websocket_welcome_msg_len);
|
|
|
|
+ ck_assert(!memcmp(ws_client1_data.data,
|
|
|
|
+ websocket_welcome_msg,
|
|
|
|
+ websocket_welcome_msg_len));
|
|
|
|
+ free(ws_client1_data.data);
|
|
|
|
+ ws_client1_data.data = NULL;
|
|
|
|
+ ws_client1_data.len = 0;
|
|
|
|
+
|
|
|
|
+ mg_websocket_write(ws_client1_conn, WEBSOCKET_OPCODE_TEXT, "data1", 5);
|
|
|
|
+
|
|
|
|
+ mg_Sleep(3); /* Should get the acknowledge message */
|
|
|
|
+ ck_assert_int_eq(ws_client1_data.closed, 0);
|
|
|
|
+ ck_assert_int_eq(ws_client2_data.closed, 0);
|
|
|
|
+ ck_assert(ws_client2_data.data == NULL);
|
|
|
|
+ ck_assert_uint_eq(ws_client2_data.len, 0);
|
|
|
|
+ ck_assert(ws_client1_data.data != NULL);
|
|
|
|
+ ck_assert_uint_eq(ws_client1_data.len, websocket_acknowledge_msg_len);
|
|
|
|
+ ck_assert(!memcmp(ws_client1_data.data,
|
|
|
|
+ websocket_acknowledge_msg,
|
|
|
|
+ websocket_acknowledge_msg_len));
|
|
|
|
+ free(ws_client1_data.data);
|
|
|
|
+ ws_client1_data.data = NULL;
|
|
|
|
+ ws_client1_data.len = 0;
|
|
|
|
+
|
|
|
|
+/* Now connect a second client */
|
|
|
|
+#ifdef USE_IPV6
|
|
|
|
+ ws_client2_conn =
|
|
|
|
+ mg_connect_websocket_client("[::1]",
|
|
|
|
+ ipv6_port,
|
|
|
|
+ 0,
|
|
|
|
+ ebuf,
|
|
|
|
+ sizeof(ebuf),
|
|
|
|
+ "/websocket",
|
|
|
|
+ NULL,
|
|
|
|
+ websocket_client_data_handler,
|
|
|
|
+ websocket_client_close_handler,
|
|
|
|
+ &ws_client2_data);
|
|
|
|
+#else
|
|
|
|
+ ws_client2_conn =
|
|
|
|
+ mg_connect_websocket_client("127.0.0.1",
|
|
|
|
+ ipv4_port,
|
|
|
|
+ 0,
|
|
|
|
+ ebuf,
|
|
|
|
+ sizeof(ebuf),
|
|
|
|
+ "/websocket",
|
|
|
|
+ NULL,
|
|
|
|
+ websocket_client_data_handler,
|
|
|
|
+ websocket_client_close_handler,
|
|
|
|
+ &ws_client2_data);
|
|
|
|
+#endif
|
|
|
|
+ ck_assert(ws_client2_conn != NULL);
|
|
|
|
+
|
|
|
|
+ mg_Sleep(3); /* Client 2 should get the websocket welcome message */
|
|
|
|
+ ck_assert(ws_client1_data.closed == 0);
|
|
|
|
+ ck_assert(ws_client2_data.closed == 0);
|
|
|
|
+ ck_assert(ws_client1_data.data == NULL);
|
|
|
|
+ ck_assert(ws_client1_data.len == 0);
|
|
|
|
+ ck_assert(ws_client2_data.data != NULL);
|
|
|
|
+ ck_assert(ws_client2_data.len == websocket_welcome_msg_len);
|
|
|
|
+ ck_assert(!memcmp(ws_client2_data.data,
|
|
|
|
+ websocket_welcome_msg,
|
|
|
|
+ websocket_welcome_msg_len));
|
|
|
|
+ free(ws_client2_data.data);
|
|
|
|
+ ws_client2_data.data = NULL;
|
|
|
|
+ ws_client2_data.len = 0;
|
|
|
|
+
|
|
|
|
+ mg_websocket_write(ws_client1_conn, WEBSOCKET_OPCODE_TEXT, "data2", 5);
|
|
|
|
+
|
|
|
|
+ mg_Sleep(3); /* Should get the acknowledge message */
|
|
|
|
+ ck_assert(ws_client1_data.closed == 0);
|
|
|
|
+ ck_assert(ws_client2_data.closed == 0);
|
|
|
|
+ ck_assert(ws_client2_data.data == NULL);
|
|
|
|
+ ck_assert(ws_client2_data.len == 0);
|
|
|
|
+ ck_assert(ws_client1_data.data != NULL);
|
|
|
|
+ ck_assert(ws_client1_data.len == websocket_acknowledge_msg_len);
|
|
|
|
+ ck_assert(!memcmp(ws_client1_data.data,
|
|
|
|
+ websocket_acknowledge_msg,
|
|
|
|
+ websocket_acknowledge_msg_len));
|
|
|
|
+ free(ws_client1_data.data);
|
|
|
|
+ ws_client1_data.data = NULL;
|
|
|
|
+ ws_client1_data.len = 0;
|
|
|
|
+
|
|
|
|
+ mg_websocket_write(ws_client1_conn, WEBSOCKET_OPCODE_TEXT, "bye", 3);
|
|
|
|
+
|
|
|
|
+ mg_Sleep(3); /* Should get the goodbye message */
|
|
|
|
+ ck_assert(ws_client1_data.closed == 0);
|
|
|
|
+ ck_assert(ws_client2_data.closed == 0);
|
|
|
|
+ ck_assert(ws_client2_data.data == NULL);
|
|
|
|
+ ck_assert(ws_client2_data.len == 0);
|
|
|
|
+ ck_assert(ws_client1_data.data != NULL);
|
|
|
|
+ ck_assert(ws_client1_data.len == websocket_goodbye_msg_len);
|
|
|
|
+ ck_assert(!memcmp(ws_client1_data.data,
|
|
|
|
+ websocket_goodbye_msg,
|
|
|
|
+ websocket_goodbye_msg_len));
|
|
|
|
+ free(ws_client1_data.data);
|
|
|
|
+ ws_client1_data.data = NULL;
|
|
|
|
+ ws_client1_data.len = 0;
|
|
|
|
+
|
|
|
|
+ mg_close_connection(ws_client1_conn);
|
|
|
|
+
|
|
|
|
+ mg_Sleep(3); /* Won't get any message */
|
|
|
|
+ ck_assert(ws_client1_data.closed == 1);
|
|
|
|
+ ck_assert(ws_client2_data.closed == 0);
|
|
|
|
+ ck_assert(ws_client1_data.data == NULL);
|
|
|
|
+ ck_assert(ws_client1_data.len == 0);
|
|
|
|
+ ck_assert(ws_client2_data.data == NULL);
|
|
|
|
+ ck_assert(ws_client2_data.len == 0);
|
|
|
|
+
|
|
|
|
+ mg_websocket_write(ws_client2_conn, WEBSOCKET_OPCODE_TEXT, "bye", 3);
|
|
|
|
+
|
|
|
|
+ mg_Sleep(3); /* Should get the goodbye message */
|
|
|
|
+ ck_assert(ws_client1_data.closed == 1);
|
|
|
|
+ ck_assert(ws_client2_data.closed == 0);
|
|
|
|
+ ck_assert(ws_client1_data.data == NULL);
|
|
|
|
+ ck_assert(ws_client1_data.len == 0);
|
|
|
|
+ ck_assert(ws_client2_data.data != NULL);
|
|
|
|
+ ck_assert(ws_client2_data.len == websocket_goodbye_msg_len);
|
|
|
|
+ ck_assert(!memcmp(ws_client2_data.data,
|
|
|
|
+ websocket_goodbye_msg,
|
|
|
|
+ websocket_goodbye_msg_len));
|
|
|
|
+ free(ws_client2_data.data);
|
|
|
|
+ ws_client2_data.data = NULL;
|
|
|
|
+ ws_client2_data.len = 0;
|
|
|
|
+
|
|
|
|
+ mg_close_connection(ws_client2_conn);
|
|
|
|
+
|
|
|
|
+ mg_Sleep(3); /* Won't get any message */
|
|
|
|
+ ck_assert(ws_client1_data.closed == 1);
|
|
|
|
+ ck_assert(ws_client2_data.closed == 1);
|
|
|
|
+ ck_assert(ws_client1_data.data == NULL);
|
|
|
|
+ ck_assert(ws_client1_data.len == 0);
|
|
|
|
+ ck_assert(ws_client2_data.data == NULL);
|
|
|
|
+ ck_assert(ws_client2_data.len == 0);
|
|
|
|
+
|
|
|
|
+ /* Connect client 3 */
|
|
|
|
+ ws_client3_conn =
|
|
|
|
+ mg_connect_websocket_client("localhost",
|
|
|
|
+ ipv4_port,
|
|
|
|
+ 0,
|
|
|
|
+ ebuf,
|
|
|
|
+ sizeof(ebuf),
|
|
|
|
+ "/websocket",
|
|
|
|
+ NULL,
|
|
|
|
+ websocket_client_data_handler,
|
|
|
|
+ websocket_client_close_handler,
|
|
|
|
+ &ws_client3_data);
|
|
|
|
+
|
|
|
|
+ mg_Sleep(3); /* Client 3 should get the websocket welcome message */
|
|
|
|
+ ck_assert(ws_client1_data.closed == 1);
|
|
|
|
+ ck_assert(ws_client2_data.closed == 1);
|
|
|
|
+ ck_assert(ws_client3_data.closed == 0);
|
|
|
|
+ ck_assert(ws_client1_data.data == NULL);
|
|
|
|
+ ck_assert(ws_client1_data.len == 0);
|
|
|
|
+ ck_assert(ws_client2_data.data == NULL);
|
|
|
|
+ ck_assert(ws_client2_data.len == 0);
|
|
|
|
+ ck_assert(ws_client3_data.data != NULL);
|
|
|
|
+ ck_assert(ws_client3_data.len == websocket_welcome_msg_len);
|
|
|
|
+ ck_assert(!memcmp(ws_client3_data.data,
|
|
|
|
+ websocket_welcome_msg,
|
|
|
|
+ websocket_welcome_msg_len));
|
|
|
|
+ free(ws_client3_data.data);
|
|
|
|
+ ws_client3_data.data = NULL;
|
|
|
|
+ ws_client3_data.len = 0;
|
|
|
|
+#endif
|
|
|
|
|
|
/* Close the server */
|
|
/* Close the server */
|
|
g_ctx = NULL;
|
|
g_ctx = NULL;
|
|
mg_stop(ctx);
|
|
mg_stop(ctx);
|
|
- mg_Sleep(1);
|
|
|
|
|
|
+ mg_Sleep(30);
|
|
|
|
+
|
|
|
|
+ ck_assert_int_eq(ws_client3_data.closed, 1);
|
|
}
|
|
}
|
|
END_TEST
|
|
END_TEST
|
|
|
|
|
|
@@ -668,6 +996,7 @@ void _ck_assert_failed(const char *file, int line, const char *expr, ...)
|
|
va_start(va, expr);
|
|
va_start(va, expr);
|
|
fprintf(stderr, "Error: %s, line %i\n", file, line); /* breakpoint here ! */
|
|
fprintf(stderr, "Error: %s, line %i\n", file, line); /* breakpoint here ! */
|
|
vfprintf(stderr, expr, va);
|
|
vfprintf(stderr, expr, va);
|
|
|
|
+ fprintf(stderr, "\n\n");
|
|
va_end(va);
|
|
va_end(va);
|
|
chk_failed++;
|
|
chk_failed++;
|
|
}
|
|
}
|