[gvfs/wip/oholy/dav-mount-check] dav: Be sure that a child is accessible when looking for a root




commit f04a3e7c323b9fa04a505044b20cc6e25d87740d
Author: Ondrej Holy <oholy redhat com>
Date:   Mon May 11 14:16:48 2020 +0200

    dav: Be sure that a child is accessible when looking for a root
    
    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

 daemon/gvfsbackenddav.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 73 insertions(+), 1 deletion(-)
---
diff --git a/daemon/gvfsbackenddav.c b/daemon/gvfsbackenddav.c
index d4d4ac9b..b23369d4 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 */
@@ -2009,7 +2070,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;


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