[PATCH 05/10] src: Unify URI params parsing

Michal Privoznik mprivozn at redhat.com
Mon Feb 6 09:16:53 UTC 2023


Now that we have VIR_EXTRACT_URI_ARG_* macros, we can use them in
the rest of the places where an URI is parsed. This also unifies
behavior wrt to query arguments handling. For instance, our
virAdmConnectOpen() accepts "?socket=..." but not "?SOCKET="
whereas plain virConnectOpen() does accept both.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 src/admin/libvirt-admin.c | 15 +++---
 src/esx/esx_util.c        | 96 +++++++++++++++++++--------------------
 src/hyperv/hyperv_util.c  | 30 ++++++------
 src/qemu/qemu_migration.c | 21 ++++-----
 src/util/virauth.c        | 12 ++---
 src/util/viruri.h         | 12 +++++
 6 files changed, 92 insertions(+), 94 deletions(-)

diff --git a/src/admin/libvirt-admin.c b/src/admin/libvirt-admin.c
index 1786a283e5..0f2410d18d 100644
--- a/src/admin/libvirt-admin.c
+++ b/src/admin/libvirt-admin.c
@@ -109,16 +109,13 @@ getSocketPath(virURI *uri)
 
 
     for (i = 0; i < uri->paramsCount; i++) {
-        virURIParam *param = &uri->params[i];
+        virURIParam *var = &uri->params[i];
 
-        if (STREQ(param->name, "socket")) {
-            g_free(sock_path);
-            sock_path = g_strdup(param->value);
-        } else {
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                           _("Unknown URI parameter '%s'"), param->name);
-            return NULL;
-        }
+        VIR_EXTRACT_URI_ARG_STR("socket", sock_path);
+
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Unknown URI parameter '%s'"), var->name);
+        return NULL;
     }
 
     if (!sock_path) {
diff --git a/src/esx/esx_util.c b/src/esx/esx_util.c
index 89d5517262..8c0f39ecc9 100644
--- a/src/esx/esx_util.c
+++ b/src/esx/esx_util.c
@@ -40,8 +40,8 @@ esxUtil_ParseUri(esxUtil_ParsedUri **parsedUri, virURI *uri)
 {
     int result = -1;
     size_t i;
-    int noVerify;
-    int autoAnswer;
+    int noVerify = -1;
+    int autoAnswer = -1;
     char *tmp;
 
     ESX_VI_CHECK_ARG_LIST(parsedUri);
@@ -49,71 +49,39 @@ esxUtil_ParseUri(esxUtil_ParsedUri **parsedUri, virURI *uri)
     *parsedUri = g_new0(esxUtil_ParsedUri, 1);
 
     for (i = 0; i < uri->paramsCount; i++) {
-        virURIParam *queryParam = &uri->params[i];
+        virURIParam *var = &uri->params[i];
 
-        if (STRCASEEQ(queryParam->name, "transport")) {
-            g_free((*parsedUri)->transport);
+        VIR_EXTRACT_URI_ARG_STR("transport", (*parsedUri)->transport);
+        VIR_EXTRACT_URI_ARG_STR("vcenter", (*parsedUri)->vCenter);
+        VIR_EXTRACT_URI_ARG_INT("no_verify", noVerify, cleanup);
+        VIR_EXTRACT_URI_ARG_INT("auto_answer", autoAnswer, cleanup);
 
-            (*parsedUri)->transport = g_strdup(queryParam->value);
-
-            if (STRNEQ((*parsedUri)->transport, "http") &&
-                STRNEQ((*parsedUri)->transport, "https")) {
-                virReportError(VIR_ERR_INVALID_ARG,
-                               _("Query parameter 'transport' has unexpected value "
-                                 "'%s' (should be http|https)"),
-                               (*parsedUri)->transport);
-                goto cleanup;
-            }
-        } else if (STRCASEEQ(queryParam->name, "vcenter")) {
-            g_free((*parsedUri)->vCenter);
-
-            (*parsedUri)->vCenter = g_strdup(queryParam->value);
-        } else if (STRCASEEQ(queryParam->name, "no_verify")) {
-            if (virStrToLong_i(queryParam->value, NULL, 10, &noVerify) < 0 ||
-                (noVerify != 0 && noVerify != 1)) {
-                virReportError(VIR_ERR_INVALID_ARG,
-                               _("Query parameter 'no_verify' has unexpected value "
-                                 "'%s' (should be 0 or 1)"), queryParam->value);
-                goto cleanup;
-            }
-
-            (*parsedUri)->noVerify = noVerify != 0;
-        } else if (STRCASEEQ(queryParam->name, "auto_answer")) {
-            if (virStrToLong_i(queryParam->value, NULL, 10, &autoAnswer) < 0 ||
-                (autoAnswer != 0 && autoAnswer != 1)) {
-                virReportError(VIR_ERR_INVALID_ARG,
-                               _("Query parameter 'auto_answer' has unexpected "
-                                 "value '%s' (should be 0 or 1)"), queryParam->value);
-                goto cleanup;
-            }
-
-            (*parsedUri)->autoAnswer = autoAnswer != 0;
-        } else if (STRCASEEQ(queryParam->name, "proxy")) {
+        if (STRCASEEQ(var->name, "proxy")) {
             /* Expected format: [<type>://]<hostname>[:<port>] */
             (*parsedUri)->proxy = true;
             (*parsedUri)->proxy_type = CURLPROXY_HTTP;
             g_clear_pointer(&(*parsedUri)->proxy_hostname, g_free);
             (*parsedUri)->proxy_port = 1080;
 
-            if ((tmp = STRSKIP(queryParam->value, "http://"))) {
+            if ((tmp = STRSKIP(var->value, "http://"))) {
                 (*parsedUri)->proxy_type = CURLPROXY_HTTP;
-            } else if ((tmp = STRSKIP(queryParam->value, "socks://")) ||
-                       (tmp = STRSKIP(queryParam->value, "socks5://"))) {
+            } else if ((tmp = STRSKIP(var->value, "socks://")) ||
+                       (tmp = STRSKIP(var->value, "socks5://"))) {
                 (*parsedUri)->proxy_type = CURLPROXY_SOCKS5;
-            } else if ((tmp = STRSKIP(queryParam->value, "socks4://"))) {
+            } else if ((tmp = STRSKIP(var->value, "socks4://"))) {
                 (*parsedUri)->proxy_type = CURLPROXY_SOCKS4;
-            } else if ((tmp = STRSKIP(queryParam->value, "socks4a://"))) {
+            } else if ((tmp = STRSKIP(var->value, "socks4a://"))) {
                 (*parsedUri)->proxy_type = CURLPROXY_SOCKS4A;
-            } else if ((tmp = strstr(queryParam->value, "://"))) {
+            } else if ((tmp = strstr(var->value, "://"))) {
                 *tmp = '\0';
 
                 virReportError(VIR_ERR_INVALID_ARG,
                                _("Query parameter 'proxy' contains unexpected "
                                  "type '%s' (should be (http|socks(|4|4a|5))"),
-                               queryParam->value);
+                               var->value);
                 goto cleanup;
             } else {
-                tmp = queryParam->value;
+                tmp = var->value;
             }
 
             (*parsedUri)->proxy_hostname = g_strdup(tmp);
@@ -141,7 +109,7 @@ esxUtil_ParseUri(esxUtil_ParsedUri **parsedUri, virURI *uri)
             }
         } else {
             VIR_WARN("Ignoring unexpected query parameter '%s'",
-                     queryParam->name);
+                     var->name);
         }
     }
 
@@ -150,6 +118,36 @@ esxUtil_ParseUri(esxUtil_ParsedUri **parsedUri, virURI *uri)
     if (!(*parsedUri)->transport)
         (*parsedUri)->transport = g_strdup("https");
 
+    if (STRNEQ((*parsedUri)->transport, "http") &&
+        STRNEQ((*parsedUri)->transport, "https")) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("Query parameter 'transport' has unexpected value '%s' (should be http|https)"),
+                       (*parsedUri)->transport);
+        goto cleanup;
+    }
+
+    if (noVerify >= 0) {
+        if (noVerify != 0 && noVerify != 1) {
+            virReportError(VIR_ERR_INVALID_ARG,
+                           _("Query parameter 'no_verify' has unexpected value '%d' (should be 0 or 1)"),
+                           noVerify);
+            goto cleanup;
+        }
+
+        (*parsedUri)->noVerify = noVerify != 0;
+    }
+
+    if (autoAnswer >= 0) {
+        if (autoAnswer != 0 && autoAnswer != 1) {
+            virReportError(VIR_ERR_INVALID_ARG,
+                           _("Query parameter 'auto_answer' has unexpected value '%d' (should be 0 or 1)"),
+                           autoAnswer);
+            goto cleanup;
+        }
+
+        (*parsedUri)->autoAnswer = autoAnswer != 0;
+    }
+
     result = 0;
 
  cleanup:
