gvfs r1214 - in trunk: . client daemon



Author: alexl
Date: Thu Jan 31 16:54:22 2008
New Revision: 1214
URL: http://svn.gnome.org/viewvc/gvfs?rev=1214&view=rev

Log:
2008-01-31  Alexander Larsson  <alexl redhat com>

	Implement uri navigation for http uris (#509341)
	
        * client/gvfsurimapper.[ch]:
        Add get_mount_info_for_path method for mount types
	like ssh that change MountInfo as the path changes.
	
        * client/httpuri.c:
	Implement get_mount_info_for_path.
	For http, set the path from the uri.
	The will be removed on i/o by the corresponding
	path being in the mount_prefix.
	
        * daemon/gvfsbackendhttp.c:
	Set mount_prefix to path from uri.
	Remove unused code in message_new_from_filename

        * client/gdaemonfile.c:
        * client/gdaemonvfs.[ch]:
	Use the new uri mapper function to change GMountInfo
	as the path changes.



Modified:
   trunk/ChangeLog
   trunk/client/gdaemonfile.c
   trunk/client/gdaemonvfs.c
   trunk/client/gdaemonvfs.h
   trunk/client/gvfsurimapper.c
   trunk/client/gvfsurimapper.h
   trunk/client/httpuri.c
   trunk/daemon/gvfsbackendhttp.c

Modified: trunk/client/gdaemonfile.c
==============================================================================
--- trunk/client/gdaemonfile.c	(original)
+++ trunk/client/gdaemonfile.c	Thu Jan 31 16:54:22 2008
@@ -88,66 +88,6 @@
 {
 }
 
-static char *
-canonicalize_path (const char *path)
-{
-  char *canon, *start, *p, *q;
-
-  if (*path != '/')
-    canon = g_strconcat ("/", path, NULL);
-  else
-    canon = g_strdup (path);
-
-  /* Skip initial slash */
-  start = canon + 1;
-
-  p = start;
-  while (*p != 0)
-    {
-      if (p[0] == '.' && (p[1] == 0 || p[1] == '/'))
-	{
-	  memmove (p, p+1, strlen (p+1)+1);
-	}
-      else if (p[0] == '.' && p[1] == '.' && (p[2] == 0 || p[2] == '/'))
-	{
-	  q = p + 2;
-	  /* Skip previous separator */
-	  p = p - 2;
-	  if (p < start)
-	    p = start;
-	  while (p > start && *p != '/')
-	    p--;
-	  if (*p == '/')
-	    p++;
-	  memmove (p, q, strlen (q)+1);
-	}
-      else
-	{
-	  /* Skip until next separator */
-	  while (*p != 0 && *p != '/')
-	    p++;
-
-	  /* Keep one separator */
-	  if (*p != 0)
-	    p++;
-	}
-
-      /* Remove additional separators */
-      q = p;
-      while (*q && *q == '/')
-	q++;
-
-      if (p != q)
-	memmove (p, q, strlen (q)+1);
-    }
-
-  /* Remove trailing slashes */
-  if (p > start && *(p-1) == '/')
-    *(p-1) = 0;
-  
-  return canon;
-}
-
 GFile *
 g_daemon_file_new (GMountSpec *mount_spec,
 		   const char *path)
@@ -156,7 +96,7 @@
 
   daemon_file = g_object_new (G_TYPE_DAEMON_FILE, NULL);
   daemon_file->mount_spec = g_mount_spec_get_unique_for (mount_spec);
-  daemon_file->path = canonicalize_path (path);
+  daemon_file->path = g_mount_spec_canonicalize_path (path);
  
   return G_FILE (daemon_file);
 }
@@ -262,11 +202,28 @@
 }
 
 static GFile *
