[Spice-devel] [spice-gtk 06/13] http-proxy: add https proxy
Christophe Fergeau
cfergeau at redhat.com
Tue Feb 11 09:20:21 PST 2014
On Mon, Feb 03, 2014 at 07:02:37PM +0100, Marc-André Lureau wrote:
> From: Marc-André Lureau <marcandre.lureau at redhat.com>
>
> This will require glib 2.28 for GTls support, atm
> ---
> gtk/spice-session.c | 3 +
> gtk/wocky-http-proxy.c | 166 +++++++++++++++++++++++++++++++++++++++++--------
> gtk/wocky-http-proxy.h | 14 +++++
> 3 files changed, 157 insertions(+), 26 deletions(-)
>
> diff --git a/gtk/spice-session.c b/gtk/spice-session.c
> index ae14a1f..6ac397c 100644
> --- a/gtk/spice-session.c
> +++ b/gtk/spice-session.c
> @@ -636,6 +636,9 @@ static void spice_session_class_init(SpiceSessionClass *klass)
> #if GLIB_CHECK_VERSION(2, 26, 0)
> _wocky_http_proxy_get_type();
> #endif
> +#if GLIB_CHECK_VERSION(2, 28, 0)
> + _wocky_https_proxy_get_type();
> +#endif
>
> gobject_class->dispose = spice_session_dispose;
> gobject_class->finalize = spice_session_finalize;
> diff --git a/gtk/wocky-http-proxy.c b/gtk/wocky-http-proxy.c
> index 7210859..25f2af5 100644
> --- a/gtk/wocky-http-proxy.c
> +++ b/gtk/wocky-http-proxy.c
> @@ -1,7 +1,9 @@
> /* wocky-http-proxy.c: Source for WockyHttpProxy
> *
> * Copyright (C) 2010 Collabora, Ltd.
> + * Copyright (C) 2014 Red Hat, Inc.
> * @author Nicolas Dufresne <nicolas.dufresne at collabora.co.uk>
> + * @author Marc-André Lureau <marcandre.lureau at redhat.com>
> *
> * This library is free software; you can redistribute it and/or
> * modify it under the terms of the GNU Lesser General Public
> @@ -40,13 +42,13 @@ static void wocky_http_proxy_iface_init (GProxyInterface *proxy_iface);
>
> #define wocky_http_proxy_get_type _wocky_http_proxy_get_type
> G_DEFINE_TYPE_WITH_CODE (WockyHttpProxy, wocky_http_proxy, G_TYPE_OBJECT,
> - G_IMPLEMENT_INTERFACE (G_TYPE_PROXY,
> - wocky_http_proxy_iface_init)
> - g_io_extension_point_set_required_type (
> - g_io_extension_point_register (G_PROXY_EXTENSION_POINT_NAME),
> - G_TYPE_PROXY);
> - g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME,
> - g_define_type_id, "http", 0))
> + G_IMPLEMENT_INTERFACE (G_TYPE_PROXY,
> + wocky_http_proxy_iface_init)
> + g_io_extension_point_set_required_type (
> + g_io_extension_point_register (G_PROXY_EXTENSION_POINT_NAME),
> + G_TYPE_PROXY);
> + g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME,
> + g_define_type_id, "http", 0))
Not having whitespace changes as one of the first hunks of the patch would
have been nice ;)
>
> static void
> wocky_http_proxy_init (WockyHttpProxy *proxy)
> @@ -180,10 +182,34 @@ wocky_http_proxy_connect (GProxy *proxy,
> {
> GInputStream *in;
> GOutputStream *out;
> - GDataInputStream *data_in;
> - gchar *buffer;
> + GDataInputStream *data_in = NULL;
> + gchar *buffer = NULL;
> gboolean has_cred;
>
> +#if GLIB_CHECK_VERSION(2, 28, 0)
> + if (WOCKY_IS_HTTPS_PROXY (proxy))
Having runtime type checks in a interface virtual method is not very nice,
having a wocky_https_proxy_iface_init would allow to call directly the
right implementation without having to resort to runtime type checking.
> + {
> + GIOStream *tlsconn;
> +
> + tlsconn = g_tls_client_connection_new (io_stream,
> + G_SOCKET_CONNECTABLE(proxy_address),
> + error);
> + if (!tlsconn)
> + goto error;
> +
> + GTlsCertificateFlags tls_validation_flags = G_TLS_CERTIFICATE_VALIDATE_ALL;
> +#ifdef DEBUG
> + tls_validation_flags -= G_TLS_CERTIFICATE_UNKNOWN_CA + G_TLS_CERTIFICATE_BAD_IDENTITY;
> +#endif
I'd rather have tls_validation_flags &= ~(G_TLS_CERTIFICATE_UNKNOWN_CA | G_TLS_CERTIFICATE_BAD_IDENTITY)
as we are manipulating bit flags.
> + g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (tlsconn),
> + tls_validation_flags);
> + if (!g_tls_connection_handshake (G_TLS_CONNECTION (tlsconn), cancellable, error))
> + goto error;
> +
> + io_stream = tlsconn;
> + }
> +#endif
> +
> in = g_io_stream_get_input_stream (io_stream);
> out = g_io_stream_get_output_stream (io_stream);
>
> @@ -291,6 +317,41 @@ do_write (GAsyncReadyCallback callback, ConnectAsyncData *data)
> }
>
> static void
> +stream_connected (ConnectAsyncData *data,
> + GIOStream *io_stream)
> +{
> + GInputStream *in;
> +
> + data->io_stream = g_object_ref (io_stream);
> + in = g_io_stream_get_input_stream (io_stream);
> + data->data_in = g_data_input_stream_new (in);
> + g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (data->data_in),
> + FALSE);
> +
> + do_write (request_write_cb, data);
> +}
> +
> +#if GLIB_CHECK_VERSION(2, 28, 0)
> +static void
> +handshake_completed (GObject *source_object,
> + GAsyncResult *res,
> + gpointer user_data)
> +{
> + GTlsConnection *conn = G_TLS_CONNECTION (source_object);
> + ConnectAsyncData *data = user_data;
> + GError *error = NULL;
> +
> + if (!g_tls_connection_handshake_finish (conn, res, &error))
> + {
> + complete_async_from_error (data, error);
> + return;
> + }
> +
> + stream_connected (data, G_IO_STREAM (conn));
> +}
> +#endif
> +
> +static void
> wocky_http_proxy_connect_async (GProxy *proxy,
> GIOStream *io_stream,
> GProxyAddress *proxy_address,
> @@ -300,34 +361,55 @@ wocky_http_proxy_connect_async (GProxy *proxy,
> {
> GSimpleAsyncResult *simple;
> ConnectAsyncData *data;
> - GInputStream *in;
>
> simple = g_simple_async_result_new (G_OBJECT (proxy),
> - callback, user_data,
> - wocky_http_proxy_connect_async);
> + callback, user_data,
> + wocky_http_proxy_connect_async);
>
> data = g_slice_new0 (ConnectAsyncData);
> -
> - data->simple = simple;
> - data->io_stream = g_object_ref (io_stream);
> -
> if (cancellable != NULL)
> data->cancellable = g_object_ref (cancellable);
> -
> - in = g_io_stream_get_input_stream (io_stream);
> -
> - data->data_in = g_data_input_stream_new (in);
> - g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (data->data_in),
> - FALSE);
> -
> - g_simple_async_result_set_op_res_gpointer (simple, data,
> - (GDestroyNotify) free_connect_data);
> + data->simple = simple;
>
> data->buffer = create_request (proxy_address, &data->has_cred);
> data->length = strlen (data->buffer);
> data->offset = 0;
>
> - do_write (request_write_cb, data);
> + g_simple_async_result_set_op_res_gpointer (simple, data,
> + (GDestroyNotify) free_connect_data);
> +
> +#if GLIB_CHECK_VERSION(2, 28, 0)
> + if (WOCKY_IS_HTTPS_PROXY (proxy))
> + {
Same comment as before
> + GError *error = NULL;
> + GIOStream *tlsconn;
> +
> + tlsconn = g_tls_client_connection_new (io_stream,
> + G_SOCKET_CONNECTABLE(proxy_address),
> + &error);
> + if (error)
> + {
> + complete_async_from_error (data, error);
> + return;
> + }
> +
> + g_return_if_fail (tlsconn != NULL);
> +
> + GTlsCertificateFlags tls_validation_flags = G_TLS_CERTIFICATE_VALIDATE_ALL;
> +#ifdef DEBUG
> + tls_validation_flags -= G_TLS_CERTIFICATE_UNKNOWN_CA + G_TLS_CERTIFICATE_BAD_IDENTITY;
Same comment as before.
Looks good otherwise,
Christophe
> +#endif
> + g_tls_client_connection_set_validation_flags (G_TLS_CLIENT_CONNECTION (tlsconn),
> + tls_validation_flags);
> + g_tls_connection_handshake_async (G_TLS_CONNECTION (tlsconn),
> + G_PRIORITY_DEFAULT, cancellable,
> + handshake_completed, data);
> + }
> + else
> +#endif
> + {
> + stream_connected (data, io_stream);
> + }
> }
>
> static void
> @@ -427,3 +509,35 @@ wocky_http_proxy_iface_init (GProxyInterface *proxy_iface)
> proxy_iface->connect_finish = wocky_http_proxy_connect_finish;
> proxy_iface->supports_hostname = wocky_http_proxy_supports_hostname;
> }
> +
> +#if GLIB_CHECK_VERSION(2, 28, 0)
> +struct _WockyHttpsProxy
> +{
> + WockyHttpProxy parent;
> +};
> +
> +struct _WockyHttpsProxyClass
> +{
> + WockyHttpProxyClass parent_class;
> +};
> +
> +#define wocky_https_proxy_get_type _wocky_https_proxy_get_type
> +G_DEFINE_TYPE_WITH_CODE (WockyHttpsProxy, wocky_https_proxy, WOCKY_TYPE_HTTP_PROXY,
> + G_IMPLEMENT_INTERFACE (G_TYPE_PROXY,
> + wocky_http_proxy_iface_init)
> + g_io_extension_point_set_required_type (
> + g_io_extension_point_register (G_PROXY_EXTENSION_POINT_NAME),
> + G_TYPE_PROXY);
> + g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME,
> + g_define_type_id, "https", 0))
> +
> +static void
> +wocky_https_proxy_init (WockyHttpsProxy *proxy)
> +{
> +}
> +
> +static void
> +wocky_https_proxy_class_init (WockyHttpsProxyClass *class)
> +{
> +}
> +#endif
> diff --git a/gtk/wocky-http-proxy.h b/gtk/wocky-http-proxy.h
> index 3b91e63..9484b51 100644
> --- a/gtk/wocky-http-proxy.h
> +++ b/gtk/wocky-http-proxy.h
> @@ -37,6 +37,20 @@ typedef struct _WockyHttpProxyClass WockyHttpProxyClass;
>
> GType _wocky_http_proxy_get_type (void);
>
> +#if GLIB_CHECK_VERSION(2, 28, 0)
> +#define WOCKY_TYPE_HTTPS_PROXY (_wocky_https_proxy_get_type ())
> +#define WOCKY_HTTPS_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), WOCKY_TYPE_HTTPS_PROXY, WockyHttpsProxy))
> +#define WOCKY_HTTPS_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), WOCKY_TYPE_HTTPS_PROXY, WockyHttpsProxyClass))
> +#define WOCKY_IS_HTTPS_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), WOCKY_TYPE_HTTPS_PROXY))
> +#define WOCKY_IS_HTTPS_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), WOCKY_TYPE_HTTPS_PROXY))
> +#define WOCKY_HTTPS_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), WOCKY_TYPE_HTTPS_PROXY, WockyHttpsProxyClass))
> +
> +typedef struct _WockyHttpsProxy WockyHttpsProxy;
> +typedef struct _WockyHttpsProxyClass WockyHttpsProxyClass;
> +
> +GType _wocky_https_proxy_get_type (void);
> +#endif
> +
> G_END_DECLS
>
> #endif /* _WOCKY_HTTP_PROXY_H_ */
> --
> 1.8.4.2
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 181 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/spice-devel/attachments/20140211/1abd3b14/attachment.pgp>
More information about the Spice-devel
mailing list