blob: 67545df3883ec5bb097eb65b06d1789d942e13c2 [file] [log] [blame]
From afee3002ff45b7a00df3d6804fa7d329b907d361 Mon Sep 17 00:00:00 2001
From: Carlos Garcia Campos <cgarcia@igalia.com>
Date: Mon, 30 Jan 2017 13:57:12 +0100
Subject: [PATCH 1/2] auth: Fix async authentication when flag
SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE is used
When the flag SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE is used, it's not possible
to successfully authenticate, and SOUP_STATUS_UNAUTHORIZED is always
returned even when soup_auth_autenticate was called with the right
credentials. This happens because we set the auth on the soup message right
after emitting the authenticate signal only if it was authenticated. If the
signal pauses the message, the auth will no longer be associated to the message,
and not cached either because flag SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE is
present. Since we always check if the auth returned by
soup_auth_get_message is ready before trying to use it, we can simply
always set the auth on the mssage right after emitting the authenticate
signal even if it was not authenticated yet. If it's eventually
authenticated then got-body callback will check it's ready to re-queue
the message as expected.
https://bugzilla.gnome.org/show_bug.cgi?id=777936
---
libsoup/soup-auth-manager.c | 4 +--
tests/auth-test.c | 61 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 63 insertions(+), 2 deletions(-)
diff --git a/libsoup/soup-auth-manager.c b/libsoup/soup-auth-manager.c
index 704661bc..9ff446cc 100644
--- a/libsoup/soup-auth-manager.c
+++ b/libsoup/soup-auth-manager.c
@@ -625,7 +625,7 @@ auth_got_headers (SoupMessage *msg, gpointer manager)
/* If we need to authenticate, try to do it. */
authenticate_auth (manager, auth, msg,
prior_auth_failed, FALSE, TRUE);
- soup_message_set_auth (msg, soup_auth_is_ready (auth, msg) ? auth : NULL);
+ soup_message_set_auth (msg, auth);
g_object_unref (auth);
g_mutex_unlock (&priv->lock);
}
@@ -689,7 +689,7 @@ proxy_auth_got_headers (SoupMessage *msg, gpointer manager)
/* If we need to authenticate, try to do it. */
authenticate_auth (manager, auth, msg,
prior_auth_failed, TRUE, TRUE);
- soup_message_set_proxy_auth (msg, soup_auth_is_ready (auth, msg) ? auth : NULL);
+ soup_message_set_proxy_auth (msg, auth);
g_object_unref (auth);
g_mutex_unlock (&priv->lock);
}
diff --git a/tests/auth-test.c b/tests/auth-test.c
index b674c61c..23e22133 100644
--- a/tests/auth-test.c
+++ b/tests/auth-test.c
@@ -1336,6 +1336,66 @@ do_message_do_not_use_auth_cache_test (void)
}
static void
+async_no_auth_cache_authenticate (SoupSession *session, SoupMessage *msg,
+ SoupAuth *auth, gboolean retrying, SoupAuth **auth_out)
+{
+ debug_printf (1, " async_no_auth_cache_authenticate\n");
+
+ soup_session_pause_message (session, msg);
+ *auth_out = g_object_ref (auth);
+ g_main_loop_quit (loop);
+}
+
+static void
+async_no_auth_cache_finished (SoupSession *session, SoupMessage *msg, gpointer user_data)
+{
+ debug_printf (1, " async_no_auth_cache_finished\n");
+
+ g_main_loop_quit (loop);
+}
+
+static void
+do_async_message_do_not_use_auth_cache_test (void)
+{
+ SoupSession *session;
+ SoupMessage *msg;
+ char *uri;
+ SoupAuth *auth = NULL;
+ SoupMessageFlags flags;
+
+ SOUP_TEST_SKIP_IF_NO_APACHE;
+
+ loop = g_main_loop_new (NULL, TRUE);
+ session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
+ uri = g_strconcat (base_uri, "Basic/realm1/", NULL);
+
+ msg = soup_message_new ("GET", uri);
+ g_free (uri);
+ g_signal_connect (session, "authenticate",
+ G_CALLBACK (async_no_auth_cache_authenticate), &auth);
+ flags = soup_message_get_flags (msg);
+ soup_message_set_flags (msg, flags | SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE);
+ g_object_ref (msg);
+ soup_session_queue_message (session, msg, async_no_auth_cache_finished, NULL);
+ g_main_loop_run (loop);
+
+ soup_test_assert_message_status (msg, SOUP_STATUS_UNAUTHORIZED);
+
+ soup_test_assert (auth, "msg didn't get authenticate signal");
+ soup_auth_authenticate (auth, "user1", "realm1");
+ g_object_unref (auth);
+
+ soup_session_unpause_message (session, msg);
+ g_main_loop_run (loop);
+
+ soup_test_assert_message_status (msg, SOUP_STATUS_OK);
+
+ soup_test_session_abort_unref (session);
+ g_object_unref (msg);
+ g_main_loop_unref (loop);
+}
+
+static void
has_authorization_header_authenticate (SoupSession *session, SoupMessage *msg,
SoupAuth *auth, gboolean retrying, gpointer data)
{
@@ -1432,6 +1492,7 @@ main (int argc, char **argv)
g_test_add_func ("/auth/disappearing-auth", do_disappearing_auth_test);
g_test_add_func ("/auth/clear-credentials", do_clear_credentials_test);
g_test_add_func ("/auth/message-do-not-use-auth-cache", do_message_do_not_use_auth_cache_test);
+ g_test_add_func ("/auth/async-message-do-not-use-auth-cache", do_async_message_do_not_use_auth_cache_test);
g_test_add_func ("/auth/authorization-header-request", do_message_has_authorization_header_test);
ret = g_test_run ();
--
2.11.0