From e92090335468e14d25f2197e0cb5085e8b8d03cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Helleu?= Date: Sun, 2 Jun 2024 09:05:40 +0200 Subject: [PATCH] relay: enable websocket extension "permessage-deflate" with "api" relay only --- ChangeLog.adoc | 5 ++ .../relay/api/remote/relay-remote-network.c | 3 +- src/plugins/relay/relay-http.c | 21 +++++-- src/plugins/relay/relay-websocket.c | 4 +- src/plugins/relay/relay-websocket.h | 3 +- .../plugins/relay/test-relay-websocket.cpp | 55 +++++++++++++------ 6 files changed, 67 insertions(+), 24 deletions(-) diff --git a/ChangeLog.adoc b/ChangeLog.adoc index 0e255d47d..7fc6713cf 100644 --- a/ChangeLog.adoc +++ b/ChangeLog.adoc @@ -11,6 +11,11 @@ [[v4.3.2]] == Version 4.3.2 (under dev) +[[v4.3.2_changed]] +=== Changed + +* relay: enable websocket extension "permessage-deflate" with "api" relay only + [[v4.3.2_added]] === Added diff --git a/src/plugins/relay/api/remote/relay-remote-network.c b/src/plugins/relay/api/remote/relay-remote-network.c index 673096772..b43b210f6 100644 --- a/src/plugins/relay/api/remote/relay-remote-network.c +++ b/src/plugins/relay/api/remote/relay-remote-network.c @@ -206,7 +206,8 @@ relay_remote_network_check_auth (struct t_relay_remote *remote, relay_websocket_parse_extensions ( weechat_hashtable_get (http_resp->headers, "sec-websocket-extensions"), - remote->ws_deflate); + remote->ws_deflate, + 1); /* ws_deflate_allowed */ if (!accept_ok) { diff --git a/src/plugins/relay/relay-http.c b/src/plugins/relay/relay-http.c index 63f803389..94a73da08 100644 --- a/src/plugins/relay/relay-http.c +++ b/src/plugins/relay/relay-http.c @@ -385,6 +385,10 @@ error: /* * Parses and saves a HTTP header in hashtable "headers". * + * The parameter "ws_deflate_allowed" controls whether the websocket extension + * "permessage-deflate" is allowed or not (it is allowed only with "api" + * protocol). + * * Returns: * 1: OK, header saved * 0: error: invalid format @@ -392,7 +396,8 @@ error: int relay_http_parse_header (struct t_relay_http_request *request, - const char *header) + const char *header, + int ws_deflate_allowed) { char *pos, *name, *name_lower, *error, **items; const char *ptr_value; @@ -465,7 +470,12 @@ relay_http_parse_header (struct t_relay_http_request *request, * extensions */ if (strcmp (name_lower, "sec-websocket-extensions") == 0) - relay_websocket_parse_extensions (ptr_value, request->ws_deflate); + { + relay_websocket_parse_extensions ( + ptr_value, + request->ws_deflate, + ws_deflate_allowed); + } free (name); free (name_lower); @@ -891,7 +901,7 @@ void relay_http_recv (struct t_relay_client *client, const char *data) { char *new_partial, *pos; - int length; + int length, ws_deflate_allowed; if (client->partial_message) { @@ -924,8 +934,11 @@ relay_http_recv (struct t_relay_client *client, const char *data) } else { + ws_deflate_allowed = (client->protocol == RELAY_PROTOCOL_API) ? + 1 : 0; relay_http_parse_header (client->http_req, - client->partial_message); + client->partial_message, + ws_deflate_allowed); } pos[0] = '\r'; pos++; diff --git a/src/plugins/relay/relay-websocket.c b/src/plugins/relay/relay-websocket.c index 4e6f167f2..6fd290859 100644 --- a/src/plugins/relay/relay-websocket.c +++ b/src/plugins/relay/relay-websocket.c @@ -301,7 +301,8 @@ relay_websocket_client_handshake_valid (struct t_relay_http_request *request) void relay_websocket_parse_extensions (const char *extensions, - struct t_relay_websocket_deflate *ws_deflate) + struct t_relay_websocket_deflate *ws_deflate, + int ws_deflate_allowed) { char **exts, **params, **items, *error; int i, j, num_exts, num_params, num_items; @@ -319,6 +320,7 @@ relay_websocket_parse_extensions (const char *extensions, params = weechat_string_split (exts[i], ";", " ", 0, 0, &num_params); if (params && (num_params >= 1) && (strcmp (params[0], "permessage-deflate") == 0) + && ws_deflate_allowed && (weechat_config_integer (relay_config_network_compression) > 0)) { ws_deflate->enabled = 1; diff --git a/src/plugins/relay/relay-websocket.h b/src/plugins/relay/relay-websocket.h index 64d9d5b7e..5845a4e8f 100644 --- a/src/plugins/relay/relay-websocket.h +++ b/src/plugins/relay/relay-websocket.h @@ -71,7 +71,8 @@ extern int relay_websocket_is_valid_http_get (enum t_relay_protocol protocol, const char *message); extern int relay_websocket_client_handshake_valid (struct t_relay_http_request *request); extern void relay_websocket_parse_extensions (const char *extensions, - struct t_relay_websocket_deflate *ws_deflate); + struct t_relay_websocket_deflate *ws_deflate, + int ws_deflate_allowed); extern char *relay_websocket_build_handshake (struct t_relay_http_request *request); extern int relay_websocket_decode_frame (const unsigned char *buffer, unsigned long long length, diff --git a/tests/unit/plugins/relay/test-relay-websocket.cpp b/tests/unit/plugins/relay/test-relay-websocket.cpp index 7ff3c00d3..4c44850cc 100644 --- a/tests/unit/plugins/relay/test-relay-websocket.cpp +++ b/tests/unit/plugins/relay/test-relay-websocket.cpp @@ -167,7 +167,7 @@ TEST(RelayWebsocket, ClientHandshakeValid) LONGS_EQUAL(0, relay_websocket_client_handshake_valid (request)); relay_websocket_deflate_reinit (request->ws_deflate); - relay_websocket_parse_extensions ("permessage-deflate", request->ws_deflate); + relay_websocket_parse_extensions ("permessage-deflate", request->ws_deflate, 1); LONGS_EQUAL(1, request->ws_deflate->enabled); LONGS_EQUAL(1, request->ws_deflate->server_context_takeover); LONGS_EQUAL(1, request->ws_deflate->client_context_takeover); @@ -187,7 +187,8 @@ TEST(RelayWebsocket, ClientHandshakeValid) relay_websocket_deflate_reinit (request->ws_deflate); relay_websocket_parse_extensions ( "permessage-deflate; client_max_window_bits", - request->ws_deflate); + request->ws_deflate, + 1); LONGS_EQUAL(1, request->ws_deflate->enabled); LONGS_EQUAL(1, request->ws_deflate->server_context_takeover); LONGS_EQUAL(1, request->ws_deflate->client_context_takeover); @@ -207,7 +208,8 @@ TEST(RelayWebsocket, ClientHandshakeValid) relay_websocket_deflate_reinit (request->ws_deflate); relay_websocket_parse_extensions ( "permessage-deflate; client_max_window_bits = 12; server_no_context_takeover", - request->ws_deflate); + request->ws_deflate, + 1); LONGS_EQUAL(1, request->ws_deflate->enabled); LONGS_EQUAL(0, request->ws_deflate->server_context_takeover); LONGS_EQUAL(1, request->ws_deflate->client_context_takeover); @@ -227,7 +229,8 @@ TEST(RelayWebsocket, ClientHandshakeValid) relay_websocket_deflate_reinit (request->ws_deflate); relay_websocket_parse_extensions ( "permessage-deflate; client_max_window_bits = 12; server_max_window_bits=8; client_no_context_takeover; server_no_context_takeover", - request->ws_deflate); + request->ws_deflate, + 1); LONGS_EQUAL(1, request->ws_deflate->enabled); LONGS_EQUAL(0, request->ws_deflate->server_context_takeover); LONGS_EQUAL(0, request->ws_deflate->client_context_takeover); @@ -256,16 +259,26 @@ TEST(RelayWebsocket, ParseExtensions) { struct t_relay_websocket_deflate ws_deflate; - relay_websocket_parse_extensions (NULL, NULL); - relay_websocket_parse_extensions ("test", NULL); - relay_websocket_parse_extensions (NULL, &ws_deflate); + relay_websocket_parse_extensions (NULL, NULL, 1); + relay_websocket_parse_extensions ("test", NULL, 1); + relay_websocket_parse_extensions (NULL, &ws_deflate, 1); memset (&ws_deflate, 0, sizeof (ws_deflate)); - relay_websocket_parse_extensions ("test", &ws_deflate); + relay_websocket_parse_extensions ("test", &ws_deflate, 1); LONGS_EQUAL(0, ws_deflate.enabled); memset (&ws_deflate, 0, sizeof (ws_deflate)); - relay_websocket_parse_extensions ("permessage-deflate", &ws_deflate); + relay_websocket_parse_extensions ("permessage-deflate", &ws_deflate, 0); + LONGS_EQUAL(0, ws_deflate.enabled); + LONGS_EQUAL(0, ws_deflate.server_context_takeover); + LONGS_EQUAL(0, ws_deflate.client_context_takeover); + LONGS_EQUAL(0, ws_deflate.window_bits_deflate); + LONGS_EQUAL(0, ws_deflate.window_bits_inflate); + POINTERS_EQUAL(NULL, ws_deflate.strm_deflate); + POINTERS_EQUAL(NULL, ws_deflate.strm_inflate); + + memset (&ws_deflate, 0, sizeof (ws_deflate)); + relay_websocket_parse_extensions ("permessage-deflate", &ws_deflate, 1); LONGS_EQUAL(1, ws_deflate.enabled); LONGS_EQUAL(1, ws_deflate.server_context_takeover); LONGS_EQUAL(1, ws_deflate.client_context_takeover); @@ -276,7 +289,8 @@ TEST(RelayWebsocket, ParseExtensions) memset (&ws_deflate, 0, sizeof (ws_deflate)); relay_websocket_parse_extensions ("permessage-deflate; client_max_window_bits", - &ws_deflate); + &ws_deflate, + 1); LONGS_EQUAL(1, ws_deflate.enabled); LONGS_EQUAL(1, ws_deflate.server_context_takeover); LONGS_EQUAL(1, ws_deflate.client_context_takeover); @@ -289,7 +303,8 @@ TEST(RelayWebsocket, ParseExtensions) memset (&ws_deflate, 0, sizeof (ws_deflate)); relay_websocket_parse_extensions ( "permessage-deflate; client_max_window_bits=4", - &ws_deflate); + &ws_deflate, + 1); LONGS_EQUAL(1, ws_deflate.enabled); LONGS_EQUAL(1, ws_deflate.server_context_takeover); LONGS_EQUAL(1, ws_deflate.client_context_takeover); @@ -302,7 +317,8 @@ TEST(RelayWebsocket, ParseExtensions) memset (&ws_deflate, 0, sizeof (ws_deflate)); relay_websocket_parse_extensions ( "permessage-deflate; client_max_window_bits=30", - &ws_deflate); + &ws_deflate, + 1); LONGS_EQUAL(1, ws_deflate.enabled); LONGS_EQUAL(1, ws_deflate.server_context_takeover); LONGS_EQUAL(1, ws_deflate.client_context_takeover); @@ -315,7 +331,8 @@ TEST(RelayWebsocket, ParseExtensions) memset (&ws_deflate, 0, sizeof (ws_deflate)); relay_websocket_parse_extensions ( "permessage-deflate; client_max_window_bits=test", - &ws_deflate); + &ws_deflate, + 1); LONGS_EQUAL(1, ws_deflate.enabled); LONGS_EQUAL(1, ws_deflate.server_context_takeover); LONGS_EQUAL(1, ws_deflate.client_context_takeover); @@ -327,7 +344,8 @@ TEST(RelayWebsocket, ParseExtensions) memset (&ws_deflate, 0, sizeof (ws_deflate)); relay_websocket_parse_extensions ( "permessage-deflate; client_max_window_bits=9", - &ws_deflate); + &ws_deflate, + 1); LONGS_EQUAL(1, ws_deflate.enabled); LONGS_EQUAL(1, ws_deflate.server_context_takeover); LONGS_EQUAL(1, ws_deflate.client_context_takeover); @@ -339,7 +357,8 @@ TEST(RelayWebsocket, ParseExtensions) memset (&ws_deflate, 0, sizeof (ws_deflate)); relay_websocket_parse_extensions ( "permessage-deflate; client_max_window_bits=9; server_max_window_bits=10", - &ws_deflate); + &ws_deflate, + 1); LONGS_EQUAL(1, ws_deflate.enabled); LONGS_EQUAL(1, ws_deflate.server_context_takeover); LONGS_EQUAL(1, ws_deflate.client_context_takeover); @@ -352,7 +371,8 @@ TEST(RelayWebsocket, ParseExtensions) relay_websocket_parse_extensions ( "permessage-deflate; client_max_window_bits=9; server_max_window_bits=10; " "server_no_context_takeover", - &ws_deflate); + &ws_deflate, + 1); LONGS_EQUAL(1, ws_deflate.enabled); LONGS_EQUAL(0, ws_deflate.server_context_takeover); LONGS_EQUAL(1, ws_deflate.client_context_takeover); @@ -365,7 +385,8 @@ TEST(RelayWebsocket, ParseExtensions) relay_websocket_parse_extensions ( "permessage-deflate; client_max_window_bits=9; server_max_window_bits=10; " "server_no_context_takeover; client_no_context_takeover", - &ws_deflate); + &ws_deflate, + 1); LONGS_EQUAL(1, ws_deflate.enabled); LONGS_EQUAL(0, ws_deflate.server_context_takeover); LONGS_EQUAL(0, ws_deflate.client_context_takeover);