diff --git a/src/hyperv/hyperv_util.c b/src/hyperv/hyperv_util.c
index fe71e47285..38daa27743 100644
--- a/src/hyperv/hyperv_util.c
+++ b/src/hyperv/hyperv_util.c
@@ -45,30 +45,26 @@ hypervParseUri(hypervParsedUri **parsedUri, virURI *uri)
     *parsedUri = g_new0(hypervParsedUri, 1);
 
     for (i = 0; i < uri->paramsCount; i++) {
-        virURIParam *queryParam = &uri->params[i];
+        virURIParam *var = &uri->params[i];
 
-        if (STRCASEEQ(queryParam->name, "transport")) {
-            VIR_FREE((*parsedUri)->transport);
+        VIR_EXTRACT_URI_ARG_STR("transport", (*parsedUri)->transport);
 
-            (*parsedUri)->transport = g_strdup(queryParam->value);
-
-            if (STRNEQ((*parsedUri)->transport, "http") &&
-                STRNEQ((*parsedUri)->transport, "https")) {
-                virReportError(VIR_ERR_INVALID_ARG,
-                               _("Query parameter 'transport' has unexpected value "
-                                 "'%s' (should be http|https)"),
-                               (*parsedUri)->transport);
-                goto cleanup;
-            }
-        } else {
-            VIR_WARN("Ignoring unexpected query parameter '%s'",
-                     queryParam->name);
-        }
+        VIR_WARN("Ignoring unexpected query parameter '%s'",
+                 var->name);
     }
 
     if (!(*parsedUri)->transport)
         (*parsedUri)->transport = g_strdup("https");
 
