/* Overview:
*
* We have an echo server, two proxy servers, two GProxy
- * implementations, and a GProxyResolver implementation.
+ * implementations, and two GProxyResolver implementations.
*
* The echo server runs at @server.server_addr (on
* @server.server_port).
* hostname resolution (but it just ignores the hostname and always
* connects to @server_addr anyway).
*
- * The GProxyResolver (GTestProxyResolver) looks at its URI and
- * returns [ "direct://" ] for "simple://" URIs, and [ proxy_a.uri,
- * proxy_b.uri ] for other URIs.
+ * The default GProxyResolver (GTestProxyResolver) looks at its URI
+ * and returns [ "direct://" ] for "simple://" URIs, and [
+ * proxy_a.uri, proxy_b.uri ] for other URIs. The other GProxyResolver
+ * (GTestAltProxyResolver) always returns [ proxy_a.uri ].
*/
typedef struct {
static void g_test_proxy_resolver_iface_init (GProxyResolverInterface *iface);
+static GType _g_test_proxy_resolver_get_type (void);
#define g_test_proxy_resolver_get_type _g_test_proxy_resolver_get_type
G_DEFINE_TYPE_WITH_CODE (GTestProxyResolver, g_test_proxy_resolver, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER,
gpointer user_data)
{
GError *error = NULL;
- GSimpleAsyncResult *simple;
+ GTask *task;
gchar **proxies;
- proxies = g_test_proxy_resolver_lookup (resolver, uri, cancellable, &error);
-
- simple = g_simple_async_result_new (G_OBJECT (resolver),
- callback, user_data,
- g_test_proxy_resolver_lookup_async);
+ proxies = g_proxy_resolver_lookup (resolver, uri, cancellable, &error);
+ task = g_task_new (resolver, NULL, callback, user_data);
if (proxies == NULL)
- g_simple_async_result_take_error (simple, error);
+ g_task_return_error (task, error);
else
- g_simple_async_result_set_op_res_gpointer (simple, proxies, (GDestroyNotify) g_strfreev);
+ g_task_return_pointer (task, proxies, (GDestroyNotify) g_strfreev);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
+ g_object_unref (task);
}
static gchar **
GAsyncResult *result,
GError **error)
{
- if (G_IS_SIMPLE_ASYNC_RESULT (result))
- {
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
- gchar **proxies;
-
- if (g_simple_async_result_propagate_error (simple, error))
- return NULL;
-
- proxies = g_simple_async_result_get_op_res_gpointer (simple);
- return g_strdupv (proxies);
- }
-
- return NULL;
+ return g_task_propagate_pointer (G_TASK (result), error);
}
static void
iface->lookup_finish = g_test_proxy_resolver_lookup_finish;
}
+/****************************/
+/* Alternate GProxyResolver */
+/****************************/
+
+typedef GTestProxyResolver GTestAltProxyResolver;
+typedef GTestProxyResolverClass GTestAltProxyResolverClass;
+
+static void g_test_alt_proxy_resolver_iface_init (GProxyResolverInterface *iface);
+
+static GType _g_test_alt_proxy_resolver_get_type (void);
+#define g_test_alt_proxy_resolver_get_type _g_test_alt_proxy_resolver_get_type
+G_DEFINE_TYPE_WITH_CODE (GTestAltProxyResolver, g_test_alt_proxy_resolver, g_test_proxy_resolver_get_type (),
+ G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER,
+ g_test_alt_proxy_resolver_iface_init);
+ )
+
+static void
+g_test_alt_proxy_resolver_init (GTestProxyResolver *resolver)
+{
+}
+
+static gchar **
+g_test_alt_proxy_resolver_lookup (GProxyResolver *resolver,
+ const gchar *uri,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gchar **proxies;
+
+ proxies = g_new (gchar *, 2);
+
+ proxies[0] = g_strdup (proxy_a.uri);
+ proxies[1] = NULL;
+
+ last_proxies = g_strdupv (proxies);
+
+ return proxies;
+}
+
+static void
+g_test_alt_proxy_resolver_class_init (GTestProxyResolverClass *resolver_class)
+{
+}
+
+static void
+g_test_alt_proxy_resolver_iface_init (GProxyResolverInterface *iface)
+{
+ iface->lookup = g_test_alt_proxy_resolver_lookup;
+}
+
/****************************************/
/* Test proxy implementation base class */
GObjectClass parent_class;
} GProxyBaseClass;
+static GType _g_proxy_base_get_type (void);
#define g_proxy_base_get_type _g_proxy_base_get_type
G_DEFINE_ABSTRACT_TYPE (GProxyBase, g_proxy_base, G_TYPE_OBJECT)
gpointer user_data)
{
GError *error = NULL;
- GSimpleAsyncResult *simple;
+ GTask *task;
GIOStream *proxy_io_stream;
- simple = g_simple_async_result_new (G_OBJECT (proxy),
- callback, user_data,
- g_proxy_base_connect_async);
+ task = g_task_new (proxy, NULL, callback, user_data);
proxy_io_stream = g_proxy_connect (proxy, io_stream, proxy_address,
cancellable, &error);
if (proxy_io_stream)
- {
- g_simple_async_result_set_op_res_gpointer (simple, proxy_io_stream,
- g_object_unref);
- }
+ g_task_return_pointer (task, proxy_io_stream, g_object_unref);
else
- g_simple_async_result_take_error (simple, error);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
+ g_task_return_error (task, error);
+ g_object_unref (task);
}
static GIOStream *
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
-
- if (g_simple_async_result_propagate_error (simple, error))
- return NULL;
-
- return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
+ return g_task_propagate_pointer (G_TASK (result), error);
}
static void
static void g_proxy_a_iface_init (GProxyInterface *proxy_iface);
+static GType _g_proxy_a_get_type (void);
#define g_proxy_a_get_type _g_proxy_a_get_type
G_DEFINE_TYPE_WITH_CODE (GProxyA, g_proxy_a, g_proxy_base_get_type (),
G_IMPLEMENT_INTERFACE (G_TYPE_PROXY,
static void g_proxy_b_iface_init (GProxyInterface *proxy_iface);
+static GType _g_proxy_b_get_type (void);
#define g_proxy_b_get_type _g_proxy_b_get_type
G_DEFINE_TYPE_WITH_CODE (GProxyB, g_proxy_b, g_proxy_base_get_type (),
G_IMPLEMENT_INTERFACE (G_TYPE_PROXY,
typedef GResolver GFakeResolver;
typedef GResolverClass GFakeResolverClass;
+static GType g_fake_resolver_get_type (void);
G_DEFINE_TYPE (GFakeResolver, g_fake_resolver, G_TYPE_RESOLVER)
static void
GCancellable *cancellable,
GError **error)
{
- /* This is only ever called with lookups that are expected to
- * fail.
- */
- g_set_error (error,
- G_RESOLVER_ERROR,
- G_RESOLVER_ERROR_NOT_FOUND,
- "Not found");
- return NULL;
+ if (!strcmp (hostname, "example.com"))
+ return g_list_prepend (NULL, g_inet_address_new_from_string ("127.0.0.1"));
+ else
+ {
+ /* Anything else is expected to fail. */
+ g_set_error (error,
+ G_RESOLVER_ERROR,
+ G_RESOLVER_ERROR_NOT_FOUND,
+ "Not found");
+ return NULL;
+ }
}
static void
GAsyncReadyCallback callback,
gpointer user_data)
{
- g_simple_async_report_error_in_idle (G_OBJECT (resolver),
- callback, user_data,
- G_RESOLVER_ERROR,
- G_RESOLVER_ERROR_NOT_FOUND,
- "Not found");
+ GTask *task;
+
+ task = g_task_new (resolver, cancellable, callback, user_data);
+
+ if (!strcmp (hostname, "example.com"))
+ {
+ GList *result;
+
+ result = g_list_prepend (NULL, g_inet_address_new_from_string ("127.0.0.1"));
+ g_task_return_pointer (task, result, (GDestroyNotify) g_resolver_free_addresses);
+ }
+ else
+ {
+ g_task_return_new_error (task,
+ G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND,
+ "Not found");
+ }
+ g_object_unref (task);
+}
+
+static GList *
+g_fake_resolver_lookup_by_name_finish (GResolver *resolver,
+ GAsyncResult *result,
+ GError **error)
+{
+ return g_task_propagate_pointer (G_TASK (result), error);
}
static void
resolver_class->lookup_by_name = g_fake_resolver_lookup_by_name;
resolver_class->lookup_by_name_async = g_fake_resolver_lookup_by_name_async;
+ resolver_class->lookup_by_name_finish = g_fake_resolver_lookup_by_name_finish;
}
addr = g_socket_connection_get_remote_address (conn, &error);
g_assert_no_error (error);
- g_assert (!G_IS_PROXY_ADDRESS (addr));
+ g_assert (addr != NULL && !G_IS_PROXY_ADDRESS (addr));
g_object_unref (addr);
addr = g_socket_connection_get_local_address (conn, &error);
teardown_test (NULL, NULL);
}
+static void
+assert_override (GSocketConnection *conn)
+{
+ g_assert_cmpint (g_strv_length (last_proxies), ==, 1);
+ g_assert_cmpstr (last_proxies[0], ==, proxy_a.uri);
+
+ if (conn)
+ g_assert_no_error (proxy_a.last_error);
+ else
+ g_assert_error (proxy_a.last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
+}
+
+static void
+test_override (gpointer fixture,
+ gconstpointer user_data)
+{
+ GProxyResolver *alt_resolver;
+ GSocketConnection *conn;
+ GError *error = NULL;
+ gchar *uri;
+
+ g_assert (g_socket_client_get_proxy_resolver (client) == g_proxy_resolver_get_default ());
+ alt_resolver = g_object_new (g_test_alt_proxy_resolver_get_type (), NULL);
+ g_socket_client_set_proxy_resolver (client, alt_resolver);
+ g_assert (g_socket_client_get_proxy_resolver (client) == alt_resolver);
+
+ /* Alt proxy resolver always returns Proxy A, so alpha:// should
+ * succeed, and simple:// and beta:// should fail.
+ */
+
+ /* simple */
+ uri = g_strdup_printf ("simple://127.0.0.1:%u", server.server_port);
+ conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
+ g_clear_error (&error);
+ assert_override (conn);
+ teardown_test (NULL, NULL);
+
+ g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
+ async_got_error, &error);
+ while (error == NULL)
+ g_main_context_iteration (NULL, TRUE);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
+ g_clear_error (&error);
+ assert_override (conn);
+ g_free (uri);
+ teardown_test (NULL, NULL);
+
+ /* alpha */
+ uri = g_strdup_printf ("alpha://127.0.0.1:%u", server.server_port);
+ conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
+ g_assert_no_error (error);
+ assert_override (conn);
+ do_echo_test (conn);
+ g_clear_object (&conn);
+ teardown_test (NULL, NULL);
+
+ conn = NULL;
+ g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
+ async_got_conn, &conn);
+ while (conn == NULL)
+ g_main_context_iteration (NULL, TRUE);
+ assert_override (conn);
+ do_echo_test (conn);
+ g_clear_object (&conn);
+ g_free (uri);
+ teardown_test (NULL, NULL);
+
+ /* beta */
+ uri = g_strdup_printf ("beta://127.0.0.1:%u", server.server_port);
+ conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
+ g_clear_error (&error);
+ assert_override (conn);
+ teardown_test (NULL, NULL);
+
+ g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
+ async_got_error, &error);
+ while (error == NULL)
+ g_main_context_iteration (NULL, TRUE);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
+ g_clear_error (&error);
+ assert_override (conn);
+ g_free (uri);
+ teardown_test (NULL, NULL);
+
+ g_assert (g_socket_client_get_proxy_resolver (client) == alt_resolver);
+ g_socket_client_set_proxy_resolver (client, NULL);
+ g_assert (g_socket_client_get_proxy_resolver (client) == g_proxy_resolver_get_default ());
+ g_object_unref (alt_resolver);
+}
+
+static void
+assert_destination_port (GSocketAddressEnumerator *etor,
+ guint16 port)
+{
+ GSocketAddress *addr;
+ GProxyAddress *paddr;
+ GError *error = NULL;
+
+ while ((addr = g_socket_address_enumerator_next (etor, NULL, &error)))
+ {
+ g_assert_no_error (error);
+
+ g_assert (G_IS_PROXY_ADDRESS (addr));
+ paddr = G_PROXY_ADDRESS (addr);
+ g_assert_cmpint (g_proxy_address_get_destination_port (paddr), ==, port);
+ g_object_unref (addr);
+ }
+ g_assert_no_error (error);
+}
+
+static void
+test_proxy_enumerator_ports (void)
+{
+ GSocketAddressEnumerator *etor;
+
+ etor = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
+ "uri", "http://example.com/",
+ NULL);
+ assert_destination_port (etor, 0);
+ g_object_unref (etor);
+
+ /* Have to call this to clear last_proxies so the next call to
+ * g_test_proxy_resolver_lookup() won't assert.
+ */
+ teardown_test (NULL, NULL);
+
+ etor = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
+ "uri", "http://example.com:8080/",
+ NULL);
+ assert_destination_port (etor, 8080);
+ g_object_unref (etor);
+
+ teardown_test (NULL, NULL);
+
+ etor = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
+ "uri", "http://example.com/",
+ "default-port", 80,
+ NULL);
+ assert_destination_port (etor, 80);
+ g_object_unref (etor);
+
+ teardown_test (NULL, NULL);
+
+ etor = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
+ "uri", "http://example.com:8080/",
+ "default-port", 80,
+ NULL);
+ assert_destination_port (etor, 8080);
+ g_object_unref (etor);
+
+ teardown_test (NULL, NULL);
+}
+
int
main (int argc,
char *argv[])
GCancellable *cancellable;
gint result;
- g_type_init ();
g_test_init (&argc, &argv, NULL);
/* Register stuff. The dummy g_proxy_get_default_for_protocol() call
g_test_add_vtable ("/proxy/multiple_sync", 0, NULL, setup_test, test_multiple_sync, teardown_test);
g_test_add_vtable ("/proxy/multiple_async", 0, NULL, setup_test, test_multiple_async, teardown_test);
g_test_add_vtable ("/proxy/dns", 0, NULL, setup_test, test_dns, teardown_test);
+ g_test_add_vtable ("/proxy/override", 0, NULL, setup_test, test_override, teardown_test);
+ g_test_add_func ("/proxy/enumerator-ports", test_proxy_enumerator_ports);
result = g_test_run();