[libsoup/new-io] Rewrite FTP handling on top of gvfs



commit 1b242976395a546318afae01fa1d2e577d977518
Author: Benjamin Otte <otte gnome org>
Date:   Sun Dec 20 23:27:35 2009 +0100

    Rewrite FTP handling on top of gvfs
    
    Caveat: mounting doesn't work yet, so unless you did gvfs-mount the
    server previously, ou'll get a "not mounted" error.

 libsoup/Makefile.am             |    6 -
 libsoup/soup-ftp-connection.c   | 1781 ---------------------------------------
 libsoup/soup-ftp-connection.h   |   54 --
 libsoup/soup-ftp-input-stream.c |  178 ----
 libsoup/soup-ftp-input-stream.h |   43 -
 libsoup/soup-request-file.c     |  110 +++-
 libsoup/soup-request-ftp.c      |  173 ----
 libsoup/soup-request-ftp.h      |   33 -
 libsoup/soup-session.c          |    3 +-
 9 files changed, 103 insertions(+), 2278 deletions(-)
---
diff --git a/libsoup/Makefile.am b/libsoup/Makefile.am
index b4cab41..c14fade 100644
--- a/libsoup/Makefile.am
+++ b/libsoup/Makefile.am
@@ -139,10 +139,6 @@ libsoup_2_4_la_SOURCES =		\
 	soup-directory-input-stream.h	\
 	soup-directory-input-stream.c	\
 	soup-form.c			\
-	soup-ftp-connection.h		\
-	soup-ftp-connection.c		\
-	soup-ftp-input-stream.h		\
-	soup-ftp-input-stream.c		\
 	soup-gnutls.c			\
 	soup-headers.c			\
 	soup-http-input-stream.h	\
@@ -173,8 +169,6 @@ libsoup_2_4_la_SOURCES =		\
 	soup-request-data.c		\
 	soup-request-file.h		\
 	soup-request-file.c		\
-	soup-request-ftp.h		\
-	soup-request-ftp.c		\
 	soup-request-http.h		\
 	soup-request-http.c		\
 	soup-server.c			\
diff --git a/libsoup/soup-request-file.c b/libsoup/soup-request-file.c
index 13bcc6b..2957754 100644
--- a/libsoup/soup-request-file.c
+++ b/libsoup/soup-request-file.c
@@ -52,24 +52,112 @@ soup_request_file_check_uri (SoupRequest  *request,
 			     SoupURI      *uri,
 			     GError      **error)
 {
-	SoupRequestFile *file = SOUP_REQUEST_FILE (request);
-	char *path_decoded;
-
 	/* "file:/foo" is not valid */
 	if (!uri->host)
 		return FALSE;
 
 	/* but it must be "file:///..." or "file://localhost/..." */
-	if (*uri->host && g_ascii_strcasecmp (uri->host, "localhost") != 0)
+	if (uri->scheme == SOUP_URI_SCHEME_FILE &&
+            *uri->host && 
+            g_ascii_strcasecmp (uri->host, "localhost") != 0)
 		return FALSE;
 
-	path_decoded = soup_uri_decode (uri->path);
-	file->priv->gfile = g_file_new_for_path (path_decoded);
-	g_free (path_decoded);
-
 	return TRUE;
 }
 
