[libsoup/websockets-fixes-2.66: 11/19] WebSockets: ignore any messages after close has been sent and received
- From: Claudio Saavedra <csaavedra src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsoup/websockets-fixes-2.66: 11/19] WebSockets: ignore any messages after close has been sent and received
- Date: Fri, 11 Dec 2020 14:41:15 +0000 (UTC)
commit a972c27352af299bf1ea069fcf85651a206d61ed
Author: Carlos Garcia Campos <cgarcia igalia com>
Date: Fri Jul 19 14:56:05 2019 +0200
WebSockets: ignore any messages after close has been sent and received
We currently ignore data frames when close has been received, but we
should also ignore any frame after close has been sent and received.
Currently, if we receive two close frames we end up with the code and
reason of the second frame, while the RFC says: "The WebSocket
Connection Close Code is defined as the status code contained in the
first Close control frame received by the application implementing
this protocol."
libsoup/soup-websocket-connection.c | 3 +++
tests/websocket-test.c | 48 +++++++++++++++++++++++++++++++++++++
2 files changed, 51 insertions(+)
---
diff --git a/libsoup/soup-websocket-connection.c b/libsoup/soup-websocket-connection.c
index b30fddf2..71a4a48f 100644
--- a/libsoup/soup-websocket-connection.c
+++ b/libsoup/soup-websocket-connection.c
@@ -772,6 +772,9 @@ process_contents (SoupWebsocketConnection *self,
SoupWebsocketConnectionPrivate *pv = self->pv;
GBytes *message;
+ if (pv->close_sent && pv->close_received)
+ return;
+
if (control) {
/* Control frames must never be fragmented */
if (!fin) {
diff --git a/tests/websocket-test.c b/tests/websocket-test.c
index 890f358c..d7e1bfb3 100644
--- a/tests/websocket-test.c
+++ b/tests/websocket-test.c
@@ -804,6 +804,49 @@ test_message_after_closing (Test *test,
g_bytes_unref (message);
}
+static gpointer
+close_after_close_server_thread (gpointer user_data)
+{
+ Test *test = user_data;
+ gsize written;
+ const char frames[] =
+ "\x88\x09\x03\xe8""reason1"
+ "\x88\x09\x03\xe8""reason2";
+ GError *error = NULL;
+
+ g_mutex_lock (&test->mutex);
+ g_mutex_unlock (&test->mutex);
+
+ g_output_stream_write_all (g_io_stream_get_output_stream (test->raw_server),
+ frames, sizeof (frames) -1, &written, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_cmpuint (written, ==, sizeof (frames) - 1);
+ g_io_stream_close (test->raw_server, NULL, &error);
+ g_assert_no_error (error);
+
+ return NULL;
+}
+
+static void
+test_close_after_close (Test *test,
+ gconstpointer data)
+{
+ GThread *thread;
+
+ g_mutex_lock (&test->mutex);
+
+ thread = g_thread_new ("close-after-close-thread", close_after_close_server_thread, test);
+
+ soup_websocket_connection_close (test->client, SOUP_WEBSOCKET_CLOSE_NORMAL, "reason1");
+ g_mutex_unlock (&test->mutex);
+
+ g_thread_join (thread);
+
+ WAIT_UNTIL (soup_websocket_connection_get_state (test->client) == SOUP_WEBSOCKET_STATE_CLOSED);
+ g_assert_cmpuint (soup_websocket_connection_get_close_code (test->client), ==,
SOUP_WEBSOCKET_CLOSE_NORMAL);
+ g_assert_cmpstr (soup_websocket_connection_get_close_data (test->client), ==, "reason1");
+}
+
static gpointer
timeout_server_thread (gpointer user_data)
{
@@ -1198,6 +1241,11 @@ main (int argc,
test_message_after_closing,
teardown_soup_connection);
+ g_test_add ("/websocket/direct/close-after-close", Test, NULL,
+ setup_half_direct_connection,
+ test_close_after_close,
+ teardown_direct_connection);
+
g_test_add ("/websocket/direct/protocol-negotiate", Test, NULL, NULL,
test_protocol_negotiate_direct,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]