mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-10-27 14:41:28 +01:00
The RFC8441 was not respected by haproxy in regards with server support for Extended CONNECT. The Extended CONNECT method was used to convert an Upgrade header stream even if no SETTINGS_ENABLE_CONNECT_PROTOCOL was received, which is forbidden by the RFC8441. In this case, the behavior of the http/2 server is unspecified. Fix this by flagging the connection on receiption of the RFC8441 settings SETTINGS_ENABLE_CONNECT_PROTOCOL. Extended CONNECT is thus only be used if the flag is present. In the other case, the stream is immediatly closed as there is no way to handle it in http/2. It results in a http/1.1 502 or http/2 RESET_STREAM to the client side. The protocol-upgrade regtest has been extended to test that haproxy does not emit Extended CONNECT on servers without RFC8441 support. It must be backported up to 2.4.
229 lines
4.8 KiB
Plaintext
229 lines
4.8 KiB
Plaintext
# This reg-test checks the full support of HTTP protocol upgrade, using a GET
|
|
# method and a Connection: Upgrade header. The equivalent mechanism has been
|
|
# defined in rfc8441 for HTTP/2 using CONNECT and a new pseudo-header
|
|
# :protocol. Check that haproxy handles properly h1/h2 translation of protocol
|
|
# upgrade requests and responses.
|
|
|
|
varnishtest "h1/h2 support for protocol upgrade test"
|
|
|
|
feature ignore_unknown_macro
|
|
|
|
#REQUIRE_VERSION=2.4
|
|
|
|
# http/1.1 server
|
|
server srv_h1 {
|
|
rxreq
|
|
expect req.method == "GET"
|
|
expect req.http.connection == "upgrade"
|
|
expect req.http.upgrade == "custom_protocol"
|
|
|
|
txresp \
|
|
-status 101 \
|
|
-hdr "connection: upgrade" \
|
|
-hdr "upgrade: custom_protocol"
|
|
} -repeat 2 -start
|
|
|
|
# http2 server
|
|
server srv_h2 {
|
|
rxpri
|
|
|
|
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 {
|
|
rxhdrs
|
|
expect req.method == "CONNECT"
|
|
expect req.http.:scheme == "https"
|
|
expect req.http.:path == "/"
|
|
expect req.http.:authority == "127.0.0.1"
|
|
expect req.http.:protocol == "custom_protocol"
|
|
|
|
txresp \
|
|
-status 200
|
|
} -run
|
|
} -repeat 2 -start
|
|
|
|
# http2 server without support for RFC8441
|
|
server srv_h2_no_ws {
|
|
rxpri
|
|
|
|
stream 0 {
|
|
txsettings
|
|
rxsettings
|
|
txsettings -ack
|
|
rxsettings
|
|
expect settings.ack == true
|
|
} -run
|
|
|
|
stream 1 {
|
|
rxrst
|
|
} -run
|
|
} -start
|
|
|
|
# http2 server without support for RFC8441 : settings announced with value 0
|
|
server srv_h2_no_ws2 {
|
|
rxpri
|
|
|
|
stream 0 {
|
|
# manually send RFC8441 SETTINGS_ENABLE_CONNECT_PROTOCOL with a value of 0
|
|
sendhex "00 00 06 04 00 00 00 00 00 00 08 00 00 00 00"
|
|
txsettings
|
|
rxsettings
|
|
txsettings -ack
|
|
rxsettings
|
|
expect settings.ack == true
|
|
} -run
|
|
|
|
stream 1 {
|
|
rxrst
|
|
} -run
|
|
} -start
|
|
|
|
haproxy hap -conf {
|
|
defaults
|
|
mode http
|
|
timeout connect 1s
|
|
timeout client 1s
|
|
timeout server 1s
|
|
|
|
# h1 frontend connected to h2 frontend
|
|
listen frt_h1_h2
|
|
bind "fd@${frt_h1_h2}"
|
|
server feh2_srv ${hap_frt_h2_addr}:${hap_frt_h2_port} proto h2
|
|
|
|
# h2 frontend connected to srv_h1
|
|
listen frt_h2
|
|
bind "fd@${frt_h2}" proto h2
|
|
server srv_h1 ${srv_h1_addr}:${srv_h1_port}
|
|
|
|
# h1 frontend connected to srv_h2
|
|
listen frt_h1
|
|
bind "fd@${frt_h1}"
|
|
server srv_h2 ${srv_h2_addr}:${srv_h2_port} proto h2
|
|
|
|
# h1 frontend connected to srv_h2_no_ws
|
|
listen frt_h1_no_ws
|
|
bind "fd@${frt_h1_no_ws}"
|
|
server srv_h2_no_ws ${srv_h2_no_ws_addr}:${srv_h2_no_ws_port} proto h2
|
|
|
|
# h1 frontend connected to srv_h2_no_ws2
|
|
listen frt_h1_no_ws2
|
|
bind "fd@${frt_h1_no_ws2}"
|
|
server srv_h2_no_ws2 ${srv_h2_no_ws2_addr}:${srv_h2_no_ws2_port} proto h2
|
|
|
|
# h2 frontend connected to h1 frontend
|
|
listen frt_h2_h1
|
|
bind "fd@${frt_h2_h1}" proto h2
|
|
server frt_h1 ${hap_frt_h1_addr}:${hap_frt_h1_port}
|
|
} -start
|
|
|
|
## connect to h1 translation frontend
|
|
client c1_h1_h2 -connect ${hap_frt_h1_h2_sock} {
|
|
txreq \
|
|
-req "GET" \
|
|
-url "/" \
|
|
-hdr "host: 127.0.0.1" \
|
|
-hdr "connection: upgrade" \
|
|
-hdr "upgrade: custom_protocol"
|
|
|
|
rxresp
|
|
expect resp.status == 101
|
|
expect resp.http.connection == "upgrade"
|
|
expect resp.http.upgrade == "custom_protocol"
|
|
} -run
|
|
|
|
# connect to h2 server frontend
|
|
client c2_h2 -connect ${hap_frt_h2_sock} {
|
|
txpri
|
|
stream 0 {
|
|
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"
|
|
|
|
rxhdrs
|
|
expect resp.status == 200
|
|
} -run
|
|
} -run
|
|
|
|
# connect to h2 translation frontend
|
|
client c3_h2_h1 -connect ${hap_frt_h2_h1_sock} {
|
|
txpri
|
|
stream 0 {
|
|
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"
|
|
|
|
rxhdrs
|
|
expect resp.status == 200
|
|
} -run
|
|
} -run
|
|
|
|
# connect to h1 server frontend
|
|
client c4_h1 -connect ${hap_frt_h1_sock} {
|
|
txreq \
|
|
-req "GET" \
|
|
-url "/" \
|
|
-hdr "host: 127.0.0.1" \
|
|
-hdr "connection: upgrade" \
|
|
-hdr "upgrade: custom_protocol"
|
|
|
|
rxresp
|
|
expect resp.status == 101
|
|
expect resp.http.connection == "upgrade"
|
|
expect resp.http.upgrade == "custom_protocol"
|
|
} -run
|
|
|
|
# connect via h1 server frontend to h2 server without RFC8441 support
|
|
client c5 -connect ${hap_frt_h1_no_ws_sock} {
|
|
txreq \
|
|
-req "GET" \
|
|
-url "/" \
|
|
-hdr "host: 127.0.0.1" \
|
|
-hdr "connection: upgrade" \
|
|
-hdr "upgrade: custom_protocol"
|
|
|
|
rxresp
|
|
expect resp.status == 502
|
|
} -run
|
|
|
|
# connect via h1 server frontend to h2 server without RFC8441 support
|
|
client c6 -connect ${hap_frt_h1_no_ws2_sock} {
|
|
txreq \
|
|
-req "GET" \
|
|
-url "/" \
|
|
-hdr "host: 127.0.0.1" \
|
|
-hdr "connection: upgrade" \
|
|
-hdr "upgrade: custom_protocol"
|
|
|
|
rxresp
|
|
expect resp.status == 502
|
|
} -run
|