varnishtest "Test connection upgrades from TCP to HTTP" #REQUIRE_VERSION=2.4 feature ignore_unknown_macro server s1 { # TCP > H1 using "switch-mode http" rxreq expect req.http.x-stream-mode == tcp expect req.http.x-name == fe1 txresp rxreq expect req.http.x-stream-mode == http expect req.http.x-name == fe1 txresp accept # TCP > H1 using backend mode rxreq expect req.http.x-name == be txresp rxreq expect req.http.x-name == be txresp accept # TCP > H2 using "switch-mode http" rxreq expect req.http.x-stream-mode == http expect req.http.x-name == fe1 txresp rxreq expect req.http.x-stream-mode == http expect req.http.x-name == fe1 txresp # To be sure no other request was received accept rxreq txresp } -start haproxy h1 -conf { defaults timeout client 30s timeout server 30s timeout connect 30s frontend fe1 mode tcp bind "fd@${fe1h1}" tcp-request inspect-delay 1s tcp-request content set-var(req.stream_mode) internal.strm.is_htx,iif(http,tcp) tcp-request content switch-mode http if HTTP tcp-request content reject # never reached http-request set-header x-stream-mode %[var(req.stream_mode)] http-request set-header x-name %[fe_name] default_backend be frontend fe2 mode tcp bind "fd@${fe2h1}" default_backend be backend be mode http http-request set-header x-name %[be_name] unless { req.fhdr(x-name) -m found } server s1 ${s1_addr}:${s1_port} listen li1 mode http bind "fd@${li1h1}" server s1 ${h1_fe1h1_addr}:${h1_fe1h1_port} proto h2 listen err1 mode http bind "fd@${err1h1}" proto h1 server s1 ${s1_addr}:${s1_port} listen err2 mode tcp bind "fd@${err2h1}" tcp-request inspect-delay 1s tcp-request content switch-mode http proto h1 if HTTP tcp-request content reject # never reached default_backend be listen err3 mode tcp bind "fd@${err3h1}" proto none tcp-request inspect-delay 1s tcp-request content switch-mode http if HTTP tcp-request content reject # never reached default_backend be } -start # TCP > H1 using "switch-mode http" client c1 -connect ${h1_fe1h1_sock} { txreq rxresp expect resp.status == 200 txreq rxresp expect resp.status == 200 } -run # TCP > H1 using backend mode client c2 -connect ${h1_fe2h1_sock} { txreq rxresp expect resp.status == 200 txreq rxresp expect resp.status == 200 } -run # TCP > H2 using "switch-mode http" client c3 -connect ${h1_li1h1_sock} { txreq rxresp expect resp.status == 200 txreq rxresp expect resp.status == 200 } -run # implicit H1 > H2 upgrade not performed client c_err1 -connect ${h1_err1h1_sock} { send "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" rxresp expect resp.status == 400 } -run # TCP > H1 > H2 upgrade not allowed client c_err2 -connect ${h1_err2h1_sock} { send "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" rxresp expect resp.status == 400 } -run # TCP > HTTP upgrade not allowed client c_err3 -connect ${h1_err3h1_sock} { txreq expect_close } -run # TCP > HTTP upgrade with a parsing error client c_err4 -connect ${h1_fe2h1_sock} { send "GET / BAD-VERSION\r\n\r\n" rxresp expect resp.status == 400 } -run # To be sure no other request was received by the server client c_end -connect ${s1_sock} { txreq rxresp } -run