varnishtest "HTTP request tests: H2 to H1 (HTX and legacy mode)"

# Run it with HAPROXY_PROGRAM=$PWD/haproxy varnishtest -l -k -t 1 "$1"

feature ignore_unknown_macro

# synchronize requests between streams
barrier b1 cond 2 -cyclic
barrier b2 cond 2 -cyclic
barrier b3 cond 2 -cyclic
barrier b4 cond 2 -cyclic
barrier b5 cond 2 -cyclic
barrier b6 cond 2 -cyclic

server s1 {
	rxreq
	txresp \
	  -status 200 \
	  -body "response 1"

	barrier b2 sync
	rxreq
	txresp \
	  -status 200 \
	  -body "response 2"

	barrier b3 sync
	rxreq
	txresp \
	  -status 200 \
	  -body "response 3"

	barrier b4 sync
	# the next request is never received

	barrier b5 sync
	# the next request is never received

	barrier b6 sync
	# the next request is never received
} -repeat 2 -start

haproxy h1 -conf {
    global
        # WT: limit false-positives causing "HTTP header incomplete" due to
        # idle server connections being randomly used and randomly expiring
        # under us.
        tune.idle-pool.shared off

    defaults
	#log stdout format raw daemon
	mode http
	option http-buffer-request
	timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
	timeout client  "${HAPROXY_TEST_TIMEOUT-5s}"
	timeout server  "${HAPROXY_TEST_TIMEOUT-5s}"

    listen feh1
	bind "fd@${feh1}"
	bind "fd@${feh2}" proto h2
	server s1 ${s1_addr}:${s1_port}
} -start

client c1h2 -connect ${h1_feh2_sock} {
	txpri
	stream 0 {
		txsettings
		rxsettings
		txsettings -ack
		rxsettings
		expect settings.ack == true
	} -run

	# first request is valid
	stream 1 {
		txreq \
		  -req "GET" \
		  -scheme "https" \
		  -url "/test1.html"
		rxhdrs
		expect resp.status == 200
		rxdata -all
		expect resp.body == "response 1"
	} -run

	# second request is valid and advertises C-L:0
	stream 3 {
		barrier b2 sync
		txreq \
		  -req "GET" \
		  -scheme "https" \
		  -url "/test2.html" \
		  -hdr "content-length" "0"
		rxhdrs
		expect resp.status == 200
		rxdata -all
		expect resp.body == "response 2"
	} -run

	# third request sends a body with a GET
	stream 5 {
		barrier b3 sync
		txreq \
		  -req "GET" \
		  -scheme "https" \
		  -url "/test3.html" \
		  -nostrend \
		  -body "this must be delivered, like it or not"
		rxwinup
		rxhdrs
		expect resp.status == 200
		rxdata -all
		expect resp.body == "response 3"
	} -run

	# fourth request is valid and advertises C-L:2, and close, and is
	# followed by a string "this is not sent\r\n\r\n" which causes a
	# stream error of type PROTOCOL_ERROR.
	stream 7 {
		barrier b4 sync
		txreq \
		  -req "GET" \
		  -scheme "https" \
		  -url "/test4.html" \
		  -hdr "content-length" "2" \
		  -nostrend
		txdata -data "this is sent and ignored"
		rxrst
	} -run

	# fifth request is invalid and advertises an invalid C-L ending with an
        # empty value, which results in a stream error.
	stream 9 {
		barrier b5 sync
		txreq \
		  -req "GET" \
		  -scheme "https" \
		  -url "/test5.html" \
		  -hdr "content-length" "0," \
		  -nostrend
		rxrst
	} -run

	# sixth request is invalid and advertises an empty C-L, which results
	# in a stream error.
	stream 11 {
		barrier b6 sync
		txreq \
		  -req "GET" \
		  -scheme "https" \
		  -url "/test6.html" \
		  -hdr "content-length" "" \
		  -nostrend
		rxrst
	} -run
} -run

