diff options
author | Carlos Garcia Campos <cgarcia@igalia.com> | 2021-02-10 14:53:12 +0100 |
---|---|---|
committer | Carlos Garcia Campos <cgarcia@igalia.com> | 2021-02-10 14:53:12 +0100 |
commit | 046aac0bbc6bf9745e6cf970d2507c1a4342071f (patch) | |
tree | 9764734bcc5e641f84ae06fbfc59245cae156a8f | |
parent | 607feb72333bf0553d966bafa0f93866e31d8240 (diff) | |
download | libsoup-carlosgc/websocket-connection-error.tar.gz |
WebSockets: do not report connection errors as handshake failurescarlosgc/websocket-connection-error
We are assuming that when not switching protocols after a request is
because the server didn't accept the handshake, but we can fail even
earlier if there's a connection error. In libsoup 2 we could check if
it was a connection error by checking the message status was
SOUP_STATUS_CANT_CONNECT or SOUP_STATUS_CANT_CONNECT_PROXY. Now that we
no longer use the message status for transport errors, we should make
soup_session_websocket_connect_async() fail with the connection error.
-rw-r--r-- | libsoup/soup-session.c | 12 | ||||
-rw-r--r-- | tests/websocket-test.c | 32 |
2 files changed, 41 insertions, 3 deletions
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c index 4509993a..baecb245 100644 --- a/libsoup/soup-session.c +++ b/libsoup/soup-session.c @@ -3729,14 +3729,20 @@ static void websocket_connect_async_complete (SoupSession *session, SoupMessage *msg, gpointer user_data) { GTask *task = user_data; + SoupMessageQueueItem *item = g_task_get_task_data (task); /* Disconnect websocket_connect_async_stop() handler. */ g_signal_handlers_disconnect_matched (msg, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, task); - g_task_return_new_error (task, - SOUP_WEBSOCKET_ERROR, SOUP_WEBSOCKET_ERROR_NOT_WEBSOCKET, - "%s", _("The server did not accept the WebSocket handshake.")); + if (item->error) { + g_task_return_error (task, g_error_copy (item->error)); + } else { + g_task_return_new_error (task, + SOUP_WEBSOCKET_ERROR, SOUP_WEBSOCKET_ERROR_NOT_WEBSOCKET, + "%s", _("The server did not accept the WebSocket handshake.")); + } + g_object_unref (task); } diff --git a/tests/websocket-test.c b/tests/websocket-test.c index 714f77fb..5c8a83a4 100644 --- a/tests/websocket-test.c +++ b/tests/websocket-test.c @@ -1986,6 +1986,36 @@ test_cookies_in_response (Test *test, soup_cookie_free (cookie); } +static void +test_connection_error_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + GError **error = user_data; + + g_assert_null (soup_session_websocket_connect_finish (SOUP_SESSION (object), result, error)); +} + +static void +test_connection_error (void) +{ + SoupSession *session; + SoupMessage *msg; + GError *error = NULL; + + session = soup_test_session_new (NULL); + + msg = soup_message_new ("GET", "ws://127.0.0.1:1234/unix"); + soup_session_websocket_connect_async (session, msg, NULL, NULL, G_PRIORITY_DEFAULT, + NULL, test_connection_error_cb, &error); + WAIT_UNTIL (error != NULL); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_REFUSED); + + g_error_free (error); + g_object_unref (msg); + soup_test_session_abort_unref (session); +} + int main (int argc, char *argv[]) @@ -2219,6 +2249,8 @@ main (int argc, test_cookies_in_response, teardown_soup_connection); + g_test_add_func ("/websocket/soup/connection-error", test_connection_error); + ret = g_test_run (); test_cleanup (); |