diff options
author | Carlos Garcia Campos <cgarcia@igalia.com> | 2023-04-08 09:15:59 +0200 |
---|---|---|
committer | Carlos Garcia Campos <cgarcia@igalia.com> | 2023-05-08 14:58:55 +0200 |
commit | cad8cc385338bf5681e62b82979c4442bc64319b (patch) | |
tree | 8015291b3a94bc8e330149aeb900457588aa2b30 /libsoup/soup-session.c | |
parent | b78cb58ee9b47f8ffe18697ee3b096743a01e6a8 (diff) | |
download | libsoup-master.tar.gz |
session: handle request cancellation earlierHEADmastercarlosgc/early-cancellation
Check if the message was cancelled before the request is sent.
Diffstat (limited to 'libsoup/soup-session.c')
-rw-r--r-- | libsoup/soup-session.c | 86 |
1 files changed, 59 insertions, 27 deletions
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c index 1020feed..5a0dce23 100644 --- a/libsoup/soup-session.c +++ b/libsoup/soup-session.c @@ -107,6 +107,9 @@ static void soup_session_process_queue_item (SoupSession *session, SoupMessageQueueItem *item, gboolean loop); +static void async_send_request_return_result (SoupMessageQueueItem *item, + gpointer stream, GError *error); + #define SOUP_SESSION_MAX_CONNS_DEFAULT 10 #define SOUP_SESSION_MAX_CONNS_PER_HOST_DEFAULT 2 @@ -1366,7 +1369,20 @@ soup_session_append_queue_item (SoupSession *session, return item; } -static void +static gboolean +finish_request_if_item_cancelled (SoupMessageQueueItem *item) +{ + if (!g_cancellable_is_cancelled (item->cancellable)) + return FALSE; + + if (item->async) + async_send_request_return_result (item, NULL, NULL); + + item->state = SOUP_MESSAGE_FINISHING; + return TRUE; +} + +static gboolean soup_session_send_queue_item (SoupSession *session, SoupMessageQueueItem *item, SoupMessageIOCompletionFn completion_cb) @@ -1405,9 +1421,13 @@ soup_session_send_queue_item (SoupSession *session, soup_message_headers_set_content_length (request_headers, 0); } - soup_message_starting (item->msg); - if (item->state == SOUP_MESSAGE_RUNNING) - soup_message_send_item (item->msg, item, completion_cb, item); + soup_message_starting (item->msg); + finish_request_if_item_cancelled (item); + if (item->state != SOUP_MESSAGE_RUNNING) + return FALSE; + + soup_message_send_item (item->msg, item, completion_cb, item); + return TRUE; } static void @@ -1541,15 +1561,19 @@ tunnel_message_completed (SoupMessage *msg, SoupMessageIOCompletion completion, g_object_unref (conn); g_clear_object (&tunnel_item->error); tunnel_item->state = SOUP_MESSAGE_RUNNING; - soup_session_send_queue_item (session, tunnel_item, - (SoupMessageIOCompletionFn)tunnel_message_completed); - soup_message_io_run (msg, !tunnel_item->async); + if (soup_session_send_queue_item (session, tunnel_item, (SoupMessageIOCompletionFn)tunnel_message_completed)) + soup_message_io_run (msg, !tunnel_item->async); + else + tunnel_message_completed (msg, SOUP_MESSAGE_IO_INTERRUPTED, tunnel_item); return; } item->state = SOUP_MESSAGE_RESTARTING; } + if (item->state == SOUP_MESSAGE_FINISHING) + soup_message_finished (tunnel_item->msg); + tunnel_item->state = SOUP_MESSAGE_FINISHED; soup_session_unqueue_item (session, tunnel_item); @@ -1601,9 +1625,10 @@ tunnel_connect (SoupMessageQueueItem *item) g_clear_object (&conn); tunnel_item->state = SOUP_MESSAGE_RUNNING; - soup_session_send_queue_item (session, tunnel_item, - (SoupMessageIOCompletionFn)tunnel_message_completed); - soup_message_io_run (msg, !item->async); + if (soup_session_send_queue_item (session, tunnel_item, (SoupMessageIOCompletionFn)tunnel_message_completed)) + soup_message_io_run (msg, !item->async); + else + tunnel_message_completed (msg, SOUP_MESSAGE_IO_INTERRUPTED, tunnel_item); g_object_unref (msg); } @@ -1742,20 +1767,24 @@ soup_session_process_queue_item (SoupSession *session, switch (item->state) { case SOUP_MESSAGE_STARTING: - if (!soup_session_ensure_item_connection (session, item)) - return; + if (!finish_request_if_item_cancelled (item)) { + if (!soup_session_ensure_item_connection (session, item)) + return; + } break; - case SOUP_MESSAGE_CONNECTED: { - SoupConnection *conn = soup_message_get_connection (item->msg); + case SOUP_MESSAGE_CONNECTED: + if (!finish_request_if_item_cancelled (item)) { + SoupConnection *conn = soup_message_get_connection (item->msg); - if (soup_connection_is_tunnelled (conn)) + if (soup_connection_is_tunnelled (conn)) tunnel_connect (item); - else - item->state = SOUP_MESSAGE_READY; - g_object_unref (conn); + else + item->state = SOUP_MESSAGE_READY; + g_object_unref (conn); + } break; - } + case SOUP_MESSAGE_READY: if (item->connect_only) { item->state = SOUP_MESSAGE_FINISHING; @@ -1767,16 +1796,17 @@ soup_session_process_queue_item (SoupSession *session, break; } - item->state = SOUP_MESSAGE_RUNNING; + if (!finish_request_if_item_cancelled (item)) { + item->state = SOUP_MESSAGE_RUNNING; - soup_message_set_metrics_timestamp (item->msg, SOUP_MESSAGE_METRICS_REQUEST_START); + soup_message_set_metrics_timestamp (item->msg, SOUP_MESSAGE_METRICS_REQUEST_START); - soup_session_send_queue_item (session, item, - (SoupMessageIOCompletionFn)message_completed); + if (soup_session_send_queue_item (session, item, (SoupMessageIOCompletionFn)message_completed) && item->async) + async_send_request_running (session, item); - if (item->async) - async_send_request_running (session, item); - return; + return; + } + break; case SOUP_MESSAGE_RUNNING: if (item->async) @@ -3192,8 +3222,10 @@ soup_session_send (SoupSession *session, while (!stream) { /* Get a connection, etc */ soup_session_process_queue_item (session, item, TRUE); - if (item->state != SOUP_MESSAGE_RUNNING) + if (item->state != SOUP_MESSAGE_RUNNING) { + g_cancellable_set_error_if_cancelled (item->cancellable, &my_error); break; + } /* Send request, read headers */ if (!soup_message_io_run_until_read (msg, item->cancellable, &my_error)) { |