+static void
+soup_request_file_ftp_main_loop_quit (GObject      *object,
+                                      GAsyncResult *result,
+                                      gpointer      loop)
+{
+        g_main_loop_quit (loop);
+}
+
+/* This is a somewhat hacky way to get FTP to almost work. The proper way to
+ * get FTP to _really_ work involves hacking GIO to have APIs to handle 
+ * canoncial URLs.
+ */
+static GFile *
+soup_request_file_ensure_file_ftp (SoupURI       *uri,
+                                   GCancellable  *cancellable,
+                                   GError       **error)
+{
+        SoupURI *host;
+        char *s;
+        GFile *file, *result;
+        GMount *mount;
+
+        host = soup_uri_copy_host (uri);
+        s = soup_uri_to_string (host, FALSE);
+        file = g_file_new_for_uri (s);
+        soup_uri_free (host);
+        g_free (s);
+
+        mount = g_file_find_enclosing_mount (file, cancellable, error);
+        if (mount == NULL && g_file_supports_thread_contexts (file)) {
+              GMainContext *context = g_main_context_new ();
+              GMainLoop *loop = g_main_loop_new (context, FALSE);
+
+              g_clear_error (error);
+              g_main_context_push_thread_default (context);
+              g_file_mount_enclosing_volume (file,
+                                             G_MOUNT_MOUNT_NONE,
+                                             NULL, /* FIXME! */
+                                             cancellable,
+                                             soup_request_file_ftp_main_loop_quit,
+                                             loop);
+              g_main_loop_run (loop);
+              g_main_context_pop_thread_default (context);
+              g_main_loop_unref (loop);
+              g_main_context_unref (context);
+              mount = g_file_find_enclosing_mount (file, cancellable, error);
+        }
+        if (mount == NULL)
+              return NULL;
+        g_object_unref (file);
+        
+        file = g_mount_get_default_location (mount);
+        g_object_unref (mount);
+
+        s = g_strdup (uri->path);
+        if (strchr (s, ';'))
+          *strchr (s, ';') = 0;
+
+        result = g_file_resolve_relative_path (file, s);
+        g_free (s);
+        g_object_unref (file);
+
+        return result;
+}
+
+static gboolean
+soup_request_file_ensure_file (SoupRequestFile  *file,
+                               GCancellable     *cancellable,
+                               GError          **error)
+{
+        SoupURI *uri;
+
+        if (file->priv->gfile)
+                return TRUE;
+
+        uri = soup_request_get_uri (SOUP_REQUEST (file));
+        if (uri->scheme == SOUP_URI_SCHEME_FILE) {
+                char *path_decoded = soup_uri_decode (uri->path);
+                file->priv->gfile = g_file_new_for_path (path_decoded);
+                g_free (path_decoded);
+                return TRUE;
+        } else if (uri->scheme == SOUP_URI_SCHEME_FTP) {
+                file->priv->gfile = soup_request_file_ensure_file_ftp (uri,
+                                                                       cancellable,
+                                                                       error);
+                return file->priv->gfile != NULL;
+        }
+
+        g_set_error (error, SOUP_ERROR, SOUP_ERROR_UNSUPPORTED_URI_SCHEME,
+                     _("Unsupported URI scheme '%s'"), uri->scheme);
+        return FALSE;
+}
+
 static GInputStream *
 soup_request_file_send (SoupRequest          *request,
 			GCancellable         *cancellable,
@@ -79,6 +167,9 @@ soup_request_file_send (SoupRequest          *request,
         GInputStream *stream;
         GError *my_error = NULL;
 
+        if (!soup_request_file_ensure_file (file, cancellable, error))
+                return NULL;
+
 	file->priv->info = g_file_query_info (file->priv->gfile,
 					      G_FILE_ATTRIBUTE_STANDARD_TYPE ","
 					      G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
@@ -153,6 +244,9 @@ soup_request_file_send_finish (SoupRequest          *request,
 
         g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == soup_request_file_send_async);
 
+        if (g_simple_async_result_propagate_error (simple, error))
+                return NULL;
+
         return g_simple_async_result_get_op_res_gpointer (simple);
 }
 
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index 34c9bd5..ccb6f3e 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -29,7 +29,6 @@
 #include "soup-proxy-uri-resolver.h"
 #include "soup-request-data.h"
 #include "soup-request-file.h"
-#include "soup-request-ftp.h"
 #include "soup-request-http.h"
 #include "soup-session.h"
 #include "soup-session-feature.h"
@@ -2006,7 +2005,7 @@ init_request_types (SoupSessionPrivate *priv)
 	g_hash_table_insert (priv->request_types, g_strdup ("https"),
 			     GSIZE_TO_POINTER (SOUP_TYPE_REQUEST_HTTP));
 	g_hash_table_insert (priv->request_types, g_strdup ("ftp"),
-			     GSIZE_TO_POINTER (SOUP_TYPE_REQUEST_FTP));
+			     GSIZE_TO_POINTER (SOUP_TYPE_REQUEST_FILE));
 }
 
 /* RFC 2396, 3.1 */



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