[Asterisk-code-review] http.c: Add an http test server (asterisk[master])

Kevin Harwell asteriskteam at digium.com
Mon Nov 15 15:49:25 CST 2021


Kevin Harwell has uploaded this change for review. ( https://gerrit.asterisk.org/c/asterisk/+/17471 )


Change subject: http.c: Add an http test server
......................................................................

http.c: Add an http test server

This patch adds the ability to start and stop an http server from
unit tests, if TEST_FRAMWORK is enabled. This will only start and
stop a server if one has not already been enabled through standard
configuration.

Change-Id: Ic5fb5f11e62c019a1c51310f4667b32a4dae52f5
---
M include/asterisk/http.h
M main/http.c
2 files changed, 125 insertions(+), 21 deletions(-)



  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/71/17471/1

diff --git a/include/asterisk/http.h b/include/asterisk/http.h
index 63fb223..340645e 100644
--- a/include/asterisk/http.h
+++ b/include/asterisk/http.h
@@ -354,4 +354,25 @@
 int ast_http_header_match_in(const char *name, const char *expected_name,
 			     const char *value, const char *expected_value);
 
+#ifdef TEST_FRAMEWORK
+/*!\brief Resolve given address, and start an HTTP server listening on it
+ *        only if a server has not been enabled in the config file.
+ *
+ * \param args Optional session arguments
+ * \param bindaddr Optional address to bind server to (defaults to 127.0.0.1)
+ * \param bindport Optional port (defaults to 8088)
+ *
+ * \return 0 if success, -1 if an error occurred and server not started
+ */
+int ast_http_test_server_resolve_and_start(struct ast_tcptls_session_args *args,
+	const char *bindaddr, uint32_t bindport);
+
+/*!\brief Stop a test server
+ *
+ * \param args Optional session arguments
+ */
+void ast_http_test_server_stop(struct ast_tcptls_session_args *args);
+
+#endif
+
 #endif /* _ASTERISK_SRV_H */
diff --git a/main/http.c b/main/http.c
index a0f15f43..9446f10 100644
--- a/main/http.c
+++ b/main/http.c
@@ -2074,6 +2074,107 @@
 	AST_RWLIST_UNLOCK(&uri_redirects);
 }
 
+static int http_server_start(struct ast_tcptls_session_args *args,
+	struct ast_sockaddr *addr, uint32_t bindport)
+{
+	ast_sockaddr_copy(&args->local_address, addr);
+	if (!ast_sockaddr_port(&args->local_address)) {
+		ast_sockaddr_set_port(&args->local_address, bindport);
+	}
+
+	ast_tcptls_server_start(args);
+	if (args->accept_fd == -1) {
+		ast_log(LOG_WARNING, "Failed to start HTTP server for address %s\n", ast_sockaddr_stringify(addr));
+		ast_sockaddr_setnull(&args->local_address);
+		return -1;
+	}
+
+	ast_verb(1, "Bound HTTP server to address %s\n", ast_sockaddr_stringify(addr));
+	return 0;
+}
+
+static int http_server_start_available(struct ast_tcptls_session_args *args,
+	struct ast_sockaddr *addrs, int num_addrs, uint32_t bindport)
+{
+	int i;
+
+	for (i = 0; i < num_addrs; ++i) {
+		if (!http_server_start(args, &addrs[i], bindport)) {
+			break;
+		}
+	}
+
+	return i == num_addrs ? -1 : 0;
+}
+
+static int http_server_resolve_and_start(struct ast_tcptls_session_args *args,
+	const char *bindaddr, uint32_t bindport)
+{
+	struct ast_sockaddr *addrs = NULL;
+	int num_addrs;
+	int res;
+
+	if (!(num_addrs = ast_sockaddr_resolve(&addrs, bindaddr, 0, AST_AF_UNSPEC))) {
+		ast_log(LOG_WARNING, "Invalid bind address %s\n", bindaddr);
+		return -1;
+	}
+
+	if (bindport == 0) {
+		bindport = DEFAULT_PORT;
+	}
+
+	res = http_server_start_available(args, addrs, num_addrs, bindport);
+	ast_free(addrs);
+	return res;
+}
+
+#ifdef TEST_FRAMEWORK
+
+static struct ast_tcptls_session_args http_test_args = {
+	.accept_fd = -1,
+	.master = AST_PTHREADT_NULL,
+	.tls_cfg = NULL,
+	.poll_timeout = -1,
+	.name = "http test server",
+	.accept_fn = ast_tcptls_server_root,
+	.worker_fn = httpd_helper_thread,
+};
+
+int ast_http_test_server_resolve_and_start(struct ast_tcptls_session_args *args,
+	const char *bindaddr, uint32_t bindport)
+{
+	if (!args) {
+		if (!ast_sockaddr_isnull(&http_desc.old_address)) {
+			/* An http server is already enabled, just use that one */
+			return 0;
+		}
+
+		/* Disabled in config, so enable one for testing */
+		args = &http_test_args;
+	}
+
+	if (ast_strlen_zero(bindaddr)) {
+		bindaddr = "127.0.0.1";
+	}
+
+	return http_server_resolve_and_start(args, bindaddr, bindport);
+}
+
+void ast_http_test_server_stop(struct ast_tcptls_session_args *args)
+{
+	if (!args) {
+		if (!ast_sockaddr_isnull(&http_desc.old_address)) {
+			/* The config enabled server was used, so don't stop */
+			return;
+		}
+
+		args = &http_test_args;
+	}
+
+	ast_tcptls_server_stop(args);
+}
+#endif
+
 static int __ast_http_load(int reload)
 {
 	struct ast_config *cfg;
@@ -2086,9 +2187,8 @@
 	struct http_uri_redirect *redirect;
 	struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
 	uint32_t bindport = DEFAULT_PORT;
-	RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free);
-	int num_addrs = 0;
 	int http_tls_was_enabled = 0;
