[libsoup] Port SoupAddress to use GResolver, remove soup-dns
- From: Dan Winship <danw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [libsoup] Port SoupAddress to use GResolver, remove soup-dns
- Date: Mon, 10 Aug 2009 20:29:56 +0000 (UTC)
commit d689d9121bd743975fa1ab7e4bfdded51d36b015
Author: Dan Winship <danw gnome org>
Date: Sat Sep 27 18:55:35 2008 -0400
Port SoupAddress to use GResolver, remove soup-dns
configure.in | 4 +-
libsoup/Makefile.am | 2 -
libsoup/soup-address.c | 232 +++++++++---
libsoup/soup-cookie.c | 3 +-
libsoup/soup-dns.c | 729 ----------------------------------
libsoup/soup-dns.h | 39 --
libsoup/soup-proxy-resolver-static.c | 1 -
libsoup/soup-session.c | 9 +
8 files changed, 196 insertions(+), 823 deletions(-)
---
diff --git a/configure.in b/configure.in
index 265f064..9e00854 100644
--- a/configure.in
+++ b/configure.in
@@ -82,9 +82,9 @@ dnl ***********************
dnl *** Checks for glib ***
dnl ***********************
-AM_PATH_GLIB_2_0(2.15.3,,,gobject gthread gio)
+AM_PATH_GLIB_2_0(2.21.3,,,gobject gthread gio)
if test "$GLIB_LIBS" = ""; then
- AC_MSG_ERROR(GLIB 2.15.3 or later is required to build libsoup)
+ AC_MSG_ERROR(GLIB 2.21.3 or later is required to build libsoup)
fi
GLIB_CFLAGS="$GLIB_CFLAGS -DG_DISABLE_SINGLE_INCLUDES"
diff --git a/libsoup/Makefile.am b/libsoup/Makefile.am
index ace934d..d5b8be2 100644
--- a/libsoup/Makefile.am
+++ b/libsoup/Makefile.am
@@ -125,8 +125,6 @@ libsoup_2_4_la_SOURCES = \
soup-cookie-jar.c \
soup-cookie-jar-text.c \
soup-date.c \
- soup-dns.h \
- soup-dns.c \
soup-form.c \
soup-gnutls.c \
soup-headers.c \
diff --git a/libsoup/soup-address.c b/libsoup/soup-address.c
index 2041580..043bac2 100644
--- a/libsoup/soup-address.c
+++ b/libsoup/soup-address.c
@@ -16,8 +16,9 @@
#include <string.h>
#include <sys/types.h>
+#include <gio/gio.h>
+
#include "soup-address.h"
-#include "soup-dns.h"
#include "soup-enum-types.h"
#include "soup-marshal.h"
#include "soup-misc.h"
@@ -156,8 +157,6 @@ soup_address_class_init (SoupAddressClass *address_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (address_class);
- soup_dns_init ();
-
g_type_class_add_private (address_class, sizeof (SoupAddressPrivate));
/* virtual method override */
@@ -478,10 +477,23 @@ soup_address_get_sockaddr (SoupAddress *addr, int *len)
if (priv->sockaddr && len)
*len = SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (SOUP_ADDRESS_GET_FAMILY (priv));
-
return priv->sockaddr;
}
+static GInetAddress *
+soup_address_make_inet_address (SoupAddress *addr)
+{
+ SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
+ GSocketAddress *gsa;
+ GInetAddress *gia;
+
+ gsa = g_socket_address_new_from_native (priv->sockaddr,
+ SOUP_ADDRESS_FAMILY_SOCKADDR_SIZE (SOUP_ADDRESS_GET_FAMILY (priv)));
+ gia = g_inet_socket_address_get_address ((GInetSocketAddress *)gsa);
+ g_object_unref (gsa);
+ return gia;
+}
+
/**
* soup_address_get_physical:
* @addr: a #SoupAddress
@@ -502,8 +514,13 @@ soup_address_get_physical (SoupAddress *addr)
if (!priv->sockaddr)
return NULL;
- if (!priv->physical)
- priv->physical = soup_dns_ntop (priv->sockaddr);
+ if (!priv->physical) {
+ GInetAddress *gia;
+
+ gia = soup_address_make_inet_address (addr);
+ priv->physical = g_inet_address_to_string (gia);
+ g_object_unref (gia);
+ }
return priv->physical;
}
@@ -525,47 +542,122 @@ soup_address_get_port (SoupAddress *addr)
}
-static void
-update_address (SoupAddress *addr, SoupDNSLookup *lookup)
+static guint
+update_addrs (SoupAddress *addr, GList *addrs, GError *error)
{
SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
+ GInetAddress *gia;
+ GSocketAddress *gsa;
+ gsize len;
+
+ if (error) {
+ if (error->domain == G_IO_ERROR &&
+ error->code == G_IO_ERROR_CANCELLED)
+ return SOUP_STATUS_CANCELLED;
+ else
+ return SOUP_STATUS_CANT_RESOLVE;
+ } else if (!addrs)
+ return SOUP_STATUS_CANT_RESOLVE;
+ else if (priv->sockaddr)
+ return SOUP_STATUS_OK;
- if (!priv->name)
- priv->name = soup_dns_lookup_get_hostname (lookup);
+ gia = addrs->data;
+ gsa = g_inet_socket_address_new (gia, priv->port);
- if (!priv->sockaddr) {
- priv->sockaddr = soup_dns_lookup_get_address (lookup);
- SOUP_ADDRESS_SET_PORT (priv, htons (priv->port));
- }
+ len = g_socket_address_get_native_size (gsa);
+ priv->sockaddr = g_malloc (len);
+ g_socket_address_to_native (gsa, priv->sockaddr, len, NULL);
+
+ return SOUP_STATUS_OK;
+}
+
+static guint
+update_name (SoupAddress *addr, const char *name, GError *error)
+{
+ SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
+
+ if (error) {
+ if (error->domain == G_IO_ERROR &&
+ error->code == G_IO_ERROR_CANCELLED)
+ return SOUP_STATUS_CANCELLED;
+ else
+ return SOUP_STATUS_CANT_RESOLVE;
+ } else if (!name)
+ return SOUP_STATUS_CANT_RESOLVE;
+ else if (priv->name)
+ return SOUP_STATUS_OK;
+
+ priv->name = g_strdup (name);
+ return SOUP_STATUS_OK;
}
typedef struct {
SoupAddress *addr;
SoupAddressCallback callback;
gpointer callback_data;
+ gboolean lookup_name;
+
+ GMainContext *async_context;
+ GCancellable *cancellable;
+ guint status;
} SoupAddressResolveAsyncData;
static void
-lookup_resolved (SoupDNSLookup *lookup, guint status, gpointer user_data)
+complete_resolve_async (SoupAddressResolveAsyncData *res_data)
{
- SoupAddressResolveAsyncData *res_data = user_data;
- SoupAddress *addr;
- SoupAddressCallback callback;
- gpointer callback_data;
-
- addr = res_data->addr;
- callback = res_data->callback;
- callback_data = res_data->callback_data;
- g_free (res_data);
-
- if (status == SOUP_STATUS_OK)
- update_address (addr, lookup);
+ SoupAddress *addr = res_data->addr;
+ SoupAddressCallback callback = res_data->callback;
+ gpointer callback_data = res_data->callback_data;
if (callback)
- callback (addr, status, callback_data);
+ callback (addr, res_data->status, callback_data);
+
+ if (res_data->async_context)
+ g_main_context_unref (res_data->async_context);
+ if (res_data->cancellable)
+ g_object_unref (res_data->cancellable);
g_object_unref (addr);
- soup_dns_lookup_free (lookup);
+ g_slice_free (SoupAddressResolveAsyncData, res_data);
+}
+
+static void
+lookup_resolved (GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ GResolver *resolver = G_RESOLVER (source);
+ SoupAddressResolveAsyncData *res_data = user_data;
+ SoupAddress *addr = res_data->addr;
+ SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr);
+ GError *error = NULL;
+
+ if (!priv->sockaddr) {
+ GList *addrs;
+
+ addrs = g_resolver_lookup_by_name_finish (resolver, result,
+ &error);
+ res_data->status = update_addrs (addr, addrs, error);
+ g_resolver_free_addresses (addrs);
+ } else if (!priv->name) {
+ char *name;
+
+ name = g_resolver_lookup_by_address_finish (resolver, result,
+ &error);
+ res_data->status = update_name (addr, name, error);
+ g_free (name);
+ } else
+ res_data->status = SOUP_STATUS_OK;
+
+ if (error)
+ g_error_free (error);
+
+ complete_resolve_async (res_data);
+}
+
+static gboolean
+idle_complete_resolve (gpointer res_data)
+{
+ complete_resolve_async (res_data);
+ return FALSE;
}
/**
@@ -603,22 +695,48 @@ soup_address_resolve_async (SoupAddress *addr, GMainContext *async_context,
{
SoupAddressPrivate *priv;
SoupAddressResolveAsyncData *res_data;
- SoupDNSLookup *lookup;
+ GResolver *resolver;
g_return_if_fail (SOUP_IS_ADDRESS (addr));
priv = SOUP_ADDRESS_GET_PRIVATE (addr);
+ g_return_if_fail (priv->name || priv->sockaddr);
- res_data = g_new (SoupAddressResolveAsyncData, 1);
+ res_data = g_slice_new0 (SoupAddressResolveAsyncData);
res_data->addr = g_object_ref (addr);
res_data->callback = callback;
res_data->callback_data = user_data;
- if (priv->name)
- lookup = soup_dns_lookup_name (priv->name);
- else
- lookup = soup_dns_lookup_address (priv->sockaddr);
- soup_dns_lookup_resolve_async (lookup, async_context, cancellable,
- lookup_resolved, res_data);
+ if (priv->name && priv->sockaddr) {
+ res_data->status = SOUP_STATUS_OK;
+ soup_add_completion (async_context, idle_complete_resolve, res_data);
+ return;
+ }
+
+ resolver = g_resolver_get_default ();
+
+ if (async_context && async_context != g_main_context_default ())
+ g_main_context_push_thread_default (async_context);
+
+ if (priv->name) {
+ res_data->lookup_name = TRUE;
+ g_resolver_lookup_by_name_async (resolver, priv->name,
+ cancellable,
+ lookup_resolved, res_data);
+ } else {
+ GInetAddress *gia;
+
+ res_data->lookup_name = FALSE;
+ gia = soup_address_make_inet_address (addr);
+ g_resolver_lookup_by_address_async (resolver, gia,
+ cancellable,
+ lookup_resolved, res_data);
+ g_object_unref (gia);
+ }
+
+ if (async_context && async_context != g_main_context_default ())
+ g_main_context_pop_thread_default (async_context);
+
+ g_object_unref (resolver);
}
/**
@@ -640,22 +758,40 @@ guint
soup_address_resolve_sync (SoupAddress *addr, GCancellable *cancellable)
{
SoupAddressPrivate *priv;
- SoupDNSLookup *lookup;
+ GResolver *resolver;
+ GError *error = NULL;
guint status;
g_return_val_if_fail (SOUP_IS_ADDRESS (addr), SOUP_STATUS_MALFORMED);
priv = SOUP_ADDRESS_GET_PRIVATE (addr);
+ g_return_val_if_fail (priv->name || priv->sockaddr, SOUP_STATUS_MALFORMED);
+
+ resolver = g_resolver_get_default ();
+
+ if (!priv->sockaddr) {
+ GList *addrs;
+
+ addrs = g_resolver_lookup_by_name (resolver, priv->name,
+ cancellable, &error);
+ status = update_addrs (addr, addrs, error);
+ g_resolver_free_addresses (addrs);
+ } else if (!priv->name) {
+ GInetAddress *gia;
+ char *name;
+
+ gia = soup_address_make_inet_address (addr);
+ name = g_resolver_lookup_by_address (resolver, gia,
+ cancellable, &error);
+ g_object_unref (gia);
+ status = update_name (addr, name, error);
+ g_free (name);
+ } else
+ status = SOUP_STATUS_OK;
+
+ if (error)
+ g_error_free (error);
+ g_object_unref (resolver);
- g_object_ref (addr);
- if (priv->name)
- lookup = soup_dns_lookup_name (priv->name);
- else
- lookup = soup_dns_lookup_address (priv->sockaddr);
- status = soup_dns_lookup_resolve (lookup, cancellable);
- if (status == SOUP_STATUS_OK)
- update_address (addr, lookup);
- g_object_unref (addr);
- soup_dns_lookup_free (lookup);
return status;
}
diff --git a/libsoup/soup-cookie.c b/libsoup/soup-cookie.c
index 5e18bd0..92eb385 100644
--- a/libsoup/soup-cookie.c
+++ b/libsoup/soup-cookie.c
@@ -14,7 +14,6 @@
#include "soup-cookie.h"
#include "soup-date.h"
-#include "soup-dns.h"
#include "soup-headers.h"
#include "soup-message.h"
#include "soup-message-headers.h"
@@ -359,7 +358,7 @@ parse_one_cookie (const char **header_p, SoupURI *origin)
/* If the domain string isn't an IP addr, and doesn't
* start with a '.', prepend one.
*/
- if (!soup_dns_is_ip_address (cookie->domain) &&
+ if (!g_hostname_is_ip_address (cookie->domain) &&
cookie->domain[0] != '.') {
char *tmp = g_strdup_printf (".%s", cookie->domain);
g_free (cookie->domain);
diff --git a/libsoup/soup-proxy-resolver-static.c b/libsoup/soup-proxy-resolver-static.c
index 575eac1..cf1fd29 100644
--- a/libsoup/soup-proxy-resolver-static.c
+++ b/libsoup/soup-proxy-resolver-static.c
@@ -13,7 +13,6 @@
#include "soup-proxy-resolver-static.h"
#include "soup-address.h"
-#include "soup-dns.h"
#include "soup-message.h"
#include "soup-misc.h"
#include "soup-session-feature.h"
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index e436387..cdb2bf8 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -90,6 +90,8 @@ typedef struct {
GMutex *host_lock;
GMainContext *async_context;
+
+ GResolver *resolver;
} SoupSessionPrivate;
#define SOUP_SESSION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_SESSION, SoupSessionPrivate))
@@ -174,6 +176,11 @@ soup_session_init (SoupSession *session)
soup_auth_manager_add_type (auth_manager, SOUP_TYPE_AUTH_DIGEST);
soup_session_add_feature (session, SOUP_SESSION_FEATURE (auth_manager));
g_object_unref (auth_manager);
+
+ /* We'll be doing DNS continuously-ish while the session is active,
+ * so hold a ref on the default GResolver.
+ */
+ priv->resolver = g_resolver_get_default ();
}
static void
@@ -212,6 +219,8 @@ finalize (GObject *object)
g_hash_table_destroy (priv->features_cache);
+ g_object_unref (priv->resolver);
+
G_OBJECT_CLASS (soup_session_parent_class)->finalize (object);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]