Пример #1
0
END_TEST


START_TEST(test_mg_server_and_client_tls)
{
#ifndef NO_SSL

	struct mg_context *ctx;

	int ports_cnt;
	struct mg_server_ports ports[16];
	struct mg_callbacks callbacks;
	char errmsg[256];

	struct mg_connection *client_conn;
	char client_err[256];
	const struct mg_request_info *client_ri;
	int client_res;
	struct mg_client_options client_options;

	const char *OPTIONS[32]; /* initializer list here is rejected by CI test */
	int opt_idx = 0;
	char server_cert[256];
	char client_cert[256];
	const char *res_dir = locate_resources();

	ck_assert(res_dir != NULL);
	strcpy(server_cert, res_dir);
	strcpy(client_cert, res_dir);
#ifdef _WIN32
	strcat(server_cert, "cert\\server.pem");
	strcat(client_cert, "cert\\client.pem");
#else
	strcat(server_cert, "cert/server.pem");
	strcat(client_cert, "cert/client.pem");
#endif

	memset((void *)OPTIONS, 0, sizeof(OPTIONS));
#if !defined(NO_FILES)
	OPTIONS[opt_idx++] = "document_root";
	OPTIONS[opt_idx++] = ".";
#endif
	OPTIONS[opt_idx++] = "listening_ports";
	OPTIONS[opt_idx++] = "8080r,8443s";
	OPTIONS[opt_idx++] = "ssl_certificate";
	OPTIONS[opt_idx++] = server_cert;
	OPTIONS[opt_idx++] = "ssl_verify_peer";
	OPTIONS[opt_idx++] = "yes";
	OPTIONS[opt_idx++] = "ssl_ca_file";
	OPTIONS[opt_idx++] = client_cert;

	ck_assert_int_le(opt_idx, (int)(sizeof(OPTIONS) / sizeof(OPTIONS[0])));
	ck_assert(OPTIONS[sizeof(OPTIONS) / sizeof(OPTIONS[0]) - 1] == NULL);
	ck_assert(OPTIONS[sizeof(OPTIONS) / sizeof(OPTIONS[0]) - 2] == NULL);

	memset(ports, 0, sizeof(ports));
	memset(&callbacks, 0, sizeof(callbacks));
	memset(errmsg, 0, sizeof(errmsg));

	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);

	ports_cnt = mg_get_server_ports(ctx, 16, ports);
	ck_assert_int_eq(ports_cnt, 2);
	ck_assert_int_eq(ports[0].protocol, 1);
	ck_assert_int_eq(ports[0].port, 8080);
	ck_assert_int_eq(ports[0].is_ssl, 0);
	ck_assert_int_eq(ports[0].is_redirect, 1);
	ck_assert_int_eq(ports[1].protocol, 1);
	ck_assert_int_eq(ports[1].port, 8443);
	ck_assert_int_eq(ports[1].is_ssl, 1);
	ck_assert_int_eq(ports[1].is_redirect, 0);
	ck_assert_int_eq(ports[2].protocol, 0);
	ck_assert_int_eq(ports[2].port, 0);
	ck_assert_int_eq(ports[2].is_ssl, 0);
	ck_assert_int_eq(ports[2].is_redirect, 0);

	test_sleep(1);
	mark_point();

	memset(client_err, 0, sizeof(client_err));
	client_conn =
	    mg_connect_client("127.0.0.1", 8443, 1, client_err, sizeof(client_err));
	ck_assert(client_conn == NULL);
	ck_assert_str_ne(client_err, "");

	memset(client_err, 0, sizeof(client_err));
	memset(&client_options, 0, sizeof(client_options));
	client_options.host = "127.0.0.1";
	client_options.port = 8443;
	client_options.client_cert = client_cert;
	client_options.server_cert = server_cert;

	client_conn = mg_connect_client_secure(&client_options,
	                                       client_err,
	                                       sizeof(client_err));
	ck_assert(client_conn != NULL);
	ck_assert_str_eq(client_err, "");
	mg_printf(client_conn, "GET / HTTP/1.0\r\n\r\n");
	client_res =
	    mg_get_response(client_conn, client_err, sizeof(client_err), 10000);
	ck_assert_int_ge(client_res, 0);
	ck_assert_str_eq(client_err, "");
	client_ri = mg_get_request_info(client_conn);
	ck_assert(client_ri != NULL);

