gvfs r1220 - in trunk: . daemon



Author: gicmo
Date: Sun Feb  3 22:26:50 2008
New Revision: 1220
URL: http://svn.gnome.org/viewvc/gvfs?rev=1220&view=rev

Log:
2008-02-03  Christian Kellner  <gicmo gnome org>

	* daemon/gvfsbackenddav.c:
	* daemon/gvfsbackendhttp.c:
	Move write logic (replace, create) to the dav backend.


Modified:
   trunk/ChangeLog
   trunk/daemon/gvfsbackenddav.c
   trunk/daemon/gvfsbackendhttp.c

Modified: trunk/daemon/gvfsbackenddav.c
==============================================================================
--- trunk/daemon/gvfsbackenddav.c	(original)
+++ trunk/daemon/gvfsbackenddav.c	Sun Feb  3 22:26:50 2008
@@ -58,7 +58,7 @@
 #include "gvfsdaemonprotocol.h"
 
 #include "soup-input-stream.h"
-
+#include "soup-output-stream.h"
 
 struct _GVfsBackendDav
 {
@@ -531,7 +531,7 @@
 static void
 soup_authenticate (SoupSession *session,
                    SoupMessage *msg,
-	           SoupAuth    *auth,
+                   SoupAuth    *auth,
                    gboolean     retrying,
                    gpointer     user_data)
 {
@@ -837,12 +837,12 @@
 
   /* RFC 4437 */
   if (flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS)
-      redirect_header = "F";
+    redirect_header = "F";
   else
-      redirect_header = "T";
+    redirect_header = "T";
 
   soup_message_headers_append (msg->request_headers,
-                           "Apply-To-Redirect-Ref", redirect_header);
+                               "Apply-To-Redirect-Ref", redirect_header);
 
   soup_message_set_request (msg, "application/xml",
                             SOUP_MEMORY_TAKE,
@@ -971,6 +971,259 @@
 /* ************************************************************************* */
 /*  */
 
+/* *** create () *** */
+static void
+try_create_tested_existence (SoupSession *session, SoupMessage *msg,
+                             gpointer user_data)
+{
+  GVfsJob *job = G_VFS_JOB (user_data);
+  GVfsBackendHttp *op_backend = job->backend_data;
+  GOutputStream   *stream;
+  SoupMessage     *put_msg;
+
+  if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code))
+    {
+      g_vfs_job_failed (job,
+                        G_IO_ERROR,
+                        G_IO_ERROR_EXISTS,
+                        _("Target file already exists"));
+      return;
+    }
+  /* FIXME: other errors */
+
+  put_msg = message_new_from_uri ("PUT", soup_message_get_uri (msg));
+
+  soup_message_headers_append (put_msg->request_headers, "If-None-Match", "*");
+  stream = soup_output_stream_new (op_backend->session, put_msg, -1);
+  g_object_unref (put_msg);
+
+  g_vfs_job_open_for_write_set_handle (G_VFS_JOB_OPEN_FOR_WRITE (job), stream);
+  g_vfs_job_succeeded (job);
+}  
+
+static gboolean
+try_create (GVfsBackend *backend,
+            GVfsJobOpenForWrite *job,
+            const char *filename,
+            GFileCreateFlags flags)
+{
+  GVfsBackendHttp *op_backend;
+  SoupMessage     *msg;
+
+  /* FIXME: if SoupOutputStream supported chunked requests, we could
+   * use a PUT with "If-None-Match: *" and "Expect: 100-continue"
+   */
+
+  op_backend = G_VFS_BACKEND_HTTP (backend);
+
+  msg = message_new_from_filename (backend, "HEAD", filename);
+
+  g_vfs_job_set_backend_data (G_VFS_JOB (job), op_backend, NULL);
+  soup_session_queue_message (op_backend->session, msg,
+                              try_create_tested_existence, job);
+  return TRUE;
+}
+
+/* *** replace () *** */
+static void
+open_for_replace_succeeded (GVfsBackendHttp *op_backend, GVfsJob *job,
+                            SoupURI *uri, const char *etag)
+{
+  SoupMessage     *put_msg;
+  GOutputStream   *stream;
+
+  put_msg = message_new_from_uri (SOUP_METHOD_PUT, uri);
+
+  if (etag)
+    soup_message_headers_append (put_msg->request_headers, "If-Match", etag);
+
+  stream = soup_output_stream_new (op_backend->session, put_msg, -1);
+  g_object_unref (put_msg);
+
+  g_vfs_job_open_for_write_set_handle (G_VFS_JOB_OPEN_FOR_WRITE (job), stream);
+  g_vfs_job_succeeded (job);
+}
+
+static void
+try_replace_checked_etag (SoupSession *session, SoupMessage *msg,
+                          gpointer user_data)
+{
+  GVfsJob *job = G_VFS_JOB (user_data);
+  GVfsBackendHttp *op_backend = job->backend_data;
+
+  if (msg->status_code == SOUP_STATUS_PRECONDITION_FAILED)
+    {
+      g_vfs_job_failed (G_VFS_JOB (job),
+                        G_IO_ERROR,
+                        G_IO_ERROR_WRONG_ETAG,
+                        _("The file was externally modified"));
+      return;
+    }
+  /* FIXME: other errors */
+
+  open_for_replace_succeeded (op_backend, job, soup_message_get_uri (msg),
+                              soup_message_headers_get (msg->request_headers, "If-Match"));
+}  
+
+static gboolean
+try_replace (GVfsBackend *backend,
+             GVfsJobOpenForWrite *job,
+             const char *filename,
+             const char *etag,
+             gboolean make_backup,
+             GFileCreateFlags flags)
+{
+  GVfsBackendHttp *op_backend;
+  SoupURI         *uri;
+
+  /* FIXME: if SoupOutputStream supported chunked requests, we could
+   * use a PUT with "If-Match: ..." and "Expect: 100-continue"
+   */
+
+  op_backend = G_VFS_BACKEND_HTTP (backend);
+
+  if (make_backup)
+    {
+      g_vfs_job_failed (G_VFS_JOB (job),
+                        G_IO_ERROR,
+                        G_IO_ERROR_CANT_CREATE_BACKUP,
+                        _("Backup file creation failed"));
+      return TRUE;
+    }
+
+
+
+  uri = g_vfs_backend_uri_for_filename (backend, filename);
+
+  if (etag)
+    {
+      SoupMessage *msg;
+
+      msg = soup_message_new_from_uri (SOUP_METHOD_HEAD, uri);
+      soup_uri_free (uri);
+      soup_message_headers_append (msg->request_headers, "User-Agent", "gvfs/" VERSION);
+      soup_message_headers_append (msg->request_headers, "If-Match", etag);
+
+      g_vfs_job_set_backend_data (G_VFS_JOB (job), op_backend, NULL);
+      soup_session_queue_message (op_backend->session, msg,
+                                  try_replace_checked_etag, job);
+      return TRUE;
+    }
+
+  open_for_replace_succeeded (op_backend, G_VFS_JOB (job), uri, NULL);
+  soup_uri_free (uri);
+  return TRUE;
+}
+
+/* *** write () *** */
+static void
+write_ready (GObject      *source_object,
+             GAsyncResult *result,
+             gpointer      user_data)
+{
+  GOutputStream *stream;
+  GVfsJob       *job;
+  GError        *error;
+  gssize         nwrote;
+
+  stream = G_OUTPUT_STREAM (source_object); 
+  error  = NULL;
+  job    = G_VFS_JOB (user_data);
+
+  nwrote = g_output_stream_write_finish (stream, result, &error);
+
+  if (nwrote < 0)
+   {
+     g_vfs_job_failed (G_VFS_JOB (job),
+                       error->domain,
+                       error->code,
+                       error->message);
+
+     g_error_free (error);
+     return;
+   }
+
+  g_vfs_job_write_set_written_size (G_VFS_JOB_WRITE (job), nwrote);
+  g_vfs_job_succeeded (job);
+}
+
+static gboolean
+try_write (GVfsBackend *backend,
+           GVfsJobWrite *job,
+           GVfsBackendHandle handle,
+           char *buffer,
+           gsize buffer_size)
+{
+  GVfsBackendHttp *op_backend;
+  GOutputStream   *stream;
+
+  op_backend = G_VFS_BACKEND_HTTP (backend);
+  stream = G_OUTPUT_STREAM (handle);
+
+  g_output_stream_write_async (stream,
+                               buffer,
+                               buffer_size,
+                               G_PRIORITY_DEFAULT,
+                               G_VFS_JOB (job)->cancellable,
+                               write_ready,
+                               job);
+  return TRUE;
+}
+
+/* *** close_write () *** */
+static void
+close_write_ready (GObject      *source_object,
+                   GAsyncResult *result,
+                   gpointer      user_data)
+{
+  GOutputStream *stream;
+  GVfsJob       *job;
+  GError        *error;
+  gboolean       res;
+
+  job = G_VFS_JOB (user_data);
+  stream = G_OUTPUT_STREAM (source_object);
+  res = g_output_stream_close_finish (stream,
+                                      result,
+                                      &error);
+  if (res == FALSE)
+    {
+      g_vfs_job_failed (G_VFS_JOB (job),
+                        error->domain,
+                        error->code,
+                        error->message);
+
+      g_error_free (error);
+    }
+  else
+    g_vfs_job_succeeded (job);
+
+  g_object_unref (stream);
+}
+
+static gboolean
+try_close_write (GVfsBackend *backend,
+                 GVfsJobCloseWrite *job,
+                 GVfsBackendHandle handle)
+{
+  GVfsBackendHttp *op_backend;
+  GOutputStream   *stream;
+
+  op_backend = G_VFS_BACKEND_HTTP (backend);
+  stream = G_OUTPUT_STREAM (handle);
+
+  g_output_stream_close_async (stream,
+                               G_PRIORITY_DEFAULT,
+                               G_VFS_JOB (job)->cancellable,
+                               close_write_ready,
+                               job);
+
+  return TRUE;
+}
+
+/* ************************************************************************* */
+/*  */
+
 static void
 g_vfs_backend_dav_class_init (GVfsBackendDavClass *klass)
 {
@@ -981,7 +1234,13 @@
   gobject_class->finalize  = g_vfs_backend_dav_finalize;
 
   backend_class = G_VFS_BACKEND_CLASS (klass); 
+
   backend_class->try_mount         = try_mount;
   backend_class->try_query_info    = try_query_info;
   backend_class->try_enumerate     = try_enumerate;
+  backend_class->try_create        = try_create;
+  backend_class->try_replace       = try_replace;
+  backend_class->try_write         = try_write;
+  backend_class->try_close_write   = try_close_write;
+
 }