+new_file_for_new_path (GDaemonFile *daemon_file,
+		       const char *new_path)
+{
+  GFile *new_file;
+  GMountSpec *new_spec;
+
+  new_spec = _g_daemon_vfs_get_mount_spec_for_path (daemon_file->mount_spec,
+						    daemon_file->path,
+						    new_path);
+
+  new_file = g_daemon_file_new (new_spec, new_path);
+  g_mount_spec_unref (new_spec);
+
+  return new_file;
+}
+
+static GFile *
 g_daemon_file_get_parent (GFile *file)
 {
   GDaemonFile *daemon_file = G_DAEMON_FILE (file);
   const char *path;
-  GDaemonFile *parent;
+  GFile *parent;
   const char *base;
   char *parent_path;
   gsize len;    
@@ -286,11 +243,10 @@
   g_memmove (parent_path, path, len);
   parent_path[len] = 0;
 
-  parent = g_object_new (G_TYPE_DAEMON_FILE, NULL);
-  parent->mount_spec = g_mount_spec_ref (daemon_file->mount_spec);
-  parent->path = parent_path;
+  parent = new_file_for_new_path (daemon_file, parent_path);
+  g_free (parent_path);
   
-  return G_FILE (parent);
+  return parent;
 }
 
 static GFile *
@@ -387,10 +343,10 @@
   GFile *child;
 
   if (*relative_path == '/')
-    return g_daemon_file_new (daemon_file->mount_spec, relative_path);
-  
+    return new_file_for_new_path (daemon_file, relative_path);
+
   path = g_build_path ("/", daemon_file->path, relative_path, NULL);
-  child = g_daemon_file_new (daemon_file->mount_spec, path);
+  child = new_file_for_new_path (daemon_file, path);
   g_free (path);
   
   return child;
@@ -1642,7 +1598,7 @@
       goto out;
     }
 
-  file = g_daemon_file_new (daemon_file->mount_spec, new_path);
+  file = new_file_for_new_path (daemon_file, new_path);
   g_free (new_path);
 
  out:

Modified: trunk/client/gdaemonvfs.c
==============================================================================
--- trunk/client/gdaemonvfs.c	(original)
+++ trunk/client/gdaemonvfs.c	Thu Jan 31 16:54:22 2008
@@ -122,7 +122,7 @@
 	{
 	  spec = g_mount_spec_new_from_data (info->keys, NULL);
 	  path = info->path;
-	  /* We took over ownership, custom free: */
+	  /* We took over ownership of info parts, custom free: */
 	  g_free (info);
 	}
     }
@@ -282,6 +282,43 @@
   return g_vfs_get_file_for_uri (G_DAEMON_VFS (vfs)->wrapped_vfs, uri);
 }
 
+GMountSpec *
+_g_daemon_vfs_get_mount_spec_for_path (GMountSpec *spec,
+				       const char *path,
+				       const char *new_path)
+{
+  const char *type;
+  GVfsUriMapper *mapper;
+  GMountSpec *new_spec;
+
+  type = g_mount_spec_get_type (spec);
+
+  if (type == NULL)
+    return g_mount_spec_ref (spec);
+  
+  new_spec = NULL;
+  mapper = g_hash_table_lookup (the_vfs->to_uri_hash, type);
+  if (mapper)
+    {
+      GVfsUriMountInfo info, *new_info;
+      info.keys = spec->items;
+      info.path = (char *)path;
+      new_info = g_vfs_uri_mapper_get_mount_info_for_path (mapper, &info, new_path);
+      if (new_info != NULL)
+	{
+	  new_spec = g_mount_spec_new_from_data (new_info->keys, NULL);
+	  /* We took over ownership of parts of new_info, custom free: */
+	  g_free (new_info->path);
+	  g_free (new_info);
+	}
+    }
+
+  if (new_spec == NULL)
+    new_spec = g_mount_spec_ref (spec);
+
+  return new_spec;
+}
+
 char *
 _g_daemon_vfs_get_uri_for_mountspec (GMountSpec *spec,
 				     char *path,

Modified: trunk/client/gdaemonvfs.h
==============================================================================
--- trunk/client/gdaemonvfs.h	(original)
+++ trunk/client/gdaemonvfs.h	Thu Jan 31 16:54:22 2008
@@ -60,6 +60,9 @@
 GMountInfo *    _g_daemon_vfs_get_mount_info_sync      (GMountSpec               *spec,
 							const char               *path,
 							GError                  **error);
+GMountSpec *    _g_daemon_vfs_get_mount_spec_for_path  (GMountSpec               *spec,
+						        const char               *path,
+						        const char               *new_path);
 void            _g_daemon_vfs_invalidate_dbus_id       (const char               *dbus_id);
 DBusConnection *_g_daemon_vfs_get_async_bus            (void);
 

Modified: trunk/client/gvfsurimapper.c
==============================================================================
--- trunk/client/gvfsurimapper.c	(original)
+++ trunk/client/gvfsurimapper.c	Thu Jan 31 16:54:22 2008
@@ -170,6 +170,21 @@
   return (* class->from_uri) (mapper, uri);
 }
 
