[Spice-devel] [spice-gtk 06/13] http-proxy: add https proxy

Marc-André Lureau mlureau at redhat.com
Tue Feb 11 09:37:53 PST 2014



----- Original Message -----
> 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.

I decided to use this consciously, as doing it differently added much more boilerplate for no clear benefit. And, I don't expect a third implementation.

> 
> > +    {
> > +      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.

I'll remove it, it's debugging code.

> 
> > +      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
> 
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
> 


More information about the Spice-devel mailing list