Modified: trunk/daemon/gvfsbackendhttp.c
==============================================================================
--- trunk/daemon/gvfsbackendhttp.c	(original)
+++ trunk/daemon/gvfsbackendhttp.c	Sun Feb  3 22:26:50 2008
@@ -50,7 +50,6 @@
 #include "gvfsdaemonprotocol.h"
 
 #include "soup-input-stream.h"
-#include "soup-output-stream.h"
 
 
 G_DEFINE_TYPE (GVfsBackendHttp, g_vfs_backend_http, G_VFS_TYPE_BACKEND);
@@ -150,183 +149,28 @@
 /* ************************************************************************* */
 /*  */
 
-typedef void (*StatCallback) (GFileInfo *info, gpointer user_data, GError *error);
-
-typedef struct _StatData {
-
-  StatCallback callback;
-  gpointer     user_data;
-
-  GFileQueryInfoFlags    flags;
-  GFileAttributeMatcher *matcher;
-
-} StatData;
-
-
 static void
-gvfs_error_from_http_status (GError **error, guint status_code, const char *message)
+g_vfs_job_failed_from_http_status (GVfsJob *job, guint status_code, const char *message)
 {
   switch (status_code) {
 
-    case SOUP_STATUS_NOT_FOUND:
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
-                   message);
-      break;
-
-    case SOUP_STATUS_UNAUTHORIZED:
-    case SOUP_STATUS_PAYMENT_REQUIRED:
-    case SOUP_STATUS_FORBIDDEN:
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
-                   _("HTTP Client Error: %s"), message);
-      break;
-    default:
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                   _("HTTP Error: %s"), message);
+  case SOUP_STATUS_NOT_FOUND:
+    g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
+                      message);
+    break;
+
+  case SOUP_STATUS_UNAUTHORIZED:
+  case SOUP_STATUS_PAYMENT_REQUIRED:
+  case SOUP_STATUS_FORBIDDEN:
+    g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
+                      _("HTTP Client Error: %s"), message);
+    break;
+  default:
+    g_vfs_job_failed (job, G_IO_ERROR, G_IO_ERROR_FAILED,
+                      _("HTTP Error: %s"), message);
   }
 }
 
