summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Holy <oholy@redhat.com>2020-05-11 14:16:48 +0200
committerOndrej Holy <oholy@redhat.com>2020-09-21 17:31:17 +0200
commit65265e9ece4e81efccbc5ce6d3b07e1ed6226f29 (patch)
tree5804779f479ecd8da31b85eecc254085e6d8dabd
parentc0913921ff07a7d800e931962f466a34fb0621ee (diff)
downloadgvfs-wip/oholy/dav-mount-check.tar.gz
dav: Be sure that a child is accessible when looking for a rootwip/oholy/dav-mount-check
The DAV backend tries to find the top-most directory when mounting. But it seems that even if a parent directory is a WebDAV collection, it doesn't always mean that the previous path is listed in that directory. Let's check that when mounting and use the parent directory only if the child is listed. Fixes: https://gitlab.gnome.org/GNOME/gvfs/-/issues/468
-rw-r--r--daemon/gvfsbackenddav.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/daemon/gvfsbackenddav.c b/daemon/gvfsbackenddav.c
index 4ac94aca..45956d93 100644
--- a/daemon/gvfsbackenddav.c
+++ b/daemon/gvfsbackenddav.c
@@ -1446,6 +1446,67 @@ stat_location (GVfsBackend *backend,
return res;
}
+static gboolean
+is_child_accessible (GVfsBackend *backend,
+ const char *child,
+ GError **error)
+{
+ SoupMessage *msg;
+ Multistatus ms;
+ xmlNodeIter iter;
+ gboolean res;
+ gboolean retval = FALSE;
+
+ msg = propfind_request_new (backend, "/", 1, NULL);
+ if (msg == NULL)
+ {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Could not create request"));
+ return FALSE;
+ }
+
+ message_add_redirect_header (msg, G_FILE_QUERY_INFO_NONE);
+
+ g_vfs_backend_dav_send_message (backend, msg);
+
+ res = multistatus_parse (msg, &ms, error);
+ if (res == FALSE)
+ {
+ g_object_unref (msg);
+ return FALSE;
+ }
+
+ multistatus_get_response_iter (&ms, &iter);
+ while (xml_node_iter_next (&iter))
+ {
+ MsResponse response;
+
+ if (!multistatus_get_response (&iter, &response))
+ continue;
+
+ if (response.is_target == FALSE)
+ {
+ gchar *basename;
+
+ basename = ms_response_get_basename (&response);
+ if (g_strcmp0 (basename, child) == 0)
+ {
+ retval = TRUE;
+ break;
+ }
+
+ g_free (basename);
+ }
+
+ ms_response_clear (&response);
+ }
+
+ multistatus_free (&ms);
+ g_object_unref (msg);
+
+ return retval;
+}
+
/* ************************************************************************* */
/* Authentication */
@@ -2012,7 +2073,18 @@ do_mount (GVfsBackend *backend,
if (is_collection == FALSE)
break;
-
+
+ /* Be sure that it is possible to access the requested path again, see:
+ https://gitlab.gnome.org/GNOME/gvfs/-/issues/468 */
+ if (last_good_path != NULL)
+ {
+ const char *child;
+
+ child = last_good_path + strlen (mount_base->path) + 1;
+ if (is_child_accessible (backend, child, NULL) == FALSE)
+ break;
+ }
+
/* we have found a new good root, try the parent ... */
g_free (last_good_path);
last_good_path = mount_base->path;