[Spice-devel] [PATCH spice-gtk 3/5] webdav: use a pipe to connect to server

Christophe Fergeau cfergeau at redhat.com
Mon Feb 23 06:57:42 PST 2015


On Sat, Feb 21, 2015 at 01:40:14AM +0100, Marc-André Lureau wrote:
> Instead of listening on TCP sockets, and proxying connections there,
> make the webdav server accept new connections from stream. The streams
> are user-space GIOStream pipe, one side is connected to the Spice webdav
> channel muxer/demuxer, the other side is a SoupSocket client.
> 
> This makes the server not exposed any local public access, avoid the
> need for server threads, or proxying the connections through system
> sockets.
> ---
>  gtk/channel-webdav.c | 83 +++++++++++++++++++++++++++++++++++++++-------------
>  1 file changed, 62 insertions(+), 21 deletions(-)
> 
> diff --git a/gtk/channel-webdav.c b/gtk/channel-webdav.c
> index 8cf53cf..95c0521 100644
> --- a/gtk/channel-webdav.c
> +++ b/gtk/channel-webdav.c
> @@ -24,6 +24,7 @@
>  #include "spice-marshal.h"
>  #include "glib-compat.h"
>  #include "vmcstream.h"
> +#include "giopipe.h"
>  
>  /**
>   * SECTION:channel-webdav
> @@ -185,8 +186,7 @@ typedef struct Client
>  {
>      guint refs;
>      SpiceWebdavChannel *self;
> -    GIOStream *conn;
> -    OutputQueue *output;
> +    GIOStream *pipe;
>      gint64 id;
>      GCancellable *cancellable;
>  
> @@ -204,9 +204,8 @@ client_unref(Client *client)
>          return;
>  
>      g_free(client->mux.buf);
> -    output_queue_free(client->output);
>  
> -    g_object_unref(client->conn);
> +    g_object_unref(client->pipe);
>      g_object_unref(client->cancellable);
>  
>      g_free(client);
> @@ -289,7 +288,7 @@ static void client_start_read(SpiceWebdavChannel *self, Client *client)
>  {
>      GInputStream *input;
>  
> -    input = g_io_stream_get_input_stream(G_IO_STREAM(client->conn));
> +    input = g_io_stream_get_input_stream(G_IO_STREAM(client->pipe));
>      g_input_stream_read_async(input, client->mux.buf, MAX_MUX_SIZE,
>                                G_PRIORITY_DEFAULT, client->cancellable, server_reply_cb,
>                                client_ref(client));
> @@ -297,43 +296,71 @@ static void client_start_read(SpiceWebdavChannel *self, Client *client)
>  
>  static void start_demux(SpiceWebdavChannel *self);
>  
> -static void pushed_client_cb(OutputQueue *q, gpointer user_data)
> +static void demux_to_client_finish(SpiceWebdavChannel *self,
> +                                   Client *client, gssize size)
>  {
> -    Client *client = user_data;
> -    SpiceWebdavChannel *self = client->self;
>      SpiceWebdavChannelPrivate *c = self->priv;
>  
> +    if (size <= 0) {
> +        remove_client(self, client);
> +    }
> +
>      c->demuxing = FALSE;
>      start_demux(self);
>  }
>  
> +static void demux_to_client_cb(GObject *source, GAsyncResult *result, gpointer user_data)
> +{
> +    Client *client = user_data;
> +    SpiceWebdavChannelPrivate *c = client->self->priv;
> +    GError *error = NULL;
> +    gssize size;
> +
> +    size = g_output_stream_write_finish(G_OUTPUT_STREAM(source), result, &error);
> +
> +    if (error) {
> +        CHANNEL_DEBUG(client->self, "write failed: %s", error->message);
> +        g_clear_error(&error);
> +    }
> +
> +    g_warn_if_fail(size == c->demux.size);
> +    demux_to_client_finish(client->self, client, size);
> +}
> +
>  static void demux_to_client(SpiceWebdavChannel *self,
> -                           Client *client)
> +                            Client *client)
>  {
>      SpiceWebdavChannelPrivate *c = self->priv;
>      gssize size = c->demux.size;
>  
>      CHANNEL_DEBUG(self, "pushing %"G_GSSIZE_FORMAT" to client %p", size, client);
>  
> -    if (size != 0) {
> -        output_queue_push(client->output, (guint8 *)c->demux.buf, size,
> -                          (GFunc)pushed_client_cb, client);
> +    if (size > 0) {
> +        g_output_stream_write_async(g_io_stream_get_output_stream(client->pipe),
> +                                    c->demux.buf, size, G_PRIORITY_DEFAULT,
> +                                    c->cancellable, demux_to_client_cb, client);
> +        return;
>      } else {
> -        remove_client(self, client);
> -        c->demuxing = FALSE;
> -        start_demux(self);
> +        demux_to_client_finish(self, client, size);
>      }
>  }
>  
>  static void start_client(SpiceWebdavChannel *self)
>  {
> +#ifdef USE_PHODAV
>      SpiceWebdavChannelPrivate *c = self->priv;
> -    GOutputStream *output;
>      Client *client;
> +    GIOStream *peer = NULL;
> +    SpiceSession *session;
> +    SoupServer *server;
> +    GSocketAddress *addr;
> +    GError *error = NULL;
> +
> +    session = spice_channel_get_session(SPICE_CHANNEL(self));
> +    server = phodav_server_get_soup_server(spice_session_get_webdav_server(session));
>  
>      CHANNEL_DEBUG(self, "starting client %" G_GINT64_FORMAT, c->demux.client);
>  
> -    /* FIXME: connect to server */
>      client = g_new0(Client, 1);
>      client->refs = 1;
>      client->id = c->demux.client;
> @@ -341,15 +368,29 @@ static void start_client(SpiceWebdavChannel *self)
>      client->mux.id = GINT64_TO_LE(client->id);
>      client->mux.buf = g_malloc0(MAX_MUX_SIZE);
>      client->cancellable = g_cancellable_new();
> +    spice_make_pipe(&client->pipe, &peer);
>  
> -    output = g_buffered_output_stream_new(g_io_stream_get_output_stream(G_IO_STREAM(client->conn)));
> -    client->output = output_queue_new(output);
> -    g_object_unref(output);
> +    addr = g_inet_socket_address_new_from_string ("127.0.0.1", 0);

Is it required to pass this fake 127.0.0.1 address?
soup_server_accept_iostream says it can accept NULL local/remote
addresses.

> +    if (!soup_server_accept_iostream(server, peer, addr, addr, &error))
> +        goto fail;

Looks good otherwise from a cursory look (iow trusting that it has been
tested and works ok).

Christophe
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/spice-devel/attachments/20150223/e5d97c00/attachment-0001.sig>


More information about the Spice-devel mailing list