mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-05-08 14:36:11 +02:00
BUG/MEDIUM: mux-h2: fix the detection of the ext connect support
As reported by Huangbin Zhan (@zhanhb) in github issue #3355, latest commit 96f7ff4fdd ("MINOR: mux-h2: add a new message flag to indicate ext connect support") was not correct and can break RFC8441-compliant clients, as it did for them with a variant of Chrome 142. The problem is that while RFC9113 says that new pseudo-headers are only permitted with *negotiated* extensions, and RFC8441 doesn't indicate whether or not SETTINGS_ENABLE_CONNECT_PROTOCOL is needed from clients, it only says that clients know that servers support the extension when seeing it in their settings and can use it, which seems to imply that they don't need to send it to indicate their willingness to use it. This also means that the server cannot know if a client is expected to use it or not by default. It only know that a client is not allowed to use it if the server didn't emit support mentioning it, which haproxy can do using h2-workaround-bogus-websocket-clients. Thus the fix proposed by @zhanhb is right, when presetting the flag for the parser to indicate whether or not we're willing to accept RFC8441's :protocol pseudo-header, we should: - consider the received setting on the backend side (though the pseudo-header is neither used nor supported there, but at least we pass the info regarding the support of the extension) - consider the configuration for the frontend (since it's the only place where we can decide on support or not) This patch does just that and reverts the accompanying changes to the regtests that made them want to see the client's setting. It must be backported to 2.6. In the mean time, placing this option in the global section will force the clients to downgrade to h1: h2-workaround-bogus-websocket-clients Many thanks again to @zhanbb this feedback and proposing a tested fix.
This commit is contained in:
parent
b587ea1f27
commit
00941af7b7
@ -72,7 +72,7 @@ server srv_h2 {
|
||||
txresp \
|
||||
-status 200
|
||||
} -run
|
||||
} -repeat 4 -start
|
||||
} -repeat 2 -start
|
||||
|
||||
# http2 server without support for RFC8441
|
||||
server srv_h2_no_ws {
|
||||
@ -219,8 +219,7 @@ client c1_h1_h2 -connect ${hap_frt_h1_h2_sock} {
|
||||
client c2_h2 -connect ${hap_frt_h2_sock} {
|
||||
txpri
|
||||
stream 0 {
|
||||
# manually send RFC8441 SETTINGS_ENABLE_CONNECT_PROTOCOL
|
||||
sendhex "00 00 06 04 00 00 00 00 00 00 08 00 00 00 01"
|
||||
txsettings
|
||||
rxsettings
|
||||
txsettings -ack
|
||||
rxsettings
|
||||
@ -242,62 +241,11 @@ client c2_h2 -connect ${hap_frt_h2_sock} {
|
||||
} -run
|
||||
} -run
|
||||
|
||||
# connect to h2 server frontend without extension: must fail
|
||||
client c2_h2_rej1 -connect ${hap_frt_h2_sock} {
|
||||
txpri
|
||||
stream 0 {
|
||||
# no extension sent
|
||||
txsettings
|
||||
rxsettings
|
||||
txsettings -ack
|
||||
rxsettings
|
||||
expect settings.ack == true
|
||||
} -run
|
||||
|
||||
stream 1 {
|
||||
txreq \
|
||||
-req "CONNECT" \
|
||||
-scheme "http" \
|
||||
-url "/" \
|
||||
-hdr ":authority" "127.0.0.1" \
|
||||
-hdr ":protocol" "custom_protocol" \
|
||||
-nostrend
|
||||
|
||||
rxrst
|
||||
} -run
|
||||
} -run
|
||||
|
||||
# connect to h2 server with ext but :proto with bad method: must fail
|
||||
client c2_h2_rej2 -connect ${hap_frt_h2_sock} {
|
||||
txpri
|
||||
stream 0 {
|
||||
# manually send RFC8441 SETTINGS_ENABLE_CONNECT_PROTOCOL
|
||||
sendhex "00 00 06 04 00 00 00 00 00 00 08 00 00 00 01"
|
||||
rxsettings
|
||||
txsettings -ack
|
||||
rxsettings
|
||||
expect settings.ack == true
|
||||
} -run
|
||||
|
||||
stream 1 {
|
||||
txreq \
|
||||
-req "GET" \
|
||||
-scheme "http" \
|
||||
-url "/" \
|
||||
-hdr ":authority" "127.0.0.1" \
|
||||
-hdr ":protocol" "custom_protocol" \
|
||||
-nostrend
|
||||
|
||||
rxrst
|
||||
} -run
|
||||
} -run
|
||||
|
||||
# connect to h2 translation frontend
|
||||
client c3_h2_h1 -connect ${hap_frt_h2_h1_sock} {
|
||||
txpri
|
||||
stream 0 {
|
||||
# manually send RFC8441 SETTINGS_ENABLE_CONNECT_PROTOCOL
|
||||
sendhex "00 00 06 04 00 00 00 00 00 00 08 00 00 00 01"
|
||||
txsettings
|
||||
rxsettings
|
||||
txsettings -ack
|
||||
rxsettings
|
||||
@ -391,8 +339,7 @@ client c8_h2c -connect ${hap_frt_h1_h2c_sock} {
|
||||
client c9_h2c -connect ${hap_frt_h2_h1_sock} {
|
||||
txpri
|
||||
stream 0 {
|
||||
# manually send RFC8441 SETTINGS_ENABLE_CONNECT_PROTOCOL
|
||||
sendhex "00 00 06 04 00 00 00 00 00 00 08 00 00 00 01"
|
||||
txsettings
|
||||
rxsettings
|
||||
txsettings -ack
|
||||
rxsettings
|
||||
|
||||
@ -177,8 +177,7 @@ client c3 -connect ${hap_fe2_sock} {
|
||||
client c4 -connect ${hap_fe3_sock} {
|
||||
txpri
|
||||
stream 0 {
|
||||
# manually send RFC8441 SETTINGS_ENABLE_CONNECT_PROTOCOL
|
||||
sendhex "00 00 06 04 00 00 00 00 00 00 08 00 00 00 01"
|
||||
txsettings
|
||||
rxsettings
|
||||
txsettings -ack
|
||||
rxsettings
|
||||
@ -206,8 +205,7 @@ client c4 -connect ${hap_fe3_sock} {
|
||||
client c5 -connect ${hap_fe4_sock} {
|
||||
txpri
|
||||
stream 0 {
|
||||
# manually send RFC8441 SETTINGS_ENABLE_CONNECT_PROTOCOL
|
||||
sendhex "00 00 06 04 00 00 00 00 00 00 08 00 00 00 01"
|
||||
txsettings
|
||||
rxsettings
|
||||
txsettings -ack
|
||||
rxsettings
|
||||
|
||||
10
src/mux_h2.c
10
src/mux_h2.c
@ -6286,8 +6286,16 @@ next_frame:
|
||||
/* If an Extended CONNECT has been sent on this stream, set message flag
|
||||
* to convert 200 response to 101 htx response. We only support this if
|
||||
* the connection supports RFC8441.
|
||||
* On the backend, that means the origin server advertised the setting.
|
||||
* On the frontend, RFC 8441 §3 only requires the server (us) to
|
||||
* advertise it; clients are not required to echo it back. Use whether
|
||||
* we ourselves advertised it as the gate.
|
||||
*/
|
||||
msgf |= (h2c->flags & H2_CF_RCVD_RFC8441) ? H2_MSGF_EXT_CONN_OK : 0;
|
||||
if (h2c->flags & H2_CF_IS_BACK)
|
||||
msgf |= (h2c->flags & H2_CF_RCVD_RFC8441) ? H2_MSGF_EXT_CONN_OK : 0;
|
||||
else if (!(global.tune.options & GTUNE_DISABLE_H2_WEBSOCKET))
|
||||
msgf |= H2_MSGF_EXT_CONN_OK;
|
||||
|
||||
msgf |= (*flags & H2_SF_EXT_CONNECT_SENT) ? H2_MSGF_EXT_CONNECT: 0;
|
||||
|
||||
/* when dealing with trailers, we need to check the content-length */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user