[libsoup/carlosgc/status: 4/5] session: make it possible to cancel a message that is paused




commit d9c314719411fea27b1e68646e7431cb4f08cf3d
Author: Carlos Garcia Campos <cgarcia igalia com>
Date:   Sun Nov 15 14:26:51 2020 +0100

    session: make it possible to cancel a message that is paused
    
    When using the operation cancellable instead of
    soup_session_cancel_message().

 libsoup/soup-message-io-data.c |  2 +-
 libsoup/soup-message-io.c      |  4 +--
 libsoup/soup-session.c         |  3 ++-
 tests/auth-test.c              | 55 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 60 insertions(+), 4 deletions(-)
---
diff --git a/libsoup/soup-message-io-data.c b/libsoup/soup-message-io-data.c
index 8af99467..9fd76e5b 100644
--- a/libsoup/soup-message-io-data.c
+++ b/libsoup/soup-message-io-data.c
@@ -210,7 +210,7 @@ soup_message_io_data_get_source (SoupMessageIOData     *io,
        if (!io) {
                base_source = g_timeout_source_new (0);
        } else if (io->paused) {
-               base_source = NULL;
+               base_source = cancellable ? g_cancellable_source_new (cancellable) : NULL;
        } else if (io->async_wait) {
                base_source = g_cancellable_source_new (io->async_wait);
        } else if (SOUP_MESSAGE_IO_STATE_POLLABLE (io->read_state)) {
diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io.c
index a9714aa5..f4b2d663 100644
--- a/libsoup/soup-message-io.c
+++ b/libsoup/soup-message-io.c
@@ -821,7 +821,7 @@ soup_message_io_run (SoupMessage *msg,
                soup_message_io_finished (msg);
        } else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
                g_clear_error (&error);
-               io->io_source = soup_message_io_data_get_source (io, G_OBJECT (msg), NULL,
+               io->io_source = soup_message_io_data_get_source (io, G_OBJECT (msg), cancellable,
                                                                 (SoupMessageIOSourceFunc)io_run_ready,
                                                                 NULL);
                g_source_set_priority (io->io_source,
@@ -896,7 +896,7 @@ io_run_until_read_async (SoupMessage *msg,
 
         if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
                 g_error_free (error);
-                io->io_source = soup_message_io_data_get_source (io, G_OBJECT (msg), NULL,
+                io->io_source = soup_message_io_data_get_source (io, G_OBJECT (msg), g_task_get_cancellable 
(task),
                                                                 
(SoupMessageIOSourceFunc)io_run_until_read_ready,
                                                                 task);
                g_source_set_priority (io->io_source, g_task_get_priority (task));
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index 0cf5c081..a5b7b3c6 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -2801,6 +2801,7 @@ run_until_read_done (SoupMessage          *msg,
        if (item->state != SOUP_MESSAGE_FINISHED) {
                if (soup_message_io_in_progress (msg))
                        soup_message_io_finished (msg);
+               item->paused = FALSE;
                item->state = SOUP_MESSAGE_FINISHING;
                soup_session_process_queue_item (item->session, item, NULL, FALSE);
        }
@@ -3222,7 +3223,7 @@ soup_session_send (SoupSession   *session,
                        soup_message_io_finished (msg);
                else if (item->state != SOUP_MESSAGE_FINISHED)
                        item->state = SOUP_MESSAGE_FINISHING;
-
+               item->paused = FALSE;
                if (item->state != SOUP_MESSAGE_FINISHED)
                        soup_session_process_queue_item (session, item, NULL, TRUE);
        }
diff --git a/tests/auth-test.c b/tests/auth-test.c
index cf0c59a3..48357162 100644
--- a/tests/auth-test.c
+++ b/tests/auth-test.c
@@ -749,6 +749,60 @@ do_async_auth_no_password_test (void)
        g_main_loop_unref (loop);
 }
 
+typedef struct {
+       SoupAuth *auth;
+       GCancellable *cancellable;
+} AsyncAuthCancelData;
+
+static gboolean
+async_authenticate_cancel_idle (AsyncAuthCancelData *data)
+{
+       g_cancellable_cancel (data->cancellable);
+       return FALSE;
+}
+
+static gboolean
+async_authenticate_cancel_authenticate (SoupMessage         *msg,
+                                       SoupAuth            *auth,
+                                       gboolean             retrying,
+                                       AsyncAuthCancelData *data)
+{
+       data->auth = g_object_ref (auth);
+       g_idle_add ((GSourceFunc)async_authenticate_cancel_idle, data);
+
+       return TRUE;
+}
+
+static void
+do_async_auth_cancel_test (void)
+{
+       SoupSession *session;
+       SoupMessage *msg;
+       char *uri;
+       AsyncAuthCancelData data = { NULL, NULL };
+       GError *error = NULL;
+
+       SOUP_TEST_SKIP_IF_NO_APACHE;
+
+       session = soup_test_session_new (NULL);
+       uri = g_strconcat (base_uri, "Basic/realm1/", NULL);
+
+       msg = soup_message_new ("GET", uri);
+       data.cancellable = g_cancellable_new ();
+       g_signal_connect (msg, "authenticate",
+                         G_CALLBACK (async_authenticate_cancel_authenticate),
+                         &data);
+       soup_test_session_async_send (session, msg, data.cancellable, &error);
+       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
+
+       g_object_unref (data.auth);
+       g_object_unref (data.cancellable);
+       g_object_unref (msg);
+       g_free (uri);
+
+       soup_test_session_abort_unref (session);
+}
+
 typedef struct {
        const char *password;
        struct {
@@ -1603,6 +1657,7 @@ main (int argc, char **argv)
        g_test_add_func ("/auth/async-auth/good-password", do_async_auth_good_password_test);
        g_test_add_func ("/auth/async-auth/bad-password", do_async_auth_bad_password_test);
        g_test_add_func ("/auth/async-auth/no-password", do_async_auth_no_password_test);
+       g_test_add_func ("/auth/async-auth/cancel", do_async_auth_cancel_test);
        g_test_add_func ("/auth/select-auth", do_select_auth_test);
        g_test_add_func ("/auth/auth-close", do_auth_close_test);
        g_test_add_func ("/auth/infinite-auth", do_infinite_auth_test);


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