diff options
author | Ondrej Holy <oholy@redhat.com> | 2020-05-11 14:16:48 +0200 |
---|---|---|
committer | Ondrej Holy <oholy@redhat.com> | 2020-09-21 17:31:17 +0200 |
commit | 65265e9ece4e81efccbc5ce6d3b07e1ed6226f29 (patch) | |
tree | 5804779f479ecd8da31b85eecc254085e6d8dabd | |
parent | c0913921ff07a7d800e931962f466a34fb0621ee (diff) | |
download | gvfs-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.c | 74 |
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; |