+	char *bindaddr = NULL;
 
 	cfg = ast_config_load2("http.conf", "http", config_flags);
 	if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
@@ -2169,9 +2269,7 @@
 					v->value, DEFAULT_PORT);
 			}
 		} else if (!strcasecmp(v->name, "bindaddr")) {
-			if (!(num_addrs = ast_sockaddr_resolve(&addrs, v->value, 0, AST_AF_UNSPEC))) {
-				ast_log(LOG_WARNING, "Invalid bind address %s\n", v->value);
-			}
+			bindaddr = ast_strdupa(v->value);
 		} else if (!strcasecmp(v->name, "prefix")) {
 			if (!ast_strlen_zero(v->value)) {
 				newprefix[0] = '/';
@@ -2213,22 +2311,7 @@
 
 	ast_copy_string(http_server_name, server_name, sizeof(http_server_name));
 
-	if (num_addrs && enabled) {
-		int i;
-		for (i = 0; i < num_addrs; ++i) {
-			ast_sockaddr_copy(&http_desc.local_address, &addrs[i]);
-			if (!ast_sockaddr_port(&http_desc.local_address)) {
-				ast_sockaddr_set_port(&http_desc.local_address, bindport);
-			}
-			ast_tcptls_server_start(&http_desc);
-			if (http_desc.accept_fd == -1) {
-				ast_log(LOG_WARNING, "Failed to start HTTP server for address %s\n", ast_sockaddr_stringify(&addrs[i]));
-				ast_sockaddr_setnull(&http_desc.local_address);
-			} else {
-				ast_verb(1, "Bound HTTP server to address %s\n", ast_sockaddr_stringify(&addrs[i]));
-				break;
-			}
-		}
+	if (enabled && !http_server_resolve_and_start(&http_desc, bindaddr, bindport)) {
 		/* When no specific TLS bindaddr is specified, we just use
 		 * the non-TLS bindaddress here.
 		 */

-- 
To view, visit https://gerrit.asterisk.org/c/asterisk/+/17471
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Change-Id: Ic5fb5f11e62c019a1c51310f4667b32a4dae52f5
Gerrit-Change-Number: 17471
Gerrit-PatchSet: 1
Gerrit-Owner: Kevin Harwell <kharwell at digium.com>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20211115/1387ad7c/attachment.html>


More information about the asterisk-code-review mailing list