-static void 
-stat_location_ready (SoupSession *session,
-                     SoupMessage *msg,
-                     gpointer     user_data)
-{
-  GFileInfo  *info;
-  StatData   *data;
-  GError     *error;
-  const char *text;
-
-  data  = (StatData *) user_data; 
-  info  = NULL;
-  error = NULL;
-
-  if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code))
-    {
-      char          *basename;
-      const SoupURI *uri;
-
-      info = g_file_info_new ();
-
-      uri = soup_message_get_uri (msg);
-      basename = uri_get_basename (uri->path);
-      
-      g_print ("basename:%s\n", basename);
-
-      /* read http/1.1 rfc, until then we copy the local files
-       * behaviour */ 
-      if (basename != NULL &&
-          g_file_attribute_matcher_matches (data->matcher,
-                                            G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME))
-        {
-          char *display_name = g_filename_display_name (basename);
-
-          if (strstr (display_name, "\357\277\275") != NULL)
-            {
-              char *p = display_name;
-              display_name = g_strconcat (display_name, _(" (invalid encoding)"), NULL);
-              g_free (p);
-            }
-
-          g_file_info_set_display_name (info, display_name);
-          g_free (display_name);
-        }
-
-      if (basename != NULL &&
-          g_file_attribute_matcher_matches (data->matcher,
-                                            G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME))
-        {
-          char *edit_name = g_filename_display_name (basename);
-          g_file_info_set_edit_name (info, edit_name);
-          g_free (edit_name);
-        } 
-
-      g_free (basename);
-
-      text = soup_message_headers_get (msg->response_headers,
-                                       "Content-Length");
-      if (text)
-        {
-          guint64 size = g_ascii_strtoull (text, NULL, 10);
-          g_file_info_set_size (info, size);
-        }
-
-
-      text = soup_message_headers_get (msg->response_headers,
-                                       "Content-Type");
-      if (text)
-        {
-          char *p = strchr (text, ';');
-
-          if (p != NULL)
-            {
-              char *tmp = g_strndup (text, p - text);
-              g_file_info_set_content_type (info, tmp);
-              g_free (tmp);
-            }
-          else
-            g_file_info_set_content_type (info, text);
-        }
-
-
-      text = soup_message_headers_get (msg->response_headers,
-                                       "Last-Modified");
-      if (text)
-        {
-          GTimeVal tv;
-          if (g_time_val_from_iso8601 (text, &tv))
-            g_file_info_set_modification_time (info, &tv);
-        }
-
-      text = soup_message_headers_get (msg->response_headers,
-                                       "ETag");
-      if (text)
-        {
-          g_file_info_set_attribute_string (info,
-                                            G_FILE_ATTRIBUTE_ETAG_VALUE,
-                                            text);
-        }
-    }
-  else
-    {
-      gvfs_error_from_http_status (&error, msg->status_code,
-                                   msg->reason_phrase);
-    }
-
-  data->callback (info, data->user_data, error);
-  
-  if (error)
-    g_error_free (error);
-
-  g_free (data);
-}
-
-static void
-stat_location (GVfsBackend           *backend,
-               const char            *filename,
-               GFileQueryInfoFlags    flags,
-               GFileAttributeMatcher *attribute_matcher,
-               StatCallback           callback,
-               gpointer               user_data)
-{
-  GVfsBackendHttp *op_backend;
-  StatData        *data;
-  SoupMessage     *msg;
-
-  op_backend = G_VFS_BACKEND_HTTP (backend);
-
-  msg = message_new_from_filename (backend, "HEAD", filename);
-
-  data = g_new0 (StatData, 1);
-
-  data->user_data = user_data;
-  data->callback = callback;
-  data->flags = flags;
-  data->matcher = attribute_matcher;
-
-
-  soup_session_queue_message (op_backend->session, msg,
-                              stat_location_ready, data);
-}
-
 /* ************************************************************************* */
 /* public utility functions */
 
