ok, changed ----- Original Message ----- > On Sat, Feb 21, 2015 at 01:40:13AM +0100, Marc-André Lureau wrote: > > This change breaks webdav server, since libphodav-2 no longer > > set up a TCP service running in a thread. It's up to the client > > to decide how best to accept and handle new connections. > > > > This commits remove all the hacks related to proxying the incoming > > connections to a TCP socket, and protected with a magic sequence. > > > > The following commit will use GIOStream pipes to handle each client > > connections. > > --- > > configure.ac | 2 +- > > gtk/channel-webdav.c | 187 > > +++------------------------------------------------ > > gtk/spice-session.c | 41 ++++++----- > > 3 files changed, 29 insertions(+), 201 deletions(-) > > > > diff --git a/configure.ac b/configure.ac > > index d98e502..84cf568 100644 > > --- a/configure.ac > > +++ b/configure.ac > > @@ -278,7 +278,7 @@ AC_ARG_ENABLE([webdav], > > if test "x$enable_webdav" = "xno"; then > > have_phodav="no" > > else > > - PKG_CHECK_MODULES(PHODAV, [libphodav-1.0 glib-2.0 >= 2.43.90], > > [have_phodav=yes], [have_phodav=no]) > > + PKG_CHECK_MODULES(PHODAV, [libphodav-2.0 glib-2.0 >= 2.43.90 libsoup-2.4 > > >= 2.50], [have_phodav=yes], [have_phodav=no]) > > AC_SUBST(PHODAV_CFLAGS) > > AC_SUBST(PHODAV_LIBS) > > > > diff --git a/gtk/channel-webdav.c b/gtk/channel-webdav.c > > index 75b027b..8cf53cf 100644 > > --- a/gtk/channel-webdav.c > > +++ b/gtk/channel-webdav.c > > @@ -25,8 +25,6 @@ > > #include "glib-compat.h" > > #include "vmcstream.h" > > > > -static PhodavServer* phodav_server_get(SpiceSession *session, gint *port); > > - > > /** > > * SECTION:channel-webdav > > * @short_description: exports a directory > > @@ -187,7 +185,7 @@ typedef struct Client > > { > > guint refs; > > SpiceWebdavChannel *self; > > - GSocketConnection *conn; > > + GIOStream *conn; > > OutputQueue *output; > > gint64 id; > > GCancellable *cancellable; > > @@ -327,102 +325,31 @@ static void demux_to_client(SpiceWebdavChannel > > *self, > > } > > } > > > > -static void magic_written(GObject *source_object, > > - GAsyncResult *res, > > - gpointer user_data) > > -{ > > - Client *client = user_data; > > - SpiceWebdavChannel *self = client->self; > > - SpiceWebdavChannelPrivate *c = self->priv; > > - gssize bytes_written; > > - GError *err = NULL; > > - > > - bytes_written = > > g_output_stream_write_finish(G_OUTPUT_STREAM(source_object), > > - res, &err); > > - > > - if (err || bytes_written != WEBDAV_MAGIC_SIZE) > > - goto error; > > - > > - client_start_read(self, client); > > - g_hash_table_insert(c->clients, &client->id, client); > > - > > - demux_to_client(self, client); > > - > > - return; > > - > > -error: > > - if (err) { > > - g_critical("socket creation failed %s", err->message); > > - g_clear_error(&err); > > - } > > - if (client) { > > - client_unref(client); > > - } > > -} > > - > > -static void client_connected(GObject *source_object, > > - GAsyncResult *res, > > - gpointer user_data) > > +static void start_client(SpiceWebdavChannel *self) > > { > > - SpiceWebdavChannel *self = user_data; > > SpiceWebdavChannelPrivate *c = self->priv; > > - GSocketClient *sclient = G_SOCKET_CLIENT(source_object); > > - GError *err = NULL; > > - GSocketConnection *conn; > > - SpiceSession *session; > > - Client *client = NULL; > > GOutputStream *output; > > + Client *client; > > > > - session = spice_channel_get_session(SPICE_CHANNEL(self)); > > - > > - conn = g_socket_client_connect_to_host_finish(sclient, res, &err); > > - g_object_unref(sclient); > > - if (err) > > - goto error; > > + 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; > > client->self = self; > > - client->conn = conn; > > client->mux.id = GINT64_TO_LE(client->id); > > client->mux.buf = g_malloc0(MAX_MUX_SIZE); > > client->cancellable = g_cancellable_new(); > > > > - output = > > g_buffered_output_stream_new(g_io_stream_get_output_stream(G_IO_STREAM(conn))); > > + 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); > > > > - > > g_output_stream_write_async(g_io_stream_get_output_stream(G_IO_STREAM(conn)), > > - spice_session_get_webdav_magic(session), > > WEBDAV_MAGIC_SIZE, > > - G_PRIORITY_DEFAULT, c->cancellable, > > - magic_written, client); > > - return; > > - > > -error: > > - if (err) { > > - g_critical("socket creation failed %s", err->message); > > - g_clear_error(&err); > > - } > > - if (client) { > > - client_unref(client); > > - } > > -} > > - > > -static void start_client(SpiceWebdavChannel *self) > > -{ > > - SpiceWebdavChannelPrivate *c = self->priv; > > - GSocketClient *sclient; > > - gint davport = -1; > > - SpiceSession *session; > > - > > - session = spice_channel_get_session(SPICE_CHANNEL(self)); > > - phodav_server_get(session, &davport); > > - CHANNEL_DEBUG(self, "starting client %" G_GINT64_FORMAT, > > c->demux.client); > > + client_start_read(self, client); > > + g_hash_table_insert(c->clients, &client->id, client); > > > > - sclient = g_socket_client_new(); > > - g_socket_client_connect_to_host_async(sclient, "localhost", davport, > > - c->cancellable, > > client_connected, self); > > + demux_to_client(self, client); > > } > > > > static void data_read_cb(GObject *source_object, > > @@ -639,99 +566,3 @@ static void spice_webdav_handle_msg(SpiceChannel > > *channel, SpiceMsgIn *msg) > > else > > g_return_if_reached(); > > } > > - > > - > > - > > -#ifdef USE_PHODAV > > -static void new_connection(SoupSocket *sock, > > - SoupSocket *new, > > - gpointer user_data) > > -{ > > - SpiceSession *session = user_data; > > - SoupAddress *addr; > > - GSocketAddress *gaddr; > > - GInetAddress *iaddr; > > - guint port; > > - guint8 magic[WEBDAV_MAGIC_SIZE]; > > - gsize nread; > > - gboolean success = FALSE; > > - SoupSocketIOStatus status; > > - > > - /* note: this is sync calls, since webdav server is in a seperate > > thread */ > > - addr = soup_socket_get_remote_address(new); > > - gaddr = soup_address_get_gsockaddr(addr); > > - iaddr = > > g_inet_socket_address_get_address(G_INET_SOCKET_ADDRESS(gaddr)); > > - port = g_inet_socket_address_get_port(G_INET_SOCKET_ADDRESS(gaddr)); > > - > > - SPICE_DEBUG("port %d %p", port, iaddr); > > - if (!g_inet_address_get_is_loopback(iaddr)) { > > - g_warn_if_reached(); > > - goto end; > > - } > > - > > - g_object_set(new, "non-blocking", FALSE, NULL); > > - status = soup_socket_read(new, magic, sizeof(magic), &nread, NULL, > > NULL); > > - if (status != SOUP_SOCKET_OK) { > > - g_warning("bad initial socket read: %d", status); > > - goto end; > > - } > > - g_object_set(new, "non-blocking", TRUE, NULL); > > - > > - /* check we got the right magic */ > > - if (memcmp(spice_session_get_webdav_magic(session), magic, > > sizeof(magic))) { > > - g_warn_if_reached(); > > - goto end; > > - } > > - > > - success = TRUE; > > - > > -end: > > - if (!success) { > > - g_warn_if_reached(); > > - soup_socket_disconnect(new); > > - g_signal_stop_emission_by_name(sock, "new_connection"); > > - } > > - g_object_unref(gaddr); > > -} > > - > > -G_GNUC_INTERNAL > > -PhodavServer* channel_webdav_server_new(SpiceSession *session) > > -{ > > - PhodavServer *dav; > > - SoupServer *server; > > - SoupSocket *listener; > > - const char *shared_dir; > > - > > - shared_dir = spice_session_get_shared_dir(session); > > - if (shared_dir == NULL) { > > - g_debug("No shared dir set, not creating webdav channel"); > > - return NULL; > > - } > > - > > - dav = phodav_server_new(0, shared_dir); > > - > > - server = phodav_server_get_soup_server(dav); > > - listener = soup_server_get_listener(server); > > - spice_g_signal_connect_object(listener, "new_connection", > > - G_CALLBACK(new_connection), session, > > - 0); > > - > > - return dav; > > -} > > -#endif /* USE_PHODAV */ > > - > > -static PhodavServer* phodav_server_get(SpiceSession *session, gint *port) > > -{ > > - g_return_val_if_fail(SPICE_IS_SESSION(session), NULL); > > - > > -#ifdef USE_PHODAV > > - PhodavServer *server = spice_session_get_webdav_server(session); > > - > > - if (port) > > - *port = phodav_server_get_port(server); > > - > > - return server; > > -#else > > - g_return_val_if_reached(NULL); > > -#endif > > -} > > diff --git a/gtk/spice-session.c b/gtk/spice-session.c > > index 82ea55f..ab7b25c 100644 > > --- a/gtk/spice-session.c > > +++ b/gtk/spice-session.c > > @@ -122,7 +122,6 @@ struct _SpiceSessionPrivate { > > SpiceUsbDeviceManager *usb_manager; > > SpicePlaybackChannel *playback_channel; > > PhodavServer *webdav; > > - guint8 webdav_magic[WEBDAV_MAGIC_SIZE]; > > }; > > > > > > @@ -2604,36 +2603,34 @@ gboolean > > spice_session_get_smartcard_enabled(SpiceSession *session) > > } > > > > G_GNUC_INTERNAL > > -const guint8* spice_session_get_webdav_magic(SpiceSession *session) > > -{ > > - g_return_val_if_fail(SPICE_IS_SESSION(session), NULL); > > - > > - return session->priv->webdav_magic; > > -} > > - > > -G_GNUC_INTERNAL > > PhodavServer* spice_session_get_webdav_server(SpiceSession *session) > > { > > + SpiceSessionPrivate *priv; > > + > > g_return_val_if_fail(SPICE_IS_SESSION(session), NULL); > > + priv = session->priv; > > > > #ifdef USE_PHODAV > > - static GStaticMutex mutex = G_STATIC_MUTEX_INIT; > > - int i; > > - > > - g_static_mutex_lock(&mutex); > > - if (!session->priv->webdav) { > > - for (i = 0; i < sizeof(session->priv->webdav_magic); i++) > > - session->priv->webdav_magic[i] = g_random_int_range(0, 255); > > + static GMutex mutex; > > > > - session->priv->webdav = channel_webdav_server_new(session); > > - if (session->priv->webdav != NULL) { > > - phodav_server_run(session->priv->webdav); > > - } > > + const gchar *shared_dir = spice_session_get_shared_dir(session); > > + if (shared_dir == NULL) { > > + g_debug("No shared dir set, not creating webdav server"); > > + return NULL; > > } > > - g_static_mutex_unlock(&mutex); > > + > > + g_mutex_lock(&mutex); > > + > > + if (priv->webdav) > > + goto end; > > + > > + priv->webdav = phodav_server_new(shared_dir); > > Hmm looking again at that code, I'd write this as > > g_mutex_lock(&mutex); > > if (priv->webdav == NULL) { > priv->webdav = phodav_server_new(shared_dir); > } > > g_mutex_unlock(&mutex); > > The 'end' label is not needed. > > Christophe > _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel