diff options
author | Carlos Garcia Campos <cgarcia@igalia.com> | 2021-04-23 11:57:43 +0200 |
---|---|---|
committer | Carlos Garcia Campos <cgarcia@igalia.com> | 2021-04-23 11:57:43 +0200 |
commit | 33cffbe5aa3952e86a4fc0eab436c46ea8e62f4b (patch) | |
tree | 1afb9e4a871e1acdd989bcb8462b559d424d0b4e | |
parent | 0a6b2555b7ca74d7b879fa5ff06daf1bd22a56f6 (diff) | |
download | libsoup-carlosgc/preconnect-stolen.tar.gz |
preconnect: preconnect should never steal a connectioncarlosgc/preconnect-stolen
-rw-r--r-- | libsoup/soup-session.c | 3 | ||||
-rw-r--r-- | tests/connection-test.c | 116 |
2 files changed, 119 insertions, 0 deletions
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c index 393f01f1..64adb1de 100644 --- a/libsoup/soup-session.c +++ b/libsoup/soup-session.c @@ -1780,6 +1780,9 @@ steal_preconnection (SoupSession *session, if (!item->async) return FALSE; + if (item->connect_only) + return FALSE; + preconnect_item = soup_session_lookup_queue_item_by_connection (session, conn); if (!preconnect_item) return FALSE; diff --git a/tests/connection-test.c b/tests/connection-test.c index ec40bc5b..4bb13027 100644 --- a/tests/connection-test.c +++ b/tests/connection-test.c @@ -1401,6 +1401,119 @@ do_steal_connection_preconnect_fail_test (const char *uri, soup_test_session_abort_unref (session); } +typedef struct { + GMainLoop *loop; + guint count; +} StealPreconnectTestData; + +static void +steal_preconnect_finished (SoupSession *session, + GAsyncResult *result, + StealPreconnectTestData *data) +{ + soup_session_preconnect_finish (session, result, NULL); + if (++data->count == 2) + g_main_loop_quit (data->loop); +} + +static void +steal_preconnect_send_and_read_finished (SoupSession *session, + GAsyncResult *result, + StealPreconnectTestData *data) +{ + GBytes *bytes; + + bytes = soup_session_send_and_read_finish (session, result, NULL); + g_bytes_unref (bytes); + if (++data->count == 2) + g_main_loop_quit (data->loop); +} + +static void +do_steal_preconnect_connection_test (void) +{ + SoupSession *session; + SoupMessage *msg; + StealPreconnectTestData data = { NULL, 0 }; + PreconnectTestData data1 = { NULL, NULL, "rRcCx", SOUP_CONNECTION_DISCONNECTED, NULL, FALSE }; + PreconnectTestData data2 = { NULL, NULL, "rRcCx", SOUP_CONNECTION_DISCONNECTED, NULL, FALSE }; + + session = soup_test_session_new (NULL); + + /* Preconnect requests should never steal the connection of another preconnect. */ + + data.loop = g_main_loop_new (NULL, FALSE); + msg = soup_message_new ("HEAD", HTTP_SERVER); + g_signal_connect (msg, "network-event", + G_CALLBACK (preconnection_test_message_network_event), + &data1); + soup_session_preconnect_async (session, msg, G_PRIORITY_DEFAULT, NULL, + (GAsyncReadyCallback)steal_preconnect_finished, + &data); + g_object_unref (msg); + + msg = soup_message_new ("HEAD", HTTP_SERVER); + g_signal_connect (msg, "network-event", + G_CALLBACK (preconnection_test_message_network_event), + &data2); + soup_session_preconnect_async (session, msg, G_PRIORITY_DEFAULT, NULL, + (GAsyncReadyCallback)steal_preconnect_finished, + &data); + g_object_unref (msg); + + g_main_loop_run (data.loop); + g_assert_nonnull (data1.conn); + g_assert_nonnull (data2.conn); + g_assert_false (data1.conn == data2.conn); + g_assert_cmpint (data1.state, ==, SOUP_CONNECTION_IDLE); + g_assert_cmpint (data2.state, ==, SOUP_CONNECTION_IDLE); + + while (*data1.events) { + soup_test_assert (!*data1.events, + "Expected %s", + event_name_from_abbrev (*data1.events)); + soup_test_assert (!*data2.events, + "Expected %s", + event_name_from_abbrev (*data2.events)); + data1.events++; + data2.events++; + } + + data.count = 0; + g_clear_object (&data1.conn); + g_clear_object (&data2.conn); + + msg = soup_message_new ("GET", HTTP_SERVER); + g_signal_connect (msg, "network-event", + G_CALLBACK (preconnection_test_message_network_event), + &data1); + soup_session_send_and_read_async (session, msg, G_PRIORITY_DEFAULT, NULL, + (GAsyncReadyCallback)steal_preconnect_send_and_read_finished, + &data); + g_object_unref (msg); + + msg = soup_message_new ("GET", HTTP_SERVER); + g_signal_connect (msg, "network-event", + G_CALLBACK (preconnection_test_message_network_event), + &data2); + soup_session_send_and_read_async (session, msg, G_PRIORITY_DEFAULT, NULL, + (GAsyncReadyCallback)steal_preconnect_send_and_read_finished, + &data); + g_object_unref (msg); + + g_main_loop_run (data.loop); + + /* connection-created hasn't been called. */ + g_assert_null (data1.conn); + g_assert_null (data2.conn); + g_assert_cmpint (data1.state, ==, SOUP_CONNECTION_IDLE); + g_assert_cmpint (data2.state, ==, SOUP_CONNECTION_IDLE); + + g_main_loop_unref (data.loop); + + soup_test_session_abort_unref (session); +} + static void do_connection_preconnect_test (void) { @@ -1440,6 +1553,9 @@ do_connection_preconnect_test (void) "r"); } else debug_printf (1, " https -- SKIPPING\n"); + + debug_printf (1, " preconnect should never steal a connection\n"); + do_steal_preconnect_connection_test (); } static void |