summaryrefslogtreecommitdiff
path: root/tests/test-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test-utils.c')
-rw-r--r--tests/test-utils.c224
1 files changed, 180 insertions, 44 deletions
diff --git a/tests/test-utils.c b/tests/test-utils.c
index f4632a9b..650a5eb6 100644
--- a/tests/test-utils.c
+++ b/tests/test-utils.c
@@ -268,77 +268,209 @@ soup_test_session_abort_unref (SoupSession *session)
}
}
-static gpointer run_server_thread (gpointer user_data);
+static void
+server_listen (SoupServer *server)
+{
+ GError *error = NULL;
+ SoupServerListenOptions options =
+ GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (server), "listen-options"));
-static SoupServer *
-test_server_new (gboolean in_own_thread, gboolean ssl)
+ soup_server_listen_local (server, 0, options, &error);
+ if (error) {
+ g_printerr ("Unable to create server: %s\n", error->message);
+ exit (1);
+ }
+}
+
+static GMutex server_start_mutex;
+static GCond server_start_cond;
+
+static gpointer
+run_server_thread (gpointer user_data)
{
- SoupServer *server;
- GMainContext *async_context;
- const char *ssl_cert_file, *ssl_key_file;
- SoupAddress *addr;
+ SoupServer *server = user_data;
+ GMainContext *context;
+ GMainLoop *loop;
- async_context = in_own_thread ? g_main_context_new () : NULL;
+ context = g_main_context_new ();
+ g_main_context_push_thread_default (context);
+ loop = g_main_loop_new (context, FALSE);
+ g_object_set_data (G_OBJECT (server), "GMainLoop", loop);
- if (ssl) {
- ssl_cert_file = SRCDIR "/test-cert.pem";
- ssl_key_file = SRCDIR "/test-key.pem";
- } else
- ssl_cert_file = ssl_key_file = NULL;
+ server_listen (server);
- addr = soup_address_new ("127.0.0.1", SOUP_ADDRESS_ANY_PORT);
- soup_address_resolve_sync (addr, NULL);
+ g_mutex_lock (&server_start_mutex);
+ g_cond_signal (&server_start_cond);
+ g_mutex_unlock (&server_start_mutex);
- server = soup_server_new (SOUP_SERVER_INTERFACE, addr,
- SOUP_SERVER_ASYNC_CONTEXT, async_context,
- SOUP_SERVER_SSL_CERT_FILE, ssl_cert_file,
- SOUP_SERVER_SSL_KEY_FILE, ssl_key_file,
- NULL);
- g_object_unref (addr);
- if (async_context)
- g_main_context_unref (async_context);
+ g_main_loop_run (loop);
+ g_main_loop_unref (loop);
- if (!server) {
- g_printerr ("Unable to create server\n");
- exit (1);
+ soup_server_disconnect (server);
+
+ g_main_context_pop_thread_default (context);
+ g_main_context_unref (context);
+
+ return NULL;
+}
+
+SoupServer *
+soup_test_server_new (SoupTestServerOptions options)
+{
+ SoupServer *server;
+ GTlsCertificate *cert = NULL;
+ GError *error = NULL;
+
+ if (tls_available) {
+ cert = g_tls_certificate_new_from_files (SRCDIR "/test-cert.pem",
+ SRCDIR "/test-key.pem",
+ &error);
+ if (error) {
+ g_printerr ("Unable to create server: %s\n", error->message);
+ exit (1);
+ }
}
+
+ server = soup_server_new (SOUP_SERVER_TLS_CERTIFICATE, cert,
+ NULL);
+ g_clear_object (&cert);
- if (in_own_thread) {
+ g_object_set_data (G_OBJECT (server), "options", GUINT_TO_POINTER (options));
+
+ if (options & SOUP_TEST_SERVER_IN_THREAD) {
GThread *thread;
+ g_mutex_lock (&server_start_mutex);
+
thread = g_thread_new ("server_thread", run_server_thread, server);
g_object_set_data (G_OBJECT (server), "thread", thread);
+
+ /* We have to call soup_server_listen() from the server's
+ * thread, but want to be sure we don't return from here
+ * until it happens, hence the locking.
+ */
+ g_cond_wait (&server_start_cond, &server_start_mutex);
+ g_mutex_unlock (&server_start_mutex);
} else
- soup_server_run_async (server);
+ server_listen (server);
return server;
}
-SoupServer *
-soup_test_server_new (gboolean in_own_thread)
+static SoupURI *
+find_server_uri (SoupServer *server, const char *scheme, const char *host)
+{
+ GSList *uris, *u;
+ SoupURI *uri, *ret_uri = NULL;
+
+ uris = soup_server_get_uris (server);
+ for (u = uris; u; u = u->next) {
+ uri = u->data;
+
+ if (scheme && strcmp (uri->scheme, scheme) != 0)
+ continue;
+ if (host && strcmp (uri->host, host) != 0)
+ continue;
+
+ ret_uri = soup_uri_copy (uri);
+ break;
+ }
+ g_slist_free_full (uris, (GDestroyNotify)soup_uri_free);
+
+ return ret_uri;
+}
+
+static SoupURI *
+add_listener (SoupServer *server, const char *scheme, const char *host)
{
- return test_server_new (in_own_thread, FALSE);
+ SoupServerListenOptions options = 0;
+ GError *error = NULL;
+
+ if (!g_strcmp0 (scheme, SOUP_URI_SCHEME_HTTPS))
+ options |= SOUP_SERVER_LISTEN_HTTPS;
+ if (!g_strcmp0 (host, "127.0.0.1"))
+ options |= SOUP_SERVER_LISTEN_IPV4_ONLY;
+ else if (!g_strcmp0 (host, "::1"))
+ options |= SOUP_SERVER_LISTEN_IPV6_ONLY;
+
+ soup_server_listen_local (server, 0, options, &error);
+ g_assert_no_error (error);
+
+ return find_server_uri (server, scheme, host);
}
-SoupServer *
-soup_test_server_new_ssl (gboolean in_own_thread)
+typedef struct {
+ GMutex mutex;
+ GCond cond;
+
+ SoupServer *server;
+ const char *scheme;
+ const char *host;
+
+ SoupURI *uri;
+} AddListenerData;
+
+static gboolean
+add_listener_in_thread (gpointer user_data)
{
- return test_server_new (in_own_thread, TRUE);
+ AddListenerData *data = user_data;
+
+ data->uri = add_listener (data->server, data->scheme, data->host);
+ g_mutex_lock (&data->mutex);
+ g_cond_signal (&data->cond);
+ g_mutex_unlock (&data->mutex);
+
+ return FALSE;
}
-static gpointer
-run_server_thread (gpointer user_data)
+SoupURI *
+soup_test_server_get_uri (SoupServer *server,
+ const char *scheme,
+ const char *host)
{
- SoupServer *server = user_data;
+ SoupURI *uri;
+ GMainLoop *loop;
- soup_server_run (server);
- return NULL;
+ uri = find_server_uri (server, scheme, host);
+ if (uri)
+ return uri;
+
+ /* Need to add a new listener */
+ uri = soup_uri_new (NULL);
+ soup_uri_set_scheme (uri, scheme);
+ soup_uri_set_host (uri, host);
+
+ loop = g_object_get_data (G_OBJECT (server), "GMainLoop");
+ if (loop) {
+ GMainContext *context = g_main_loop_get_context (loop);
+ AddListenerData data;
+
+ g_mutex_init (&data.mutex);
+ g_cond_init (&data.cond);
+ data.server = server;
+ data.scheme = scheme;
+ data.host = host;
+ data.uri = NULL;
+
+ g_mutex_lock (&data.mutex);
+ soup_add_completion (context, add_listener_in_thread, &data);
+
+ while (!data.uri)
+ g_cond_wait (&data.cond, &data.mutex);
+
+ g_mutex_clear (&data.mutex);
+ g_cond_clear (&data.cond);
+ uri = data.uri;
+ } else
+ uri = add_listener (server, scheme, host);
+
+ return uri;
}
static gboolean
-idle_quit_server (gpointer server)
+idle_quit_server (gpointer loop)
{
- soup_server_quit (server);
+ g_main_loop_quit (loop);
return FALSE;
}
@@ -352,11 +484,15 @@ soup_test_server_quit_unref (SoupServer *server)
thread = g_object_get_data (G_OBJECT (server), "thread");
if (thread) {
- soup_add_completion (soup_server_get_async_context (server),
- idle_quit_server, server);
+ GMainLoop *loop;
+ GMainContext *context;
+
+ loop = g_object_get_data (G_OBJECT (server), "GMainLoop");
+ context = g_main_loop_get_context (loop);
+ soup_add_completion (context, idle_quit_server, loop);
g_thread_join (thread);
} else
- soup_server_quit (server);
+ soup_server_disconnect (server);
g_object_unref (server);
if (server) {