@@ -615,274 +459,114 @@
   return TRUE;
 }
 
-/* *** create () *** */
-static void
-try_create_tested_existence (SoupSession *session, SoupMessage *msg,
-                             gpointer user_data)
-{
-  GVfsJob *job = G_VFS_JOB (user_data);
-  GVfsBackendHttp *op_backend = job->backend_data;
-  GOutputStream   *stream;
-  SoupMessage     *put_msg;
-
-  if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code))
-    {
-      g_vfs_job_failed (job,
-                        G_IO_ERROR,
-                        G_IO_ERROR_EXISTS,
-                        _("Target file already exists"));
-      return;
-    }
-  /* FIXME: other errors */
-
-  put_msg = message_new_from_uri ("PUT", soup_message_get_uri (msg));
-
-  soup_message_headers_append (put_msg->request_headers, "If-None-Match", "*");
-  stream = soup_output_stream_new (op_backend->session, put_msg, -1);
-  g_object_unref (put_msg);
-
-  g_vfs_job_open_for_write_set_handle (G_VFS_JOB_OPEN_FOR_WRITE (job), stream);
-  g_vfs_job_succeeded (job);
-}  
-
-static gboolean
-try_create (GVfsBackend *backend,
-            GVfsJobOpenForWrite *job,
-            const char *filename,
-            GFileCreateFlags flags)
-{
-  GVfsBackendHttp *op_backend;
-  SoupMessage     *msg;
-
-  /* FIXME: if SoupOutputStream supported chunked requests, we could
-   * use a PUT with "If-None-Match: *" and "Expect: 100-continue"
-   */
-
-  op_backend = G_VFS_BACKEND_HTTP (backend);
-
-  msg = message_new_from_filename (backend, "HEAD", filename);
-
-  g_vfs_job_set_backend_data (G_VFS_JOB (job), op_backend, NULL);
-  soup_session_queue_message (op_backend->session, msg,
-                              try_create_tested_existence, job);
-  return TRUE;
-}
-
-/* *** replace () *** */
-static void
-open_for_replace_succeeded (GVfsBackendHttp *op_backend, GVfsJob *job,
-                            SoupURI *uri, const char *etag)
-{
-  SoupMessage     *put_msg;
-  GOutputStream   *stream;
-
-  put_msg = message_new_from_uri (SOUP_METHOD_PUT, uri);
-
-  if (etag)
-    soup_message_headers_append (put_msg->request_headers, "If-Match", etag);
-
-  stream = soup_output_stream_new (op_backend->session, put_msg, -1);
-  g_object_unref (put_msg);
 
-  g_vfs_job_open_for_write_set_handle (G_VFS_JOB_OPEN_FOR_WRITE (job), stream);
-  g_vfs_job_succeeded (job);
-}
+/* *** query_info () *** */
 
