diff options
author | Carlos Garcia Campos <cgarcia@igalia.com> | 2019-06-17 12:36:40 +0200 |
---|---|---|
committer | Claudio Saavedra <csaavedra@igalia.com> | 2020-12-11 16:40:19 +0200 |
commit | a128be3514ca3dd4af3eae0a3ce5fbfe0268511f (patch) | |
tree | cb90adfc764f4637a65e22e9c8e0928170d80046 | |
parent | 405060e6d165d88340ba6ca5a62bacdb7a3668f4 (diff) | |
download | libsoup-a128be3514ca3dd4af3eae0a3ce5fbfe0268511f.tar.gz |
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.
-rw-r--r-- | libsoup/soup-session.c | 2 | ||||
-rw-r--r-- | tests/websocket-test.c | 53 |
2 files changed, 55 insertions, 0 deletions
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, |