# HEAD requests : don't work well yet
#client c2h2 -connect ${h1_feh2_sock} {
#	txpri
#	stream 0 {
#		txsettings
#		rxsettings
#		txsettings -ack
#		rxsettings
#		expect settings.ack == true
#	} -run
#
#	# first request is valid
#	stream 1 {
#		txreq \
#		  -req "HEAD" \
#		  -scheme "https" \
#		  -url "/test11.html"
#		rxhdrs
#		expect resp.status == 200
#		rxdata -all
#		expect resp.bodylen == 0
#	} -run
#
#	# second request is valid and advertises C-L:0
#	stream 3 {
#		barrier b2 sync
#		txreq \
#		  -req "HEAD" \
#		  -scheme "https" \
#		  -url "/test12.html" \
#		  -hdr "content-length" "0"
#		rxhdrs
#		expect resp.status == 200
#		rxdata -all
#		expect resp.bodylen == 0
#	} -run
#
#	# third request sends a body with a GET
#	stream 5 {
#		barrier b3 sync
#		txreq \
#		  -req "HEAD" \
#		  -scheme "https" \
#		  -url "/test13.html" \
#		  -nostrend \
#		  -body "this must be delivered, like it or not"
#		rxwinup
#		rxhdrs
#		expect resp.status == 200
#		rxdata -all
#		expect resp.bodylen == 0
#	} -run
#
#	# fourth request is valid and advertises C-L:0, and close, and is
#	# followed by a string "this is not sent\r\n\r\n" which must be
#	# dropped.
#	stream 7 {
#		barrier b4 sync
#		txreq \
#		  -req "HEAD" \
#		  -scheme "https" \
#		  -url "/test14.html" \
#		  -hdr "content-length" "0" \
#		  -nostrend
#		txdata -data "this is sent and ignored"
#		rxwinup
#		rxhdrs
#		expect resp.status == 200
#		rxdata -all
#		expect resp.bodylen == 0
#	} -run
#} -run

# POST requests
client c3h2 -connect ${h1_feh2_sock} {
	txpri
	stream 0 {
		txsettings
		rxsettings
		txsettings -ack
		rxsettings
		expect settings.ack == true
	} -run

	# first request is valid
	stream 1 {
		txreq \
		  -req "POST" \
		  -scheme "https" \
		  -url "/test21.html"
		rxhdrs
		expect resp.status == 200
		rxdata -all
		expect resp.body == "response 1"
	} -run

	# second request is valid and advertises C-L:0
	stream 3 {
		barrier b2 sync
		txreq \
		  -req "POST" \
		  -scheme "https" \
		  -url "/test22.html" \
		  -hdr "content-length" "0"
		rxhdrs
		expect resp.status == 200
		rxdata -all
		expect resp.body == "response 2"
	} -run

	# third request sends a body with a GET
	stream 5 {
		barrier b3 sync
		txreq \
		  -req "POST" \
		  -scheme "https" \
		  -url "/test23.html" \
		  -nostrend \
		  -body "this must be delivered, like it or not"
		rxwinup
		rxhdrs
		expect resp.status == 200
		rxdata -all
		expect resp.body == "response 3"
	} -run

	# fourth request is valid and advertises C-L:2, and close, and is
	# followed by a string "this is not sent\r\n\r\n" which results
	# in a stream error.
	stream 7 {
		barrier b4 sync
		txreq \
		  -req "POST" \
		  -scheme "https" \
		  -url "/test24.html" \
		  -hdr "content-length" "2" \
		  -nostrend
		txdata -data "this is sent and ignored"
		rxrst
	} -run

	# fifth request is invalid and advertises invalid C-L ending with an
        # empty value, which results in a stream error.
	stream 9 {
		barrier b5 sync
		txreq \
		  -req "POST" \
		  -scheme "https" \
		  -url "/test25.html" \
		  -hdr "content-length" "0," \
		  -nostrend
		rxrst
	} -run

	# sixth request is invalid and advertises an empty C-L, which results
	# in a stream error.
	stream 11 {
		barrier b6 sync
		txreq \
		  -req "POST" \
		  -scheme "https" \
		  -url "/test26.html" \
		  -hdr "content-length" "" \
		  -nostrend
		rxrst
	} -run
} -run