-static void
-try_replace_checked_etag (SoupSession *session, SoupMessage *msg,
-                          gpointer user_data)
+static void 
+query_info_ready (SoupSession *session,
+                  SoupMessage *msg,
+                  gpointer     user_data)
 {
-  GVfsJob *job = G_VFS_JOB (user_data);
-  GVfsBackendHttp *op_backend = job->backend_data;
+  GFileAttributeMatcher *matcher;
+  GVfsJobQueryInfo      *job;
+  const SoupURI         *uri;
+  const char            *text;
+  GFileInfo             *info;
+  char                  *basename;
+
+  job     = G_VFS_JOB_QUERY_INFO (user_data);
+  info    = job->file_info;
+  matcher = job->attribute_matcher;
 
-  if (msg->status_code == SOUP_STATUS_PRECONDITION_FAILED)
+  if (! SOUP_STATUS_IS_SUCCESSFUL (msg->status_code))
     {
-      g_vfs_job_failed (G_VFS_JOB (job),
-                        G_IO_ERROR,
-                        G_IO_ERROR_WRONG_ETAG,
-                        _("The file was externally modified"));
+      g_vfs_job_failed_from_http_status (G_VFS_JOB (job), msg->status_code,
+                                         msg->reason_phrase);
       return;
     }
-  /* FIXME: other errors */
 
-  open_for_replace_succeeded (op_backend, job, soup_message_get_uri (msg),
-                              soup_message_headers_get (msg->request_headers, "If-Match"));
-}  
+  uri = soup_message_get_uri (msg);
+  basename = uri_get_basename (uri->path);
 
