[gvfs] dav: Fix copying of remote folders to disk



commit d3fcf41ef3676139b5a035757c6d67c6fef073c9
Author: Christian Kellner <gicmo gnome org>
Date:   Wed May 4 00:11:57 2011 +0200

    dav: Fix copying of remote folders to disk
    
    Do stat() the location, i.e. do a PROPFIND, on open () and correctly
    report G_IO_ERROR_IS_DIRECTORY for collections instead of trying
    to fetch (GET) them.
    Should finally fix bug 551339

 daemon/gvfsbackenddav.c  |   79 ++++++++++++++++++++++++++++++++++++++++++++++
 daemon/gvfsbackendhttp.c |   24 ++++++++++---
 daemon/gvfsbackendhttp.h |    4 ++
 3 files changed, 101 insertions(+), 6 deletions(-)
---
diff --git a/daemon/gvfsbackenddav.c b/daemon/gvfsbackenddav.c
index 0adf9a2..d63059f 100644
--- a/daemon/gvfsbackenddav.c
+++ b/daemon/gvfsbackenddav.c
@@ -1909,6 +1909,84 @@ do_enumerate (GVfsBackend           *backend,
 /* ************************************************************************* */
 /*  */
 
+/* *** open () *** */
+static void
+try_open_stat_done (SoupSession *session,
+		    SoupMessage *msg,
+		    gpointer     user_data)
+{
+  GVfsJob         *job = G_VFS_JOB (user_data);
+  GVfsBackend     *backend = job->backend_data;
+  GFileType        target_type;
+  SoupURI         *uri;
+  gboolean         res;
+  guint            status;
+
+  status = msg->status_code;
+
+  if (status != 207)
+    {
+      g_vfs_job_failed_literal (job,
+				G_IO_ERROR,
+				http_error_code_from_status (status),
+				msg->reason_phrase);
+      return;
+    }
+
+  res = stat_location_finish (msg, &target_type, NULL);
+
+  if (res == FALSE)
+    {
+      g_vfs_job_failed (job,
+			G_IO_ERROR, G_IO_ERROR_FAILED,
+			_("Response invalid"));
+      return;
+    }
+
+  if (target_type == G_FILE_TYPE_DIRECTORY)
+    {
+      g_vfs_job_failed (job,
+			G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY,
+			_("File is directory"));
+      return;
+    }
+
+  uri = soup_message_get_uri (msg);
+
+  http_backend_open_for_read (backend, job, uri);
+}
+
+
+static gboolean
+try_open_for_read (GVfsBackend        *backend,
+                   GVfsJobOpenForRead *job,
+                   const char         *filename)
+{
+  SoupMessage     *msg;
+  SoupURI         *uri;
+
+  uri = http_backend_uri_for_filename (backend, filename, FALSE);
+  msg = stat_location_begin (uri, FALSE);
+  soup_uri_free (uri);
+
+  if (msg == NULL)
+    {
+      g_vfs_job_failed (G_VFS_JOB (job),
+                        G_IO_ERROR, G_IO_ERROR_FAILED,
+                        _("Could not create request"));
+
+      return FALSE;
+    }
+
+  g_vfs_job_set_backend_data (G_VFS_JOB (job), backend, NULL);
+  http_backend_queue_message (backend, msg, try_open_stat_done, job);
+
+  return TRUE;
+}
+
+
+
+
 /* *** create () *** */
 static void
 try_create_tested_existence (SoupSession *session, SoupMessage *msg,
@@ -2329,6 +2407,7 @@ g_vfs_backend_dav_class_init (GVfsBackendDavClass *klass)
   backend_class->try_query_info    = NULL;
   backend_class->query_info        = do_query_info;
   backend_class->enumerate         = do_enumerate;
+  backend_class->try_open_for_read = try_open_for_read;
   backend_class->try_create        = try_create;
   backend_class->try_replace       = try_replace;
   backend_class->try_write         = try_write;
diff --git a/daemon/gvfsbackendhttp.c b/daemon/gvfsbackendhttp.c
index 976e0ed..4926724 100644
--- a/daemon/gvfsbackendhttp.c
+++ b/daemon/gvfsbackendhttp.c
@@ -373,20 +373,33 @@ open_for_read_ready (GObject      *source_object,
   g_vfs_job_succeeded (job);
 }
 
-static gboolean 
+static gboolean
 try_open_for_read (GVfsBackend        *backend,
                    GVfsJobOpenForRead *job,
                    const char         *filename)
 {
+  SoupURI *uri;
+
+  uri = http_backend_uri_for_filename (backend, filename, FALSE);
+
+  http_backend_open_for_read (backend, G_VFS_JOB (job), uri);
+  soup_uri_free (uri);
+
+  return TRUE;
+}
+
+void
+http_backend_open_for_read (GVfsBackend *backend,
+			    GVfsJob     *job,
+			    SoupURI     *uri)
+{
   GVfsBackendHttp *op_backend;
   GInputStream    *stream;
   SoupMessage     *msg;
-  SoupURI         *uri;
 
   op_backend = G_VFS_BACKEND_HTTP (backend);
-  uri = http_backend_uri_for_filename (backend, filename, FALSE);
+
   msg = soup_message_new_from_uri (SOUP_METHOD_GET, uri);
-  soup_uri_free (uri);
 
   soup_message_body_set_accumulate (msg->response_body, FALSE);
 
@@ -395,10 +408,9 @@ try_open_for_read (GVfsBackend        *backend,
 
   soup_input_stream_send_async (stream,
                                 G_PRIORITY_DEFAULT,
-                                G_VFS_JOB (job)->cancellable,
+                                job->cancellable,
                                 open_for_read_ready,
                                 job);
-  return TRUE;
 }
 
 /* *** read () *** */
diff --git a/daemon/gvfsbackendhttp.h b/daemon/gvfsbackendhttp.h
index c323324..19df3a0 100644
--- a/daemon/gvfsbackendhttp.h
+++ b/daemon/gvfsbackendhttp.h
@@ -74,6 +74,10 @@ void          http_backend_queue_message     (GVfsBackend         *backend,
                                               SoupSessionCallback  callback,
                                               gpointer             user_data);
 
+void          http_backend_open_for_read     (GVfsBackend         *backend,
+					      GVfsJob             *job,
+					      SoupURI             *uri);
+
 G_END_DECLS
 
 #endif /* __G_VFS_BACKEND_HTTP_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]