diff options
author | Carlos Garcia Campos <cgarcia@igalia.com> | 2020-09-10 15:49:37 +0200 |
---|---|---|
committer | Carlos Garcia Campos <carlosgc@gnome.org> | 2020-09-10 15:56:10 +0200 |
commit | e85c8c23895e12516e3266ab22a54ec3e4ba47f9 (patch) | |
tree | bb6ced71498fac12218a9fc1f8f7704269cc4b3c | |
parent | e2e6fa43bb677f33dc89f2c6a0914a88a7b1a24b (diff) | |
download | libsoup-carlosgc/auth-retry-cancel.tar.gz |
Fix runtime critical when message is cancelled after a failed authcarlosgc/auth-retry-cancel
When the message is restarted due to the failed auth, we fail to
properly reset the SoupSession:ostream data on the item task and we end up
calling async_send_request_return_result() twice causing the following
critical the second time:
(auth-test:66750): libsoup-CRITICAL **: 15:48:08.156: async_send_request_return_result: assertion 'item->task != NULL' failed
SoupSession:ostream data is set in item task, but we reset in item
message.
-rw-r--r-- | libsoup/soup-session.c | 3 | ||||
-rw-r--r-- | tests/auth-test.c | 60 |
2 files changed, 62 insertions, 1 deletions
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c index 6d68c9fb..dd3cdc46 100644 --- a/libsoup/soup-session.c +++ b/libsoup/soup-session.c @@ -3944,7 +3944,8 @@ async_send_request_restarted (SoupMessage *msg, gpointer user_data) SoupMessageQueueItem *item = user_data; /* We won't be needing this, then. */ - g_object_set_data (G_OBJECT (item->msg), "SoupSession:ostream", NULL); + if (item->task) + g_object_set_data (G_OBJECT (item->task), "SoupSession:ostream", NULL); item->io_started = FALSE; } diff --git a/tests/auth-test.c b/tests/auth-test.c index 95de60c2..8295ec32 100644 --- a/tests/auth-test.c +++ b/tests/auth-test.c @@ -1490,6 +1490,65 @@ do_message_has_authorization_header_test (void) soup_test_session_abort_unref (session); } +static void +cancel_after_retry_authenticate (SoupSession *session, + SoupMessage *msg, + SoupAuth *auth, + gboolean retrying, + GCancellable *cancellable) +{ + if (retrying) { + soup_session_cancel_message (session, msg, SOUP_STATUS_CANCELLED); + g_cancellable_cancel (cancellable); + } else + soup_auth_authenticate (auth, "user1", "wrong"); +} + +static void +request_send_cb (SoupSession *session, + GAsyncResult *result, + GMainLoop *loop) +{ + GInputStream *stream; + GError *error = NULL; + + stream = soup_session_send_finish (session, result, &error); + g_assert_null (stream); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); + + g_main_loop_quit (loop); +} + +static void +do_cancel_after_retry_test (void) +{ + SoupSession *session; + SoupMessage *msg; + char *uri; + GCancellable *cancellable; + GMainLoop *loop; + + SOUP_TEST_SKIP_IF_NO_APACHE; + + session = soup_test_session_new (SOUP_TYPE_SESSION, NULL); + cancellable = g_cancellable_new (); + g_signal_connect (session, "authenticate", + G_CALLBACK (cancel_after_retry_authenticate), + cancellable); + + loop = g_main_loop_new (NULL, FALSE); + + uri = g_strconcat (base_uri, "Digest/realm1/", NULL); + msg = soup_message_new ("GET", uri); + soup_session_send_async (session, msg, cancellable, (GAsyncReadyCallback)request_send_cb, loop); + g_main_loop_run (loop); + + g_object_unref (msg); + g_object_unref (cancellable); + g_free (uri); + soup_test_session_abort_unref (session); +} + int main (int argc, char **argv) { @@ -1516,6 +1575,7 @@ main (int argc, char **argv) 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); + g_test_add_func ("/auth/cancel-after-retry", do_cancel_after_retry_test); ret = g_test_run (); |