From 5a2f77e4449b6ad88ac8c05a273f87c249a458d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Wed, 24 Jun 2026 12:47:02 +0200 Subject: [PATCH 1/2] Don't send server_max_window_bits=15, it's the default --- src/gun_http.erl | 2 +- src/gun_http2.erl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gun_http.erl b/src/gun_http.erl index da7af5c6..2828f8d4 100644 --- a/src/gun_http.erl +++ b/src/gun_http.erl @@ -1031,7 +1031,7 @@ ws_upgrade(State=#http_state{out=head}, StreamRef, ReplyTo, Host, Port, Path, Headers0, WsOpts, CookieStore0, EvHandler, EvHandlerState0) -> {Headers1, GunExtensions} = case maps:get(compress, WsOpts, false) of true -> {[{<<"sec-websocket-extensions">>, - <<"permessage-deflate; client_max_window_bits; server_max_window_bits=15">>} + <<"permessage-deflate; client_max_window_bits">>} |Headers0], [<<"permessage-deflate">>]}; false -> {Headers0, []} diff --git a/src/gun_http2.erl b/src/gun_http2.erl index ff5ff117..043e4236 100644 --- a/src/gun_http2.erl +++ b/src/gun_http2.erl @@ -1591,7 +1591,7 @@ ws_upgrade1(State=#http2_state{socket=Socket, transport=Transport, {Headers2, GunExtensions} = case maps:get(compress, WsOpts, false) of true -> {[{<<"sec-websocket-extensions">>, - <<"permessage-deflate; client_max_window_bits; server_max_window_bits=15">>} + <<"permessage-deflate; client_max_window_bits">>} |Headers1], [<<"permessage-deflate">>]}; false -> {Headers1, []} From e7af4a9f758d2799cc8234f5dbd21fa2f9e74b66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Wed, 24 Jun 2026 13:27:36 +0200 Subject: [PATCH 2/2] Add compat Websocket compression option --- doc/src/manual/gun.asciidoc | 7 ++++++- doc/src/manual/gun.ws_upgrade.asciidoc | 2 +- src/gun.erl | 2 +- src/gun_http.erl | 12 ++++++++---- src/gun_http2.erl | 3 +++ src/gun_ws.erl | 2 ++ 6 files changed, 21 insertions(+), 7 deletions(-) diff --git a/doc/src/manual/gun.asciidoc b/doc/src/manual/gun.asciidoc index f9234a7d..248391cb 100644 --- a/doc/src/manual/gun.asciidoc +++ b/doc/src/manual/gun.asciidoc @@ -573,7 +573,7 @@ detail. ---- ws_opts() :: #{ closing_timeout => timeout(), - compress => boolean(), + compress => boolean() | compat, default_protocol => module(), flow => pos_integer(), invalid_request_headers => raise | ignore, @@ -599,6 +599,10 @@ compress (false):: Whether to enable permessage-deflate compression. This does not guarantee that compression will be used as it is the server that ultimately decides. Defaults to false. ++ +The value `compat` will enable compression without sending +any parameter. It should help connecting to servers that +reject parameters that Gun sends by default. default_protocol (gun_ws_h):: @@ -645,6 +649,7 @@ By default no user option is defined. == Changelog +* *2.5*: Websocket `compress` option value `compat` was added. * *2.4*: The `max_header_block_size` and `max_trailer_block_size` HTTP/1.1 options were added. * *2.4*: The `invalid_request_headers` request option was added diff --git a/doc/src/manual/gun.ws_upgrade.asciidoc b/doc/src/manual/gun.ws_upgrade.asciidoc index c6e3850f..142ed15a 100644 --- a/doc/src/manual/gun.ws_upgrade.asciidoc +++ b/doc/src/manual/gun.ws_upgrade.asciidoc @@ -93,7 +93,7 @@ end. [source,erlang] ---- StreamRef = gun:ws_upgrade(ConnPid, "/ws", [], #{ - compress => false + compress => true }). ---- diff --git a/src/gun.erl b/src/gun.erl index ea8fe279..39bb1ac9 100644 --- a/src/gun.erl +++ b/src/gun.erl @@ -290,7 +290,7 @@ -type ws_opts() :: #{ closing_timeout => timeout(), - compress => boolean(), + compress => boolean() | compat, default_protocol => module(), flow => pos_integer(), invalid_request_headers => raise | ignore, diff --git a/src/gun_http.erl b/src/gun_http.erl index 2828f8d4..a04ad053 100644 --- a/src/gun_http.erl +++ b/src/gun_http.erl @@ -1030,11 +1030,15 @@ ws_upgrade(State=#http_state{version='HTTP/1.0'}, ws_upgrade(State=#http_state{out=head}, StreamRef, ReplyTo, Host, Port, Path, Headers0, WsOpts, CookieStore0, EvHandler, EvHandlerState0) -> {Headers1, GunExtensions} = case maps:get(compress, WsOpts, false) of - true -> {[{<<"sec-websocket-extensions">>, + true -> + {[{<<"sec-websocket-extensions">>, <<"permessage-deflate; client_max_window_bits">>} - |Headers0], - [<<"permessage-deflate">>]}; - false -> {Headers0, []} + |Headers0], [<<"permessage-deflate">>]}; + compat -> + {[{<<"sec-websocket-extensions">>, <<"permessage-deflate">>} + |Headers0], [<<"permessage-deflate">>]}; + false -> + {Headers0, []} end, Headers2 = case maps:get(protocols, WsOpts, []) of [] -> Headers1; diff --git a/src/gun_http2.erl b/src/gun_http2.erl index 043e4236..5730c454 100644 --- a/src/gun_http2.erl +++ b/src/gun_http2.erl @@ -1593,6 +1593,9 @@ ws_upgrade1(State=#http2_state{socket=Socket, transport=Transport, {[{<<"sec-websocket-extensions">>, <<"permessage-deflate; client_max_window_bits">>} |Headers1], [<<"permessage-deflate">>]}; + compat -> + {[{<<"sec-websocket-extensions">>, <<"permessage-deflate">>} + |Headers1], [<<"permessage-deflate">>]}; false -> {Headers1, []} end, diff --git a/src/gun_ws.erl b/src/gun_ws.erl index e356d97b..cb5f79e2 100644 --- a/src/gun_ws.erl +++ b/src/gun_ws.erl @@ -70,6 +70,8 @@ do_check_options([{closing_timeout, T}|Opts]) when is_integer(T), T > 0 -> do_check_options(Opts); do_check_options([{compress, B}|Opts]) when is_boolean(B) -> do_check_options(Opts); +do_check_options([{compress, compat}|Opts]) -> + do_check_options(Opts); do_check_options([{default_protocol, M}|Opts]) when is_atom(M) -> do_check_options(Opts); do_check_options([{flow, InitialFlow}|Opts]) when is_integer(InitialFlow), InitialFlow > 0 ->