+    if (STRNEQ((*parsedUri)->transport, "http") &&
+        STRNEQ((*parsedUri)->transport, "https")) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("Query parameter 'transport' has unexpected value "
+                         "'%s' (should be http|https)"),
+                       (*parsedUri)->transport);
+        goto cleanup;
+    }
+
     result = 0;
 
  cleanup:
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 2720f0b083..3c38be46f7 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2080,7 +2080,7 @@ qemuMigrationSrcGraphicsRelocate(virDomainObj *vm,
     int type = -1;
     int port = -1;
     int tlsPort = -1;
-    const char *tlsSubject = NULL;
+    g_autofree char *tlsSubject = NULL;
     int rc = -1;
 
     if (!cookie || (!cookie->graphics && !graphicsuri))
@@ -2101,7 +2101,7 @@ qemuMigrationSrcGraphicsRelocate(virDomainObj *vm,
 
         port = cookie->graphics->port;
         tlsPort = cookie->graphics->tlsPort;
-        tlsSubject = cookie->graphics->tlsSubject;
+        tlsSubject = g_strdup(cookie->graphics->tlsSubject);
     }
 
     if (uri) {
@@ -2119,18 +2119,10 @@ qemuMigrationSrcGraphicsRelocate(virDomainObj *vm,
             port = uri->port;
 
         for (i = 0; i < uri->paramsCount; i++) {
-            virURIParam *param = uri->params + i;
+            virURIParam *var = &uri->params[i];
 
-            if (STRCASEEQ(param->name, "tlsPort")) {
-                if (virStrToLong_i(param->value, NULL, 10, &tlsPort) < 0) {
-                    virReportError(VIR_ERR_INVALID_ARG,
-                                   _("invalid tlsPort number: %s"),
-                                   param->value);
-                    return -1;
-                }
-            } else if (STRCASEEQ(param->name, "tlsSubject")) {
-                tlsSubject = param->value;
-            }
+            VIR_EXTRACT_URI_ARG_INT("tlsPort", tlsPort, error);
+            VIR_EXTRACT_URI_ARG_STR("tlsSubject", tlsSubject);
         }
     }
 
@@ -2157,6 +2149,9 @@ qemuMigrationSrcGraphicsRelocate(virDomainObj *vm,
     }
 
     return rc;
+
+ error:
+    return -1;
 }
 
 
diff --git a/src/util/virauth.c b/src/util/virauth.c
index 7b4a1bd8a5..afebb609a7 100644
--- a/src/util/virauth.c
+++ b/src/util/virauth.c
@@ -57,13 +57,13 @@ virAuthGetConfigFilePathURI(virURI *uri,
 
     if (uri) {
         for (i = 0; i < uri->paramsCount; i++) {
-            if (STREQ_NULLABLE(uri->params[i].name, "authfile") &&
-                uri->params[i].value) {
-                VIR_DEBUG("Using path from URI '%s'", uri->params[i].value);
-                *path = g_strdup(uri->params[i].value);
-                return 0;
-            }
+            virURIParam *var = &uri->params[i];
+
+            VIR_EXTRACT_URI_ARG_STR("authfile", *path);
         }
+
+        if (*path)
+            return 0;
     }
 
     userdir = virGetUserConfigDirectory();
diff --git a/src/util/viruri.h b/src/util/viruri.h
index 0e4176c037..7e4f95a2b1 100644
--- a/src/util/viruri.h
+++ b/src/util/viruri.h
@@ -72,6 +72,18 @@ bool virURICheckUnixSocket(virURI *uri);
         continue; \
     }
 
+#define VIR_EXTRACT_URI_ARG_INT(ARG_NAME, ARG_VAR, LABEL) \
+    if (STRCASEEQ(var->name, ARG_NAME)) { \
+        if (virStrToLong_i(var->value, NULL, 10, &(ARG_VAR)) < 0) { \
+            virReportError(VIR_ERR_INVALID_ARG, \
+                           _("Failed to parse value of URI component %s"), \
+                           var->name); \
+            goto LABEL; \
+        } \
+        var->ignore = 1; \
+        continue; \
+    }
+
 #define VIR_EXTRACT_URI_ARG_BOOL(ARG_NAME, ARG_VAR, LABEL) \
     if (STRCASEEQ(var->name, ARG_NAME)) { \
         int tmp; \
-- 
2.39.1



More information about the libvir-list mailing list