summaryrefslogtreecommitdiff
path: root/daemon/gvfsbackenddav.c
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2008-12-01 09:24:00 +0000
committerAlexander Larsson <alexl@src.gnome.org>2008-12-01 09:24:00 +0000
commitf8875b2649a0f85624e0da7df96fa6d47840c4a9 (patch)
treedf7f32b8849652f03b597aead9f1b56d697d806a /daemon/gvfsbackenddav.c
parent6e89574f1656ff71f5aba339ff38e8e0417b172b (diff)
downloadgvfs-f8875b2649a0f85624e0da7df96fa6d47840c4a9.tar.gz
Added. Added. Added. Added.
2008-12-01 Alexander Larsson <alexl@redhat.com> * common/Makefile.am: * common/gvfsdnssdresolver.c: Added. * common/gvfsdnssdresolver.h: Added. * common/gvfsdnssdutils.c: Added. * common/gvfsdnssdutils.h: Added. * daemon/Makefile.am: * daemon/dav+sd.mount.in: Added. * daemon/dav.mount.in: * daemon/gvfsbackenddav.c: * daemon/gvfsbackenddnssd.c: * daemon/gvfsbackendnetwork.c: For references to dns-sd dav services, use a dav+sd: uri, since this is stable over e.g. port changes and as such work better in e.g. bookmarks. Patch from David Zeuthen (#555436) svn path=/trunk/; revision=2112
Diffstat (limited to 'daemon/gvfsbackenddav.c')
-rw-r--r--daemon/gvfsbackenddav.c152
1 files changed, 146 insertions, 6 deletions
diff --git a/daemon/gvfsbackenddav.c b/daemon/gvfsbackenddav.c
index 24c2b34c..a693ac90 100644
--- a/daemon/gvfsbackenddav.c
+++ b/daemon/gvfsbackenddav.c
@@ -61,10 +61,20 @@
#include "soup-input-stream.h"
#include "soup-output-stream.h"
+#ifdef HAVE_AVAHI
+#include "gvfsdnssdutils.h"
+#include "gvfsdnssdresolver.h"
+#endif
+
typedef struct _MountAuthData MountAuthData;
static void mount_auth_info_free (MountAuthData *info);
+
+#ifdef HAVE_AVAHI
+static void dns_sd_resolver_changed (GVfsDnsSdResolver *resolver, GVfsBackendDav *dav_backend);
+#endif
+
typedef struct _AuthInfo {
/* for server authentication */
@@ -91,6 +101,11 @@ struct _GVfsBackendDav
GVfsBackendHttp parent_instance;
MountAuthData auth_info;
+
+#ifdef HAVE_AVAHI
+ /* only set if we're handling a [dav|davs]+sd:// mounts */
+ GVfsDnsSdResolver *resolver;
+#endif
};
G_DEFINE_TYPE (GVfsBackendDav, g_vfs_backend_dav, G_VFS_TYPE_BACKEND_HTTP);
@@ -102,6 +117,14 @@ g_vfs_backend_dav_finalize (GObject *object)
dav_backend = G_VFS_BACKEND_DAV (object);
+#ifdef HAVE_AVAHI
+ if (dav_backend->resolver != NULL)
+ {
+ g_signal_handlers_disconnect_by_func (dav_backend->resolver, dns_sd_resolver_changed, dav_backend);
+ g_object_unref (dav_backend->resolver);
+ }
+#endif
+
mount_auth_info_free (&(dav_backend->auth_info));
if (G_OBJECT_CLASS (g_vfs_backend_dav_parent_class)->finalize)
@@ -209,10 +232,10 @@ path_equal (const char *a, const char *b, gboolean relax)
a_len = strlen (a);
b_len = strlen (b);
- while (a[a_len - 1] == '/')
+ while (a_len > 0 && a[a_len - 1] == '/')
a_len--;
- while (b[b_len - 1] == '/')
+ while (b_len > 0 && b[b_len - 1] == '/')
b_len--;
if (a_len == b_len)
@@ -1392,11 +1415,32 @@ g_mount_spec_to_dav_uri (GMountSpec *spec)
}
static GMountSpec *
-g_mount_spec_from_dav_uri (SoupURI *uri)
+g_mount_spec_from_dav_uri (GVfsBackendDav *dav_backend,
+ SoupURI *uri)
{
GMountSpec *spec;
const char *ssl;
+#ifdef HAVE_AVAHI
+ if (dav_backend->resolver != NULL)
+ {
+ const char *type;
+ const char *service_type;
+
+ service_type = g_vfs_dns_sd_resolver_get_service_type (dav_backend->resolver);
+ if (strcmp (service_type, "_webdavs._tcp") == 0)
+ type = "davs+sd";
+ else
+ type = "dav+sd";
+
+ spec = g_mount_spec_new (type);
+ g_mount_spec_set (spec,
+ "host",
+ g_vfs_dns_sd_resolver_get_encoded_triple (dav_backend->resolver));
+ return spec;
+ }
+#endif
+
spec = g_mount_spec_new ("dav");
g_mount_spec_set (spec, "host", uri->host);
@@ -1423,6 +1467,63 @@ g_mount_spec_from_dav_uri (SoupURI *uri)
return spec;
}
+#ifdef HAVE_AVAHI
+static SoupURI *
+dav_uri_from_dns_sd_resolver (GVfsBackendDav *dav_backend)
+{
+ SoupURI *uri;
+ char *user;
+ char *path;
+ char *address;
+ const char *service_type;
+ guint port;
+
+ service_type = g_vfs_dns_sd_resolver_get_service_type (dav_backend->resolver);
+ address = g_vfs_dns_sd_resolver_get_address (dav_backend->resolver);
+ port = g_vfs_dns_sd_resolver_get_port (dav_backend->resolver);
+ user = g_vfs_dns_sd_resolver_lookup_txt_record (dav_backend->resolver, "u"); /* mandatory */
+ path = g_vfs_dns_sd_resolver_lookup_txt_record (dav_backend->resolver, "path"); /* optional */
+
+ /* TODO: According to http://www.dns-sd.org/ServiceTypes.html
+ * there's also a TXT record "p" for password. Handle this.
+ */
+
+ uri = soup_uri_new (NULL);
+
+ if (strcmp (service_type, "_webdavs._tcp") == 0)
+ soup_uri_set_scheme (uri, SOUP_URI_SCHEME_HTTPS);
+ else
+ soup_uri_set_scheme (uri, SOUP_URI_SCHEME_HTTP);
+
+ soup_uri_set_user (uri, user);
+
+ soup_uri_set_port (uri, port);
+
+ soup_uri_set_host (uri, address);
+
+ if (path != NULL)
+ soup_uri_set_path (uri, path);
+ else
+ soup_uri_set_path (uri, "/");
+
+
+ g_free (address);
+ g_free (user);
+ g_free (path);
+
+ return uri;
+}
+#endif
+
+#ifdef HAVE_AVAHI
+static void
+dns_sd_resolver_changed (GVfsDnsSdResolver *resolver,
+ GVfsBackendDav *dav_backend)
+{
+ /* TODO: handle when DNS-SD data changes */
+}
+#endif
+
/* ************************************************************************* */
/* Backend Functions */
static void
@@ -1432,6 +1533,7 @@ do_mount (GVfsBackend *backend,
GMountSource *mount_source,
gboolean is_automount)
{
+ GVfsBackendDav *dav_backend = G_VFS_BACKEND_DAV (backend);
MountAuthData *data;
SoupSession *session;
SoupMessage *msg_opts;
@@ -1444,10 +1546,43 @@ do_mount (GVfsBackend *backend,
gboolean res;
char *last_good_path;
char *display_name;
+ const char *host;
+ const char *type;
g_print ("+ mount\n");
- mount_base = g_mount_spec_to_dav_uri (mount_spec);
+ host = g_mount_spec_get (mount_spec, "host");
+ type = g_mount_spec_get (mount_spec, "type");
+
+#ifdef HAVE_AVAHI
+ /* resolve DNS-SD style URIs */
+ if ((strcmp (type, "dav+sd") == 0 || strcmp (type, "davs+sd") == 0) && host != NULL)
+ {
+ GError *error;
+
+ dav_backend->resolver = g_vfs_dns_sd_resolver_new_for_encoded_triple (host, "u");
+
+ error = NULL;
+ if (!g_vfs_dns_sd_resolver_resolve_sync (dav_backend->resolver,
+ NULL,
+ &error))
+ {
+ g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
+ g_error_free (error);
+ return;
+ }
+ g_signal_connect (dav_backend->resolver,
+ "changed",
+ (GCallback) dns_sd_resolver_changed,
+ dav_backend);
+
+ mount_base = dav_uri_from_dns_sd_resolver (dav_backend);
+ }
+ else
+#endif
+ {
+ mount_base = g_mount_spec_to_dav_uri (mount_spec);
+ }
if (mount_base == NULL)
{
@@ -1546,12 +1681,17 @@ do_mount (GVfsBackend *backend,
mount_base->path = last_good_path;
/* dup the mountspec, but only copy known fields */
- mount_spec = g_mount_spec_from_dav_uri (mount_base);
+ mount_spec = g_mount_spec_from_dav_uri (dav_backend, mount_base);
g_vfs_backend_set_mount_spec (backend, mount_spec);
g_vfs_backend_set_icon_name (backend, "folder-remote");
- display_name = g_strdup_printf (_("WebDAV on %s"), mount_base->host);
+#ifdef HAVE_AVAHI
+ if (dav_backend->resolver != NULL)
+ display_name = g_strdup (g_vfs_dns_sd_resolver_get_service_name (dav_backend->resolver));
+ else
+#endif
+ display_name = g_strdup_printf (_("WebDAV on %s"), mount_base->host);
g_vfs_backend_set_display_name (backend, display_name);
g_free (display_name);