[Spice-devel] [PATCH spice-gtk] WIP: use GUri if available

Marc-André Lureau marcandre.lureau at redhat.com
Sun Mar 29 16:53:50 PDT 2015


From: Marc-André Lureau <marcandre.lureau at gmail.com>

Hi

This is a proof-of-concept patch, to show how nicely GUri would
eventually replace spice-gtk URI handling code, not to be applied
before GUri is accepted in glib.

(I wish SpiceUri could be made deprecated, but that would break API
and would require upcoming glib version, as compat code wouldn't be
enough to deal with GUri in public API)


---
 gtk/spice-session.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 gtk/spice-uri.c     |  42 ++++++++++++++++++++
 2 files changed, 154 insertions(+)

diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index 1a68d7d..aacb3d5 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -349,6 +349,117 @@ spice_session_finalize(GObject *gobject)
         G_OBJECT_CLASS(spice_session_parent_class)->finalize(gobject);
 }
 
+#if GLIB_CHECK_VERSION(2,45,0)
+static gchar* spice_uri_create(SpiceSession *session)
+{
+    SpiceSessionPrivate *s = session->priv;
+    const char *scheme = s->unix_path ? "spice+unix" : "spice";
+    GString *query = g_string_new(NULL);
+
+    if (s->port != NULL)
+        g_string_append_printf(query, "port=%s&", s->port);
+    if (s->tls_port != NULL)
+        g_string_append_printf(query, "tls-port=%s", s->tls_port);
+
+    return g_uri_join_with_user(G_URI_FLAGS_HAS_PASSWORD,
+                                scheme, s->username, s->password, NULL,
+                                s->host, -1, s->unix_path ?: "",
+                                g_string_free(query, FALSE), NULL);
+}
+
+static int spice_parse_uri(SpiceSession *session, const char *uri)
+{
+    SpiceSessionPrivate *s = session->priv;
+    g_autoptr(GError) error = NULL;
+    g_autofree gchar *user = NULL, *pass = NULL, *host = NULL, *path = NULL,
+        *query = NULL, *sport = NULL, *tlsport = NULL;
+    g_autoptr(GHashTable) params = NULL;
+    GHashTableIter iter;
+    const gchar *scheme;
+    gchar *key, *value;
+    gint port;
+
+    scheme = g_uri_peek_scheme(uri);
+    if (g_strcmp0(scheme, "spice") &&
+        g_strcmp0(scheme, "spice+unix"))
+        return -1;
+
+    g_uri_split_with_user(uri, G_URI_FLAGS_HAS_PASSWORD,
+                          NULL,
+                          &user,
+                          &pass,
+                          NULL,
+                          &host,
+                          &port,
+                          &path,
+                          &query,
+                          NULL,
+                          &error);
+    if (error) {
+        g_warning("Failed parsing URI: %s", error->message);
+        return -1;
+    }
+
+    if (port != -1)
+        sport = g_strdup_printf("%d", port);
+
+    if (!query)
+        goto end;
+
+    params = g_uri_parse_params(query, -1, '&', TRUE);
+    g_hash_table_iter_init (&iter, params);
+    while (g_hash_table_iter_next (&iter, (gpointer*)&key, (gpointer*)&value)) {
+        gchar **target = NULL;
+
+        g_return_val_if_fail(value, FALSE);
+        if ((!g_strcmp0(key, "port") || !g_strcmp0(key, "tls-port")) &&
+            strlen(value) == 0) {
+            continue;
+        }
+
+        if (!g_strcmp0(key, "port")) {
+            target = &sport;
+        } else if (!g_strcmp0(key, "tls-port")) {
+            target = &tlsport;
+        } else if (!g_strcmp0(key, "password")) {
+            g_warning("password may be visible in process listings");
+            target = &pass;
+        } else {
+            g_warning("Unhandled parameter in URI: %s", key);
+            continue;
+        }
+
+        if (*target) {
+            g_warning("Already set parameter in URI: %s", key);
+            return -1;
+        }
+
+        *target = value;
+        g_hash_table_iter_steal (&iter);
+        g_free (key);
+    }
+
+end:
+    if (path && strlen(path)) {
+        s->unix_path = path;
+        path = NULL;
+    }
+    s->host = host;
+    host = NULL;
+    s->port = sport;
+    sport = NULL;
+    s->tls_port = tlsport;
+    tlsport = NULL;
+    s->username = user;
+    user = NULL;
+    s->password = pass;
+    pass = NULL;
+
+    return 0;
+}
+
+#else
+
 #define URI_SCHEME_SPICE "spice://"
 #define URI_SCHEME_SPICE_UNIX "spice+unix://"
 #define URI_QUERY_START ";?"
@@ -549,6 +660,7 @@ fail:
     g_free(password);
     return -1;
 }
+#endif /* !glib 2.46 */
 
 static void spice_session_get_property(GObject    *gobject,
                                        guint       prop_id,
diff --git a/gtk/spice-uri.c b/gtk/spice-uri.c
index 82aefdb..be27f86 100644
--- a/gtk/spice-uri.c
+++ b/gtk/spice-uri.c
@@ -68,6 +68,47 @@ SpiceURI* spice_uri_new(void)
     return self;
 }
 
+#if GLIB_CHECK_VERSION(2,45,0)
+gboolean spice_uri_parse(SpiceURI *self, const gchar *_uri, GError **error)
+{
+    g_autofree gchar *uri = NULL, *scheme = NULL, *user = NULL, *pass = NULL, *host = NULL;
+    gint port;
+
+    g_return_val_if_fail(self != NULL, FALSE);
+    g_return_val_if_fail(uri != NULL, FALSE);
+
+    uri = g_strdup_printf("%s%s",
+                          g_uri_peek_scheme(_uri) ? "" : "http://",
+                          _uri);
+
+    if (!g_uri_split_with_user(uri, G_URI_FLAGS_HAS_PASSWORD,
+                               &scheme,
+                               &user,
+                               &pass,
+                               NULL,
+                               &host,
+                               &port,
+                               NULL,
+                               NULL,
+                               NULL,
+                               error))
+        return FALSE;
+
+    spice_uri_set_scheme(self, scheme);
+    spice_uri_set_user(self, user);
+    spice_uri_set_password(self, pass);
+    spice_uri_set_hostname(self, host);
+    if (port == -1) {
+        if (g_strcmp0(scheme, "http"))
+            port = 3128;
+        else if (g_strcmp0(scheme, "https"))
+            port = 3129;
+    }
+    spice_uri_set_port(self, port);
+
+    return TRUE;
+}
+#else
 G_GNUC_INTERNAL
 gboolean spice_uri_parse(SpiceURI *self, const gchar *_uri, GError **error)
 {
@@ -146,6 +187,7 @@ end:
     g_strfreev(uriv);
     return success;
 }
+#endif /* !glib 2.45 */
 
 /**
  * spice_uri_get_scheme:
-- 
2.1.0



More information about the Spice-devel mailing list