+GVfsUriMountInfo *
+g_vfs_uri_mapper_get_mount_info_for_path (GVfsUriMapper    *mapper,
+					  GVfsUriMountInfo *info,
+					  const char       *new_path)
+{
+  GVfsUriMapperClass *class;
+
+  class = G_VFS_URI_MAPPER_GET_CLASS (mapper);
+
+  if (class->get_mount_info_for_path != NULL)
+    return (* class->get_mount_info_for_path) (mapper, info, new_path);
+  else
+    return NULL;
+}
+
 const char * const *
 g_vfs_uri_mapper_get_handled_mount_types (GVfsUriMapper  *mapper)
 {

Modified: trunk/client/gvfsurimapper.h
==============================================================================
--- trunk/client/gvfsurimapper.h	(original)
+++ trunk/client/gvfsurimapper.h	Thu Jan 31 16:54:22 2008
@@ -42,6 +42,7 @@
   GObject parent;
 };
 
+/* Keep in sync with GMountSpecItem */
 typedef struct {
   char *key;
   char *value;
@@ -61,7 +62,10 @@
   const char * const * (*get_handled_schemes)     (GVfsUriMapper *mapper);
   GVfsUriMountInfo *   (*from_uri)                (GVfsUriMapper *mapper,
 					           const char *uri);
-  
+  GVfsUriMountInfo *   (*get_mount_info_for_path) (GVfsUriMapper *mapper,
+						   GVfsUriMountInfo *mount_info,
+					           const char *new_path);
+
   const char * const * (*get_handled_mount_types) (GVfsUriMapper *mapper);
   char *               (*to_uri)                  (GVfsUriMapper *mapper,
 					           GVfsUriMountInfo *mount_info,
@@ -88,6 +92,9 @@
 const char * const *g_vfs_uri_mapper_get_handled_schemes     (GVfsUriMapper    *mapper);
 GVfsUriMountInfo *  g_vfs_uri_mapper_from_uri                (GVfsUriMapper    *mapper,
 							      const char       *uri);
+GVfsUriMountInfo *  g_vfs_uri_mapper_get_mount_info_for_path (GVfsUriMapper    *mapper,
+							      GVfsUriMountInfo *mount_info,
+							      const char       *new_path);
 
 const char * const *g_vfs_uri_mapper_get_handled_mount_types (GVfsUriMapper    *mapper);
 char *              g_vfs_uri_mapper_to_uri                  (GVfsUriMapper    *mapper,

Modified: trunk/client/httpuri.c
==============================================================================
--- trunk/client/httpuri.c	(original)
+++ trunk/client/httpuri.c	Thu Jan 31 16:54:22 2008
@@ -67,17 +67,28 @@
 
 static GVfsUriMountInfo *
 http_from_uri (GVfsUriMapper *mapper,
-	      const char     *uri_str)
+	       const char     *uri_str)
 {
   GVfsUriMountInfo *info;
   char *path;
   gboolean ssl;
 
+  path = NULL;
   if (!g_ascii_strncasecmp (uri_str, "http", 4))
     {
+      GDecodedUri *uri;
+
+      uri = g_vfs_decode_uri (uri_str);
+
       info = g_vfs_uri_mount_info_new ("http");
       g_vfs_uri_mount_info_set (info, "uri", uri_str);
-      path = g_strdup ("/");
+      
+      if (uri)
+	{
+	  path = uri->path;
+	  uri->path = NULL;
+	  g_vfs_decoded_uri_free (uri);
+	}
     }
   else
     {
@@ -116,6 +127,60 @@
   return info;
 }
 
+static GVfsUriMountInfo *
+http_get_mount_info_for_path (GVfsUriMapper *mapper,
+			      GVfsUriMountInfo *info,
+			      const char *new_path)
+{
+  const char *type;
+
+  type = g_vfs_uri_mount_info_get (info, "type");
+
+  if (strcmp (type, "http") == 0)
+    {
+      const char *uri_str;
+      char *new_uri;
+      GDecodedUri *uri;
+      GVfsUriMountInfo *new_info;
+
+      uri_str = g_vfs_uri_mount_info_get (info, "uri");
+
+      uri = g_vfs_decode_uri (uri_str);
+
+      if (uri == NULL)
+	return NULL;
+
+      if (strcmp (uri->path, new_path) == 0)
+	{
+	  g_vfs_decoded_uri_free (uri);
+	  return NULL;
+	}
+
+      g_free (uri->path);
+      uri->path = g_strdup (new_path);
+
+      g_free (uri->query);
+      uri->query = NULL;
+
+      g_free (uri->fragment);
+      uri->fragment = NULL;
+
+      new_info = g_vfs_uri_mount_info_new ("http");
+
+      new_uri = g_vfs_encode_uri (uri, TRUE);
+      g_vfs_uri_mount_info_set (new_info, "uri", new_uri);
+      g_free (new_uri);
+
+      uri->path = NULL;
+
+      g_vfs_decoded_uri_free (uri);
+
+      return new_info;
+    }
+  else
+    return NULL;
+}
+
 static const char * const *
 http_get_handled_mount_types (GVfsUriMapper *mapper)
 {
@@ -228,6 +293,7 @@
   mapper_class = G_VFS_URI_MAPPER_CLASS (class);
   mapper_class->get_handled_schemes     = http_get_handled_schemes;
   mapper_class->from_uri                = http_from_uri;
+  mapper_class->get_mount_info_for_path = http_get_mount_info_for_path;
   mapper_class->get_handled_mount_types = http_get_handled_mount_types;
   mapper_class->to_uri                  = http_to_uri;
   mapper_class->to_uri_scheme           = http_to_uri_scheme;

Modified: trunk/daemon/gvfsbackendhttp.c
==============================================================================
--- trunk/daemon/gvfsbackendhttp.c	(original)
+++ trunk/daemon/gvfsbackendhttp.c	Thu Jan 31 16:54:22 2008
@@ -35,7 +35,6 @@
 #include <gio/gio.h>
 
 #include <libsoup/soup.h>
-
 #include "gvfsbackendhttp.h"
 #include "gvfsjobopenforread.h"
 #include "gvfsjobread.h"
@@ -355,24 +354,10 @@
   SoupURI         *uri;
 
   op_backend = G_VFS_BACKEND_HTTP (backend);
-  uri = soup_uri_copy (op_backend->mount_base);
 
   uri = g_vfs_backend_uri_for_filename (backend, filename);
   msg = message_new_from_uri (method, uri);
 
-  /* "/" means "whatever mount_base is" */
-  if (strcmp (filename, "/"))
-    {
-      char *path;
-      /* Otherwise, we append filename to mount_base (which is assumed to
-       * be a directory in this case).
-       */
-
-      path = g_build_path ("/", uri->path, filename, NULL);
-      soup_uri_set_path (uri, path);
-      g_free (path);
-    }
-  
   soup_uri_free (uri);
   return msg;
 }
@@ -389,6 +374,7 @@
 {
   GVfsBackendHttp *op_backend;
   const char      *uri_str;
+  char            *path;
   SoupURI         *uri;
   GMountSpec      *real_mount_spec;
 
@@ -412,6 +398,15 @@
 
   real_mount_spec = g_mount_spec_new ("http");
   g_mount_spec_set (real_mount_spec, "uri", uri_str);
+
+  if (uri->path != NULL)
+    {
+      path = g_uri_unescape_string (uri->path, "/");
+      g_free (real_mount_spec->mount_prefix);
+      real_mount_spec->mount_prefix = g_mount_spec_canonicalize_path (path);
+      g_free (path);
+    }
+  
   g_vfs_backend_set_mount_spec (backend, real_mount_spec);
   
   op_backend->mount_base = uri;
@@ -439,7 +434,6 @@
   res = soup_input_stream_send_finish (stream,
                                        result,
                                        &error);
-
   if (res == FALSE)
     {
       g_vfs_job_failed (G_VFS_JOB (job),



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