mirror of
https://github.com/weechat/weechat.git
synced 2026-06-12 14:14:48 +02:00
relay: fix websocket permessage-deflate extension when the client doesn't send the max window bits parameters
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
- xfer: fix send of data on the DCC chat buffer after `/upgrade` if the buffer was opened before the upgrade ([#2092](https://github.com/weechat/weechat/issues/2092))
|
||||
- php: fix return value of function hdata_longlong
|
||||
- tcl: fix return value of function hdata_longlong ([#2119](https://github.com/weechat/weechat/issues/2119))
|
||||
- relay: fix websocket permessage-deflate extension when the client doesn't send the max window bits parameters
|
||||
- relay: fix allocation and reinit of field "client_context_takeover" in websocket deflate structure
|
||||
- core: fix detection of libgcrypt ≥ 1.11 ([debian #1071960](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1071960))
|
||||
- core, relay: fix include directory of libcjson and libzstd
|
||||
|
||||
@@ -1620,6 +1620,8 @@ relay_client_new_with_infolist (struct t_infolist *infolist)
|
||||
new_client->ws_deflate->client_context_takeover = weechat_infolist_integer (infolist, "ws_deflate_client_context_takeover");
|
||||
new_client->ws_deflate->window_bits_deflate = weechat_infolist_integer (infolist, "ws_deflate_window_bits_deflate");
|
||||
new_client->ws_deflate->window_bits_inflate = weechat_infolist_integer (infolist, "ws_deflate_window_bits_inflate");
|
||||
new_client->ws_deflate->server_max_window_bits_recv = weechat_infolist_integer (infolist, "ws_deflate_server_max_window_bits_recv");
|
||||
new_client->ws_deflate->client_max_window_bits_recv = weechat_infolist_integer (infolist, "ws_deflate_client_max_window_bits_recv");
|
||||
new_client->ws_deflate->strm_deflate = NULL;
|
||||
new_client->ws_deflate->strm_inflate = NULL;
|
||||
if (weechat_infolist_search_var (infolist, "ws_deflate_strm_deflate_dict"))
|
||||
@@ -2073,6 +2075,10 @@ relay_client_add_to_infolist (struct t_infolist *infolist,
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_integer (ptr_item, "ws_deflate_window_bits_inflate", client->ws_deflate->window_bits_inflate))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_integer (ptr_item, "ws_deflate_server_max_window_bits_recv", client->ws_deflate->server_max_window_bits_recv))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_integer (ptr_item, "ws_deflate_client_max_window_bits_recv", client->ws_deflate->client_max_window_bits_recv))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_pointer (ptr_item, "ws_deflate_strm_deflate", client->ws_deflate->strm_deflate))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_pointer (ptr_item, "ws_deflate_strm_inflate", client->ws_deflate->strm_inflate))
|
||||
|
||||
@@ -544,6 +544,8 @@ relay_remote_new_with_infolist (struct t_infolist *infolist)
|
||||
new_remote->ws_deflate->client_context_takeover = weechat_infolist_integer (infolist, "ws_deflate_client_context_takeover");
|
||||
new_remote->ws_deflate->window_bits_deflate = weechat_infolist_integer (infolist, "ws_deflate_window_bits_deflate");
|
||||
new_remote->ws_deflate->window_bits_inflate = weechat_infolist_integer (infolist, "ws_deflate_window_bits_inflate");
|
||||
new_remote->ws_deflate->server_max_window_bits_recv = weechat_infolist_integer (infolist, "ws_deflate_server_max_window_bits_recv");
|
||||
new_remote->ws_deflate->client_max_window_bits_recv = weechat_infolist_integer (infolist, "ws_deflate_client_max_window_bits_recv");
|
||||
new_remote->ws_deflate->strm_deflate = NULL;
|
||||
new_remote->ws_deflate->strm_inflate = NULL;
|
||||
if (weechat_infolist_search_var (infolist, "ws_deflate_strm_deflate_dict"))
|
||||
|
||||
@@ -52,6 +52,8 @@ relay_websocket_deflate_alloc ()
|
||||
new_ws_deflate->client_context_takeover = 0;
|
||||
new_ws_deflate->window_bits_deflate = 0;
|
||||
new_ws_deflate->window_bits_inflate = 0;
|
||||
new_ws_deflate->server_max_window_bits_recv = 0;
|
||||
new_ws_deflate->client_max_window_bits_recv = 0;
|
||||
new_ws_deflate->strm_deflate = NULL;
|
||||
new_ws_deflate->strm_inflate = NULL;
|
||||
|
||||
@@ -148,6 +150,8 @@ relay_websocket_deflate_reinit (struct t_relay_websocket_deflate *ws_deflate)
|
||||
ws_deflate->client_context_takeover = 0;
|
||||
ws_deflate->window_bits_deflate = 0;
|
||||
ws_deflate->window_bits_inflate = 0;
|
||||
ws_deflate->server_max_window_bits_recv = 0;
|
||||
ws_deflate->client_max_window_bits_recv = 0;
|
||||
relay_websocket_deflate_free_stream_deflate (ws_deflate);
|
||||
relay_websocket_deflate_free_stream_inflate (ws_deflate);
|
||||
}
|
||||
@@ -322,6 +326,8 @@ relay_websocket_parse_extensions (const char *extensions,
|
||||
ws_deflate->client_context_takeover = 1;
|
||||
ws_deflate->window_bits_deflate = 15;
|
||||
ws_deflate->window_bits_inflate = 15;
|
||||
ws_deflate->server_max_window_bits_recv = 0;
|
||||
ws_deflate->client_max_window_bits_recv = 0;
|
||||
for (j = 1; j < num_params; j++)
|
||||
{
|
||||
items = weechat_string_split (params[j], "=", " ", 0, 0, &num_items);
|
||||
@@ -356,9 +362,15 @@ relay_websocket_parse_extensions (const char *extensions,
|
||||
}
|
||||
}
|
||||
if (strcmp (items[0], "server_max_window_bits") == 0)
|
||||
{
|
||||
ws_deflate->server_max_window_bits_recv = 1;
|
||||
ws_deflate->window_bits_deflate = (int)number;
|
||||
}
|
||||
else
|
||||
{
|
||||
ws_deflate->client_max_window_bits_recv = 1;
|
||||
ws_deflate->window_bits_inflate = (int)number;
|
||||
}
|
||||
}
|
||||
}
|
||||
weechat_string_free_split (items);
|
||||
@@ -388,7 +400,7 @@ relay_websocket_build_handshake (struct t_relay_http_request *request)
|
||||
{
|
||||
const char *sec_websocket_key;
|
||||
char *key, sec_websocket_accept[128], handshake[4096], hash[160 / 8];
|
||||
char sec_websocket_extensions[512];
|
||||
char **extensions, str_window_bits[128], sec_websocket_extensions[1024];
|
||||
int length, hash_size;
|
||||
|
||||
if (!request)
|
||||
@@ -426,17 +438,41 @@ relay_websocket_build_handshake (struct t_relay_http_request *request)
|
||||
|
||||
if (request->ws_deflate->enabled)
|
||||
{
|
||||
extensions = weechat_string_dyn_alloc (128);
|
||||
if (!extensions)
|
||||
return NULL;
|
||||
weechat_string_dyn_concat (extensions, "permessage-deflate", -1);
|
||||
if (!request->ws_deflate->server_context_takeover)
|
||||
{
|
||||
weechat_string_dyn_concat (extensions, "; ", -1);
|
||||
weechat_string_dyn_concat (extensions, "server_no_context_takeover", -1);
|
||||
}
|
||||
if (!request->ws_deflate->client_context_takeover)
|
||||
{
|
||||
weechat_string_dyn_concat (extensions, "; ", -1);
|
||||
weechat_string_dyn_concat (extensions, "client_no_context_takeover", -1);
|
||||
}
|
||||
if (request->ws_deflate->server_max_window_bits_recv)
|
||||
{
|
||||
weechat_string_dyn_concat (extensions, "; ", -1);
|
||||
snprintf (str_window_bits, sizeof (str_window_bits),
|
||||
"server_max_window_bits=%d",
|
||||
request->ws_deflate->window_bits_deflate);
|
||||
weechat_string_dyn_concat (extensions, str_window_bits, -1);
|
||||
}
|
||||
if (request->ws_deflate->client_max_window_bits_recv)
|
||||
{
|
||||
weechat_string_dyn_concat (extensions, "; ", -1);
|
||||
snprintf (str_window_bits, sizeof (str_window_bits),
|
||||
"client_max_window_bits=%d",
|
||||
request->ws_deflate->window_bits_inflate);
|
||||
weechat_string_dyn_concat (extensions, str_window_bits, -1);
|
||||
}
|
||||
snprintf (
|
||||
sec_websocket_extensions, sizeof (sec_websocket_extensions),
|
||||
"Sec-WebSocket-Extensions: permessage-deflate; "
|
||||
"%s"
|
||||
"%s"
|
||||
"server_max_window_bits=%d; "
|
||||
"client_max_window_bits=%d\r\n",
|
||||
(!request->ws_deflate->server_context_takeover) ? "server_no_context_takeover; " : "",
|
||||
(!request->ws_deflate->client_context_takeover) ? "client_no_context_takeover; " : "",
|
||||
request->ws_deflate->window_bits_deflate,
|
||||
request->ws_deflate->window_bits_inflate);
|
||||
"Sec-WebSocket-Extensions: %s\r\n",
|
||||
*extensions);
|
||||
weechat_string_dyn_free (extensions, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -951,11 +987,13 @@ relay_websocket_deflate_print_log (struct t_relay_websocket_deflate *ws_deflate,
|
||||
const char *prefix)
|
||||
{
|
||||
weechat_log_printf ("%s ws_deflate:", prefix);
|
||||
weechat_log_printf ("%s enabled . . . . . . . . : %d", prefix, ws_deflate->enabled);
|
||||
weechat_log_printf ("%s server_context_takeover : %d", prefix, ws_deflate->server_context_takeover);
|
||||
weechat_log_printf ("%s client_context_takeover : %d", prefix, ws_deflate->client_context_takeover);
|
||||
weechat_log_printf ("%s window_bits_deflate . . : %d", prefix, ws_deflate->window_bits_deflate);
|
||||
weechat_log_printf ("%s window_bits_inflate . . : %d", prefix, ws_deflate->window_bits_inflate);
|
||||
weechat_log_printf ("%s strm_deflate. . . . . . : %p", prefix, ws_deflate->strm_deflate);
|
||||
weechat_log_printf ("%s strm_inflate. . . . . . : %p", prefix, ws_deflate->strm_inflate);
|
||||
weechat_log_printf ("%s enabled. . . . . . . . . . : %d", prefix, ws_deflate->enabled);
|
||||
weechat_log_printf ("%s server_context_takeover. . : %d", prefix, ws_deflate->server_context_takeover);
|
||||
weechat_log_printf ("%s client_context_takeover. . : %d", prefix, ws_deflate->client_context_takeover);
|
||||
weechat_log_printf ("%s window_bits_deflate. . . . : %d", prefix, ws_deflate->window_bits_deflate);
|
||||
weechat_log_printf ("%s window_bits_inflate. . . . : %d", prefix, ws_deflate->window_bits_inflate);
|
||||
weechat_log_printf ("%s server_max_window_bits_recv: %d", prefix, ws_deflate->server_max_window_bits_recv);
|
||||
weechat_log_printf ("%s client_max_window_bits_recv: %d", prefix, ws_deflate->client_max_window_bits_recv);
|
||||
weechat_log_printf ("%s strm_deflate . . . . . . . : %p", prefix, ws_deflate->strm_deflate);
|
||||
weechat_log_printf ("%s strm_inflate . . . . . . . : %p", prefix, ws_deflate->strm_inflate);
|
||||
}
|
||||
|
||||
@@ -49,6 +49,8 @@ struct t_relay_websocket_deflate
|
||||
/* ("server_max_window_bits") */
|
||||
int window_bits_inflate; /* window bits for client (decomp.) */
|
||||
/* ("client_max_window_bits") */
|
||||
int server_max_window_bits_recv; /* "server_max_window_bits" received?*/
|
||||
int client_max_window_bits_recv; /* "client_max_window_bits" received?*/
|
||||
z_stream *strm_deflate; /* stream for deflate (compression) */
|
||||
z_stream *strm_inflate; /* stream for inflate (decompression)*/
|
||||
};
|
||||
|
||||
@@ -65,6 +65,8 @@ TEST(RelayWebsocket, DeflateAllocFree)
|
||||
LONGS_EQUAL(0, ws_deflate->client_context_takeover);
|
||||
LONGS_EQUAL(0, ws_deflate->window_bits_deflate);
|
||||
LONGS_EQUAL(0, ws_deflate->window_bits_inflate);
|
||||
LONGS_EQUAL(0, ws_deflate->server_max_window_bits_recv);
|
||||
LONGS_EQUAL(0, ws_deflate->client_max_window_bits_recv);
|
||||
POINTERS_EQUAL(NULL, ws_deflate->strm_deflate);
|
||||
POINTERS_EQUAL(NULL, ws_deflate->strm_inflate);
|
||||
|
||||
@@ -164,33 +166,75 @@ TEST(RelayWebsocket, ClientHandshakeValid)
|
||||
hashtable_set (request->headers, "origin", "example.com");
|
||||
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);
|
||||
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);
|
||||
LONGS_EQUAL(15, request->ws_deflate->window_bits_deflate);
|
||||
LONGS_EQUAL(15, request->ws_deflate->window_bits_inflate);
|
||||
LONGS_EQUAL(0, request->ws_deflate->server_max_window_bits_recv);
|
||||
LONGS_EQUAL(0, request->ws_deflate->client_max_window_bits_recv);
|
||||
WEE_TEST_STR(
|
||||
"HTTP/1.1 101 Switching Protocols\r\n"
|
||||
"Upgrade: websocket\r\n"
|
||||
"Connection: Upgrade\r\n"
|
||||
"Sec-WebSocket-Accept: fhLJYtv//ugX2vQXpifQgByRZ5Y=\r\n"
|
||||
"Sec-WebSocket-Extensions: permessage-deflate\r\n"
|
||||
"\r\n",
|
||||
relay_websocket_build_handshake (request));
|
||||
|
||||
relay_websocket_deflate_reinit (request->ws_deflate);
|
||||
relay_websocket_parse_extensions (
|
||||
"permessage-deflate; client_max_window_bits",
|
||||
request->ws_deflate);
|
||||
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);
|
||||
LONGS_EQUAL(15, request->ws_deflate->window_bits_deflate);
|
||||
LONGS_EQUAL(15, request->ws_deflate->window_bits_inflate);
|
||||
LONGS_EQUAL(0, request->ws_deflate->server_max_window_bits_recv);
|
||||
LONGS_EQUAL(1, request->ws_deflate->client_max_window_bits_recv);
|
||||
WEE_TEST_STR(
|
||||
"HTTP/1.1 101 Switching Protocols\r\n"
|
||||
"Upgrade: websocket\r\n"
|
||||
"Connection: Upgrade\r\n"
|
||||
"Sec-WebSocket-Accept: fhLJYtv//ugX2vQXpifQgByRZ5Y=\r\n"
|
||||
"Sec-WebSocket-Extensions: permessage-deflate; server_max_window_bits=15; client_max_window_bits=15\r\n"
|
||||
"Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits=15\r\n"
|
||||
"\r\n",
|
||||
relay_websocket_build_handshake (request));
|
||||
|
||||
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);
|
||||
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);
|
||||
LONGS_EQUAL(15, request->ws_deflate->window_bits_deflate);
|
||||
LONGS_EQUAL(12, request->ws_deflate->window_bits_inflate);
|
||||
LONGS_EQUAL(0, request->ws_deflate->server_max_window_bits_recv);
|
||||
LONGS_EQUAL(1, request->ws_deflate->client_max_window_bits_recv);
|
||||
WEE_TEST_STR(
|
||||
"HTTP/1.1 101 Switching Protocols\r\n"
|
||||
"Upgrade: websocket\r\n"
|
||||
"Connection: Upgrade\r\n"
|
||||
"Sec-WebSocket-Accept: fhLJYtv//ugX2vQXpifQgByRZ5Y=\r\n"
|
||||
"Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; server_max_window_bits=15; client_max_window_bits=12\r\n"
|
||||
"Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_max_window_bits=12\r\n"
|
||||
"\r\n",
|
||||
relay_websocket_build_handshake (request));
|
||||
|
||||
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);
|
||||
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);
|
||||
LONGS_EQUAL(8, request->ws_deflate->window_bits_deflate);
|
||||
LONGS_EQUAL(12, request->ws_deflate->window_bits_inflate);
|
||||
LONGS_EQUAL(1, request->ws_deflate->server_max_window_bits_recv);
|
||||
LONGS_EQUAL(1, request->ws_deflate->client_max_window_bits_recv);
|
||||
WEE_TEST_STR(
|
||||
"HTTP/1.1 101 Switching Protocols\r\n"
|
||||
"Upgrade: websocket\r\n"
|
||||
|
||||
Reference in New Issue
Block a user