-static gboolean
-try_replace (GVfsBackend *backend,
-             GVfsJobOpenForWrite *job,
-             const char *filename,
-             const char *etag,
-             gboolean make_backup,
-             GFileCreateFlags flags)
-{
-  GVfsBackendHttp *op_backend;
-  SoupURI         *uri;
+  g_print ("basename:%s\n", basename);
 
-  /* FIXME: if SoupOutputStream supported chunked requests, we could
-   * use a PUT with "If-Match: ..." and "Expect: 100-continue"
-   */
+  /* read http/1.1 rfc, until then we copy the local files
+   * behaviour */ 
+  if (basename != NULL &&
+      g_file_attribute_matcher_matches (matcher,
+                                        G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME))
+    {
+      char *display_name = g_filename_display_name (basename);
 
-  op_backend = G_VFS_BACKEND_HTTP (backend);
+      if (strstr (display_name, "\357\277\275") != NULL)
+        {
+          char *p = display_name;
+          display_name = g_strconcat (display_name, _(" (invalid encoding)"), NULL);
+          g_free (p);
+        }
 
-  if (make_backup)
-    {
-      g_vfs_job_failed (G_VFS_JOB (job),
-                        G_IO_ERROR,
-                        G_IO_ERROR_CANT_CREATE_BACKUP,
-                        _("Backup file creation failed"));
-      return TRUE;
+      g_file_info_set_display_name (info, display_name);
+      g_free (display_name);
     }
 
+  if (basename != NULL &&
+      g_file_attribute_matcher_matches (matcher,
+                                        G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME))
+    {
+      char *edit_name = g_filename_display_name (basename);
+      g_file_info_set_edit_name (info, edit_name);
+      g_free (edit_name);
+    } 
 
+  g_free (basename);
 
-  uri = g_vfs_backend_uri_for_filename (backend, filename);
 
-  if (etag)
+  text = soup_message_headers_get (msg->response_headers,
+                                   "Content-Length");
+  if (text)
     {
-      SoupMessage *msg;
-
-      msg = soup_message_new_from_uri (SOUP_METHOD_HEAD, uri);
-      soup_uri_free (uri);
-      soup_message_headers_append (msg->request_headers, "User-Agent", "gvfs/" VERSION);
-      soup_message_headers_append (msg->request_headers, "If-Match", etag);
-
-      g_vfs_job_set_backend_data (G_VFS_JOB (job), op_backend, NULL);
-      soup_session_queue_message (op_backend->session, msg,
-                                  try_replace_checked_etag, job);
-      return TRUE;
+      guint64 size = g_ascii_strtoull (text, NULL, 10);
+      g_file_info_set_size (info, size);
     }
 
-  open_for_replace_succeeded (op_backend, G_VFS_JOB (job), uri, NULL);
-  soup_uri_free (uri);
-  return TRUE;
-}
-
-/* *** write () *** */
-static void
-write_ready (GObject      *source_object,
-             GAsyncResult *result,
-             gpointer      user_data)
-{
-  GOutputStream *stream;
-  GVfsJob       *job;
-  GError        *error;
-  gssize         nwrote;
-
-  stream = G_OUTPUT_STREAM (source_object); 
-  error  = NULL;
-  job    = G_VFS_JOB (user_data);
 
-  nwrote = g_output_stream_write_finish (stream, result, &error);
-
-  if (nwrote < 0)
-   {
-     g_vfs_job_failed (G_VFS_JOB (job),
-                       error->domain,
-                       error->code,
-                       error->message);
-
-     g_error_free (error);
-     return;
-   }
-
-  g_vfs_job_write_set_written_size (G_VFS_JOB_WRITE (job), nwrote);
-  g_vfs_job_succeeded (job);
-}
-
-static gboolean
-try_write (GVfsBackend *backend,
-           GVfsJobWrite *job,
-           GVfsBackendHandle handle,
-           char *buffer,
-           gsize buffer_size)
-{
-  GVfsBackendHttp *op_backend;
-  GOutputStream   *stream;
-
-  op_backend = G_VFS_BACKEND_HTTP (backend);
-  stream = G_OUTPUT_STREAM (handle);
-
-  g_output_stream_write_async (stream,
-                               buffer,
-                               buffer_size,
-                               G_PRIORITY_DEFAULT,
-                               G_VFS_JOB (job)->cancellable,
-                               write_ready,
-                               job);
-  return TRUE;
-}
-
-/* *** close_write () *** */
-static void
-close_write_ready (GObject      *source_object,
-                   GAsyncResult *result,
-                   gpointer      user_data)
-{
-  GOutputStream *stream;
-  GVfsJob       *job;
-  GError        *error;
-  gboolean       res;
-
-  job = G_VFS_JOB (user_data);
-  stream = G_OUTPUT_STREAM (source_object);
-  res = g_output_stream_close_finish (stream,
-                                      result,
-                                      &error);
-  if (res == FALSE)
+  text = soup_message_headers_get (msg->response_headers,
+                                   "Content-Type");
+  if (text)
     {
-      g_vfs_job_failed (G_VFS_JOB (job),
-                        error->domain,
-                        error->code,
-                        error->message);
+      char *p = strchr (text, ';');
 
-      g_error_free (error);
+      if (p != NULL)
+        {
+          char *tmp = g_strndup (text, p - text);
+          g_file_info_set_content_type (info, tmp);
+          g_free (tmp);
+        }
+      else
+        g_file_info_set_content_type (info, text);
     }
-  else
-    g_vfs_job_succeeded (job);
-
-  g_object_unref (stream);
-}
-
-static gboolean
-try_close_write (GVfsBackend *backend,
-                 GVfsJobCloseWrite *job,
-                 GVfsBackendHandle handle)
-{
-  GVfsBackendHttp *op_backend;
-  GOutputStream   *stream;
-
-  op_backend = G_VFS_BACKEND_HTTP (backend);
-  stream = G_OUTPUT_STREAM (handle);
-
-  g_output_stream_close_async (stream,
-                               G_PRIORITY_DEFAULT,
-                               G_VFS_JOB (job)->cancellable,
-                               close_write_ready,
-                               job);
-
-  return TRUE;
-}
 
-/* *** query_info () *** */
 
-static void 
-query_info_ready (GFileInfo *info,
-                  gpointer   user_data,
-                  GError    *error)
-{
-  GVfsJobQueryInfo *job;
+  text = soup_message_headers_get (msg->response_headers,
+                                   "Last-Modified");
+  if (text)
+    {
+      GTimeVal tv;
+      if (g_time_val_from_iso8601 (text, &tv))
+        g_file_info_set_modification_time (info, &tv);
+    }
 
-  job = G_VFS_JOB_QUERY_INFO (user_data);
 
-  if (info == NULL)
+  text = soup_message_headers_get (msg->response_headers,
+                                   "ETag");
+  if (text)
     {
-      g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
-      return;
+      g_file_info_set_attribute_string (info,
+                                        G_FILE_ATTRIBUTE_ETAG_VALUE,
+                                        text);
     }
-  
-  g_file_info_copy_into (info, job->file_info);
+
+
   g_vfs_job_succeeded (G_VFS_JOB (job));
 }
 
@@ -895,12 +579,15 @@
                 GFileInfo             *info,
                 GFileAttributeMatcher *attribute_matcher)
 {
-  stat_location (backend, 
-                 filename,
-                 flags,
-                 attribute_matcher, 
-                 query_info_ready,
-                 job);
+  GVfsBackendHttp *op_backend;
+  SoupMessage     *msg;
+
+  op_backend = G_VFS_BACKEND_HTTP (backend);
+
+  msg = message_new_from_filename (backend, "HEAD", filename);
+
+  soup_session_queue_message (op_backend->session, msg,
+                              query_info_ready, job);
   return TRUE;
 }
 
@@ -920,10 +607,6 @@
   backend_class->try_read          = try_read;
   backend_class->try_seek_on_read  = try_seek_on_read;
   backend_class->try_close_read    = try_close_read;
-  backend_class->try_create        = try_create;
-  backend_class->try_replace       = try_replace;
-  backend_class->try_write         = try_write;
-  backend_class->try_close_write   = try_close_write;
   backend_class->try_query_info    = try_query_info;
 
 }



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