[libsoup/websockets-fixes-2.64: 2/19] WebSockets: fix runtime critical warning when handshake fails




commit 9d97c99533eabfe99845c4288909ed2f221cbce9
Author: Carlos Garcia Campos <cgarcia igalia com>
Date:   Mon Jun 17 12:36:40 2019 +0200

    WebSockets: fix runtime critical warning when handshake fails
    
    (process:20018): GLib-GIO-CRITICAL **: 12:26:09.686: g_task_return_error: assertion 'G_IS_TASK (task)' 
failed
    (process:20018): GLib-GObject-CRITICAL **: 12:26:09.686: g_object_unref: assertion 'G_IS_OBJECT (object)' 
failed
    
    We are trying to complete the GTask twice, first in
    websocket_connect_async_stop() and then in
    websocket_connect_async_complete(). The latter should only be called if
    the item finishes before got-informational signal is emitted.

 libsoup/soup-session.c |  2 ++
 tests/websocket-test.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)
---
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index f4a68507..5ecae857 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -4804,6 +4804,8 @@ websocket_connect_async_stop (SoupMessage *msg, gpointer user_data)
        /* Disconnect websocket_connect_async_stop() handler. */
        g_signal_handlers_disconnect_matched (msg, G_SIGNAL_MATCH_DATA,
                                              0, 0, NULL, NULL, task);
+       /* Ensure websocket_connect_async_complete is not called either. */
+       item->callback = NULL;
 
        if (soup_websocket_client_verify_handshake (item->msg, &error)){
                stream = soup_session_steal_connection (item->session, item->msg);
diff --git a/tests/websocket-test.c b/tests/websocket-test.c
index 722ccbdf..2347ed5c 100644
--- a/tests/websocket-test.c
+++ b/tests/websocket-test.c
@@ -311,6 +311,55 @@ test_handshake (Test *test,
        g_assert_cmpint (soup_websocket_connection_get_state (test->server), ==, SOUP_WEBSOCKET_STATE_OPEN);
 }
 
+static void
+websocket_server_request_started (SoupServer *server, SoupMessage *msg,
+                                 SoupClientContext *client, gpointer user_data)
+{
+       soup_message_headers_append (msg->response_headers, "Sec-WebSocket-Extensions", "x-foo");
+}
+
+static void
+request_unqueued (SoupSession *session,
+                 SoupMessage *msg,
+                  gpointer data)
+{
+       Test *test = data;
+
+       if (test->msg == msg)
+               g_clear_object (&test->msg);
+}
+
+
+static void
+test_handshake_unsupported_extension (Test *test,
+                                     gconstpointer data)
+{
+       char *url;
+
+       setup_listener (test);
+       test->soup_server = soup_test_server_new (SOUP_TEST_SERVER_IN_THREAD);
+       soup_server_listen_socket (test->soup_server, test->listener, 0, NULL);
+       g_signal_connect (test->soup_server, "request-started",
+                         G_CALLBACK (websocket_server_request_started),
+                         NULL);
+       soup_server_add_websocket_handler (test->soup_server, "/unix", NULL, NULL,
+                                          got_server_connection, test, NULL);
+
+       test->session = soup_test_session_new (SOUP_TYPE_SESSION, NULL);
+       g_signal_connect (test->session, "request-unqueued",
+                         G_CALLBACK (request_unqueued),
+                         test);
+        url = g_strdup_printf ("ws://127.0.0.1:%u/unix", test->port);
+        test->msg = soup_message_new ("GET", url);
+        g_free (url);
+
+       soup_session_websocket_connect_async (test->session, test->msg, NULL, NULL, NULL,
+                                             got_client_connection, test);
+       WAIT_UNTIL (test->server != NULL);
+       WAIT_UNTIL (test->msg == NULL);
+       g_assert_error (test->client_error, SOUP_WEBSOCKET_ERROR, SOUP_WEBSOCKET_ERROR_BAD_HANDSHAKE);
+}
+
 #define TEST_STRING "this is a test"
 
 static void
@@ -855,6 +904,10 @@ main (int argc,
                    test_handshake,
                    teardown_soup_connection);
 
+       g_test_add ("/websocket/soup/handshake-error", Test, NULL, NULL,
+                   test_handshake_unsupported_extension,
+                   teardown_soup_connection);
+
        g_test_add ("/websocket/direct/send-client-to-server", Test, NULL,
                    setup_direct_connection,
                    test_send_client_to_server,


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