[Spice-devel] [PATCH v2 spice-gtk 4/5] Add SpiceProxy object

Marc-André Lureau marcandre.lureau at gmail.com
Fri Dec 14 08:44:41 PST 2012


Add a simple object to handle the SPICE_PROXY values.

It's not clear to me whether each GIO user needs to handle the proxy
configuration, or if there is a more global mechanism (via
g_network_address_parse_uri())

Also, the parsing is currently very limited and only support basic
HTTP proxy URI. In the future, we really want to rely on GUri or
similar instead...
---
 gtk/Makefile.am   |   2 +
 gtk/spice-proxy.c | 236 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gtk/spice-proxy.h |  59 ++++++++++++++
 3 files changed, 297 insertions(+)
 create mode 100644 gtk/spice-proxy.c
 create mode 100644 gtk/spice-proxy.h

diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index dd3744d..9f3fb84 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -243,6 +243,8 @@ libspice_client_glib_2_0_la_SOURCES =			\
 	channel-usbredir-priv.h				\
 	smartcard-manager.c				\
 	smartcard-manager-priv.h			\
+	spice-proxy.c					\
+	spice-proxy.h					\
 	usb-device-manager.c				\
 	usb-device-manager-priv.h			\
 	usbutil.c					\
diff --git a/gtk/spice-proxy.c b/gtk/spice-proxy.c
new file mode 100644
index 0000000..97c3a6b
--- /dev/null
+++ b/gtk/spice-proxy.c
@@ -0,0 +1,236 @@
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+   Copyright (C) 2012 Red Hat, Inc.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "spice-client.h"
+#include "spice-proxy.h"
+
+struct _SpiceProxyPrivate {
+    gchar *protocol;
+    gchar *hostname;
+    guint port;
+};
+
+#define SPICE_PROXY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), SPICE_TYPE_PROXY, SpiceProxyPrivate))
+
+G_DEFINE_TYPE(SpiceProxy, spice_proxy, G_TYPE_OBJECT);
+
+enum  {
+    SPICE_PROXY_DUMMY_PROPERTY,
+    SPICE_PROXY_PROTOCOL,
+    SPICE_PROXY_HOSTNAME,
+    SPICE_PROXY_PORT
+};
+
+SpiceProxy* spice_proxy_new(void)
+{
+    SpiceProxy * self = NULL;
+    self = (SpiceProxy*)g_object_new(SPICE_TYPE_PROXY, NULL);
+    return self;
+}
+
+gboolean spice_proxy_parse(SpiceProxy *self, const gchar *uri, GError **error)
+{
+    gboolean success = FALSE;
+
+    g_return_val_if_fail(self != NULL, FALSE);
+    g_return_val_if_fail(uri != NULL, FALSE);
+
+    /* FIXME: use GUri when it is ready... only support http atm */
+    /* the code is voluntarily not parsing thoroughly the uri */
+    if (g_ascii_strncasecmp("http://", uri, 7) == 0)
+        uri += 7;
+
+    spice_proxy_set_protocol(self, "http");
+    spice_proxy_set_port(self, 3128);
+
+    gchar **proxyv = g_strsplit(uri, ":", 0);
+    const gchar *proxy_port = NULL;
+
+    if (proxyv[0] == NULL || strlen(proxyv[0]) == 0) {
+        g_set_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+                    "Invalid hostname in proxy address");
+        goto end;
+    }
+
+    spice_proxy_set_hostname(self, proxyv[0]);
+    if (proxyv[0] != NULL)
+        proxy_port = proxyv[1];
+
+    if (proxy_port != NULL) {
+        char *endptr;
+        guint port = strtoul(proxy_port, &endptr, 10);
+        if (*endptr != '\0') {
+            g_set_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+                        "Invalid proxy port: %s", proxy_port);
+            goto end;
+        }
+        spice_proxy_set_port(self, port);
+    }
+
+    success = TRUE;
+
+end:
+    g_strfreev(proxyv);
+    return success;
+}
+
+const gchar* spice_proxy_get_protocol(SpiceProxy *self)
+{
+    g_return_val_if_fail(SPICE_IS_PROXY(self), NULL);
+    return self->priv->protocol;
+}
+
+void spice_proxy_set_protocol(SpiceProxy *self, const gchar *value)
+{
+    g_return_if_fail(SPICE_IS_PROXY(self));
+
+    g_free(self->priv->protocol);
+    self->priv->protocol = g_strdup(value);
+    g_object_notify((GObject *)self, "protocol");
+}
+
+const gchar* spice_proxy_get_hostname(SpiceProxy *self)
+{
+    g_return_val_if_fail(SPICE_IS_PROXY(self), NULL);
+    return self->priv->hostname;
+}
+
+
+void spice_proxy_set_hostname(SpiceProxy *self, const gchar *value)
+{
+    g_return_if_fail(SPICE_IS_PROXY(self));
+
+    g_free(self->priv->hostname);
+    self->priv->hostname = g_strdup(value);
+    g_object_notify((GObject *)self, "hostname");
+}
+
+guint spice_proxy_get_port(SpiceProxy *self)
+{
+    g_return_val_if_fail(SPICE_IS_PROXY(self), 0);
+    return self->priv->port;
+}
+
+void spice_proxy_set_port(SpiceProxy *self, guint port)
+{
+    g_return_if_fail(SPICE_IS_PROXY(self));
+    self->priv->port = port;
+    g_object_notify((GObject *)self, "port");
+}
+
+static void spice_proxy_get_property(GObject *object, guint property_id,
+                                     GValue *value, GParamSpec *pspec)
+{
+    SpiceProxy *self;
+    self = G_TYPE_CHECK_INSTANCE_CAST(object, SPICE_TYPE_PROXY, SpiceProxy);
+
+    switch (property_id) {
+    case SPICE_PROXY_PROTOCOL:
+        g_value_set_string(value, spice_proxy_get_protocol(self));
+        break;
+    case SPICE_PROXY_HOSTNAME:
+        g_value_set_string(value, spice_proxy_get_hostname(self));
+        break;
+    case SPICE_PROXY_PORT:
+        g_value_set_uint(value, spice_proxy_get_port(self));
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+        break;
+    }
+}
+
+
+static void spice_proxy_set_property(GObject *object, guint property_id,
+                                     const GValue *value, GParamSpec *pspec)
+{
+    SpiceProxy * self;
+    self = G_TYPE_CHECK_INSTANCE_CAST(object, SPICE_TYPE_PROXY, SpiceProxy);
+
+    switch (property_id) {
+    case SPICE_PROXY_PROTOCOL:
+        spice_proxy_set_protocol(self, g_value_get_string(value));
+        break;
+    case SPICE_PROXY_HOSTNAME:
+        spice_proxy_set_hostname(self, g_value_get_string(value));
+        break;
+    case SPICE_PROXY_PORT:
+        spice_proxy_set_port(self, g_value_get_uint(value));
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+        break;
+    }
+}
+
+static void spice_proxy_finalize(GObject* obj)
+{
+    SpiceProxy *self;
+
+    self = G_TYPE_CHECK_INSTANCE_CAST(obj, SPICE_TYPE_PROXY, SpiceProxy);
+    g_free(self->priv->protocol);
+    g_free(self->priv->hostname);
+
+    G_OBJECT_CLASS (spice_proxy_parent_class)->finalize (obj);
+}
+
+static void spice_proxy_init (SpiceProxy *self)
+{
+    self->priv = SPICE_PROXY_GET_PRIVATE(self);
+}
+
+
+static void spice_proxy_class_init(SpiceProxyClass *klass)
+{
+    spice_proxy_parent_class = g_type_class_peek_parent (klass);
+    g_type_class_add_private(klass, sizeof(SpiceProxyPrivate));
+
+    G_OBJECT_CLASS (klass)->get_property = spice_proxy_get_property;
+    G_OBJECT_CLASS (klass)->set_property = spice_proxy_set_property;
+    G_OBJECT_CLASS (klass)->finalize = spice_proxy_finalize;
+
+    g_object_class_install_property(G_OBJECT_CLASS (klass),
+                                    SPICE_PROXY_PROTOCOL,
+                                    g_param_spec_string ("protocol",
+                                                         "protocol",
+                                                         "protocol",
+                                                         NULL,
+                                                         G_PARAM_STATIC_STRINGS |
+                                                         G_PARAM_READWRITE));
+
+    g_object_class_install_property(G_OBJECT_CLASS (klass),
+                                    SPICE_PROXY_HOSTNAME,
+                                    g_param_spec_string ("hostname",
+                                                         "hostname",
+                                                         "hostname",
+                                                         NULL,
+                                                         G_PARAM_STATIC_STRINGS |
+                                                         G_PARAM_READWRITE));
+
+    g_object_class_install_property(G_OBJECT_CLASS (klass),
+                                    SPICE_PROXY_PORT,
+                                    g_param_spec_uint ("port",
+                                                       "port",
+                                                       "port",
+                                                       0, G_MAXUINT, 0,
+                                                       G_PARAM_STATIC_STRINGS |
+                                                       G_PARAM_READWRITE));
+}
diff --git a/gtk/spice-proxy.h b/gtk/spice-proxy.h
new file mode 100644
index 0000000..c780931
--- /dev/null
+++ b/gtk/spice-proxy.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+   Copyright (C) 2012 Red Hat, Inc.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __SPICE_PROXY_H__
+#define __SPICE_PROXY_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_PROXY (spice_proxy_get_type ())
+#define SPICE_PROXY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_TYPE_PROXY, SpiceProxy))
+#define SPICE_PROXY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_TYPE_PROXY, SpiceProxyClass))
+#define SPICE_IS_PROXY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_TYPE_PROXY))
+#define SPICE_IS_PROXY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_TYPE_PROXY))
+#define SPICE_PROXY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_TYPE_PROXY, SpiceProxyClass))
+
+typedef struct _SpiceProxy SpiceProxy;
+typedef struct _SpiceProxyClass SpiceProxyClass;
+typedef struct _SpiceProxyPrivate SpiceProxyPrivate;
+
+struct _SpiceProxy {
+    GObject parent_instance;
+    SpiceProxyPrivate * priv;
+};
+
+struct _SpiceProxyClass {
+    GObjectClass parent_class;
+};
+
+
+GType spice_proxy_get_type(void) G_GNUC_CONST;
+
+SpiceProxy* spice_proxy_new(void);
+gboolean spice_proxy_parse(SpiceProxy* self, const gchar* uri, GError** error);
+const gchar* spice_proxy_get_protocol(SpiceProxy* self);
+void spice_proxy_set_protocol(SpiceProxy* self, const gchar* value);
+const gchar* spice_proxy_get_hostname(SpiceProxy* self);
+void spice_proxy_set_hostname(SpiceProxy* self, const gchar* value);
+guint spice_proxy_get_port(SpiceProxy* self);
+void spice_proxy_set_port(SpiceProxy* self, guint port);
+
+G_END_DECLS
+
+#endif /* __SPICE_PROXY_H__ */
-- 
1.8.1.rc1.17.g75ed918



More information about the Spice-devel mailing list