#if defined(NO_FILES)
	ck_assert_str_eq(client_ri->uri, "404");
#else
	ck_assert_str_eq(client_ri->uri, "200");
	/* TODO: ck_assert_str_eq(client_ri->request_method, "HTTP/1.0"); */
	client_res = (int)mg_read(client_conn, client_err, sizeof(client_err));
	ck_assert_int_gt(client_res, 0);
	ck_assert_int_le(client_res, sizeof(client_err));
#endif
	mg_close_connection(client_conn);

	/* TODO: A client API using a client certificate is missing */

	mark_point();
	test_sleep(1);
	mark_point();

	mg_stop(ctx);
#endif
}
Пример #2
0
int
main(int argc, char *argv[])
{
	const char *options[] = {"document_root",
	                         DOCUMENT_ROOT,
	                         "listening_ports",
	                         PORT,
	                         "request_timeout_ms",
	                         "10000",
	                         "error_log_file",
	                         "error.log",
#ifdef USE_WEBSOCKET
	                         "websocket_timeout_ms",
	                         "3600000",
#endif
#ifndef NO_SSL
	                         "ssl_certificate",
                             "../../resources/cert/server.pem",
#endif
	                         0};
	struct mg_callbacks callbacks;
	struct mg_context *ctx;
	struct mg_server_ports ports[32];
	int port_cnt, n;
	int err = 0;

/* Check if libcivetweb has been built with all required features. */
#ifdef USE_IPV6
	if (!mg_check_feature(8)) {
		fprintf(stderr,
		        "Error: Embedded example built with websocket support, "
		        "but civetweb library build without.\n");
		err = 1;
	}
#endif
#ifdef USE_WEBSOCKET
	if (!mg_check_feature(16)) {
		fprintf(stderr,
		        "Error: Embedded example built with websocket support, "
		        "but civetweb library build without.\n");
		err = 1;
	}
#endif
#ifndef NO_SSL
	if (!mg_check_feature(2)) {
		fprintf(stderr,
		        "Error: Embedded example built with SSL support, "
		        "but civetweb library build without.\n");
		err = 1;
	}
#endif
	if (err) {
		fprintf(stderr, "Cannot start CivetWeb - inconsistent build.\n");
		return EXIT_FAILURE;
	}

	/* Start CivetWeb web server */
	memset(&callbacks, 0, sizeof(callbacks));
	ctx = mg_start(&callbacks, 0, options);

	/* Add handler EXAMPLE_URI, to explain the example */
	mg_set_request_handler(ctx, EXAMPLE_URI, ExampleHandler, 0);
	mg_set_request_handler(ctx, EXIT_URI, ExitHandler, 0);

	/* Add handler for /A* and special handler for /A/B */
	mg_set_request_handler(ctx, "/A", AHandler, 0);
	mg_set_request_handler(ctx, "/A/B", ABHandler, 0);

	/* Add handler for /B, /B/A, /B/B but not for /B* */
	mg_set_request_handler(ctx, "/B$", BXHandler, (void *)0);
	mg_set_request_handler(ctx, "/B/A$", BXHandler, (void *)1);
	mg_set_request_handler(ctx, "/B/B$", BXHandler, (void *)2);

	/* Add handler for all files with .foo extention */
	mg_set_request_handler(ctx, "**.foo$", FooHandler, 0);

	/* Add HTTP site to open a websocket connection */
	mg_set_request_handler(ctx, "/websocket", WebSocketStartHandler, 0);

#ifdef USE_WEBSOCKET
	/* WS site for the websocket connection */
	mg_set_websocket_handler(ctx,
	                         "/websocket",
	                         WebSocketConnectHandler,
	                         WebSocketReadyHandler,
	                         WebsocketDataHandler,
	                         WebSocketCloseHandler,
	                         0);
#endif

	/* List all listening ports */
	memset(ports, 0, sizeof(ports));
	port_cnt = mg_get_server_ports(ctx, 32, ports);
	printf("\n%i listening ports:\n\n", port_cnt);

	for (n = 0; n < port_cnt && n < 32; n++) {
		const char *proto = ports[n].is_ssl ? "https" : "http";
		const char *host;

		if ((ports[n].protocol & 1) == 1) {
			/* IPv4 */
			host = "127.0.0.1";
			printf("Browse files at %s://%s:%i/\n", proto, host, ports[n].port);
			printf("Run example at %s://%s:%i%s\n",
			       proto,
			       host,
			       ports[n].port,
			       EXAMPLE_URI);
			printf(
			    "Exit at %s://%s:%i%s\n", proto, host, ports[n].port, EXIT_URI);
			printf("\n");
		}

		if ((ports[n].protocol & 2) == 2) {
			/* IPv6 */
			host = "[::1]";
			printf("Browse files at %s://%s:%i/\n", proto, host, ports[n].port);
			printf("Run example at %s://%s:%i%s\n",
			       proto,
			       host,
			       ports[n].port,
			       EXAMPLE_URI);
			printf(
			    "Exit at %s://%s:%i%s\n", proto, host, ports[n].port, EXIT_URI);
			printf("\n");
		}
	}

	/* Wait until the server should be closed */
	while (!exitNow) {
#ifdef _WIN32
		Sleep(1000);
#else
		sleep(1);
#endif
#ifdef USE_WEBSOCKET
		InformWebsockets(ctx);
#endif
	}

	/* Stop the server */
	mg_stop(ctx);
	printf("Server stopped.\n");
	printf("Bye!\n");

	return EXIT_SUCCESS;
}
Пример #3
0
int
main(int argc, char *argv[])
{
	const char *options[] = {
	    "document_root",
	    DOCUMENT_ROOT,
	    "listening_ports",
	    PORT,
	    "request_timeout_ms",
	    "10000",
	    "error_log_file",
	    "error.log",
#ifdef USE_WEBSOCKET
	    "websocket_timeout_ms",
	    "3600000",
#endif
#ifndef NO_SSL
	    "ssl_certificate",
	    "../../resources/cert/server.pem",
	    "ssl_protocol_version",
	    "3",
	    "ssl_cipher_list",
#ifdef USE_SSL_DH
	    "ECDHE-RSA-AES256-GCM-SHA384:DES-CBC3-SHA:AES128-SHA:AES128-GCM-SHA256",
#else
	    "DES-CBC3-SHA:AES128-SHA:AES128-GCM-SHA256",
#endif
#endif
	    "enable_auth_domain_check",
	    "no",
	    0};
	struct mg_callbacks callbacks;
	struct mg_context *ctx;
	struct mg_server_ports ports[32];
	int port_cnt, n;
	int err = 0;

/* Check if libcivetweb has been built with all required features. */
#ifdef USE_IPV6
	if (!mg_check_feature(8)) {
		fprintf(stderr,
		        "Error: Embedded example built with IPv6 support, "
		        "but civetweb library build without.\n");
		err = 1;
	}
#endif
#ifdef USE_WEBSOCKET
	if (!mg_check_feature(16)) {
		fprintf(stderr,
		        "Error: Embedded example built with websocket support, "
		        "but civetweb library build without.\n");
		err = 1;
	}
#endif
#ifndef NO_SSL
	if (!mg_check_feature(2)) {
		fprintf(stderr,
		        "Error: Embedded example built with SSL support, "
		        "but civetweb library build without.\n");
		err = 1;
	}
#endif
	if (err) {
		fprintf(stderr, "Cannot start CivetWeb - inconsistent build.\n");
		return EXIT_FAILURE;
	}

	/* Start CivetWeb web server */
	memset(&callbacks, 0, sizeof(callbacks));
#ifndef NO_SSL
	callbacks.init_ssl = init_ssl;
#endif
	callbacks.log_message = log_message;
	ctx = mg_start(&callbacks, 0, options);

	/* Check return value: */
	if (ctx == NULL) {
		fprintf(stderr, "Cannot start CivetWeb - mg_start failed.\n");
		return EXIT_FAILURE;
	}

	/* Add handler EXAMPLE_URI, to explain the example */
	mg_set_request_handler(ctx, EXAMPLE_URI, ExampleHandler, 0);
	mg_set_request_handler(ctx, EXIT_URI, ExitHandler, 0);

	/* Add handler for /A* and special handler for /A/B */
	mg_set_request_handler(ctx, "/A", AHandler, 0);
	mg_set_request_handler(ctx, "/A/B", ABHandler, 0);

	/* Add handler for /B, /B/A, /B/B but not for /B* */
	mg_set_request_handler(ctx, "/B$", BXHandler, (void *)0);
	mg_set_request_handler(ctx, "/B/A$", BXHandler, (void *)1);
	mg_set_request_handler(ctx, "/B/B$", BXHandler, (void *)2);

	/* Add handler for all files with .foo extention */
	mg_set_request_handler(ctx, "**.foo$", FooHandler, 0);

	/* Add handler for /close extention */
	mg_set_request_handler(ctx, "/close", CloseHandler, 0);

	/* Add handler for /form  (serve a file outside the document root) */
	mg_set_request_handler(ctx,
	                       "/form",
	                       FileHandler,
	                       (void *)"../../test/form.html");

	/* Add handler for form data */
	mg_set_request_handler(ctx,
	                       "/handle_form.embedded_c.example.callback",
	                       FormHandler,
	                       (void *)0);

	/* Add a file upload handler for parsing files on the fly */
	mg_set_request_handler(ctx,
	                       "/on_the_fly_form",
	                       FileUploadForm,
	                       (void *)"/on_the_fly_form.md5.callback");
	mg_set_request_handler(ctx,
	                       "/on_the_fly_form.md5.callback",
	                       CheckSumHandler,
	                       (void *)0);

	/* Add handler for /cookie example */
	mg_set_request_handler(ctx, "/cookie", CookieHandler, 0);

	/* Add handler for /postresponse example */
	mg_set_request_handler(ctx, "/postresponse", PostResponser, 0);

	/* Add HTTP site to open a websocket connection */
	mg_set_request_handler(ctx, "/websocket", WebSocketStartHandler, 0);

	/* Add HTTP site with auth */
	mg_set_request_handler(ctx, "/auth", AuthStartHandler, 0);


#ifdef USE_WEBSOCKET
	/* WS site for the websocket connection */
	mg_set_websocket_handler(ctx,
	                         "/websocket",
	                         WebSocketConnectHandler,
	                         WebSocketReadyHandler,
	                         WebsocketDataHandler,
	                         WebSocketCloseHandler,
	                         0);
#endif

	/* List all listening ports */
	memset(ports, 0, sizeof(ports));
	port_cnt = mg_get_server_ports(ctx, 32, ports);
	printf("\n%i listening ports:\n\n", port_cnt);

	for (n = 0; n < port_cnt && n < 32; n++) {
		const char *proto = ports[n].is_ssl ? "https" : "http";
		const char *host;

		if ((ports[n].protocol & 1) == 1) {
			/* IPv4 */
			host = "127.0.0.1";
			printf("Browse files at %s://%s:%i/\n", proto, host, ports[n].port);
			printf("Run example at %s://%s:%i%s\n",
			       proto,
			       host,
			       ports[n].port,
			       EXAMPLE_URI);
			printf(
			    "Exit at %s://%s:%i%s\n", proto, host, ports[n].port, EXIT_URI);
			printf("\n");
		}

		if ((ports[n].protocol & 2) == 2) {
			/* IPv6 */
			host = "[::1]";
			printf("Browse files at %s://%s:%i/\n", proto, host, ports[n].port);
			printf("Run example at %s://%s:%i%s\n",
			       proto,
			       host,
			       ports[n].port,
			       EXAMPLE_URI);
			printf(
			    "Exit at %s://%s:%i%s\n", proto, host, ports[n].port, EXIT_URI);
			printf("\n");
		}
	}

	/* Wait until the server should be closed */
	while (!exitNow) {
#ifdef _WIN32
		Sleep(1000);
#else
		sleep(1);
#endif
#ifdef USE_WEBSOCKET
		InformWebsockets(ctx);
#endif
	}

	/* Stop the server */
	mg_stop(ctx);
	printf("Server stopped.\n");
	printf("Bye!\n");

	return EXIT_SUCCESS;
}