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




commit 65265e9ece4e81efccbc5ce6d3b07e1ed6226f29
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 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;


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