|  | @@ -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
 | 
	
		
			
				|  |  |   * 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__
 | 
	
		
			
				|  |  |  #pragma clang diagnostic push
 | 
	
		
			
				|  |  |  #pragma clang diagnostic ignored "-Wunreachable-code"
 | 
	
	
		
			
				|  | @@ -115,8 +119,12 @@ wait_not_null(void *volatile *data)
 | 
	
		
			
				|  |  |  #ifdef __clang__
 | 
	
		
			
				|  |  |  #pragma clang diagnostic pop
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  | +#if defined(__MINGW32__) || defined(__GNUC__)
 | 
	
		
			
				|  |  | +#pragma GCC diagnostic pop
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  START_TEST(test_the_test_environment)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  	char wd[300];
 | 
	
	
		
			
				|  | @@ -187,6 +195,7 @@ test_thread_func_t(void *param)
 | 
	
		
			
				|  |  |  	return NULL;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  START_TEST(test_threading)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  	int ok;
 | 
	
	
		
			
				|  | @@ -218,6 +227,7 @@ log_msg_func(const struct mg_connection *conn, const char *message)
 | 
	
		
			
				|  |  |  	return 1;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  START_TEST(test_mg_start_stop_http_server)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  	struct mg_context *ctx;
 | 
	
	
		
			
				|  | @@ -249,6 +259,7 @@ START_TEST(test_mg_start_stop_http_server)
 | 
	
		
			
				|  |  |  	callbacks.log_message = log_msg_func;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	ctx = mg_start(&callbacks, (void *)errmsg, OPTIONS);
 | 
	
		
			
				|  |  | +	mark_point();
 | 
	
		
			
				|  |  |  	test_sleep(1);
 | 
	
		
			
				|  |  |  	ck_assert_str_eq(errmsg, "");
 | 
	
		
			
				|  |  |  	ck_assert(ctx != NULL);
 | 
	
	
		
			
				|  | @@ -261,6 +272,7 @@ START_TEST(test_mg_start_stop_http_server)
 | 
	
		
			
				|  |  |  	ck_assert_int_eq(ssl[1], 0);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	test_sleep(1);
 | 
	
		
			
				|  |  | +	mark_point();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	memset(client_err, 0, sizeof(client_err));
 | 
	
		
			
				|  |  |  	client_conn =
 | 
	
	
		
			
				|  | @@ -286,7 +298,9 @@ START_TEST(test_mg_start_stop_http_server)
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  	mg_close_connection(client_conn);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +	mark_point();
 | 
	
		
			
				|  |  |  	test_sleep(1);
 | 
	
		
			
				|  |  | +	mark_point();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	mg_stop(ctx);
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -338,6 +352,7 @@ START_TEST(test_mg_start_stop_https_server)
 | 
	
		
			
				|  |  |  	callbacks.log_message = log_msg_func;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	ctx = mg_start(&callbacks, (void *)errmsg, OPTIONS);
 | 
	
		
			
				|  |  | +	mark_point();
 | 
	
		
			
				|  |  |  	test_sleep(1);
 | 
	
		
			
				|  |  |  	ck_assert_str_eq(errmsg, "");
 | 
	
		
			
				|  |  |  	ck_assert(ctx != NULL);
 | 
	
	
		
			
				|  | @@ -352,6 +367,7 @@ START_TEST(test_mg_start_stop_https_server)
 | 
	
		
			
				|  |  |  	ck_assert_int_eq(ssl[2], 0);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	test_sleep(1);
 | 
	
		
			
				|  |  | +	mark_point();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	memset(client_err, 0, sizeof(client_err));
 | 
	
		
			
				|  |  |  	client_conn =
 | 
	
	
		
			
				|  | @@ -377,7 +393,9 @@ START_TEST(test_mg_start_stop_https_server)
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  	mg_close_connection(client_conn);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +	mark_point();
 | 
	
		
			
				|  |  |  	test_sleep(1);
 | 
	
		
			
				|  |  | +	mark_point();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	mg_stop(ctx);
 | 
	
		
			
				|  |  |  #endif
 | 
	
	
		
			
				|  | @@ -444,6 +462,7 @@ START_TEST(test_mg_server_and_client_tls)
 | 
	
		
			
				|  |  |  	callbacks.log_message = log_msg_func;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	ctx = mg_start(&callbacks, (void *)errmsg, OPTIONS);
 | 
	
		
			
				|  |  | +	mark_point();
 | 
	
		
			
				|  |  |  	test_sleep(1);
 | 
	
		
			
				|  |  |  	ck_assert_str_eq(errmsg, "");
 | 
	
		
			
				|  |  |  	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);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	test_sleep(1);
 | 
	
		
			
				|  |  | +	mark_point();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	memset(client_err, 0, sizeof(client_err));
 | 
	
		
			
				|  |  |  	client_conn =
 | 
	
	
		
			
				|  | @@ -504,7 +524,9 @@ START_TEST(test_mg_server_and_client_tls)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	/* TODO: A client API using a client certificate is missing */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +	mark_point();
 | 
	
		
			
				|  |  |  	test_sleep(1);
 | 
	
		
			
				|  |  | +	mark_point();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	mg_stop(ctx);
 | 
	
		
			
				|  |  |  #endif
 | 
	
	
		
			
				|  | @@ -565,6 +587,7 @@ static const char *websocket_goodbye_msg = "websocket bye\n";
 | 
	
		
			
				|  |  |  static const size_t websocket_goodbye_msg_len =
 | 
	
		
			
				|  |  |      14 /* strlen(websocket_goodbye_msg) */;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  static int
 | 
	
		
			
				|  |  |  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 */
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  static void
 | 
	
		
			
				|  |  |  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");
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  static int
 | 
	
		
			
				|  |  |  websock_server_data(struct mg_connection *conn,
 | 
	
		
			
				|  |  |                      int bits,
 | 
	
	
		
			
				|  | @@ -626,6 +651,11 @@ websock_server_data(struct mg_connection *conn,
 | 
	
		
			
				|  |  |  		mg_websocket_write(conn, WEBSOCKET_OPCODE_TEXT, "ok - 3", 6);
 | 
	
		
			
				|  |  |  		mg_unlock_connection(conn);
 | 
	
		
			
				|  |  |  	} else {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#if defined(__MINGW32__) || defined(__GNUC__)
 | 
	
		
			
				|  |  | +#pragma GCC diagnostic push
 | 
	
		
			
				|  |  | +#pragma GCC diagnostic ignored "-Wunreachable-code-return"
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  |  #ifdef __clang__
 | 
	
		
			
				|  |  |  #pragma clang diagnostic push
 | 
	
		
			
				|  |  |  #pragma clang diagnostic ignored "-Wunreachable-code"
 | 
	
	
		
			
				|  | @@ -639,6 +669,9 @@ websock_server_data(struct mg_connection *conn,
 | 
	
		
			
				|  |  |  #ifdef __clang__
 | 
	
		
			
				|  |  |  #pragma clang diagnostic pop
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  | +#if defined(__MINGW32__) || defined(__GNUC__)
 | 
	
		
			
				|  |  | +#pragma GCC diagnostic pop
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	return 1; /* return 1 to keep the connetion open */
 | 
	
	
		
			
				|  | @@ -656,6 +689,7 @@ websock_server_close(const struct mg_connection *conn, void *udata)
 | 
	
		
			
				|  |  |  	 * closed */
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  /****************************************************************************/
 | 
	
		
			
				|  |  |  /* WEBSOCKET CLIENT                                                         */
 | 
	
		
			
				|  |  |  /****************************************************************************/
 | 
	
	
		
			
				|  | @@ -665,6 +699,7 @@ struct tclient_data {
 | 
	
		
			
				|  |  |  	int closed;
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  static int
 | 
	
		
			
				|  |  |  websocket_client_data_handler(struct mg_connection *conn,
 | 
	
		
			
				|  |  |                                int flags,
 | 
	
	
		
			
				|  | @@ -693,6 +728,7 @@ websocket_client_data_handler(struct mg_connection *conn,
 | 
	
		
			
				|  |  |  	return 1;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  static void
 | 
	
		
			
				|  |  |  websocket_client_close_handler(const struct mg_connection *conn,
 | 
	
		
			
				|  |  |                                 void *user_data)
 | 
	
	
		
			
				|  | @@ -710,6 +746,7 @@ websocket_client_close_handler(const struct mg_connection *conn,
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  START_TEST(test_request_handlers)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  	char ebuf[100];
 | 
	
	
		
			
				|  | @@ -865,8 +902,13 @@ START_TEST(test_request_handlers)
 | 
	
		
			
				|  |  |  	ck_assert(ri != NULL);
 | 
	
		
			
				|  |  |  	ck_assert_str_eq(ri->uri, "200");
 | 
	
		
			
				|  |  |  	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(i > 0);
 | 
	
		
			
				|  |  | +	ck_assert(i > 0);
 | 
	
		
			
				|  |  |  	ck_assert_int_eq(i, (int)strlen(expected));
 | 
	
		
			
				|  |  |  	buf[i] = 0;
 | 
	
		
			
				|  |  |  	ck_assert_str_eq(buf, expected);
 | 
	
	
		
			
				|  | @@ -1209,6 +1251,7 @@ START_TEST(test_request_handlers)
 | 
	
		
			
				|  |  |  	                          "data1",
 | 
	
		
			
				|  |  |  	                          5);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +	mark_point();
 | 
	
		
			
				|  |  |  	wait_not_null(
 | 
	
		
			
				|  |  |  	    &(ws_client1_data
 | 
	
		
			
				|  |  |  	          .data)); /* Wait for the websocket acknowledge message */
 | 
	
	
		
			
				|  | @@ -1271,6 +1314,7 @@ START_TEST(test_request_handlers)
 | 
	
		
			
				|  |  |  	                          "data2",
 | 
	
		
			
				|  |  |  	                          5);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +	mark_point();
 | 
	
		
			
				|  |  |  	wait_not_null(
 | 
	
		
			
				|  |  |  	    &(ws_client1_data
 | 
	
		
			
				|  |  |  	          .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);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +	mark_point();
 | 
	
		
			
				|  |  |  	wait_not_null(
 | 
	
		
			
				|  |  |  	    &(ws_client1_data.data)); /* Wait for the websocket goodbye message */
 | 
	
		
			
				|  |  |  	ck_assert(ws_client1_data.closed == 0);
 | 
	
	
		
			
				|  | @@ -1304,6 +1349,7 @@ START_TEST(test_request_handlers)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	mg_close_connection(ws_client1_conn);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +	mark_point();
 | 
	
		
			
				|  |  |  	test_sleep(3); /* Won't get any message */
 | 
	
		
			
				|  |  |  	ck_assert(ws_client1_data.closed == 1);
 | 
	
		
			
				|  |  |  	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);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +	mark_point();
 | 
	
		
			
				|  |  |  	wait_not_null(
 | 
	
		
			
				|  |  |  	    &(ws_client2_data.data)); /* Wait for the websocket goodbye message */
 | 
	
		
			
				|  |  |  	ck_assert(ws_client1_data.closed == 1);
 | 
	
	
		
			
				|  | @@ -1331,6 +1378,7 @@ START_TEST(test_request_handlers)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	mg_close_connection(ws_client2_conn);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +	mark_point();
 | 
	
		
			
				|  |  |  	test_sleep(3); /* Won't get any message */
 | 
	
		
			
				|  |  |  	ck_assert(ws_client1_data.closed == 1);
 | 
	
		
			
				|  |  |  	ck_assert(ws_client2_data.closed == 1);
 | 
	
	
		
			
				|  | @@ -1381,11 +1429,13 @@ START_TEST(test_request_handlers)
 | 
	
		
			
				|  |  |  	/* Close the server */
 | 
	
		
			
				|  |  |  	g_ctx = NULL;
 | 
	
		
			
				|  |  |  	mg_stop(ctx);
 | 
	
		
			
				|  |  | +	mark_point();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #ifdef USE_WEBSOCKET
 | 
	
		
			
				|  |  |  	for (i = 0; i < 100; i++) {
 | 
	
		
			
				|  |  |  		test_sleep(1);
 | 
	
		
			
				|  |  |  		if (ws_client3_data.closed != 0) {
 | 
	
		
			
				|  |  | +			mark_point();
 | 
	
		
			
				|  |  |  			break;
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  	}
 | 
	
	
		
			
				|  | @@ -1435,6 +1485,7 @@ make_public_server_suite(void)
 | 
	
		
			
				|  |  |  	return suite;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  #ifdef REPLACE_CHECK_FOR_LOCAL_DEBUGGING
 | 
	
		
			
				|  |  |  /* 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){};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  | +
 |