[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