diff --git a/doc/configuration.txt b/doc/configuration.txt
index 0d60f8e8e..b128718cd 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -982,6 +982,7 @@ The following keywords are supported in the "global" section :
- insecure-fork-wanted
- insecure-setuid-wanted
- issuers-chain-path
+ - h2-workaround-bogus-websocket-clients
- localpeer
- log
- log-tag
@@ -1404,6 +1405,15 @@ issuers-chain-path
"issuers-chain-path" directory. All other certificates with the same issuer
will share the chain in memory.
+h2-workaround-bogus-websocket-clients
+ This disables the announcement of the support for h2 websockets to clients.
+ This can be use to overcome clients which have issues when implementing the
+ relatively fresh RFC8441, such as Firefox 88. To allow clients to
+ automatically downgrade to http/1.1 for the websocket tunnel, specify h2
+ support on the bind line using "alpn" without an explicit "proto" keyword. If
+ this statement was previously activated, this can be disabled by prefixing
+ the keyword with "no'.
+
localpeer
Sets the local instance's peer name. It will be ignored if the "-L"
command line argument is specified or if used after "peers" section
diff --git a/include/haproxy/global-t.h b/include/haproxy/global-t.h
index b5ecc553a..a6bc5e1d6 100644
--- a/include/haproxy/global-t.h
+++ b/include/haproxy/global-t.h
@@ -70,6 +70,7 @@
#define GTUNE_FD_ET (1<<18)
#define GTUNE_SCHED_LOW_LATENCY (1<<19)
#define GTUNE_IDLE_POOL_SHARED (1<<20)
+#define GTUNE_DISABLE_H2_WEBSOCKET (1<<21)
/* SSL server verify mode */
enum {
diff --git a/src/cfgparse-global.c b/src/cfgparse-global.c
index f8150d454..4dc93b68a 100644
--- a/src/cfgparse-global.c
+++ b/src/cfgparse-global.c
@@ -128,6 +128,14 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
else
global.tune.options |= GTUNE_SET_DUMPABLE;
}
+ else if (strcmp(args[0], "h2-workaround-bogus-websocket-clients") == 0) { /* "no h2-workaround-bogus-websocket-clients" or "h2-workaround-bogus-websocket-clients" */
+ if (alertif_too_many_args(0, file, linenum, args, &err_code))
+ goto out;
+ if (kwm == KWM_NO)
+ global.tune.options &= ~GTUNE_DISABLE_H2_WEBSOCKET;
+ else
+ global.tune.options |= GTUNE_DISABLE_H2_WEBSOCKET;
+ }
else if (strcmp(args[0], "insecure-fork-wanted") == 0) { /* "no insecure-fork-wanted" or "insecure-fork-wanted" */
if (alertif_too_many_args(0, file, linenum, args, &err_code))
goto out;
diff --git a/src/mux_h2.c b/src/mux_h2.c
index 9cb6eba75..fbc79634b 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -1610,9 +1610,10 @@ static int h2c_send_settings(struct h2c *h2c)
chunk_memcat(&buf, "\x00\x02\x00\x00\x00\x00", 6);
}
- /* rfc 8441 #3 SETTINGS_ENABLE_CONNECT_PROTOCOL=1
- * sent automatically */
- chunk_memcat(&buf, "\x00\x08\x00\x00\x00\x01", 6);
+ /* rfc 8441 #3 SETTINGS_ENABLE_CONNECT_PROTOCOL=1,
+ * sent automatically unless disabled in the global config */
+ if (!(global.tune.options & GTUNE_DISABLE_H2_WEBSOCKET))
+ chunk_memcat(&buf, "\x00\x08\x00\x00\x00\x01", 6);
if (h2_settings_header_table_size != 4096) {
char str[6] = "\x00\x01"; /* header_table_size */