summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garcia Campos <cgarcia@igalia.com>2020-11-15 14:26:51 +0100
committerCarlos Garcia Campos <cgarcia@igalia.com>2020-11-15 15:06:05 +0100
commit1b9bfde7316f99e7e3771bdfbb48932cde9390d8 (patch)
tree2fb12944e5d5be5a2bda45f17c99787238af4dba
parent02a81e16865849ae39c579fce8c4837da3d1bbc1 (diff)
downloadlibsoup-1b9bfde7316f99e7e3771bdfbb48932cde9390d8.tar.gz
session: make it possible to cancel a message that is paused
When using the operation cancellable instead of soup_session_cancel_message().
-rw-r--r--libsoup/soup-message-io-data.c2
-rw-r--r--libsoup/soup-message-io.c4
-rw-r--r--libsoup/soup-session.c3
-rw-r--r--tests/auth-test.c55
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
@@ -750,6 +750,60 @@ do_async_auth_no_password_test (void)
}
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 {
const char *headers;
@@ -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);