[Spice-devel] [spice-gtk 11/13] Make SpiceURI a public API
Marc-André Lureau
marcandre.lureau at gmail.com
Mon Feb 3 10:02:42 PST 2014
From: Marc-André Lureau <marcandre.lureau at redhat.com>
Generalize a little bit SpiceProxy to allow easy URI manipulation by
clients.
---
doc/reference/Makefile.am | 1 +
doc/reference/spice-gtk-docs.xml | 1 +
doc/reference/spice-gtk-sections.txt | 26 ++
gtk/Makefile.am | 5 +-
gtk/map-file | 12 +
gtk/spice-client.h | 1 +
gtk/spice-glib-sym-file | 12 +
gtk/spice-proxy.c | 357 --------------------------
gtk/spice-proxy.h | 64 -----
gtk/spice-session-priv.h | 3 +-
gtk/spice-session.c | 28 +--
gtk/spice-session.h | 1 +
gtk/spice-uri-priv.h | 30 +++
gtk/spice-uri.c | 473 +++++++++++++++++++++++++++++++++++
gtk/spice-uri.h | 52 ++++
15 files changed, 627 insertions(+), 439 deletions(-)
delete mode 100644 gtk/spice-proxy.c
delete mode 100644 gtk/spice-proxy.h
create mode 100644 gtk/spice-uri-priv.h
create mode 100644 gtk/spice-uri.c
create mode 100644 gtk/spice-uri.h
diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am
index a0a856c..76c7d34 100644
--- a/doc/reference/Makefile.am
+++ b/doc/reference/Makefile.am
@@ -44,6 +44,7 @@ IGNORE_HFILES= \
spice-marshal.h \
spice-pulse.h \
spice-session-priv.h \
+ spice-uri-priv.h \
spice-util-priv.h \
spice-widget-priv.h \
usb-acl-helper.h \
diff --git a/doc/reference/spice-gtk-docs.xml b/doc/reference/spice-gtk-docs.xml
index 4a9a3cf..d2c1a2b 100644
--- a/doc/reference/spice-gtk-docs.xml
+++ b/doc/reference/spice-gtk-docs.xml
@@ -52,6 +52,7 @@
<xi:include href="xml/smartcard-manager.xml"/>
<xi:include href="xml/usb-device-manager.xml"/>
<xi:include href="xml/spice-util.xml"/>
+ <xi:include href="xml/spice-uri.xml"/>
</chapter>
</part>
diff --git a/doc/reference/spice-gtk-sections.txt b/doc/reference/spice-gtk-sections.txt
index 8d61aa9..411ca0e 100644
--- a/doc/reference/spice-gtk-sections.txt
+++ b/doc/reference/spice-gtk-sections.txt
@@ -429,3 +429,29 @@ SPICE_PORT_CHANNEL_GET_CLASS
SpicePortChannelPrivate
</SECTION>
+<SECTION>
+<FILE>spice-uri</FILE>
+spice_uri_get_scheme
+spice_uri_set_scheme
+spice_uri_get_hostname
+spice_uri_set_hostname
+spice_uri_get_port
+spice_uri_set_port
+spice_uri_get_user
+spice_uri_set_user
+spice_uri_get_password
+spice_uri_set_password
+spice_uri_to_string
+SpiceURIClass
+SpiceURI
+<SUBSECTION Standard>
+SPICE_IS_URI
+SPICE_IS_URI_CLASS
+SPICE_TYPE_URI
+SPICE_URI
+SPICE_URI_CLASS
+SPICE_URI_GET_CLASS
+spice_uri_get_type
+<SUBSECTION Private>
+SpiceURIPrivate
+</SECTION>
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 840d129..45d6796 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -248,8 +248,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 \
+ spice-uri.c \
+ spice-uri-priv.h \
usb-device-manager.c \
usb-device-manager-priv.h \
usbutil.c \
@@ -282,6 +282,7 @@ libspice_client_glibincludedir = $(includedir)/spice-client-glib-2.0
libspice_client_glibinclude_HEADERS = \
spice-audio.h \
spice-client.h \
+ spice-uri.h \
spice-types.h \
spice-session.h \
spice-channel.h \
diff --git a/gtk/map-file b/gtk/map-file
index 368b44f..cf65db0 100644
--- a/gtk/map-file
+++ b/gtk/map-file
@@ -118,6 +118,18 @@ spice_util_get_debug;
spice_util_get_version_string;
spice_util_set_debug;
spice_uuid_to_string;
+spice_uri_get_hostname;
+spice_uri_get_password;
+spice_uri_get_port;
+spice_uri_get_scheme;
+spice_uri_get_type;
+spice_uri_get_user;
+spice_uri_set_hostname;
+spice_uri_set_password;
+spice_uri_set_port;
+spice_uri_set_scheme;
+spice_uri_set_user;
+spice_uri_to_string;
local:
*;
};
diff --git a/gtk/spice-client.h b/gtk/spice-client.h
index 730d11a..975259a 100644
--- a/gtk/spice-client.h
+++ b/gtk/spice-client.h
@@ -31,6 +31,7 @@
#include "spice-session.h"
#include "spice-channel.h"
#include "spice-option.h"
+#include "spice-uri.h"
#include "channel-main.h"
#include "channel-display.h"
diff --git a/gtk/spice-glib-sym-file b/gtk/spice-glib-sym-file
index 4fc8643..ac7e871 100644
--- a/gtk/spice-glib-sym-file
+++ b/gtk/spice-glib-sym-file
@@ -92,3 +92,15 @@ spice_util_get_debug
spice_util_get_version_string
spice_util_set_debug
spice_uuid_to_string
+spice_uri_get_hostname
+spice_uri_get_password
+spice_uri_get_port
+spice_uri_get_scheme
+spice_uri_get_type
+spice_uri_get_user
+spice_uri_set_hostname
+spice_uri_set_password
+spice_uri_set_port
+spice_uri_set_scheme
+spice_uri_set_user
+spice_uri_to_string
diff --git a/gtk/spice-proxy.c b/gtk/spice-proxy.c
deleted file mode 100644
index ecf7e54..0000000
--- a/gtk/spice-proxy.c
+++ /dev/null
@@ -1,357 +0,0 @@
-/* -*- 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 "glib-compat.h"
-#include "spice-client.h"
-#include "spice-proxy.h"
-
-struct _SpiceProxyPrivate {
- gchar *protocol;
- gchar *hostname;
- guint port;
- gchar *user;
- gchar *password;
-};
-
-#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_USER,
- SPICE_PROXY_PASSWORD,
- SPICE_PROXY_HOSTNAME,
- SPICE_PROXY_PORT
-};
-
-G_GNUC_INTERNAL
-SpiceProxy* spice_proxy_new(void)
-{
- SpiceProxy * self = NULL;
- self = (SpiceProxy*)g_object_new(SPICE_TYPE_PROXY, NULL);
- return self;
-}
-
-G_GNUC_INTERNAL
-gboolean spice_proxy_parse(SpiceProxy *self, const gchar *proxyuri, GError **error)
-{
- gchar *dup, *uri;
- gboolean success = FALSE;
- size_t len;
-
- g_return_val_if_fail(self != NULL, FALSE);
- g_return_val_if_fail(proxyuri != NULL, FALSE);
-
- uri = dup = g_strdup(proxyuri);
- /* 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);
- } else if (g_ascii_strncasecmp("https://", uri, 8) == 0) {
- uri += 8;
- spice_proxy_set_protocol(self, "https");
- spice_proxy_set_port(self, 3129);
- } else {
- return FALSE;
- }
- /* remove trailing slash */
- len = strlen(uri);
- for (; len > 0; len--)
- if (uri[len-1] == '/')
- uri[len-1] = '\0';
- else
- break;
-
-
- gchar *saveptr, *auth = strtok_r(uri, "@", &saveptr);
- if (saveptr && *saveptr) {
- gchar *saveptr2;
- const gchar *user = strtok_r(auth, ":", &saveptr2);
- const gchar *pass = strtok_r(NULL, ":", &saveptr2);
- spice_proxy_set_user(self, user);
- spice_proxy_set_password(self, pass);
- uri = saveptr;
- }
-
- gchar **proxyv = g_strsplit(uri, ":", 2);
- 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_free(dup);
- g_strfreev(proxyv);
- return success;
-}
-
-G_GNUC_INTERNAL
-const gchar* spice_proxy_get_protocol(SpiceProxy *self)
-{
- g_return_val_if_fail(SPICE_IS_PROXY(self), NULL);
- return self->priv->protocol;
-}
-
-G_GNUC_INTERNAL
-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");
-}
-
-G_GNUC_INTERNAL
-const gchar* spice_proxy_get_hostname(SpiceProxy *self)
-{
- g_return_val_if_fail(SPICE_IS_PROXY(self), NULL);
- return self->priv->hostname;
-}
-
-
-G_GNUC_INTERNAL
-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");
-}
-
-G_GNUC_INTERNAL
-guint spice_proxy_get_port(SpiceProxy *self)
-{
- g_return_val_if_fail(SPICE_IS_PROXY(self), 0);
- return self->priv->port;
-}
-
-G_GNUC_INTERNAL
-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;
- case SPICE_PROXY_USER:
- g_value_set_string(value, spice_proxy_get_user(self));
- break;
- case SPICE_PROXY_PASSWORD:
- g_value_set_string(value, spice_proxy_get_password(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_USER:
- spice_proxy_set_user(self, g_value_get_string(value));
- break;
- case SPICE_PROXY_PASSWORD:
- spice_proxy_set_password(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));
-
- g_object_class_install_property(G_OBJECT_CLASS (klass),
- SPICE_PROXY_USER,
- g_param_spec_string ("user",
- "user",
- "user",
- NULL,
- G_PARAM_STATIC_STRINGS |
- G_PARAM_READWRITE));
-
- g_object_class_install_property(G_OBJECT_CLASS (klass),
- SPICE_PROXY_PASSWORD,
- g_param_spec_string ("password",
- "password",
- "password",
- NULL,
- G_PARAM_STATIC_STRINGS |
- G_PARAM_READWRITE));
-}
-
-G_GNUC_INTERNAL
-gchar* spice_proxy_to_string(SpiceProxy* self)
-{
- SpiceProxyPrivate *p;
-
- g_return_val_if_fail(SPICE_IS_PROXY(self), NULL);
- p = self->priv;
-
- if (p->protocol == NULL || p->hostname == NULL)
- return NULL;
-
- return g_strdup_printf("%s://%s:%u", p->protocol, p->hostname, p->port);
-}
-
-G_GNUC_INTERNAL
-const gchar* spice_proxy_get_user(SpiceProxy *self)
-{
- g_return_val_if_fail(SPICE_IS_PROXY(self), NULL);
- return self->priv->user;
-}
-
-
-G_GNUC_INTERNAL
-void spice_proxy_set_user(SpiceProxy *self, const gchar *value)
-{
- g_return_if_fail(SPICE_IS_PROXY(self));
-
- g_free(self->priv->user);
- self->priv->user = g_strdup(value);
- g_object_notify((GObject *)self, "user");
-}
-
-G_GNUC_INTERNAL
-const gchar* spice_proxy_get_password(SpiceProxy *self)
-{
- g_return_val_if_fail(SPICE_IS_PROXY(self), NULL);
- return self->priv->password;
-}
-
-
-G_GNUC_INTERNAL
-void spice_proxy_set_password(SpiceProxy *self, const gchar *value)
-{
- g_return_if_fail(SPICE_IS_PROXY(self));
-
- g_free(self->priv->password);
- self->priv->password = g_strdup(value);
- g_object_notify((GObject *)self, "password");
-}
diff --git a/gtk/spice-proxy.h b/gtk/spice-proxy.h
deleted file mode 100644
index e74053b..0000000
--- a/gtk/spice-proxy.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -*- 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);
-gchar *spice_proxy_to_string(SpiceProxy* self);
-const gchar* spice_proxy_get_user(SpiceProxy* self);
-void spice_proxy_set_user(SpiceProxy* self, const gchar* value);
-const gchar* spice_proxy_get_password(SpiceProxy* self);
-void spice_proxy_set_password(SpiceProxy* self, const gchar* value);
-
-G_END_DECLS
-
-#endif /* __SPICE_PROXY_H__ */
diff --git a/gtk/spice-session-priv.h b/gtk/spice-session-priv.h
index 55fee47..0dc2bfb 100644
--- a/gtk/spice-session-priv.h
+++ b/gtk/spice-session-priv.h
@@ -22,7 +22,6 @@
#include <gio/gio.h>
#include "desktop-integration.h"
#include "spice-session.h"
-#include "spice-proxy.h"
#include "spice-gtk-session.h"
#include "spice-channel-cache.h"
#include "decode.h"
@@ -45,7 +44,7 @@ struct _SpiceSessionPrivate {
char *cert_subject;
guint verify;
gboolean read_only;
- SpiceProxy *proxy;
+ SpiceURI *proxy;
/* whether to enable audio */
gboolean audio;
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index 29c84e8..e229c64 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -28,7 +28,7 @@
#include "gio-coroutine.h"
#include "glib-compat.h"
#include "wocky-http-proxy.h"
-#include "spice-proxy.h"
+#include "spice-uri-priv.h"
#include "channel-playback-priv.h"
struct channel {
@@ -139,7 +139,7 @@ static void do_emit_main_context(GObject *object, int signum, gpointer params)
static void update_proxy(SpiceSession *self, const gchar *str)
{
SpiceSessionPrivate *s = self->priv;
- SpiceProxy *proxy = NULL;
+ SpiceURI *proxy = NULL;
GError *error = NULL;
if (str == NULL)
@@ -149,8 +149,8 @@ static void update_proxy(SpiceSession *self, const gchar *str)
return;
}
- proxy = spice_proxy_new();
- if (!spice_proxy_parse(proxy, str, &error))
+ proxy = spice_uri_new();
+ if (!spice_uri_parse(proxy, str, &error))
g_clear_object(&proxy);
if (error) {
g_warning("%s", error->message);
@@ -269,7 +269,7 @@ static int spice_uri_create(SpiceSession *session, char *dest, int len)
return pos;
}
-static int spice_uri_parse(SpiceSession *session, const char *original_uri)
+static int spice_parse_uri(SpiceSession *session, const char *original_uri)
{
SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session);
gchar *host = NULL, *port = NULL, *tls_port = NULL, *uri = NULL, *password = NULL;
@@ -499,7 +499,7 @@ static void spice_session_get_property(GObject *gobject,
g_value_set_pointer(value, s->uuid);
break;
case PROP_PROXY:
- g_value_take_string(value, spice_proxy_to_string(s->proxy));
+ g_value_take_string(value, spice_uri_to_string(s->proxy));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
@@ -547,7 +547,7 @@ static void spice_session_set_property(GObject *gobject,
case PROP_URI:
str = g_value_get_string(value);
if (str != NULL)
- spice_uri_parse(session, str);
+ spice_parse_uri(session, str);
break;
case PROP_CLIENT_SOCKETS:
s->client_provided_sockets = g_value_get_boolean(value);
@@ -1664,7 +1664,7 @@ struct spice_open_host {
struct coroutine *from;
SpiceSession *session;
SpiceChannel *channel;
- SpiceProxy *proxy;
+ SpiceURI *proxy;
int port;
GCancellable *cancellable;
GError *error;
@@ -1723,11 +1723,11 @@ static void proxy_lookup_ready(GObject *source_object, GAsyncResult *result,
for (it = addresses; it != NULL; it = it->next) {
address = g_proxy_address_new(G_INET_ADDRESS(it->data),
- spice_proxy_get_port(open_host->proxy),
- spice_proxy_get_protocol(open_host->proxy),
+ spice_uri_get_port(open_host->proxy),
+ spice_uri_get_scheme(open_host->proxy),
s->host, open_host->port,
- spice_proxy_get_user(open_host->proxy),
- spice_proxy_get_password(open_host->proxy));
+ spice_uri_get_user(open_host->proxy),
+ spice_uri_get_password(open_host->proxy));
if (address != NULL)
break;
}
@@ -1755,7 +1755,7 @@ static gboolean open_host_idle_cb(gpointer data)
if (open_host->proxy)
g_resolver_lookup_by_name_async(g_resolver_get_default(),
- spice_proxy_get_hostname(open_host->proxy),
+ spice_uri_get_hostname(open_host->proxy),
open_host->cancellable,
proxy_lookup_ready, open_host);
else
@@ -1770,7 +1770,7 @@ static gboolean open_host_idle_cb(gpointer data)
SPICE_DEBUG("open host %s:%d", s->host, open_host->port);
if (open_host->proxy != NULL) {
- gchar *str = spice_proxy_to_string(open_host->proxy);
+ gchar *str = spice_uri_to_string(open_host->proxy);
SPICE_DEBUG("(with proxy %s)", str);
g_free(str);
}
diff --git a/gtk/spice-session.h b/gtk/spice-session.h
index b07f525..4ea645e 100644
--- a/gtk/spice-session.h
+++ b/gtk/spice-session.h
@@ -20,6 +20,7 @@
#include <glib-object.h>
#include "spice-types.h"
+#include "spice-uri.h"
#include "spice-glib-enums.h"
#include "spice-util.h"
diff --git a/gtk/spice-uri-priv.h b/gtk/spice-uri-priv.h
new file mode 100644
index 0000000..54351de
--- /dev/null
+++ b/gtk/spice-uri-priv.h
@@ -0,0 +1,30 @@
+/* -*- 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_URI_PRIV_H__
+#define __SPICE_URI_PRIV_H__
+
+#include "spice-uri.h"
+
+G_BEGIN_DECLS
+
+SpiceURI* spice_uri_new(void);
+gboolean spice_uri_parse(SpiceURI* self, const gchar* uri, GError** error);
+
+G_END_DECLS
+
+#endif /* __SPICE_URI_PRIV_H__ */
diff --git a/gtk/spice-uri.c b/gtk/spice-uri.c
new file mode 100644
index 0000000..8a51208
--- /dev/null
+++ b/gtk/spice-uri.c
@@ -0,0 +1,473 @@
+/* -*- 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 "glib-compat.h"
+#include "spice-client.h"
+#include "spice-uri.h"
+
+/**
+ * SECTION:spice-uri
+ * @short_description: URIs handling
+ * @title: SpiceURI
+ * @section_id:
+ * @stability: Stable
+ * @include: spice-uri.h
+ *
+ * A SpiceURI represents a (parsed) URI.
+ * Since: 0.23
+ */
+
+struct _SpiceURI {
+ GObject parent_instance;
+ SpiceURIPrivate * priv;
+};
+
+struct _SpiceURIClass {
+ GObjectClass parent_class;
+};
+
+struct _SpiceURIPrivate {
+ gchar *scheme;
+ gchar *hostname;
+ guint port;
+ gchar *user;
+ gchar *password;
+};
+
+#define SPICE_URI_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), SPICE_TYPE_URI, SpiceURIPrivate))
+
+G_DEFINE_TYPE(SpiceURI, spice_uri, G_TYPE_OBJECT);
+
+enum {
+ SPICE_URI_DUMMY_PROPERTY,
+ SPICE_URI_SCHEME,
+ SPICE_URI_USER,
+ SPICE_URI_PASSWORD,
+ SPICE_URI_HOSTNAME,
+ SPICE_URI_PORT
+};
+
+G_GNUC_INTERNAL
+SpiceURI* spice_uri_new(void)
+{
+ SpiceURI * self = NULL;
+ self = (SpiceURI*)g_object_new(SPICE_TYPE_URI, NULL);
+ return self;
+}
+
+G_GNUC_INTERNAL
+gboolean spice_uri_parse(SpiceURI *self, const gchar *_uri, GError **error)
+{
+ gchar *dup, *uri;
+ gboolean success = FALSE;
+ size_t len;
+
+ g_return_val_if_fail(self != NULL, FALSE);
+ g_return_val_if_fail(_uri != NULL, FALSE);
+
+ uri = dup = g_strdup(_uri);
+ /* 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_uri_set_scheme(self, "http");
+ spice_uri_set_port(self, 3128);
+ } else if (g_ascii_strncasecmp("https://", uri, 8) == 0) {
+ uri += 8;
+ spice_uri_set_scheme(self, "https");
+ spice_uri_set_port(self, 3129);
+ } else {
+ return FALSE;
+ }
+ /* remove trailing slash */
+ len = strlen(uri);
+ for (; len > 0; len--)
+ if (uri[len-1] == '/')
+ uri[len-1] = '\0';
+ else
+ break;
+
+
+ gchar *saveptr, *auth = strtok_r(uri, "@", &saveptr);
+ if (saveptr && *saveptr) {
+ gchar *saveptr2;
+ const gchar *user = strtok_r(auth, ":", &saveptr2);
+ const gchar *pass = strtok_r(NULL, ":", &saveptr2);
+ spice_uri_set_user(self, user);
+ spice_uri_set_password(self, pass);
+ uri = saveptr;
+ }
+
+ gchar **uriv = g_strsplit(uri, ":", 2);
+ const gchar *uri_port = NULL;
+
+ if (uriv[0] == NULL || strlen(uriv[0]) == 0) {
+ g_set_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "Invalid hostname in uri address");
+ goto end;
+ }
+
+ spice_uri_set_hostname(self, uriv[0]);
+ if (uriv[0] != NULL)
+ uri_port = uriv[1];
+
+ if (uri_port != NULL) {
+ char *endptr;
+ guint port = strtoul(uri_port, &endptr, 10);
+ if (*endptr != '\0') {
+ g_set_error(error, SPICE_CLIENT_ERROR, SPICE_CLIENT_ERROR_FAILED,
+ "Invalid uri port: %s", uri_port);
+ goto end;
+ }
+ spice_uri_set_port(self, port);
+ }
+
+ success = TRUE;
+
+end:
+ g_free(dup);
+ g_strfreev(uriv);
+ return success;
+}
+
+/**
+ * spice_uri_get_scheme:
+ * @uri: a #SpiceURI
+ *
+ * Gets @uri's scheme.
+ *
+ * Returns: @uri's scheme.
+ * Since: 0.23
+ **/
+const gchar* spice_uri_get_scheme(SpiceURI *self)
+{
+ g_return_val_if_fail(SPICE_IS_URI(self), NULL);
+
+ return self->priv->scheme;
+}
+
+/**
+ * spice_uri_set_scheme:
+ * @uri: a #SpiceURI
+ * @scheme: the scheme
+ *
+ * Sets @uri's scheme to @scheme.
+ * Since: 0.23
+ **/
+void spice_uri_set_scheme(SpiceURI *self, const gchar *value)
+{
+ g_return_if_fail(SPICE_IS_URI(self));
+
+ g_free(self->priv->scheme);
+ self->priv->scheme = g_strdup(value);
+ g_object_notify((GObject *)self, "scheme");
+}
+
+/**
+ * spice_uri_get_hostname:
+ * @uri: a #SpiceURI
+ *
+ * Gets @uri's hostname.
+ *
+ * Returns: @uri's hostname.
+ * Since: 0.23
+ **/
+const gchar* spice_uri_get_hostname(SpiceURI *self)
+{
+ g_return_val_if_fail(SPICE_IS_URI(self), NULL);
+
+ return self->priv->hostname;
+}
+
+
+/**
+ * spice_uri_set_hostname:
+ * @uri: a #SpiceURI
+ * @hostname: the hostname
+ *
+ * Sets @uri's hostname to @hostname.
+ * Since: 0.23
+ **/
+void spice_uri_set_hostname(SpiceURI *self, const gchar *hostname)
+{
+ g_return_if_fail(SPICE_IS_URI(self));
+
+ g_free(self->priv->hostname);
+ self->priv->hostname = g_strdup(hostname);
+ g_object_notify((GObject *)self, "hostname");
+}
+
+/**
+ * spice_uri_get_port:
+ * @uri: a #SpiceURI
+ *
+ * Gets @uri's port.
+ *
+ * Returns: @uri's port.
+ * Since: 0.23
+ **/
+guint spice_uri_get_port(SpiceURI *self)
+{
+ g_return_val_if_fail(SPICE_IS_URI(self), 0);
+
+ return self->priv->port;
+}
+
+/**
+ * spice_uri_set_port:
+ * @uri: a #SpiceURI
+ * @port: the port
+ *
+ * Sets @uri's port to @port.
+ * Since: 0.23
+ **/
+void spice_uri_set_port(SpiceURI *self, guint port)
+{
+ g_return_if_fail(SPICE_IS_URI(self));
+
+ self->priv->port = port;
+ g_object_notify((GObject *)self, "port");
+}
+
+static void spice_uri_get_property(GObject *object, guint property_id,
+ GValue *value, GParamSpec *pspec)
+{
+ SpiceURI *self;
+ self = G_TYPE_CHECK_INSTANCE_CAST(object, SPICE_TYPE_URI, SpiceURI);
+
+ switch (property_id) {
+ case SPICE_URI_SCHEME:
+ g_value_set_string(value, spice_uri_get_scheme(self));
+ break;
+ case SPICE_URI_HOSTNAME:
+ g_value_set_string(value, spice_uri_get_hostname(self));
+ break;
+ case SPICE_URI_PORT:
+ g_value_set_uint(value, spice_uri_get_port(self));
+ break;
+ case SPICE_URI_USER:
+ g_value_set_string(value, spice_uri_get_user(self));
+ break;
+ case SPICE_URI_PASSWORD:
+ g_value_set_string(value, spice_uri_get_password(self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void spice_uri_set_property(GObject *object, guint property_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ SpiceURI * self;
+ self = G_TYPE_CHECK_INSTANCE_CAST(object, SPICE_TYPE_URI, SpiceURI);
+
+ switch (property_id) {
+ case SPICE_URI_SCHEME:
+ spice_uri_set_scheme(self, g_value_get_string(value));
+ break;
+ case SPICE_URI_HOSTNAME:
+ spice_uri_set_hostname(self, g_value_get_string(value));
+ break;
+ case SPICE_URI_USER:
+ spice_uri_set_user(self, g_value_get_string(value));
+ break;
+ case SPICE_URI_PASSWORD:
+ spice_uri_set_password(self, g_value_get_string(value));
+ break;
+ case SPICE_URI_PORT:
+ spice_uri_set_port(self, g_value_get_uint(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+static void spice_uri_finalize(GObject* obj)
+{
+ SpiceURI *self;
+
+ self = G_TYPE_CHECK_INSTANCE_CAST(obj, SPICE_TYPE_URI, SpiceURI);
+ g_free(self->priv->scheme);
+ g_free(self->priv->hostname);
+
+ G_OBJECT_CLASS (spice_uri_parent_class)->finalize (obj);
+}
+
+static void spice_uri_init (SpiceURI *self)
+{
+ self->priv = SPICE_URI_GET_PRIVATE(self);
+}
+
+
+static void spice_uri_class_init(SpiceURIClass *klass)
+{
+ spice_uri_parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private(klass, sizeof(SpiceURIPrivate));
+
+ G_OBJECT_CLASS (klass)->get_property = spice_uri_get_property;
+ G_OBJECT_CLASS (klass)->set_property = spice_uri_set_property;
+ G_OBJECT_CLASS (klass)->finalize = spice_uri_finalize;
+
+ g_object_class_install_property(G_OBJECT_CLASS (klass),
+ SPICE_URI_SCHEME,
+ g_param_spec_string ("scheme",
+ "scheme",
+ "scheme",
+ NULL,
+ G_PARAM_STATIC_STRINGS |
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(G_OBJECT_CLASS (klass),
+ SPICE_URI_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_URI_PORT,
+ g_param_spec_uint ("port",
+ "port",
+ "port",
+ 0, G_MAXUINT, 0,
+ G_PARAM_STATIC_STRINGS |
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(G_OBJECT_CLASS (klass),
+ SPICE_URI_USER,
+ g_param_spec_string ("user",
+ "user",
+ "user",
+ NULL,
+ G_PARAM_STATIC_STRINGS |
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property(G_OBJECT_CLASS (klass),
+ SPICE_URI_PASSWORD,
+ g_param_spec_string ("password",
+ "password",
+ "password",
+ NULL,
+ G_PARAM_STATIC_STRINGS |
+ G_PARAM_READWRITE));
+}
+
+/**
+ * spice_uri_to_string:
+ * @uri: a #SpiceURI
+ *
+ * Returns a string representing @uri.
+ *
+ * Returns: a string representing @uri, which the caller must free.
+ * Since: 0.23
+ **/
+gchar* spice_uri_to_string(SpiceURI* self)
+{
+ SpiceURIPrivate *p;
+
+ g_return_val_if_fail(SPICE_IS_URI(self), NULL);
+ p = self->priv;
+
+ if (p->scheme == NULL || p->hostname == NULL)
+ return NULL;
+
+ if (p->user || p->password) {
+ return g_strdup_printf("%s://%s:%s@%s:%u",
+ p->scheme,
+ p->user ?: "", p->password ?: "",
+ p->hostname, p->port);
+ } else {
+ return g_strdup_printf("%s://%s:%u", p->scheme, p->hostname, p->port);
+ }
+}
+
+/**
+ * spice_uri_get_user:
+ * @uri: a #SpiceURI
+ *
+ * Gets @uri's user.
+ *
+ * Returns: @uri's user.
+ * Since: 0.23
+ **/
+const gchar* spice_uri_get_user(SpiceURI *self)
+{
+ g_return_val_if_fail(SPICE_IS_URI(self), NULL);
+
+ return self->priv->user;
+}
+
+
+/**
+ * spice_uri_set_user:
+ * @uri: a #SpiceURI
+ * @password: the user, or %NULL.
+ *
+ * Sets @uri's user to @password.
+ * Since: 0.23
+ **/
+void spice_uri_set_user(SpiceURI *self, const gchar *user)
+{
+ g_return_if_fail(SPICE_IS_URI(self));
+
+ g_free(self->priv->user);
+ self->priv->user = g_strdup(user);
+ g_object_notify((GObject *)self, "user");
+}
+
+/**
+ * spice_uri_get_password:
+ * @uri: a #SpiceURI
+ *
+ * Gets @uri's password.
+ *
+ * Returns: @uri's password.
+ * Since: 0.23
+ **/
+const gchar* spice_uri_get_password(SpiceURI *self)
+{
+ g_return_val_if_fail(SPICE_IS_URI(self), NULL);
+
+ return self->priv->password;
+}
+
+/**
+ * spice_uri_set_password:
+ * @uri: a #SpiceURI
+ * @password: the password, or %NULL.
+ *
+ * Sets @uri's password to @password.
+ * Since: 0.23
+ **/
+void spice_uri_set_password(SpiceURI *self, const gchar *password)
+{
+ g_return_if_fail(SPICE_IS_URI(self));
+
+ g_free(self->priv->password);
+ self->priv->password = g_strdup(password);
+ g_object_notify((GObject *)self, "password");
+}
diff --git a/gtk/spice-uri.h b/gtk/spice-uri.h
new file mode 100644
index 0000000..9e8d590
--- /dev/null
+++ b/gtk/spice-uri.h
@@ -0,0 +1,52 @@
+/* -*- 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_URI_H__
+#define __SPICE_URI_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define SPICE_TYPE_URI (spice_uri_get_type ())
+#define SPICE_URI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SPICE_TYPE_URI, SpiceURI))
+#define SPICE_URI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SPICE_TYPE_URI, SpiceURIClass))
+#define SPICE_IS_URI(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SPICE_TYPE_URI))
+#define SPICE_IS_URI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SPICE_TYPE_URI))
+#define SPICE_URI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SPICE_TYPE_URI, SpiceURIClass))
+
+typedef struct _SpiceURI SpiceURI;
+typedef struct _SpiceURIClass SpiceURIClass;
+typedef struct _SpiceURIPrivate SpiceURIPrivate;
+
+GType spice_uri_get_type(void) G_GNUC_CONST;
+
+const gchar* spice_uri_get_scheme(SpiceURI* uri);
+void spice_uri_set_scheme(SpiceURI* uri, const gchar* scheme);
+const gchar* spice_uri_get_hostname(SpiceURI* uri);
+void spice_uri_set_hostname(SpiceURI* uri, const gchar* hostname);
+guint spice_uri_get_port(SpiceURI* uri);
+void spice_uri_set_port(SpiceURI* uri, guint port);
+gchar *spice_uri_to_string(SpiceURI* uri);
+const gchar* spice_uri_get_user(SpiceURI* uri);
+void spice_uri_set_user(SpiceURI* uri, const gchar* user);
+const gchar* spice_uri_get_password(SpiceURI* uri);
+void spice_uri_set_password(SpiceURI* uri, const gchar* password);
+
+G_END_DECLS
+
+#endif /* __SPICE_URI_H__ */
--
1.8.4.2
More information about the Spice-devel
mailing list