From: Christopher Faulet Date: Fri, 28 Aug 2026 09:10:49 +0000 (+0200) Subject: REGTESTS: decomp: Add more scripts to test HTTP/TCP decompression X-Git-Tag: v3.5-dev6~44 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=a63c584b18d56702af7a4f5cbe951dbdb4493d21;p=haproxy.git REGTESTS: decomp: Add more scripts to test HTTP/TCP decompression * decompression/http.vtc: response and request decompression in HTTP. * decompression/tcp.vtc: raw TCP streams decompression. * decompression/http_recompression.vtc: decompression then recompression. --- diff --git a/reg-tests/decompression/http.vtc b/reg-tests/decompression/http.vtc new file mode 100644 index 000000000..ce0020fbc --- /dev/null +++ b/reg-tests/decompression/http.vtc @@ -0,0 +1,292 @@ +varnishtest "HTTP decompression, requests and responses" + +feature cmd "$HAPROXY_PROGRAM -cc 'feature(SLZ)'" + +feature ignore_unknown_macro + +# response decompression in "auto" mode +server s1 { + # 1. no Content-Encoding at all: nothing must be touched, the framing + # must be left as-is + rxreq + expect req.url == "/plain" + # supported algorithms are advertised to the server + expect req.http.accept-encoding == "gzip" + txresp -body "not compressed" + + # 2. gzip body: decompressed, and switched to the chunked encoding + rxreq + expect req.url == "/gzip" + txresp -gzipbody "decompressed by haproxy" + + # 3. unsupported coding: "auto" is best-effort, the body is forwarded + # as-is + rxreq + expect req.url == "/unsupported" + txresp -hdr "Content-Encoding: br" -body "still compressed" + + # 4. 304 has no body: everything, including Content-Encoding, must be + # preserved as it describes the stored representation + rxreq + expect req.url == "/304" + txresp -status 304 -nolen -hdr "Content-Encoding: gzip" -hdr "ETag: \"strong\"" + + # 5. 204 has no body either + rxreq + expect req.url == "/204" + txresp -status 204 -nolen -hdr "Content-Encoding: gzip" + + # 6. a response to HEAD has no body, the announced Content-Length must + # not be replaced by a chunked encoding + rxreq + expect req.url == "/head" + expect req.method == "HEAD" + txresp -nolen -hdr "Content-Encoding: gzip" -hdr "Content-Length: 100" + + # 7. in "auto" mode the client's own Accept-Encoding is preserved + rxreq + expect req.url == "/keep-ae" + expect req.http.accept-encoding == "br" + txresp -gzipbody "decompressed by haproxy" + + # 8. a large body, decompressed over several passes + rxreq + expect req.url == "/big" + txresp -gziplen 50000 +} -start + +# response decompression in "always" mode, with two algorithms +server s2 { + rxreq + expect req.url == "/gzip" + # "always" mode drops the client's Accept-Encoding and only advertises + # what we can decompress + expect req.http.accept-encoding != "br" + txresp -gzipbody "gzip decompressed" + + rxreq + expect req.url == "/deflate" + txresp -nolen -hdr "Content-Encoding: deflate" -hdr "Content-Length: 21" + # zlib("deflated body") + sendhex "78DA4B494DCB492C494D5148CA4FA9040023510508" + + accept + + # an unsupported coding is a hard error in "always" mode + rxreq + expect req.url == "/unsupported" + txresp -hdr "Content-Encoding: br" -body "still compressed" +} -start + +# response decompression of a raw deflate body +server s3 { + rxreq + expect req.url == "/raw-deflate" + txresp -nolen -hdr "Content-Encoding: deflate" -hdr "Content-Length: 19" + # rawdeflate("raw deflated body") + sendhex "2B4A2C5748494DCB492C494D5148CA4FA90400" +} -start + +# request decompression in "always" mode +server s4 { + # 1. gzip request body: decompressed and rechunked + rxreq + expect req.url == "/gzip" + expect req.http.content-encoding == "" + expect req.http.content-length == "" + expect req.http.transfer-encoding == "chunked" + expect req.body == "decompressed request" + txresp -body "ok" + + # 2. a request that is not compressed at all is not an error, there is + # simply nothing to decompress + rxreq + expect req.url == "/plain" + expect req.http.transfer-encoding == "" + expect req.body == "plain request" + txresp -body "ok" + + # 3. a large gzip request body + rxreq + expect req.url == "/big" + expect req.bodylen == 50000 + txresp -body "ok" +} -start + +haproxy h1 -conf { + global + .if feature(THREAD) + thread-groups 1 + .endif + + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen res-auto + mode http + bind "fd@${res_auto}" + decompression algo-res gzip + decompression mode-res auto + filter decomp-res + server s1 ${s1_addr}:${s1_port} + + listen res-always + mode http + bind "fd@${res_always}" + decompression algo-res gzip deflate + decompression mode-res always + filter decomp-res + server s2 ${s2_addr}:${s2_port} + + listen res-raw-deflate + mode http + bind "fd@${res_raw_deflate}" + # "raw-deflate" is advertised as "deflate" in Accept-Encoding, like + # for the compression + decompression algo-res raw-deflate + decompression mode-res always + filter decomp-res + server s3 ${s3_addr}:${s3_port} + + listen req-always + mode http + bind "fd@${req_always}" + decompression algo-req gzip + decompression mode-req always + filter decomp-req + server s4 ${s4_addr}:${s4_port} +} -start + +client c1 -connect ${h1_res_auto_sock} { + # 1. uncompressed response, untouched + txreq -url "/plain" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "" + expect resp.http.transfer-encoding == "" + expect resp.http.content-length == "14" + expect resp.body == "not compressed" + + # 2. gzip response, decompressed. The body size is unknown when the + # headers are processed, so the message is switched to chunked and + # the Content-Length is dropped. + txreq -url "/gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "" + expect resp.http.content-length == "" + expect resp.http.transfer-encoding == "chunked" + expect resp.body == "decompressed by haproxy" + + # 3. unsupported coding, forwarded as-is in "auto" mode + txreq -url "/unsupported" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "br" + expect resp.http.transfer-encoding == "" + expect resp.body == "still compressed" + + # 4. 304, left completely untouched + txreq -url "/304" + rxresp + expect resp.status == 304 + expect resp.http.content-encoding == "gzip" + expect resp.http.transfer-encoding == "" + expect resp.http.etag == "\"strong\"" + + # 5. 204, left completely untouched + txreq -url "/204" + rxresp + expect resp.status == 204 + expect resp.http.content-encoding == "gzip" + expect resp.http.transfer-encoding == "" + + # 6. response to HEAD, left completely untouched + txreq -req "HEAD" -url "/head" + rxresp -no_obj + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.http.content-length == "100" + expect resp.http.transfer-encoding == "" + + # 7. the client's Accept-Encoding is preserved in "auto" mode + txreq -url "/keep-ae" -hdr "Accept-Encoding: br" + rxresp + expect resp.status == 200 + expect resp.body == "decompressed by haproxy" + + # 8. large body + txreq -url "/big" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "" + expect resp.http.transfer-encoding == "chunked" + expect resp.bodylen == 50000 +} -run + +client c2 -connect ${h1_res_always_sock} { + # 1. gzip + txreq -url "/gzip" -hdr "Accept-Encoding: br" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "" + expect resp.body == "gzip decompressed" + + # 2. zlib deflate + txreq -url "/deflate" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "" + expect resp.http.content-length == "" + expect resp.http.transfer-encoding == "chunked" + expect resp.body == "deflated body" +} -run + +# an unsupported coding cannot be decompressed while "always" was requested: +# the stream is aborted. Note the headers were already received at this point, +# so for now nothing at all is reported to the client, the connection is just +# closed. +client c3 -connect ${h1_res_always_sock} { + txreq -url "/unsupported" + expect_close +} -run + +client c4 -connect ${h1_res_raw_deflate_sock} { + txreq -url "/raw-deflate" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "" + expect resp.http.transfer-encoding == "chunked" + expect resp.body == "raw deflated body" +} -run + +client c5 -connect ${h1_req_always_sock} { + # 1. gzip request body + txreq -url "/gzip" -gzipbody "decompressed request" + rxresp + expect resp.status == 200 + expect resp.body == "ok" + + # 2. uncompressed request body + txreq -url "/plain" -body "plain request" + rxresp + expect resp.status == 200 + expect resp.body == "ok" + + # 3. large gzip request body + txreq -url "/big" -gziplen 50000 + rxresp + expect resp.status == 200 + expect resp.body == "ok" +} -run + +# an unsupported coding on the request while "always" was requested: the +# stream is aborted before the request is sent to the server +client c6 -connect ${h1_req_always_sock} { + txreq -url "/unsupported" -hdr "Content-Encoding: br" -body "compressed" + rxresp + expect resp.status == 400 +} -run diff --git a/reg-tests/decompression/http_recompression.vtc b/reg-tests/decompression/http_recompression.vtc new file mode 100644 index 000000000..ac665cf9e --- /dev/null +++ b/reg-tests/decompression/http_recompression.vtc @@ -0,0 +1,227 @@ +varnishtest "HTTP decompression chained with the compression" + +feature cmd "$HAPROXY_PROGRAM -cc 'feature(SLZ)'" + +feature ignore_unknown_macro + +# The proxies below decompress the messages they receive and compress them +# again before forwarding them. This is the typical setup where haproxy has to +# inspect or transform a compressed payload, or where the two endpoints don't +# agree on the same coding. + +# same coding on both sides +server s1 { + # 1. the request was gzipped by the client, decompressed by the proxy, + # then gzipped again. The server must see a brand new gzip stream + # over a chunked message. + rxreq + expect req.url == "/both-ways" + expect req.http.content-encoding == "gzip" + expect req.http.content-length == "" + expect req.http.transfer-encoding == "chunked" + gunzip + expect req.body == "request from the client" + + # the response decompression advertises what we support, so the server + # is free to compress its response + expect req.http.accept-encoding == "gzip" + txresp -hdr "Content-Type: text/plain" -gzipbody "response from the server" + + # 2. nothing to decompress in either direction: the decompression must + # not get in the way of the compression + rxreq + expect req.url == "/nothing-to-decompress" + expect req.http.content-encoding == "gzip" + gunzip + expect req.body == "uncompressed request" + txresp -hdr "Content-Type: text/plain" -body "uncompressed response" + + # 3. the client accepts no coding at all. The response decompression + # still advertises gzip to the server on its own behalf, but that + # must not be mistaken for the client's own "Accept-Encoding": the + # response has to be delivered decompressed. + rxreq + expect req.url == "/no-accept-encoding" + expect req.http.accept-encoding == "gzip" + txresp -hdr "Content-Type: text/plain" -gzipbody "third response" +} -start + +# the client only knows gzip, the server only knows deflate +server s2 { + rxreq + expect req.url == "/transcode" + # the request was gzipped by the client and is deflated for the server + expect req.http.content-encoding == "deflate" + expect req.http.content-length == "" + expect req.http.transfer-encoding == "chunked" + # only what we are able to decompress on the response path is + # advertised, the client's own "gzip" must not leak here + expect req.http.accept-encoding == "deflate" + + txresp -nolen \ + -hdr "Content-Type: text/plain" \ + -hdr "Content-Encoding: deflate" \ + -hdr "Content-Length: 30" + # zlib("deflated by the server") + sendhex "78DA4B494DCB492C494D5148AA5428C94855284E2D2A4B2D02005EB4084D" +} -start + +# same as s2, but with the compression offloading enabled +server s3 { + rxreq + expect req.url == "/offload" + expect req.http.content-encoding == "deflate" + expect req.http.transfer-encoding == "chunked" + # "compression offload" removed the client's own codings, so only the + # one advertised by the response decompression is left. Note the + # decompression is in "auto" mode here, it does not remove anything by + # itself. + expect req.http.accept-encoding == "deflate" + + txresp -nolen \ + -hdr "Content-Type: text/plain" \ + -hdr "Content-Encoding: deflate" \ + -hdr "ETag: \"strong\"" \ + -hdr "Content-Length: 30" + # zlib("offloaded and deflated") + sendhex "78DACB4F4BCBC94F4C494D5148CC4B5148494DCB492C494D0100603B0851" +} -start + +haproxy h1 -conf { + global + .if feature(THREAD) + thread-groups 1 + .endif + + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen recomp + mode http + bind "fd@${recomp}" + + decompression algo-req gzip + decompression mode-req always + decompression algo-res gzip + decompression mode-res always + + compression direction both + compression algo-req gzip + compression type-req text/plain + compression algo-res gzip + compression type-res text/plain + + server s1 ${s1_addr}:${s1_port} + + listen recomp-transcode + mode http + bind "fd@${recomp_transcode}" + + decompression algo-req gzip + decompression mode-req always + decompression algo-res deflate + decompression mode-res always + + compression direction both + compression algo-req deflate + compression type-req text/plain + compression algo-res gzip + compression type-res text/plain + + server s2 ${s2_addr}:${s2_port} + + listen recomp-offload + mode http + bind "fd@${recomp_offload}" + + decompression algo-req gzip + decompression mode-req always + decompression algo-res deflate + decompression mode-res auto + + compression direction both + compression algo-req deflate + compression type-req text/plain + compression algo-res gzip + compression type-res text/plain + # hide the client's codings from the server. The codings advertised by + # the response decompression must survive it, otherwise the server + # would stop compressing and there would be nothing left to decompress. + compression offload + + server s3 ${s3_addr}:${s3_port} +} -start + +client c1 -connect ${h1_recomp_sock} { + # 1. compressed in both directions + txreq -url "/both-ways" \ + -hdr "Accept-Encoding: gzip" \ + -hdr "Content-Type: text/plain" \ + -gzipbody "request from the client" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.http.transfer-encoding == "chunked" + gunzip + expect resp.body == "response from the server" + + # 2. uncompressed in both directions: only the compression must kick in + txreq -url "/nothing-to-decompress" \ + -hdr "Accept-Encoding: gzip" \ + -hdr "Content-Type: text/plain" \ + -body "uncompressed request" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.http.transfer-encoding == "chunked" + gunzip + expect resp.body == "uncompressed response" + + # 3. no "Accept-Encoding" from the client: the response is only + # decompressed, it must not be compressed again + txreq -url "/no-accept-encoding" \ + -hdr "Content-Type: text/plain" \ + -gzipbody "third request" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "" + expect resp.http.transfer-encoding == "chunked" + expect resp.body == "third response" +} -run + +# gzip on the client side, deflate on the server side +client c2 -connect ${h1_recomp_transcode_sock} { + txreq -url "/transcode" \ + -hdr "Accept-Encoding: gzip" \ + -hdr "Content-Type: text/plain" \ + -gzipbody "gzipped by the client" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.http.content-length == "" + expect resp.http.transfer-encoding == "chunked" + gunzip + expect resp.body == "deflated by the server" +} -run + +# same as c2, but the compression offloading hides the client's codings from +# the server +client c3 -connect ${h1_recomp_offload_sock} { + txreq -url "/offload" \ + -hdr "Accept-Encoding: gzip, br" \ + -hdr "Content-Type: text/plain" \ + -gzipbody "gzipped by the client" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.http.transfer-encoding == "chunked" + expect resp.http.vary == "Accept-Encoding" + # both filters alter the representation but the ETag must only be + # weakened once + expect resp.http.etag == "W/\"strong\"" + gunzip + expect resp.body == "offloaded and deflated" +} -run diff --git a/reg-tests/decompression/tcp.vtc b/reg-tests/decompression/tcp.vtc new file mode 100644 index 000000000..02399e653 --- /dev/null +++ b/reg-tests/decompression/tcp.vtc @@ -0,0 +1,234 @@ +varnishtest "Decompression of raw TCP streams" + +feature cmd "$HAPROXY_PROGRAM -cc 'feature(SLZ)'" + +feature ignore_unknown_macro + +# HAProxy is in TCP mode here, so it does not parse anything: the payloads +# below are opaque byte streams for it. The clients and the servers only +# agree on HTTP because it gives us a convenient and readable way to assert +# on the *decompressed* bytes. +# +# Compressed payloads are injected as hex with "sendhex". They were produced +# with the following helper, where is 31 for gzip, 15 for zlib and -15 +# for raw deflate. The 4 gzip mtime bytes are zeroed so that the payloads stay +# stable: +# +# python3 -c 'import sys, zlib; \ +# d = sys.stdin.buffer.read(); \ +# c = zlib.compressobj(9, zlib.DEFLATED, ); \ +# o = c.compress(d) + c.flush(); \ +# o = (o[:4] + bytes(4) + o[8:]) if o[:2] == b"\x1f\x8b" else o; \ +# print(o.hex().upper())' + +# gzip in both directions +server s1 { + rxreq + expect req.method == "GET" + expect req.url == "/tcp-gzip" + expect req.http.host == "decomp" + + # gzip("HTTP/1.1 200 OK\r\nContent-Length: 17\r\n\r\ntcp gzip response") + sendhex "1F8B0800000000000203F3080909D037D4335430323050F0F7E6E572CECF2B49" + sendhex "CD2BD1F549CD4B2FC9B0523034E7E5E2E52A492E5048AFCA2C50284A2D2EC8CF" + sendhex "2B4E0500771922E238000000" +} -start + +# uslz-auto on the request only, exercised with a zlib stream then with a +# raw deflate stream +server s2 { + rxreq + expect req.url == "/tcp-auto-zlib" + txresp -body "zlib request seen" + + accept + + rxreq + expect req.url == "/tcp-auto-raw" + txresp -body "raw deflate request seen" +} -start + +# raw deflate on the response only +server s3 { + rxreq + expect req.url == "/tcp-raw-deflate" + + # rawdeflate("HTTP/1.1 200 OK\r\nContent-Length: 25\r\n\r\ntcp raw-deflate response") + sendhex "F3080909D037D4335430323050F0F7E6E572CECF2B49CD2BD1F549CD4B2FC9B0" + sendhex "523032E1E5E2E52A492E50284A2CD74D494DCB492C4955284A2D2EC8CF2B4E05" + sendhex "00" +} -start + +# decompression configured but disabled by the "none" mode +server s4 { + rxreq + expect req.url == "/tcp-none" + expect req.body == "not compressed" + txresp -body "not compressed either" +} -start + +# large payloads, to force the decompressed output to be drained over +# several passes +server s5 { + rxreq + expect req.url == "/tcp-big" + expect req.bodylen == 50000 + + # gzip("HTTP/1.1 200 OK\r\nContent-Length: 50000\r\n\r\n" + 50000 * "y") + sendhex "1F8B0800000000000203EDC1B10984300000C03E901DB2806F146C6CBF1114B4" + sendhex "7005D12A36697EFB770EB9BB69DFB7B6FB74A9CF39AD730CDFBBD4A3D46639CA" + sendhex "59AF310DF911430C3F0000000000000000000000000000000000000000000000" + sendhex "000000000000000000000000000000000000000000000000005EE50F669DE619" + sendhex "7AC30000" +} -start + +# "always" mode on a stream that is not compressed at all: the stream must be +# aborted, so the server must never see any data +server s6 { + expect_close +} -start + +haproxy h1 -conf { + global + .if feature(THREAD) + thread-groups 1 + .endif + + defaults + mode tcp + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen tcp-gzip + mode tcp + bind "fd@${tcp_gzip}" + decompression algo-req gzip + decompression mode-req always + decompression algo-res gzip + decompression mode-res always + filter decomp-req + filter decomp-res + server s1 ${s1_addr}:${s1_port} + + listen tcp-auto + mode tcp + bind "fd@${tcp_auto}" + # "uslz-auto" detects the zlib/gzip wrapper and falls back to raw + # deflate otherwise. It is only allowed on TCP proxies. + decompression algo-req uslz-auto + decompression mode-req always + filter decomp-req + server s2 ${s2_addr}:${s2_port} + + listen tcp-raw-deflate + mode tcp + bind "fd@${tcp_raw_deflate}" + decompression algo-res raw-deflate + decompression mode-res always + filter decomp-res + server s3 ${s3_addr}:${s3_port} + + listen tcp-none + mode tcp + bind "fd@${tcp_none}" + # algorithms are configured but the "none" mode disables the + # decompression: both directions must pass through untouched + decompression algo-req gzip + decompression mode-req none + decompression algo-res gzip + decompression mode-res none + filter decomp-req + filter decomp-res + server s4 ${s4_addr}:${s4_port} + + listen tcp-big + mode tcp + bind "fd@${tcp_big}" + decompression algo-req gzip + decompression mode-req always + decompression algo-res gzip + decompression mode-res always + filter decomp-req + filter decomp-res + server s5 ${s5_addr}:${s5_port} + + listen tcp-fail + mode tcp + bind "fd@${tcp_fail}" + decompression algo-req gzip + decompression mode-req always + filter decomp-req + server s6 ${s6_addr}:${s6_port} +} -start + +# 1. gzip request and gzip response on the same connection. Both streams are +# independent, each one is decompressed on its own way. +client c1 -connect ${h1_tcp_gzip_sock} { + # gzip("GET /tcp-gzip HTTP/1.1\r\nHost: decomp\r\n\r\n") + sendhex "1F8B080000000000020373770D51D02F492ED04DAFCA2C50F0080909D037D433" + sendhex "E4E5F2C82F2EB15248494DCECF2DE0E5E2E50200B410B0A128000000" + + rxresp + expect resp.status == 200 + expect resp.body == "tcp gzip response" +} -run + +# 2. zlib stream, detected by "uslz-auto" +client c2 -connect ${h1_tcp_auto_sock} { + # zlib("GET /tcp-auto-zlib HTTP/1.1\r\nHost: decomp\r\n\r\n") + sendhex "78DA73770D51D02F492ED04D2C2DC9D7ADCAC94C52F0080909D037D433E4E5F2" + sendhex "C82F2EB15248494DCECF2DE0E5E2E502003FB40D0F" + + rxresp + expect resp.status == 200 + expect resp.body == "zlib request seen" +} -run + +# 3. raw deflate stream, "uslz-auto" falls back to it since there is no +# recognizable wrapper +client c3 -connect ${h1_tcp_auto_sock} { + # rawdeflate("GET /tcp-auto-raw HTTP/1.1\r\nHost: decomp\r\n\r\n") + sendhex "73770D51D02F492ED04D2C2DC9D72D4A2C57F0080909D037D433E4E5F2C82F2E" + sendhex "B15248494DCECF2DE0E5E2E50200" + + rxresp + expect resp.status == 200 + expect resp.body == "raw deflate request seen" +} -run + +# 4. raw deflate on the response path only, the request is sent as-is +client c4 -connect ${h1_tcp_raw_deflate_sock} { + txreq -url "/tcp-raw-deflate" -hdr "Host: decomp" -nohost + rxresp + expect resp.status == 200 + expect resp.body == "tcp raw-deflate response" +} -run + +# 5. "none" mode, nothing must be altered in either direction +client c5 -connect ${h1_tcp_none_sock} { + txreq -url "/tcp-none" -body "not compressed" + rxresp + expect resp.status == 200 + expect resp.body == "not compressed either" +} -run + +# 6. large gzip payloads in both directions +client c6 -connect ${h1_tcp_big_sock} { + # gzip("GET /tcp-big HTTP/1.1\r\nHost: decomp\r\nContent-Length: 50000\r\n\r\n" + 50000 * "x") + sendhex "1F8B0800000000000203EDC1310E82300000C0BD49FFD00F2032B8B01A238383" + sendhex "435F201274B025B183CFD77798BB3B9F72EADBBC75B7E79AA69CAFFDB01B6298" + sendhex "EABB8DE9BECCF5B5C570ACA52DA57597A5ACED31A6C3FE2786183E0000000000" + sendhex "0000000000000000000000000000000000000000000000000000000000000000" + sendhex "0000000000000000000000FC952FA3C1D4B28EC30000" + + rxresp + expect resp.status == 200 + expect resp.bodylen == 50000 +} -run + +# 7. uncompressed stream while "always" is requested: the stream is rejected +client c7 -connect ${h1_tcp_fail_sock} { + txreq -url "/tcp-fail" + expect_close +} -run