[libsoup] auth: Fix async authentication when flag SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE is used



commit 25f77b5161d9278a219606e51c794426c26b2ec2
Author: Carlos Garcia Campos <cgarcia igalia com>
Date:   Mon Jan 30 13:57:12 2017 +0100

    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 704661b..9ff446c 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 b674c61..23e2213 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 ();


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]