mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-23 22:16:16 +01:00
Adding GProxyAddressEnumerator class
An implementation of GSocketAddressEnumerator that handles proxy enumeration. This class is mainly usefull for Connectables implementation such as NetworkService, NetworkAddress and SocketAddress to handle proxies. Reviewed-by: Dan Winship <danw@gnome.org>
This commit is contained in:
parent
d76de5e359
commit
a7e0e8fc08
@ -1638,6 +1638,8 @@ GSocketAddressEnumerator
|
||||
g_socket_address_enumerator_next
|
||||
g_socket_address_enumerator_next_async
|
||||
g_socket_address_enumerator_next_finish
|
||||
<SUBSECTION>
|
||||
GProxyAddressEnumerator
|
||||
<SUBSECTION Standard>
|
||||
G_IS_SOCKET_CONNECTABLE
|
||||
G_SOCKET_CONNECTABLE
|
||||
@ -1650,7 +1652,16 @@ G_SOCKET_ADDRESS_ENUMERATOR
|
||||
G_SOCKET_ADDRESS_ENUMERATOR_CLASS
|
||||
G_SOCKET_ADDRESS_ENUMERATOR_GET_CLASS
|
||||
G_TYPE_SOCKET_ADDRESS_ENUMERATOR
|
||||
GProxyAddressEnumeratorClass
|
||||
G_IS_PROXY_ADDRESS_ENUMERATOR
|
||||
G_IS_PROXY_ADDRESS_ENUMERATOR_CLASS
|
||||
G_PROXY_ADDRESS_ENUMERATOR
|
||||
G_PROXY_ADDRESS_ENUMERATOR_CLASS
|
||||
G_PROXY_ADDRESS_ENUMERATOR_GET_CLASS
|
||||
G_TYPE_PROXY_ADDRESS_ENUMERATOR
|
||||
<SUBSECTION Private>
|
||||
GProxyAddressEnumeratorPrivate
|
||||
g_proxy_address_enumerator_get_type
|
||||
g_socket_address_enumerator_get_type
|
||||
g_socket_connectable_get_type
|
||||
</SECTION>
|
||||
|
@ -75,6 +75,7 @@ g_output_stream_get_type
|
||||
g_output_stream_splice_flags_get_type
|
||||
g_password_save_get_type
|
||||
g_permission_get_type
|
||||
g_proxy_address_enumerator_get_type
|
||||
g_proxy_address_get_type
|
||||
g_proxy_get_type
|
||||
g_proxy_resolver_get_type
|
||||
|
@ -352,6 +352,7 @@ libgio_2_0_la_SOURCES = \
|
||||
gsocketoutputstream.h \
|
||||
gproxy.c \
|
||||
gproxyaddress.c \
|
||||
gproxyaddressenumerator.c \
|
||||
gsocketservice.c \
|
||||
gsrvtarget.c \
|
||||
gtcpconnection.c \
|
||||
@ -485,6 +486,7 @@ gio_headers = \
|
||||
gpermission.h \
|
||||
gproxyaddress.h \
|
||||
gproxy.h \
|
||||
gproxyaddressenumerator.h \
|
||||
gproxyresolver.h \
|
||||
gresolver.h \
|
||||
gseekable.h \
|
||||
|
@ -94,6 +94,7 @@
|
||||
#include <gio/gpermission.h>
|
||||
#include <gio/gproxy.h>
|
||||
#include <gio/gproxyaddress.h>
|
||||
#include <gio/gproxyaddressenumerator.h>
|
||||
#include <gio/gproxyresolver.h>
|
||||
#include <gio/gresolver.h>
|
||||
#include <gio/gseekable.h>
|
||||
|
@ -1162,6 +1162,12 @@ g_proxy_address_get_password
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__G_PROXY_ADDRESS_ENUMERATOR_H__)
|
||||
#if IN_FILE(__G_PROXY_ADDRESS_ENUMERATOR_C__)
|
||||
g_proxy_address_enumerator_get_type
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__G_RESOLVER_H__)
|
||||
#if IN_FILE(__G_RESOLVER_C__)
|
||||
g_resolver_error_quark
|
||||
|
@ -208,6 +208,7 @@ typedef struct _GVfs GVfs; /* Dummy typedef */
|
||||
typedef struct _GProxyResolver GProxyResolver;
|
||||
typedef struct _GProxy GProxy;
|
||||
typedef struct _GProxyAddress GProxyAddress;
|
||||
typedef struct _GProxyAddressEnumerator GProxyAddressEnumerator;
|
||||
|
||||
/**
|
||||
* GVolume:
|
||||
|
728
gio/gproxyaddressenumerator.c
Normal file
728
gio/gproxyaddressenumerator.c
Normal file
@ -0,0 +1,728 @@
|
||||
/* GIO - GLib Input, Output and Streaming Library
|
||||
*
|
||||
* Copyright (C) 2010 Collabora, Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "gproxyaddressenumerator.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "gasyncresult.h"
|
||||
#include "ginetaddress.h"
|
||||
#include "glibintl.h"
|
||||
#include "gnetworkaddress.h"
|
||||
#include "gnetworkingprivate.h"
|
||||
#include "gproxy.h"
|
||||
#include "gproxyaddress.h"
|
||||
#include "gproxyresolver.h"
|
||||
#include "gsimpleasyncresult.h"
|
||||
#include "gresolver.h"
|
||||
#include "gsocketaddress.h"
|
||||
#include "gsocketaddressenumerator.h"
|
||||
#include "gsocketconnectable.h"
|
||||
|
||||
G_DEFINE_TYPE (GProxyAddressEnumerator, g_proxy_address_enumerator, G_TYPE_SOCKET_ADDRESS_ENUMERATOR);
|
||||
|
||||
#define GET_PRIVATE(o) (G_PROXY_ADDRESS_ENUMERATOR (o)->priv)
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_URI,
|
||||
PROP_CONNECTABLE
|
||||
};
|
||||
|
||||
struct _GProxyAddressEnumeratorPrivate
|
||||
{
|
||||
/* Destination address */
|
||||
GSocketConnectable *connectable;
|
||||
gchar *dest_uri;
|
||||
gchar *dest_hostname;
|
||||
guint16 dest_port;
|
||||
GList *dest_ips;
|
||||
|
||||
/* Proxy enumeration */
|
||||
gchar **proxies;
|
||||
gchar **next_proxy;
|
||||
GSocketAddressEnumerator *addr_enum;
|
||||
GSocketAddress *proxy_address;
|
||||
gchar *proxy_type;
|
||||
gchar *proxy_username;
|
||||
gchar *proxy_password;
|
||||
gboolean supports_hostname;
|
||||
GList *next_dest_ip;
|
||||
|
||||
/* Async attributes */
|
||||
GSimpleAsyncResult *simple;
|
||||
GCancellable *cancellable;
|
||||
};
|
||||
|
||||
static void
|
||||
save_userinfo (GProxyAddressEnumeratorPrivate *priv,
|
||||
const gchar *proxy)
|
||||
{
|
||||
gchar *userinfo;
|
||||
|
||||
if (priv->proxy_username)
|
||||
{
|
||||
g_free (priv->proxy_username);
|
||||
priv->proxy_username = NULL;
|
||||
}
|
||||
|
||||
if (priv->proxy_password)
|
||||
{
|
||||
g_free (priv->proxy_password);
|
||||
priv->proxy_password = NULL;
|
||||
}
|
||||
|
||||
if (_g_uri_parse_authority (proxy, NULL, NULL, &userinfo))
|
||||
{
|
||||
if (userinfo)
|
||||
{
|
||||
gchar **split = g_strsplit (userinfo, ":", 2);
|
||||
|
||||
if (split[0] != NULL)
|
||||
{
|
||||
priv->proxy_username = g_uri_unescape_string (split[0], NULL);
|
||||
if (split[1] != NULL)
|
||||
priv->proxy_password = g_uri_unescape_string (split[1], NULL);
|
||||
}
|
||||
|
||||
g_strfreev (split);
|
||||
g_free (userinfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
next_enumerator (GProxyAddressEnumeratorPrivate *priv)
|
||||
{
|
||||
if (priv->proxy_address)
|
||||
return;
|
||||
|
||||
while (priv->addr_enum == NULL && *priv->next_proxy)
|
||||
{
|
||||
GSocketConnectable *connectable = NULL;
|
||||
const gchar *proxy_uri;
|
||||
GProxy *proxy;
|
||||
|
||||
proxy_uri = *priv->next_proxy++;
|
||||
g_free (priv->proxy_type);
|
||||
priv->proxy_type = g_uri_parse_scheme (proxy_uri);
|
||||
|
||||
if (priv->proxy_type == NULL)
|
||||
continue;
|
||||
|
||||
/* Assumes hostnames are supported for unkown protocols */
|
||||
priv->supports_hostname = TRUE;
|
||||
proxy = g_proxy_get_default_for_protocol (priv->proxy_type);
|
||||
if (proxy)
|
||||
{
|
||||
priv->supports_hostname = g_proxy_supports_hostname (proxy);
|
||||
g_object_unref (proxy);
|
||||
}
|
||||
|
||||
if (strcmp ("direct", priv->proxy_type) == 0)
|
||||
{
|
||||
if (priv->connectable)
|
||||
connectable = g_object_ref (priv->connectable);
|
||||
else
|
||||
connectable = g_network_address_new (priv->dest_hostname,
|
||||
priv->dest_port);
|
||||
}
|
||||
else
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
connectable = g_network_address_parse_uri (proxy_uri, 0, &error);
|
||||
|
||||
if (error)
|
||||
{
|
||||
g_warning ("Invalid proxy URI '%s': %s",
|
||||
proxy_uri, error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
save_userinfo (priv, proxy_uri);
|
||||
}
|
||||
|
||||
if (connectable)
|
||||
{
|
||||
priv->addr_enum = g_socket_connectable_enumerate (connectable);
|
||||
g_object_unref (connectable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static GSocketAddress *
|
||||
g_proxy_address_enumerator_next (GSocketAddressEnumerator *enumerator,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
GProxyAddressEnumeratorPrivate *priv = GET_PRIVATE (enumerator);
|
||||
GSocketAddress *result = NULL;
|
||||
GError *first_error = NULL;
|
||||
|
||||
if (priv->proxies == NULL)
|
||||
{
|
||||
GProxyResolver *resolver = g_proxy_resolver_get_default ();
|
||||
priv->proxies = g_proxy_resolver_lookup (resolver,
|
||||
priv->dest_uri,
|
||||
cancellable,
|
||||
error);
|
||||
priv->next_proxy = priv->proxies;
|
||||
|
||||
if (priv->proxies == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (result == NULL && (*priv->next_proxy || priv->addr_enum))
|
||||
{
|
||||
gchar *dest_hostname;
|
||||
GInetSocketAddress *inetsaddr;
|
||||
GInetAddress *inetaddr;
|
||||
guint16 port;
|
||||
|
||||
next_enumerator (priv);
|
||||
|
||||
if (!priv->addr_enum)
|
||||
continue;
|
||||
|
||||
if (priv->proxy_address == NULL)
|
||||
{
|
||||
priv->proxy_address = g_socket_address_enumerator_next (
|
||||
priv->addr_enum,
|
||||
cancellable,
|
||||
first_error ? NULL : &first_error);
|
||||
}
|
||||
|
||||
if (priv->proxy_address == NULL)
|
||||
{
|
||||
g_object_unref (priv->addr_enum);
|
||||
priv->addr_enum = NULL;
|
||||
|
||||
if (priv->dest_ips)
|
||||
{
|
||||
g_resolver_free_addresses (priv->dest_ips);
|
||||
priv->dest_ips = NULL;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp ("direct", priv->proxy_type) == 0)
|
||||
{
|
||||
result = priv->proxy_address;
|
||||
priv->proxy_address = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!priv->supports_hostname)
|
||||
{
|
||||
GInetAddress *dest_ip;
|
||||
|
||||
if (!priv->dest_ips)
|
||||
{
|
||||
GResolver *resolver;
|
||||
|
||||
resolver = g_resolver_get_default();
|
||||
priv->dest_ips = g_resolver_lookup_by_name (resolver,
|
||||
priv->dest_hostname,
|
||||
cancellable,
|
||||
first_error ? NULL : &first_error);
|
||||
g_object_unref (resolver);
|
||||
|
||||
if (!priv->dest_ips)
|
||||
{
|
||||
g_object_unref (priv->proxy_address);
|
||||
priv->proxy_address = NULL;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!priv->next_dest_ip)
|
||||
priv->next_dest_ip = priv->dest_ips;
|
||||
|
||||
dest_ip = G_INET_ADDRESS (priv->next_dest_ip->data);
|
||||
dest_hostname = g_inet_address_to_string (dest_ip);
|
||||
|
||||
priv->next_dest_ip = g_list_next (priv->next_dest_ip);
|
||||
}
|
||||
else
|
||||
{
|
||||
dest_hostname = g_strdup (priv->dest_hostname);
|
||||
}
|
||||
|
||||
|
||||
g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (priv->proxy_address),
|
||||
NULL);
|
||||
|
||||
inetsaddr = G_INET_SOCKET_ADDRESS (priv->proxy_address);
|
||||
inetaddr = g_inet_socket_address_get_address (inetsaddr);
|
||||
port = g_inet_socket_address_get_port (inetsaddr);
|
||||
|
||||
result = g_proxy_address_new (inetaddr, port,
|
||||
priv->proxy_type,
|
||||
dest_hostname, priv->dest_port,
|
||||
priv->proxy_username,
|
||||
priv->proxy_password);
|
||||
|
||||
g_free (dest_hostname);
|
||||
|
||||
if (priv->supports_hostname || priv->next_dest_ip == NULL)
|
||||
{
|
||||
g_object_unref (priv->proxy_address);
|
||||
priv->proxy_address = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == NULL && first_error)
|
||||
g_propagate_error (error, first_error);
|
||||
else if (first_error)
|
||||
g_error_free (first_error);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
complete_async (GProxyAddressEnumeratorPrivate *priv)
|
||||
{
|
||||
GSimpleAsyncResult *simple = priv->simple;
|
||||
|
||||
if (priv->cancellable)
|
||||
{
|
||||
g_object_unref (priv->cancellable);
|
||||
priv->cancellable = NULL;
|
||||
}
|
||||
|
||||
priv->simple = NULL;
|
||||
g_simple_async_result_complete (simple);
|
||||
g_object_unref (simple);
|
||||
}
|
||||
|
||||
static void
|
||||
save_result (GProxyAddressEnumeratorPrivate *priv)
|
||||
{
|
||||
GSocketAddress *result;
|
||||
|
||||
if (strcmp ("direct", priv->proxy_type) == 0)
|
||||
{
|
||||
result = priv->proxy_address;
|
||||
priv->proxy_address = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
gchar *dest_hostname;
|
||||
GInetSocketAddress *inetsaddr;
|
||||
GInetAddress *inetaddr;
|
||||
guint16 port;
|
||||
|
||||
if (!priv->supports_hostname)
|
||||
{
|
||||
GInetAddress *dest_ip;
|
||||
|
||||
if (!priv->next_dest_ip)
|
||||
priv->next_dest_ip = priv->dest_ips;
|
||||
|
||||
dest_ip = G_INET_ADDRESS (priv->next_dest_ip->data);
|
||||
dest_hostname = g_inet_address_to_string (dest_ip);
|
||||
|
||||
priv->next_dest_ip = g_list_next (priv->next_dest_ip);
|
||||
}
|
||||
else
|
||||
{
|
||||
dest_hostname = g_strdup (priv->dest_hostname);
|
||||
}
|
||||
|
||||
g_return_if_fail (G_IS_INET_SOCKET_ADDRESS (priv->proxy_address));
|
||||
|
||||
inetsaddr = G_INET_SOCKET_ADDRESS (priv->proxy_address);
|
||||
inetaddr = g_inet_socket_address_get_address (inetsaddr);
|
||||
port = g_inet_socket_address_get_port (inetsaddr);
|
||||
|
||||
result = g_proxy_address_new (inetaddr, port,
|
||||
priv->proxy_type,
|
||||
dest_hostname, priv->dest_port,
|
||||
priv->proxy_username,
|
||||
priv->proxy_password);
|
||||
|
||||
g_free (dest_hostname);
|
||||
|
||||
if (priv->supports_hostname || priv->next_dest_ip == NULL)
|
||||
{
|
||||
g_object_unref (priv->proxy_address);
|
||||
priv->proxy_address = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
g_simple_async_result_set_op_res_gpointer (priv->simple,
|
||||
result,
|
||||
g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
dest_hostname_lookup_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GProxyAddressEnumeratorPrivate *priv = user_data;
|
||||
GSimpleAsyncResult *simple = priv->simple;
|
||||
|
||||
priv->dest_ips = g_resolver_lookup_by_name_finish (G_RESOLVER (object),
|
||||
result,
|
||||
&error);
|
||||
if (priv->dest_ips)
|
||||
{
|
||||
save_result (priv);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_simple_async_result_set_from_error (simple, error);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
complete_async (priv);
|
||||
}
|
||||
|
||||
static void
|
||||
address_enumerate_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GProxyAddressEnumeratorPrivate *priv = user_data;
|
||||
GSimpleAsyncResult *simple = priv->simple;
|
||||
|
||||
priv->proxy_address =
|
||||
g_socket_address_enumerator_next_finish (priv->addr_enum,
|
||||
result,
|
||||
&error);
|
||||
if (priv->proxy_address)
|
||||
{
|
||||
if (!priv->supports_hostname && !priv->dest_ips)
|
||||
{
|
||||
GResolver *resolver;
|
||||
resolver = g_resolver_get_default();
|
||||
g_resolver_lookup_by_name_async (resolver,
|
||||
priv->dest_hostname,
|
||||
priv->cancellable,
|
||||
dest_hostname_lookup_cb,
|
||||
priv);
|
||||
g_object_unref (resolver);
|
||||
return;
|
||||
}
|
||||
|
||||
save_result (priv);
|
||||
}
|
||||
else if (*priv->next_proxy)
|
||||
{
|
||||
g_object_unref (priv->addr_enum);
|
||||
priv->addr_enum = NULL;
|
||||
|
||||
if (priv->dest_ips)
|
||||
{
|
||||
g_resolver_free_addresses (priv->dest_ips);
|
||||
priv->dest_ips = NULL;
|
||||
}
|
||||
|
||||
next_enumerator (priv);
|
||||
|
||||
if (priv->addr_enum)
|
||||
{
|
||||
g_socket_address_enumerator_next_async (priv->addr_enum,
|
||||
priv->cancellable,
|
||||
address_enumerate_cb,
|
||||
priv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
g_simple_async_result_set_from_error (simple, error);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
complete_async (priv);
|
||||
}
|
||||
|
||||
static void
|
||||
proxy_lookup_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GProxyAddressEnumeratorPrivate *priv = user_data;
|
||||
GSimpleAsyncResult *simple = priv->simple;
|
||||
|
||||
priv->proxies = g_proxy_resolver_lookup_finish (G_PROXY_RESOLVER (object),
|
||||
result,
|
||||
&error);
|
||||
priv->next_proxy = priv->proxies;
|
||||
|
||||
if (error)
|
||||
{
|
||||
g_simple_async_result_set_from_error (simple, error);
|
||||
g_error_free (error);
|
||||
}
|
||||
else
|
||||
{
|
||||
next_enumerator (priv);
|
||||
if (priv->addr_enum)
|
||||
{
|
||||
g_socket_address_enumerator_next_async (priv->addr_enum,
|
||||
priv->cancellable,
|
||||
address_enumerate_cb,
|
||||
priv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
complete_async (priv);
|
||||
}
|
||||
|
||||
static void
|
||||
g_proxy_address_enumerator_next_async (GSocketAddressEnumerator *enumerator,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GProxyAddressEnumeratorPrivate *priv = GET_PRIVATE (enumerator);
|
||||
|
||||
g_return_if_fail (priv->simple == NULL);
|
||||
g_return_if_fail (priv->cancellable == NULL);
|
||||
|
||||
priv->simple = g_simple_async_result_new (G_OBJECT (enumerator),
|
||||
callback, user_data,
|
||||
g_proxy_address_enumerator_next_async);
|
||||
|
||||
priv->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
|
||||
|
||||
if (priv->proxies == NULL)
|
||||
{
|
||||
GProxyResolver *resolver = g_proxy_resolver_get_default ();
|
||||
g_proxy_resolver_lookup_async (resolver,
|
||||
priv->dest_uri,
|
||||
cancellable,
|
||||
proxy_lookup_cb,
|
||||
priv);
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv->addr_enum)
|
||||
{
|
||||
if (priv->proxy_address)
|
||||
{
|
||||
save_result (priv);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_socket_address_enumerator_next_async (priv->addr_enum,
|
||||
cancellable,
|
||||
address_enumerate_cb,
|
||||
priv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
g_simple_async_result_complete_in_idle (priv->simple);
|
||||
|
||||
g_object_unref (priv->simple);
|
||||
priv->simple = NULL;
|
||||
|
||||
if (priv->cancellable)
|
||||
{
|
||||
g_object_unref (priv->cancellable);
|
||||
priv->cancellable = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static GSocketAddress *
|
||||
g_proxy_address_enumerator_next_finish (GSocketAddressEnumerator *enumerator,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
|
||||
GSocketAddress *address;
|
||||
|
||||
if (g_simple_async_result_propagate_error (simple, error))
|
||||
return NULL;
|
||||
|
||||
address = g_simple_async_result_get_op_res_gpointer (simple);
|
||||
if (address)
|
||||
g_object_ref (address);
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
static void
|
||||
g_proxy_address_enumerator_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GProxyAddressEnumeratorPrivate *priv = GET_PRIVATE (object);
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_URI:
|
||||
g_value_set_string (value, priv->dest_uri);
|
||||
break;
|
||||
|
||||
case PROP_CONNECTABLE:
|
||||
g_value_set_object (value, priv->connectable);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
g_proxy_address_enumerator_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GProxyAddressEnumeratorPrivate *priv = GET_PRIVATE (object);
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_URI:
|
||||
{
|
||||
const gchar *uri;
|
||||
|
||||
g_free (priv->dest_hostname);
|
||||
priv->dest_hostname = NULL;
|
||||
priv->dest_port = 0;
|
||||
|
||||
g_free (priv->dest_uri);
|
||||
priv->dest_uri = NULL;
|
||||
|
||||
uri = g_value_get_string (value);
|
||||
|
||||
if (uri)
|
||||
{
|
||||
GSocketConnectable *conn;
|
||||
|
||||
conn = g_network_address_parse_uri (uri, 0, NULL);
|
||||
if (conn)
|
||||
{
|
||||
priv->dest_uri = g_strdup (uri);
|
||||
|
||||
g_object_get (conn,
|
||||
"hostname", &priv->dest_hostname,
|
||||
"port", &priv->dest_port,
|
||||
NULL);
|
||||
|
||||
g_object_unref (conn);
|
||||
}
|
||||
else
|
||||
g_warning ("Invalid URI '%s'", uri);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PROP_CONNECTABLE:
|
||||
priv->connectable = g_value_dup_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
g_proxy_address_enumerator_finalize (GObject *object)
|
||||
{
|
||||
GProxyAddressEnumeratorPrivate *priv = GET_PRIVATE (object);
|
||||
|
||||
if (priv->connectable)
|
||||
g_object_unref (priv->connectable);
|
||||
|
||||
g_free (priv->dest_uri);
|
||||
g_free (priv->dest_hostname);
|
||||
|
||||
if (priv->dest_ips)
|
||||
g_resolver_free_addresses (priv->dest_ips);
|
||||
|
||||
g_strfreev (priv->proxies);
|
||||
|
||||
if (priv->addr_enum)
|
||||
g_object_unref (priv->addr_enum);
|
||||
|
||||
g_free (priv->proxy_type);
|
||||
g_free (priv->proxy_username);
|
||||
g_free (priv->proxy_password);
|
||||
|
||||
if (priv->cancellable)
|
||||
g_object_unref (priv->cancellable);
|
||||
|
||||
G_OBJECT_CLASS (g_proxy_address_enumerator_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
g_proxy_address_enumerator_init (GProxyAddressEnumerator *self)
|
||||
{
|
||||
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
|
||||
G_TYPE_PROXY_ADDRESS_ENUMERATOR,
|
||||
GProxyAddressEnumeratorPrivate);
|
||||
}
|
||||
|
||||
static void
|
||||
g_proxy_address_enumerator_class_init (GProxyAddressEnumeratorClass *proxy_enumerator_class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (proxy_enumerator_class);
|
||||
GSocketAddressEnumeratorClass *enumerator_class = G_SOCKET_ADDRESS_ENUMERATOR_CLASS (proxy_enumerator_class);
|
||||
|
||||
g_type_class_add_private (enumerator_class,
|
||||
sizeof (GProxyAddressEnumeratorPrivate));
|
||||
|
||||
object_class->set_property = g_proxy_address_enumerator_set_property;
|
||||
object_class->get_property = g_proxy_address_enumerator_get_property;
|
||||
object_class->finalize = g_proxy_address_enumerator_finalize;
|
||||
|
||||
enumerator_class->next = g_proxy_address_enumerator_next;
|
||||
enumerator_class->next_async = g_proxy_address_enumerator_next_async;
|
||||
enumerator_class->next_finish = g_proxy_address_enumerator_next_finish;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_URI,
|
||||
g_param_spec_string ("uri",
|
||||
P_("URI"),
|
||||
P_("The destination URI, use none:// for generic socket"),
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_CONNECTABLE,
|
||||
g_param_spec_object ("connectable",
|
||||
P_("Connectable"),
|
||||
P_("The connectable being enumerated."),
|
||||
G_TYPE_SOCKET_CONNECTABLE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
}
|
73
gio/gproxyaddressenumerator.h
Normal file
73
gio/gproxyaddressenumerator.h
Normal file
@ -0,0 +1,73 @@
|
||||
/* GIO - GLib Input, Output and Streaming Library
|
||||
*
|
||||
* Copyright (C) 2010 Collabora, Ltd.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
|
||||
*/
|
||||
|
||||
#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
|
||||
#error "Only <gio/gio.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __G_PROXY_ADDRESS_ENUMERATOR_H__
|
||||
#define __G_PROXY_ADDRESS_ENUMERATOR_H__
|
||||
|
||||
#include <gio/gsocketaddressenumerator.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define G_TYPE_PROXY_ADDRESS_ENUMERATOR (g_proxy_address_enumerator_get_type ())
|
||||
#define G_PROXY_ADDRESS_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_PROXY_ADDRESS_ENUMERATOR, GProxyAddressEnumerator))
|
||||
#define G_PROXY_ADDRESS_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_PROXY_ADDRESS_ENUMERATOR, GProxyAddressEnumeratorClass))
|
||||
#define G_IS_PROXY_ADDRESS_ENUMERATOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_PROXY_ADDRESS_ENUMERATOR))
|
||||
#define G_IS_PROXY_ADDRESS_ENUMERATOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_PROXY_ADDRESS_ENUMERATOR))
|
||||
#define G_PROXY_ADDRESS_ENUMERATOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_PROXY_ADDRESS_ENUMERATOR, GProxyAddressEnumeratorClass))
|
||||
|
||||
/**
|
||||
* GProxyAddressEnumerator:
|
||||
*
|
||||
* A subclass of #GSocketAddressEnumerator that takes another address
|
||||
* enumerator and wraps its results in #GProxyAddress<!-- -->es as
|
||||
* directed by the default #GProxyResolver.
|
||||
*/
|
||||
|
||||
typedef struct _GProxyAddressEnumeratorClass GProxyAddressEnumeratorClass;
|
||||
typedef struct _GProxyAddressEnumeratorPrivate GProxyAddressEnumeratorPrivate;
|
||||
|
||||
struct _GProxyAddressEnumerator
|
||||
{
|
||||
GSocketAddressEnumerator parent_instance;
|
||||
GProxyAddressEnumeratorPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GProxyAddressEnumeratorClass
|
||||
{
|
||||
GSocketAddressEnumeratorClass parent_class;
|
||||
|
||||
void (*_g_reserved1) (void);
|
||||
void (*_g_reserved2) (void);
|
||||
void (*_g_reserved3) (void);
|
||||
void (*_g_reserved4) (void);
|
||||
void (*_g_reserved5) (void);
|
||||
void (*_g_reserved6) (void);
|
||||
void (*_g_reserved7) (void);
|
||||
};
|
||||
|
||||
GType g_proxy_address_enumerator_get_type (void) G_GNUC_CONST;
|
||||
|
||||
#endif /* __G_PROXY_ADDRESS_ENUMERATOR_H__ */
|
Loading…
Reference in New Issue
Block a user