summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Kellner <gicmo@gnome.org>2011-05-04 00:11:57 +0200
committerChristian Kellner <gicmo@gnome.org>2011-05-04 00:13:15 +0200
commitd3fcf41ef3676139b5a035757c6d67c6fef073c9 (patch)
tree573e38eacc941bec902f3ef308c6eea4fb6d885d
parent342ae51fe86663dce07d18a21c9827f8ee7fd131 (diff)
downloadgvfs-d3fcf41ef3676139b5a035757c6d67c6fef073c9.tar.gz
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
-rw-r--r--daemon/gvfsbackenddav.c79
-rw-r--r--daemon/gvfsbackendhttp.c24
-rw-r--r--daemon/gvfsbackendhttp.h4
3 files changed, 101 insertions, 6 deletions
diff --git a/daemon/gvfsbackenddav.c b/daemon/gvfsbackenddav.c
index 0adf9a27..d63059fc 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 976e0ede..49267243 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 c3233246..19df3a07 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__ */