diff options
Diffstat (limited to '')
273 files changed, 25317 insertions, 0 deletions
diff --git a/reg-tests/README b/reg-tests/README new file mode 100644 index 0000000..ef721fd --- /dev/null +++ b/reg-tests/README @@ -0,0 +1,71 @@ + * Regression testing for HAProxy with VTest * + + +This little README file is about how to compile and run vtest test case files (VTC files) +to test HAProxy for any regression. + +To do so, you will have to compile vtest program sources which depends on +Varnish cache application sources. vtest, formerly varnishtest, is a very useful +program which has been developed to test Varnish cache application. vtest has been +modified in collaboration with Varnish cache conceptor Poul-Henning Kamp to support +HAProxy in addition to Varnish cache. + +See also: doc/regression-testing.txt + +* vtest compilation * + + $ git clone https://github.com/vtest/VTest + + $ cd VTest + + $ make vtest + + Then vtest program may be found at the root directory of vtest sources directory. + The Varnish cache manuals are located in 'man' directory of Varnish cache sources + directory. You will have to have a look at varnishtest(7) and vtc(7) manuals to + use vtest. + + Some information may also be found in doc/regression-testing.txt in HAProxy + sources. + + Note that VTC files for Varnish cache may be found in bin/varnishtest/tests directory + of Varnish cache sources directory which may be found here: + https://github.com/varnishcache/varnish-cache + + +* vtest execution * + + You must set HAPROXY_PROGRAM environment variable to give the location + of the HAProxy program to test to vtest: + + $ HAPROXY_PROGRAM=<my haproxy program> vtest ... + + The HAProxy VTC files found in HAProxy sources may be run with the reg-tests + Makefile target. You must set the VTEST_PROGRAM environment variable to + give the location of the vtest program which has been previously compiled. + + $ VTEST_PROGRAM=<my vtest program> make reg-tests + + "reg-tests" Makefile target run scripts/run-regtest.sh script. + To get more information about this script run it with --help option. + + Note that vtest is run with -t10 and -l option. -l option is to keep + keep vtest temporary directory in case of failed test cases. core files + may be found in this directory (if enabled by ulimit). + + +* vtest patches for HAProxy VTC files * + + When producing a patch to add a VTC regression testing file to reg-tests directory, + please follow these simple rules: + + - If your VTC file needs others files, if possible, use the same basename as that + of the VTC file, + - Put these files in a directory with the same name as the code area concerned + by the bug ('peers', 'lua', 'acl' etc). + +Please note that most tests use a common set of timeouts defined by the +environment variable HAPROXY_TEST_TIMEOUT. As much as possible, for regular I/O +(i.e. not errors), please try to reuse that setting so that the value may +easily be adjusted when running in some particularly slow environments, or be +shortened to fail faster on developers' machines. diff --git a/reg-tests/balance/balance-rr.vtc b/reg-tests/balance/balance-rr.vtc new file mode 100644 index 0000000..908a4f9 --- /dev/null +++ b/reg-tests/balance/balance-rr.vtc @@ -0,0 +1,73 @@ +vtest "Test for balance roundrobin" +feature ignore_unknown_macro + +server s1 { + rxreq + txresp -hdr "Server: s1" +} -repeat 2 -start + +server s2 { + rxreq + txresp -hdr "Server: s2" +} -repeat 2 -start + +server s3 { + rxreq + txresp -hdr "Server: s3" +} -repeat 2 -start + +server s4 { + rxreq + txresp -hdr "Server: s4" +} -repeat 2 -start + +haproxy h1 -arg "-L A" -conf { + defaults + mode http + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + + listen px + bind "fd@${px}" + balance roundrobin + server srv1 ${s1_addr}:${s1_port} + server srv2 ${s2_addr}:${s2_port} + server srv3 ${s3_addr}:${s3_port} + server srv4 ${s4_addr}:${s4_port} +} -start + +client c1 -connect ${h1_px_sock} { + txreq -url "/url1" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s1 +} -run + +client c2 -connect ${h1_px_sock} { + txreq -url "/url1" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s2 +} -run + +client c3 -connect ${h1_px_sock} { + txreq -url "/url1" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s3 +} -run + +client c4 -connect ${h1_px_sock} { + txreq -url "/url1" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s4 +} -run + +client c5 -connect ${h1_px_sock} { + txreq -url "/url1" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s1 +} -run diff --git a/reg-tests/balance/balance-uri-path-only.vtc b/reg-tests/balance/balance-uri-path-only.vtc new file mode 100644 index 0000000..f1291ee --- /dev/null +++ b/reg-tests/balance/balance-uri-path-only.vtc @@ -0,0 +1,97 @@ +vtest "Test for balance URI" +feature ignore_unknown_macro +#REQUIRE_VERSION=2.3 + +server s1 { + rxreq + txresp -hdr "Server: s1" -body "s1" +} -repeat 5 -start + +server s2 { + rxreq + txresp -hdr "Server: s2" -body "s2" +} -repeat 5 -start + +server s3 { + rxreq + txresp -hdr "Server: s3" -body "s3" +} -repeat 5 -start + +server s4 { + rxreq + txresp -hdr "Server: s4" -body "s4" +} -repeat 5 -start + +haproxy h1 -arg "-L A" -conf { + defaults + mode http + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + + listen px + bind "fd@${px}" + bind "fd@${pxh2}" proto h2 + balance uri path-only + server srv1 ${s1_addr}:${s1_port} + server srv2 ${s2_addr}:${s2_port} + server srv3 ${s3_addr}:${s3_port} + server srv4 ${s4_addr}:${s4_port} +} -start + +client c1 -connect ${h1_px_sock} { + txreq -url "http://127.0.0.1/url1" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s2 +} -run + +client c2 -connect ${h1_px_sock} { + txreq -url "/url1?ignore=this-arg" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s2 +} -run + +client c3 -connect ${h1_px_sock} { + txreq -url "http://127.0.0.1/url2" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s3 +} -run + +client c4 -connect ${h1_px_sock} { + txreq -url "/url3" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s4 +} -run + +client c5 -connect ${h1_px_sock} { + txreq -url "/url4" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s1 +} -run + +client c6h2 -connect ${h1_pxh2_sock} { + txpri + stream 0 { + txsettings + rxsettings + txsettings -ack + rxsettings + expect settings.ack == true + } -run + + stream 1 { + txreq \ + -req "GET" \ + -scheme "https" \ + -url "/url1" + rxhdrs + expect resp.status == 200 + rxdata -all + expect resp.body == "s2" + } -run +} -run diff --git a/reg-tests/balance/balance-uri.vtc b/reg-tests/balance/balance-uri.vtc new file mode 100644 index 0000000..cc65d64 --- /dev/null +++ b/reg-tests/balance/balance-uri.vtc @@ -0,0 +1,74 @@ +vtest "Test for balance URI" +feature ignore_unknown_macro +#REQUIRE_VERSION=2.0 + +server s1 { + rxreq + txresp -hdr "Server: s1" +} -repeat 2 -start + +server s2 { + rxreq + txresp -hdr "Server: s2" +} -repeat 2 -start + +server s3 { + rxreq + txresp -hdr "Server: s3" +} -repeat 2 -start + +server s4 { + rxreq + txresp -hdr "Server: s4" +} -repeat 2 -start + +haproxy h1 -arg "-L A" -conf { + defaults + mode http + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + + listen px + bind "fd@${px}" + balance uri + server srv1 ${s1_addr}:${s1_port} + server srv2 ${s2_addr}:${s2_port} + server srv3 ${s3_addr}:${s3_port} + server srv4 ${s4_addr}:${s4_port} +} -start + +client c1 -connect ${h1_px_sock} { + txreq -url "/url1" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s2 +} -run + +client c2 -connect ${h1_px_sock} { + txreq -url "/url1?ignore=this-arg" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s2 +} -run + +client c3 -connect ${h1_px_sock} { + txreq -url "/url2" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s3 +} -run + +client c4 -connect ${h1_px_sock} { + txreq -url "/url3" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s4 +} -run + +client c5 -connect ${h1_px_sock} { + txreq -url "/url4" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s1 +} -run diff --git a/reg-tests/cache/basic.vtc b/reg-tests/cache/basic.vtc new file mode 100644 index 0000000..d6a8c00 --- /dev/null +++ b/reg-tests/cache/basic.vtc @@ -0,0 +1,55 @@ +varnishtest "Basic cache test" + +#REQUIRE_VERSION=1.9 + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp -nolen -hdr "Transfer-Encoding: chunked" \ + -hdr "Cache-Control: max-age=5" + chunkedlen 1 + chunkedlen 1 + chunkedlen 2 + chunkedlen 3 + chunkedlen 5 + chunkedlen 8 + chunkedlen 13 + chunkedlen 21 + chunkedlen 34 + chunkedlen 55 + chunkedlen 89 + chunkedlen 144 + chunkedlen 233 + chunkedlen 0 +} -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + default_backend test + + backend test + http-request cache-use my_cache + server www ${s1_addr}:${s1_port} + http-response cache-store my_cache + + cache my_cache + total-max-size 3 + max-age 20 + max-object-size 3072 +} -start + + +client c1 -connect ${h1_fe_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.bodylen == 609 +} -repeat 4 -run diff --git a/reg-tests/cache/caching_rules.vtc b/reg-tests/cache/caching_rules.vtc new file mode 100644 index 0000000..61274b4 --- /dev/null +++ b/reg-tests/cache/caching_rules.vtc @@ -0,0 +1,256 @@ +varnishtest "Caching rules test" +# A response will not be cached unless it has an explicit age (Cache-Control max-age of s-maxage, Expires) or a validator (Last-Modified, or ETag) +# A response will not be cached either if it has an Age header that is either invalid (should be an integer) or greater than its max age. + +#REQUIRE_VERSION=2.4 + +feature ignore_unknown_macro + +server s1 { + rxreq + expect req.url == "/max-age" + txresp -hdr "Cache-Control: max-age=5" \ + -bodylen 150 + + rxreq + expect req.url == "/s-maxage" + txresp -hdr "Cache-Control: s-maxage=5" \ + -bodylen 160 + + rxreq + expect req.url == "/last-modified" + txresp -hdr "Last-Modified: Thu, 22 Oct 2020 16:51:12 GMT" \ + -bodylen 180 + + rxreq + expect req.url == "/etag" + txresp -hdr "ETag: \"etag\"" \ + -bodylen 190 + + rxreq + expect req.url == "/uncacheable" + txresp \ + -bodylen 200 + + rxreq + expect req.url == "/uncacheable" + txresp \ + -bodylen 210 + + # Age response header checks + + # Invalid age + rxreq + expect req.url == "/invalid_age" + txresp -hdr "Cache-Control: max-age=5" \ + -hdr "Age: abc" -bodylen 120 + + rxreq + expect req.url == "/invalid_age" + txresp -hdr "Cache-Control: max-age=5" \ + -hdr "Age: abc" -bodylen 120 + + # Old age (greater than max age) + rxreq + expect req.url == "/old_age" + txresp -hdr "Cache-Control: max-age=5" \ + -hdr "Age: 10" -bodylen 130 + + rxreq + expect req.url == "/old_age" + txresp -hdr "Cache-Control: max-age=5" \ + -hdr "Age: 10" -bodylen 130 + + # Good age + rxreq + expect req.url == "/good_age" + txresp -hdr "Cache-Control: max-age=500" \ + -hdr "Age: 100" -bodylen 140 + + + # "Control-Cache: no-cache" on client request but still stored in cache + rxreq + expect req.url == "/nocache" + txresp -hdr "Cache-Control: max-age=500" \ + -hdr "Age: 100" -bodylen 140 + + rxreq + expect req.url == "/nocache" + txresp -hdr "Cache-Control: max-age=500" \ + -hdr "Age: 100" -bodylen 140 + +} -start + +server s2 { + rxreq + expect req.url == "/expires" + # Expires header is filled directly by the expires_be backend" + txresp \ + -bodylen 170 +} -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 + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + use_backend expires_be if { path_beg /expires } + default_backend test + + backend expires_be + http-request cache-use my_cache + server www ${s2_addr}:${s2_port} + http-response set-header X-Cache-Hit %[res.cache_hit] + # Expires value set in the future (current_time+5s) + http-response set-header Expires %[date(5),http_date] + http-response cache-store my_cache + + backend test + http-request cache-use my_cache + server www ${s1_addr}:${s1_port} + http-response cache-store my_cache + http-response set-header X-Cache-Hit %[res.cache_hit] + + cache my_cache + total-max-size 3 + max-age 20 + max-object-size 3072 +} -start + + +client c1 -connect ${h1_fe_sock} { + txreq -url "/max-age" + rxresp + expect resp.status == 200 + expect resp.bodylen == 150 + + txreq -url "/max-age" + rxresp + expect resp.status == 200 + expect resp.bodylen == 150 + expect resp.http.X-Cache-Hit == 1 + + txreq -url "/s-maxage" + rxresp + expect resp.status == 200 + expect resp.bodylen == 160 + + txreq -url "/s-maxage" + rxresp + expect resp.status == 200 + expect resp.bodylen == 160 + expect resp.http.X-Cache-Hit == 1 + + txreq -url "/expires" + rxresp + expect resp.status == 200 + expect resp.bodylen == 170 + + txreq -url "/expires" + rxresp + expect resp.status == 200 + expect resp.bodylen == 170 + expect resp.http.X-Cache-Hit == 1 + + txreq -url "/last-modified" + rxresp + expect resp.status == 200 + expect resp.bodylen == 180 + + txreq -url "/last-modified" + rxresp + expect resp.status == 200 + expect resp.bodylen == 180 + expect resp.http.X-Cache-Hit == 1 + + txreq -url "/etag" + rxresp + expect resp.status == 200 + expect resp.bodylen == 190 + + txreq -url "/etag" + rxresp + expect resp.status == 200 + expect resp.bodylen == 190 + expect resp.http.X-Cache-Hit == 1 + + # The next response should not be cached + txreq -url "/uncacheable" + rxresp + expect resp.status == 200 + expect resp.bodylen == 200 + + txreq -url "/uncacheable" + rxresp + expect resp.status == 200 + expect resp.bodylen == 210 + expect resp.http.X-Cache-Hit == 0 + + # Age header tests + txreq -url "/invalid_age" + rxresp + expect resp.status == 200 + expect resp.bodylen == 120 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/invalid_age" + rxresp + expect resp.status == 200 + expect resp.bodylen == 120 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/old_age" + rxresp + expect resp.status == 200 + expect resp.bodylen == 130 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/old_age" + rxresp + expect resp.status == 200 + expect resp.bodylen == 130 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/good_age" + rxresp + expect resp.status == 200 + expect resp.bodylen == 140 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/good_age" + rxresp + expect resp.status == 200 + expect resp.bodylen == 140 + expect resp.http.X-Cache-Hit == 1 + + # Cache-Control: no-cache + txreq -url "/nocache" -hdr "Cache-Control: no-cache" + rxresp + expect resp.status == 200 + expect resp.bodylen == 140 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/nocache" -hdr "Cache-Control: no-cache" + rxresp + expect resp.status == 200 + expect resp.bodylen == 140 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/nocache" + rxresp + expect resp.status == 200 + expect resp.bodylen == 140 + expect resp.http.X-Cache-Hit == 1 + + +} -run diff --git a/reg-tests/cache/expires.vtc b/reg-tests/cache/expires.vtc new file mode 100644 index 0000000..ee5cd77 --- /dev/null +++ b/reg-tests/cache/expires.vtc @@ -0,0 +1,127 @@ +varnishtest "Expires support" + +#REQUIRE_VERSION=2.3 + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp -nolen -hdr "Transfer-Encoding: chunked" \ + -hdr "Cache-Control: max-age=5" + chunkedlen 15 + chunkedlen 15 + chunkedlen 15 + chunkedlen 0 +} -start + +server s2 { + rxreq + txresp -nolen -hdr "Transfer-Encoding: chunked" + chunkedlen 16 + chunkedlen 16 + chunkedlen 16 + chunkedlen 0 +} -start + +server s3 { + rxreq + txresp -nolen -hdr "Transfer-Encoding: chunked" + chunkedlen 16 + chunkedlen 16 + chunkedlen 16 + chunkedlen 0 + + rxreq + txresp -nolen -hdr "Transfer-Encoding: chunked" + chunkedlen 17 + chunkedlen 17 + chunkedlen 17 + chunkedlen 0 +} -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 + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + use_backend cache_control_be if { path_beg /cache_control } + use_backend future_expires_be if { path_beg /future } + default_backend past_expires_be + + backend cache_control_be + # Expires header should be ignored since a Cache-Control one is present + http-request cache-use my_cache + server www ${s1_addr}:${s1_port} + http-response set-header X-Cache-Hit %[res.cache_hit] + http-response set-header Expires %[date(-1),http_date] + http-response cache-store my_cache + + backend future_expires_be + # Expires value set in the future (current_time+5s) + http-request cache-use my_cache + server www ${s2_addr}:${s2_port} + http-response set-header X-Cache-Hit %[res.cache_hit] + http-response set-header Expires %[date(5),http_date] + http-response cache-store my_cache + + backend past_expires_be + # Expires value set in the past + http-request cache-use my_cache + server www ${s3_addr}:${s3_port} + http-response set-header X-Cache-Hit %[res.cache_hit] + http-response set-header Expires %[date(-1),http_date] + http-response cache-store my_cache + + cache my_cache + total-max-size 3 + max-age 20 + max-object-size 3072 +} -start + + +client c1 -connect ${h1_fe_sock} { + txreq -url "/cache_control" + rxresp + expect resp.status == 200 + expect resp.bodylen == 45 + + txreq -url "/cache_control" + rxresp + expect resp.status == 200 + expect resp.bodylen == 45 + expect resp.http.X-Cache-Hit == 1 + + txreq -url "/future" + rxresp + expect resp.status == 200 + expect resp.bodylen == 48 + + txreq -url "/future" + rxresp + expect resp.status == 200 + expect resp.bodylen == 48 + expect resp.http.X-Cache-Hit == 1 + + txreq -url "/past" + rxresp + expect resp.status == 200 + expect resp.bodylen == 48 + + txreq -url "/past" + rxresp + expect resp.status == 200 + expect resp.bodylen == 51 + expect resp.http.X-Cache-Hit == 0 + +} -run + diff --git a/reg-tests/cache/if-modified-since.vtc b/reg-tests/cache/if-modified-since.vtc new file mode 100644 index 0000000..a49e473 --- /dev/null +++ b/reg-tests/cache/if-modified-since.vtc @@ -0,0 +1,154 @@ +varnishtest "If-Modified-Since support" + +#REQUIRE_VERSION=2.3 + +feature ignore_unknown_macro + +server s1 { + # Response containing a "Last-Modified" field + rxreq + expect req.url == "/last_modified" + txresp -nolen -hdr "Transfer-Encoding: chunked" \ + -hdr "Last-Modified: Thu, 15 Oct 2020 22:23:24 GMT" + chunkedlen 15 + chunkedlen 15 + chunkedlen 15 + chunkedlen 0 + + # Response containing a "Date" field + rxreq + expect req.url == "/date" + txresp -nolen -hdr "Transfer-Encoding: chunked" \ + -hdr "Date: Thu, 22 Oct 2020 16:51:12 GMT" \ + -hdr "Cache-Control: max-age=5" + chunkedlen 16 + chunkedlen 16 + chunkedlen 16 + chunkedlen 0 + + # Response containing both a "Last-Modified" and a "Date" fields + # Should behave the same way as if the "Date" field was not here. + rxreq + expect req.url == "/last_modified_and_date" + txresp -nolen -hdr "Transfer-Encoding: chunked" \ + -hdr "Last-Modified: Thu, 15 Oct 2020 14:24:38 GMT" \ + -hdr "Date: Thu, 22 Oct 2020 16:51:12 GMT" + chunkedlen 17 + chunkedlen 17 + chunkedlen 17 + chunkedlen 0 +} -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 + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + default_backend test + + backend test + http-request cache-use my_cache + server www ${s1_addr}:${s1_port} + http-response cache-store my_cache + + # Remove Transfer-Encoding header because of a vtest issue with + # 304-Not-Modified responses + http-after-response del-header transfer-encoding if { status eq 304 } + + cache my_cache + total-max-size 3 + max-age 20 + max-object-size 3072 +} -start + + +client c1 -connect ${h1_fe_sock} { + txreq -url "/last_modified" + rxresp + expect resp.status == 200 + expect resp.bodylen == 45 + + txreq -url "/date" + rxresp + expect resp.status == 200 + expect resp.bodylen == 48 + + txreq -url "/last_modified_and_date" + rxresp + expect resp.status == 200 + expect resp.bodylen == 51 + + + # Earlier date + # "Last-Modified" version + txreq -url "/last_modified" \ + -hdr "If-Modified-Since: Thu, 15 Oct 2020 00:00:01 GMT" + rxresp + expect resp.status == 200 + expect resp.bodylen == 45 + # "Date" version + txreq -url "/date" \ + -hdr "If-Modified-Since: Thu, 01 Oct 2020 00:00:01 GMT" + rxresp + expect resp.status == 200 + expect resp.bodylen == 48 + # "Last-Modified" and "Date" version + txreq -url "/last_modified_and_date" \ + -hdr "If-Modified-Since: Thu, 15 Oct 2020 00:00:01 GMT" + rxresp + expect resp.status == 200 + expect resp.bodylen == 51 + + + # Same date + # "Last-Modified" version + txreq -url "/last_modified" \ + -hdr "If-Modified-Since: Thu, 15 Oct 2020 22:23:24 GMT" + rxresp + expect resp.status == 304 + expect resp.bodylen == 0 + # "Date" version + txreq -url "/date" \ + -hdr "If-Modified-Since: Thu, 22 Oct 2020 16:51:12 GMT" + rxresp + expect resp.status == 304 + expect resp.bodylen == 0 + # "Last-Modified" and "Date" version + txreq -url "/last_modified_and_date" \ + -hdr "If-Modified-Since: Thu, 15 Oct 2020 16:51:12 GMT" + rxresp + expect resp.status == 304 + expect resp.bodylen == 0 + + + # Later date + # "Last-Modified" version + txreq -url "/last_modified" \ + -hdr "If-Modified-Since: Thu, 22 Oct 2020 23:00:00 GMT" + rxresp + expect resp.status == 304 + expect resp.bodylen == 0 + # "Date" version + txreq -url "/date" \ + -hdr "If-Modified-Since: Thu, 22 Oct 2020 23:00:00 GMT" + rxresp + expect resp.status == 304 + expect resp.bodylen == 0 + # "Last-Modified" and "Date" version + txreq -url "/last_modified_and_date" \ + -hdr "If-Modified-Since: Thu, 22 Oct 2020 23:00:00 GMT" + rxresp + expect resp.status == 304 + expect resp.bodylen == 0 + +} -run diff --git a/reg-tests/cache/if-none-match.vtc b/reg-tests/cache/if-none-match.vtc new file mode 100644 index 0000000..ff90ad4 --- /dev/null +++ b/reg-tests/cache/if-none-match.vtc @@ -0,0 +1,93 @@ +varnishtest "If-None-Match support" + +#REQUIRE_VERSION=2.3 + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp -nolen -hdr "Transfer-Encoding: chunked" \ + -hdr "ETag: \"etag\"" + chunkedlen 1 + chunkedlen 1 + chunkedlen 2 + chunkedlen 3 + chunkedlen 5 + chunkedlen 8 + chunkedlen 13 + chunkedlen 21 + chunkedlen 34 + chunkedlen 55 + chunkedlen 89 + chunkedlen 144 + chunkedlen 233 + chunkedlen 0 +} -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 + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + default_backend test + + backend test + http-request cache-use my_cache + server www ${s1_addr}:${s1_port} + http-response cache-store my_cache + + # Remove Transfer-Encoding header because of a vtest issue with + # 304-Not-Modified responses + http-after-response del-header transfer-encoding if { status eq 304 } + + cache my_cache + total-max-size 3 + max-age 20 + max-object-size 3072 +} -start + + +client c1 -connect ${h1_fe_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.bodylen == 609 + txreq + rxresp + expect resp.status == 200 + expect resp.bodylen == 609 + txreq \ + -hdr "if-none-match: *" + rxresp + expect resp.status == 304 + txreq \ + -hdr "if-none-match: \"etag\"" + rxresp + expect resp.status == 304 + txreq \ + -hdr "if-none-match: W/\"etag\"" + rxresp + expect resp.status == 304 +} -run + +client c2 -connect ${h1_fe_sock} { + txreq \ + -hdr "if-none-match: \"wrong_etag\"" + rxresp + expect resp.status == 200 + expect resp.bodylen == 609 + txreq \ + -hdr "if-none-match: W/\"wrong_etag\", W/\"etag\"" + rxresp + expect resp.status == 304 +} -run diff --git a/reg-tests/cache/post_on_entry.vtc b/reg-tests/cache/post_on_entry.vtc new file mode 100644 index 0000000..66c89e4 --- /dev/null +++ b/reg-tests/cache/post_on_entry.vtc @@ -0,0 +1,65 @@ +varnishtest "A successful unsafe method (POST for instance) on a cached entry must disable it." + +#REQUIRE_VERSION=2.4 + +feature ignore_unknown_macro + +server s1 { + rxreq + expect req.url == "/cached" + txresp -hdr "Cache-Control: max-age=5" \ + -bodylen 150 + + rxreq + expect req.url == "/cached" + expect req.method == "POST" + txresp + + rxreq + expect req.url == "/cached" + txresp -hdr "Cache-Control: max-age=5" \ + -bodylen 100 + +} -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + default_backend test + + backend test + http-request cache-use my_cache + server www ${s1_addr}:${s1_port} + http-response cache-store my_cache + http-response set-header X-Cache-Hit %[res.cache_hit] + + cache my_cache + total-max-size 3 + max-age 20 + max-object-size 3072 +} -start + + +client c1 -connect ${h1_fe_sock} { + txreq -url "/cached" + rxresp + expect resp.status == 200 + expect resp.bodylen == 150 + + txreq -method "POST" -url "/cached" -bodylen 100 + rxresp + expect resp.status == 200 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/cached" + rxresp + expect resp.status == 200 + expect resp.bodylen == 100 + expect resp.http.X-Cache-Hit == 0 +} -run diff --git a/reg-tests/cache/sample_fetches.vtc b/reg-tests/cache/sample_fetches.vtc new file mode 100644 index 0000000..c2b1d15 --- /dev/null +++ b/reg-tests/cache/sample_fetches.vtc @@ -0,0 +1,139 @@ + +varnishtest "Basic cache test" + +#REQUIRE_VERSION=1.9 + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp -nolen -hdr "Transfer-Encoding: chunked" \ + -hdr "Cache-Control: max-age=5" + chunkedlen 15 + chunkedlen 15 + chunkedlen 15 + chunkedlen 0 +} -start + +server s2 { + rxreq + txresp -nolen -hdr "Transfer-Encoding: chunked" \ + -hdr "Cache-Control: max-age=5" + chunkedlen 16 + chunkedlen 16 + chunkedlen 16 + chunkedlen 0 +} -start + +server s3 { + rxreq + txresp -nolen -hdr "Transfer-Encoding: chunked" \ + -hdr "Cache-Control: max-age=5" + chunkedlen 17 + chunkedlen 17 + chunkedlen 17 + chunkedlen 0 + + rxreq + txresp -nolen -hdr "Transfer-Encoding: chunked" \ + -hdr "Cache-Control: max-age=5" + chunkedlen 17 + chunkedlen 17 + chunkedlen 17 + chunkedlen 0 +} -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 + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + use_backend first_be if { path_beg /first } + use_backend nocache_be if { path_beg /nocache } + default_backend second_be + + backend first_be + http-request cache-use first_cache + server www ${s1_addr}:${s1_port} + http-response cache-store first_cache + http-response set-header X-Cache-Hit %[res.cache_hit] + http-response set-header X-Cache-Name %[res.cache_name] + + backend second_be + http-request cache-use second_cache + server www ${s2_addr}:${s2_port} + http-response cache-store second_cache + http-response set-header X-Cache-Hit %[res.cache_hit] + http-response set-header X-Cache-Name %[res.cache_name] + + backend nocache_be + server www ${s3_addr}:${s3_port} + http-response set-header X-Cache-Hit %[res.cache_hit] + http-response set-header X-Cache-Name %[res.cache_name] + + cache first_cache + total-max-size 3 + max-age 40 + max-object-size 3000 + + cache second_cache + total-max-size 3 + max-age 20 + max-object-size 3072 +} -start + + +client c1 -connect ${h1_fe_sock} { + txreq -url "/first" + rxresp + expect resp.status == 200 + expect resp.bodylen == 45 + expect resp.http.X-Cache-Hit == 0 + expect resp.http.X-Cache-Name == "" + + txreq -url "/second" + rxresp + expect resp.status == 200 + expect resp.bodylen == 48 + expect resp.http.X-Cache-Hit == 0 + expect resp.http.X-Cache-Name == "" + + txreq -url "/nocache" + rxresp + expect resp.status == 200 + expect resp.bodylen == 51 + expect resp.http.X-Cache-Hit == 0 + expect resp.http.X-Cache-Name == "" + + # Response should come form the cache now + txreq -url "/nocache" + rxresp + expect resp.status == 200 + expect resp.bodylen == 51 + expect resp.http.X-Cache-Hit == 0 + expect resp.http.X-Cache-Name == "" + + txreq -url "/first" + rxresp + expect resp.status == 200 + expect resp.bodylen == 45 + expect resp.http.X-Cache-Hit == 1 + expect resp.http.X-Cache-Name == "first_cache" + + txreq -url "/second" + rxresp + expect resp.status == 200 + expect resp.bodylen == 48 + expect resp.http.X-Cache-Hit == 1 + expect resp.http.X-Cache-Name == "second_cache" +} -run diff --git a/reg-tests/cache/vary.vtc b/reg-tests/cache/vary.vtc new file mode 100644 index 0000000..b1c1bda --- /dev/null +++ b/reg-tests/cache/vary.vtc @@ -0,0 +1,410 @@ +varnishtest "Vary support" + +#REQUIRE_VERSION=2.4 + +feature ignore_unknown_macro + +server s1 { + # Response varying on "accept-encoding" with + # an unacceptable content-encoding + rxreq + expect req.url == "/accept-encoding" + txresp -hdr "Content-Encoding: gzip" \ + -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -bodylen 45 + + # Response varying on "accept-encoding" + rxreq + expect req.url == "/accept-encoding" + txresp -hdr "Content-Encoding: gzip" \ + -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -bodylen 45 + + # Response varying on "accept-encoding" with + # no content-encoding + rxreq + expect req.url == "/accept-encoding" + txresp -hdr "Content-Type: text/plain" \ + -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -bodylen 48 + + # Response varying on "accept-encoding" but having two different encodings + rxreq + expect req.url == "/accept-encoding-multiple" + txresp -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -bodylen 51 + + + # Unmanaged vary + rxreq + expect req.url == "/unmanaged" + txresp -hdr "Vary: accept-encoding,unmanaged" \ + -hdr "Cache-Control: max-age=5" \ + -bodylen 51 + + + rxreq + expect req.url == "/unmanaged" + txresp -hdr "Vary: accept-encoding,unmanaged" \ + -hdr "Cache-Control: max-age=5" \ + -bodylen 51 + + + + # Mixed Vary (Accept-Encoding + Referer) + rxreq + expect req.url == "/referer-accept-encoding" + txresp -hdr "Vary: accept-encoding,referer" \ + -hdr "Cache-Control: max-age=5" \ + -hdr "Content-Encoding: gzip" \ + -bodylen 51 + + rxreq + expect req.url == "/referer-accept-encoding" + txresp -hdr "Vary: referer,accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -hdr "Content-Encoding: br" \ + -bodylen 54 + + rxreq + expect req.url == "/referer-accept-encoding" + txresp -hdr "Vary: referer,accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -hdr "Content-Encoding: gzip" \ + -bodylen 57 + + # Multiple Accept-Encoding headers + rxreq + expect req.url == "/multiple_headers" + txresp -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -hdr "Content-Encoding: br" \ + -bodylen 155 + + rxreq + expect req.url == "/multiple_headers" + txresp -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -hdr "Content-Encoding: br" \ + -bodylen 166 + + + # Too many Accept-Encoding values (we will not cache responses with more than 16 encodings) + rxreq + expect req.url == "/too_many_encodings" + txresp -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -hdr "Content-Encoding: gzip" \ + -bodylen 177 + + rxreq + expect req.url == "/too_many_encodings" + txresp -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -hdr "Content-Encoding: gzip" \ + -bodylen 188 + + rxreq + expect req.url == "/empty-vs-missing" + txresp -hdr "Content-Encoding: gzip" \ + -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -bodylen 234 + + rxreq + expect req.url == "/empty-vs-missing" + txresp -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -bodylen 256 +} -start + +server s2 { + # Responses that should not be cached + rxreq + expect req.url == "/no_vary_support" + txresp -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -bodylen 57 + + rxreq + expect req.url == "/no_vary_support" + txresp -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -bodylen 57 +} -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 + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + use_backend no_vary_be if { path_beg /no_vary_support } + default_backend test + + backend test + http-request cache-use my_cache + server www ${s1_addr}:${s1_port} + http-response cache-store my_cache + http-response set-header X-Cache-Hit %[res.cache_hit] + + backend no_vary_be + http-request cache-use no_vary_cache + server www ${s2_addr}:${s2_port} + http-response cache-store no_vary_cache + http-response set-header X-Cache-Hit %[res.cache_hit] + + cache my_cache + total-max-size 3 + max-age 20 + max-object-size 3072 + process-vary on + + cache no_vary_cache + total-max-size 3 + max-age 20 + max-object-size 3072 + process-vary off +} -start + + +client c1 -connect ${h1_fe_sock} { + # Accept-Encoding Vary + txreq -url "/accept-encoding" -hdr "Accept-Encoding: first_value" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.bodylen == 45 + + # The response for the first request had an unacceptable `content-encoding` + # which might happen if that's the only thing the server supports, but + # we must not cache that and instead defer to the server. + txreq -url "/accept-encoding" -hdr "Accept-Encoding: first_value" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.bodylen == 45 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/accept-encoding" -hdr "Accept-Encoding: second_value" + rxresp + expect resp.status == 200 + expect resp.bodylen == 48 + expect resp.http.content-type == "text/plain" + expect resp.http.X-Cache-Hit == 0 + + # This request matches the cache entry for the request above, despite + # matching the `accept-encoding` of the first request because the + # request above only has the `identity` encoding which is implicitly + # added, unless explicitly forbidden. + txreq -url "/accept-encoding" -hdr "Accept-Encoding: first_value" + rxresp + expect resp.status == 200 + expect resp.bodylen == 48 + expect resp.http.content-type == "text/plain" + expect resp.http.X-Cache-Hit == 1 + + txreq -url "/accept-encoding" -hdr "Accept-Encoding: second_value" + rxresp + expect resp.status == 200 + expect resp.bodylen == 48 + expect resp.http.content-type == "text/plain" + expect resp.http.X-Cache-Hit == 1 + + # The accept-encoding normalizer function converts the header values + # to lower case then calculates the hash of every sub part before + # sorting the hashes and xor'ing them (while removing duplicates). + txreq -url "/accept-encoding-multiple" -hdr "Accept-Encoding: first,second" + rxresp + expect resp.status == 200 + expect resp.bodylen == 51 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/accept-encoding-multiple" -hdr "Accept-Encoding: first,second" + rxresp + expect resp.status == 200 + expect resp.bodylen == 51 + expect resp.http.X-Cache-Hit == 1 + + txreq -url "/accept-encoding-multiple" -hdr "Accept-Encoding: second,first" + rxresp + expect resp.status == 200 + expect resp.bodylen == 51 + expect resp.http.X-Cache-Hit == 1 + + txreq -url "/accept-encoding-multiple" -hdr "Accept-Encoding: FirsT,SECOND,first" + rxresp + expect resp.status == 200 + expect resp.bodylen == 51 + expect resp.http.X-Cache-Hit == 1 + + # Unmanaged vary + txreq -url "/unmanaged" -hdr "Accept-Encoding: first_value" + rxresp + expect resp.status == 200 + expect resp.bodylen == 51 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/unmanaged" -hdr "Accept-Encoding: first_value" + rxresp + expect resp.status == 200 + expect resp.bodylen == 51 + expect resp.http.X-Cache-Hit == 0 + + + # Mixed Vary (Accept-Encoding + Referer) + txreq -url "/referer-accept-encoding" \ + -hdr "Accept-Encoding: br, gzip" \ + -hdr "Referer: referer" + rxresp + expect resp.status == 200 + expect resp.bodylen == 51 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/referer-accept-encoding" \ + -hdr "Accept-Encoding: br" \ + -hdr "Referer: other-referer" + rxresp + expect resp.status == 200 + expect resp.bodylen == 54 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/referer-accept-encoding" \ + -hdr "Accept-Encoding: gzip" \ + -hdr "Referer: other-referer" + rxresp + expect resp.status == 200 + expect resp.bodylen == 57 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/referer-accept-encoding" \ + -hdr "Referer: referer" \ + -hdr "Accept-Encoding: gzip, br" + rxresp + expect resp.status == 200 + expect resp.bodylen == 51 + expect resp.http.X-Cache-Hit == 1 + + txreq -url "/referer-accept-encoding" \ + -hdr "Accept-Encoding: br" \ + -hdr "Referer: other-referer" + rxresp + expect resp.status == 200 + expect resp.bodylen == 54 + expect resp.http.X-Cache-Hit == 1 + + txreq -url "/referer-accept-encoding" \ + -hdr "Accept-Encoding: gzip" \ + -hdr "Referer: other-referer" + rxresp + expect resp.status == 200 + expect resp.bodylen == 57 + expect resp.http.X-Cache-Hit == 1 + + + # Multiple Accept-encoding headers + txreq -url "/multiple_headers" \ + -hdr "Accept-Encoding: gzip" \ + -hdr "Accept-Encoding: br, deflate" + rxresp + expect resp.status == 200 + expect resp.bodylen == 155 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/multiple_headers" \ + -hdr "Accept-Encoding: deflate" \ + -hdr "Accept-Encoding: br,gzip" + rxresp + expect resp.status == 200 + expect resp.bodylen == 155 + expect resp.http.X-Cache-Hit == 1 + + # Should not match a cache entry + txreq -url "/multiple_headers" \ + -hdr "Accept-Encoding: first_encoding" + rxresp + expect resp.status == 200 + expect resp.bodylen == 166 + expect resp.http.X-Cache-Hit == 0 + + # Too many accept encodings + txreq -url "/too_many_encodings" \ + -hdr "Accept-Encoding: a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17" + rxresp + expect resp.status == 200 + expect resp.bodylen == 177 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/too_many_encodings" \ + -hdr "Accept-Encoding: a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17" + rxresp + expect resp.status == 200 + expect resp.bodylen == 188 + expect resp.http.X-Cache-Hit == 0 + + # A missing 'Accept-Encoding' implies that anything is acceptable, + # while an empty 'Accept-Encoding' implies nothing is acceptable. + + # Start by caching a gzip response. + txreq -url "/empty-vs-missing" -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.bodylen == 234 + expect resp.http.content-encoding == "gzip" + expect resp.http.X-Cache-Hit == 0 + + # Check that it is cached. + txreq -url "/empty-vs-missing" -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.bodylen == 234 + expect resp.http.content-encoding == "gzip" + expect resp.http.X-Cache-Hit == 1 + + # Check that the cached response is returned when no accept-encoding is + # specified. + txreq -url "/empty-vs-missing" + rxresp + expect resp.status == 200 + expect resp.bodylen == 234 + expect resp.http.content-encoding == "gzip" + expect resp.http.X-Cache-Hit == 1 + + # Check that the cached response is not returned when an empty + # accept-encoding is specified. + txreq -url "/empty-vs-missing" -hdr "Accept-Encoding:" + rxresp + expect resp.status == 200 + expect resp.bodylen == 256 + expect resp.http.content-encoding == "<undef>" + expect resp.http.X-Cache-Hit == 0 + + # The following requests are treated by a backend that does not cache + # responses containing a Vary header + txreq -url "/no_vary_support" + rxresp + expect resp.status == 200 + expect resp.bodylen == 57 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/no_vary_support" + rxresp + expect resp.status == 200 + expect resp.bodylen == 57 + expect resp.http.X-Cache-Hit == 0 + + +} -run diff --git a/reg-tests/cache/vary_accept_encoding.vtc b/reg-tests/cache/vary_accept_encoding.vtc new file mode 100644 index 0000000..4b828a8 --- /dev/null +++ b/reg-tests/cache/vary_accept_encoding.vtc @@ -0,0 +1,333 @@ +varnishtest "Check the Accept-Encoding processing implemented in the Vary mechanism" + +#REQUIRE_VERSION=2.4 + +feature ignore_unknown_macro + +server s1 { + # Response varying on "accept-encoding" with a gzip content-encoding + rxreq + expect req.url == "/accept-encoding" + txresp -hdr "Content-Encoding: gzip" \ + -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -bodylen 45 + + # Response varying on "accept-encoding" with a deflate content-encoding + rxreq + expect req.url == "/accept-encoding" + txresp -hdr "Content-Encoding: deflate" \ + -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -bodylen 55 + + + # Response varying on "accept-encoding" with no content-encoding (identity) + rxreq + expect req.url == "/accept-encoding-identity" + txresp -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -bodylen 65 + + # Response varying on "accept-encoding" with refused identity encoding + rxreq + expect req.url == "/accept-encoding-identity" + txresp -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -hdr "Content-Encoding: deflate" \ + -bodylen 75 + + + rxreq + expect req.url == "/accept-encoding-star" + txresp -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -hdr "Content-Encoding: br" \ + -bodylen 89 + + rxreq + expect req.url == "/accept-encoding-star" + txresp -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -hdr "Content-Encoding: deflate" \ + -bodylen 99 + + + rxreq + expect req.url == "/multiple-content-encoding" + txresp -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -hdr "Content-Encoding: deflate, gzip" \ + -bodylen 109 + + rxreq + expect req.url == "/unknown-content-encoding" + txresp -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -hdr "Content-Encoding: unknown_encoding" \ + -bodylen 119 + + rxreq + expect req.url == "/unknown-content-encoding" + txresp -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -hdr "Content-Encoding: unknown_encoding" \ + -bodylen 119 + + + rxreq + expect req.url == "/hash-collision" + txresp -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -hdr "Content-Encoding: br" \ + -bodylen 129 + + rxreq + expect req.url == "/hash-collision" + txresp -hdr "Vary: accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -hdr "Content-Encoding: gzip" \ + -bodylen 139 +} -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 + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + default_backend test + + backend test + http-request cache-use my_cache + server www ${s1_addr}:${s1_port} + http-response cache-store my_cache + http-response set-header X-Cache-Hit %[res.cache_hit] + + cache my_cache + total-max-size 3 + max-age 20 + max-object-size 3072 + process-vary on +} -start + + +client c1 -connect ${h1_fe_sock} { + # + # Accept-Encoding Vary + # + + # First request + txreq -url "/accept-encoding" -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.bodylen == 45 + + # Regular case + txreq -url "/accept-encoding" -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.bodylen == 45 + expect resp.http.X-Cache-Hit == 1 + + # Regular case with upper case encoding + txreq -url "/accept-encoding" -hdr "Accept-Encoding: GZIP" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.bodylen == 45 + expect resp.http.X-Cache-Hit == 1 + + # Multiple accepted encodings (all standard) + txreq -url "/accept-encoding" -hdr "Accept-Encoding: deflate,gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.bodylen == 45 + expect resp.http.X-Cache-Hit == 1 + + # Multiple accept-encoding headers + non-standard accepted encodings + txreq -url "/accept-encoding" -hdr "Accept-Encoding: first_encoding,second_encoding" -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.bodylen == 45 + expect resp.http.X-Cache-Hit == 1 + + # Regular case with positive weight + txreq -url "/accept-encoding" -hdr "Accept-Encoding: gzip;q=0.8" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.bodylen == 45 + expect resp.http.X-Cache-Hit == 1 + + # Regular case with positive weight and extra whitespaces + txreq -url "/accept-encoding" -hdr "Accept-Encoding: gzip ; q=0.8" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.bodylen == 45 + expect resp.http.X-Cache-Hit == 1 + + # Regular case with null weight + txreq -url "/accept-encoding" -hdr "Accept-Encoding: deflate;q=0.8, gzip;q=0" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "deflate" + expect resp.bodylen == 55 + expect resp.http.X-Cache-Hit == 0 + + + # + # Identity tests + # + txreq -url "/accept-encoding-identity" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "<undef>" + expect resp.bodylen == 65 + expect resp.http.X-Cache-Hit == 0 + + # Regular case + txreq -url "/accept-encoding-identity" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "<undef>" + expect resp.bodylen == 65 + expect resp.http.X-Cache-Hit == 1 + + # Identity is allowed by default even if another encoding is specified + txreq -url "/accept-encoding-identity" -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "<undef>" + expect resp.bodylen == 65 + expect resp.http.X-Cache-Hit == 1 + + # Refused identity encoding (explicit null weight) + txreq -url "/accept-encoding-identity" -hdr "Accept-Encoding: deflate, identity;q=0" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "deflate" + expect resp.bodylen == 75 + expect resp.http.X-Cache-Hit == 0 + + + # + # Star tests + # + txreq -url "/accept-encoding-star" -hdr "Accept-Encoding: *" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "br" + expect resp.bodylen == 89 + expect resp.http.X-Cache-Hit == 0 + + # Regular case + txreq -url "/accept-encoding-star" -hdr "Accept-Encoding: *" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "br" + expect resp.bodylen == 89 + expect resp.http.X-Cache-Hit == 1 + + # Reject some encodings + txreq -url "/accept-encoding-star" -hdr "Accept-Encoding: gzip;q=0, deflate,*" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "br" + expect resp.bodylen == 89 + expect resp.http.X-Cache-Hit == 1 + + # Weighted star + txreq -url "/accept-encoding-star" -hdr "Accept-Encoding: gzip;q=0, deflate,*;q=0.1" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "br" + expect resp.bodylen == 89 + expect resp.http.X-Cache-Hit == 1 + + # Rejected identity + txreq -url "/accept-encoding-star" -hdr "Accept-Encoding: gzip;q=0, deflate,*;q=0.1,identity;q=0" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "br" + expect resp.bodylen == 89 + expect resp.http.X-Cache-Hit == 1 + + # Rejected star and "br" not accepted + txreq -url "/accept-encoding-star" -hdr "Accept-Encoding: gzip;q=0, deflate,*;q=0" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "deflate" + expect resp.bodylen == 99 + expect resp.http.X-Cache-Hit == 0 + + + # + # Multiple content-encodings + # + txreq -url "/multiple-content-encoding" -hdr "Accept-Encoding: gzip;q=0.8, deflate" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "deflate, gzip" + expect resp.bodylen == 109 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/multiple-content-encoding" -hdr "Accept-Encoding: deflate,gzip;q=0.7" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "deflate, gzip" + expect resp.bodylen == 109 + expect resp.http.X-Cache-Hit == 1 + + + # + # Unknown content-encoding + # The response should not be cached since it has an unknown content encoding + # + txreq -url "/unknown-content-encoding" -hdr "Accept-Encoding: gzip;q=0.8, deflate, first_encoding" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "unknown_encoding" + expect resp.bodylen == 119 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/unknown-content-encoding" -hdr "Accept-Encoding: deflate,gzip;q=0.8, first_encoding" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "unknown_encoding" + expect resp.bodylen == 119 + expect resp.http.X-Cache-Hit == 0 + + # + # Hash collision (https://github.com/haproxy/haproxy/issues/988) + # + # crc32(gzip) ^ crc32(br) ^ crc32(xxx) ^ crc32(jdcqiab) == crc32(gzip) + txreq -url "/hash-collision" -hdr "Accept-Encoding: br,gzip,xxx,jdcqiab" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "br" + expect resp.bodylen == 129 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/hash-collision" -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.bodylen == 139 + expect resp.http.X-Cache-Hit == 0 +} -run diff --git a/reg-tests/checks/1be_40srv_odd_health_checks.vtc b/reg-tests/checks/1be_40srv_odd_health_checks.vtc new file mode 100644 index 0000000..d0f3be5 --- /dev/null +++ b/reg-tests/checks/1be_40srv_odd_health_checks.vtc @@ -0,0 +1,117 @@ +varnishtest "Health-checks: only for servers with 'check' set" +feature ignore_unknown_macro + +# This test start 40 servers in the same backend, named srv0 up to srv39. +# Only the odd servers have health-checks enabled. +# The first health-checks passed tests are checked for all these servers +# thanks to syslog messages. + +#REQUIRE_VERSION=2.4 +#EXCLUDE_TARGETS=freebsd +#REGTEST_TYPE=slow + +syslog S -repeat 20 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv([13579]|[123][13579]) succeeded.+reason: Layer4 check passed.+check duration: [[:digit:]]+ms.+status: 1/1 UP" +} -start + +server s0 {} -start +server s1 {} -start +server s2 {} -start +server s3 {} -start +server s4 {} -start +server s5 {} -start +server s6 {} -start +server s7 {} -start +server s8 {} -start +server s9 {} -start +server s10 {} -start +server s11 {} -start +server s12 {} -start +server s13 {} -start +server s14 {} -start +server s15 {} -start +server s16 {} -start +server s17 {} -start +server s18 {} -start +server s19 {} -start +server s20 {} -start +server s21 {} -start +server s22 {} -start +server s23 {} -start +server s24 {} -start +server s25 {} -start +server s26 {} -start +server s27 {} -start +server s28 {} -start +server s29 {} -start +server s30 {} -start +server s31 {} -start +server s32 {} -start +server s33 {} -start +server s34 {} -start +server s35 {} -start +server s36 {} -start +server s37 {} -start +server s38 {} -start +server s39 {} -start + +haproxy h1 -conf { + defaults + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + default-server no-check inter 200ms downinter 100ms rise 1 fall 1 + + backend be1 + option log-health-checks + log ${S_addr}:${S_port} daemon + server srv0 ${s0_addr}:${s0_port} + server srv1 ${s1_addr}:${s1_port} check + server srv2 ${s2_addr}:${s2_port} + server srv3 ${s3_addr}:${s3_port} check + server srv4 ${s4_addr}:${s4_port} + server srv5 ${s5_addr}:${s5_port} check + server srv6 ${s6_addr}:${s6_port} + server srv7 ${s7_addr}:${s7_port} check + server srv8 ${s8_addr}:${s8_port} + server srv9 ${s9_addr}:${s9_port} check + server srv10 ${s10_addr}:${s10_port} + server srv11 ${s11_addr}:${s11_port} check + server srv12 ${s12_addr}:${s12_port} + server srv13 ${s13_addr}:${s13_port} check + server srv14 ${s14_addr}:${s14_port} + server srv15 ${s15_addr}:${s15_port} check + server srv16 ${s16_addr}:${s16_port} + server srv17 ${s17_addr}:${s17_port} check + server srv18 ${s18_addr}:${s18_port} + server srv19 ${s19_addr}:${s19_port} check + server srv20 ${s20_addr}:${s20_port} + server srv21 ${s21_addr}:${s21_port} check + server srv22 ${s22_addr}:${s22_port} + server srv23 ${s23_addr}:${s23_port} check + server srv24 ${s24_addr}:${s24_port} + server srv25 ${s25_addr}:${s25_port} check + server srv26 ${s26_addr}:${s26_port} + server srv27 ${s27_addr}:${s27_port} check + server srv28 ${s28_addr}:${s28_port} + server srv29 ${s29_addr}:${s29_port} check + server srv30 ${s30_addr}:${s30_port} + server srv31 ${s31_addr}:${s31_port} check + server srv32 ${s32_addr}:${s32_port} + server srv33 ${s33_addr}:${s33_port} check + server srv34 ${s34_addr}:${s34_port} + server srv35 ${s35_addr}:${s35_port} check + server srv36 ${s36_addr}:${s36_port} + server srv37 ${s37_addr}:${s37_port} check + server srv38 ${s38_addr}:${s38_port} + server srv39 ${s39_addr}:${s39_port} check +} -start + +syslog S -wait + +haproxy h1 -cli { + send "show servers state" + expect ~ "# be_id be_name srv_id srv_name srv_addr srv_op_state srv_admin_state srv_uweight srv_iweight srv_time_since_last_change srv_check_status srv_check_result srv_check_health srv_check_state srv_agent_state bk_f_forced_id srv_f_forced_id srv_fqdn srv_port srvrecord srv_use_ssl srv_check_port srv_check_addr srv_agent_addr srv_agent_port\n2 be1 1 srv0 ${s0_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s0_port} - 0 0 - - 0\n2 be1 2 srv1 ${s1_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s1_port} - 0 0 - - 0\n2 be1 3 srv2 ${s2_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s2_port} - 0 0 - - 0\n2 be1 4 srv3 ${s3_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s3_port} - 0 0 - - 0\n2 be1 5 srv4 ${s4_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s4_port} - 0 0 - - 0\n2 be1 6 srv5 ${s5_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s5_port} - 0 0 - - 0\n2 be1 7 srv6 ${s6_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s6_port} - 0 0 - - 0\n2 be1 8 srv7 ${s7_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s7_port} - 0 0 - - 0\n2 be1 9 srv8 ${s8_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s8_port} - 0 0 - - 0\n2 be1 10 srv9 ${s9_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s9_port} - 0 0 - - 0\n2 be1 11 srv10 ${s10_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s10_port} - 0 0 - - 0\n2 be1 12 srv11 ${s11_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s11_port} - 0 0 - - 0\n2 be1 13 srv12 ${s12_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s12_port} - 0 0 - - 0\n2 be1 14 srv13 ${s13_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s13_port} - 0 0 - - 0\n2 be1 15 srv14 ${s14_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s14_port} - 0 0 - - 0\n2 be1 16 srv15 ${s15_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s15_port} - 0 0 - - 0\n2 be1 17 srv16 ${s16_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s16_port} - 0 0 - - 0\n2 be1 18 srv17 ${s17_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s17_port} - 0 0 - - 0\n2 be1 19 srv18 ${s18_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s18_port} - 0 0 - - 0\n2 be1 20 srv19 ${s19_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s19_port} - 0 0 - - 0\n2 be1 21 srv20 ${s20_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s20_port} - 0 0 - - 0\n2 be1 22 srv21 ${s21_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s21_port} - 0 0 - - 0\n2 be1 23 srv22 ${s22_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s22_port} - 0 0 - - 0\n2 be1 24 srv23 ${s23_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s23_port} - 0 0 - - 0\n2 be1 25 srv24 ${s24_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s24_port} - 0 0 - - 0\n2 be1 26 srv25 ${s25_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s25_port} - 0 0 - - 0\n2 be1 27 srv26 ${s26_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s26_port} - 0 0 - - 0\n2 be1 28 srv27 ${s27_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s27_port} - 0 0 - - 0\n2 be1 29 srv28 ${s28_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s28_port} - 0 0 - - 0\n2 be1 30 srv29 ${s29_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s29_port} - 0 0 - - 0\n2 be1 31 srv30 ${s30_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s30_port} - 0 0 - - 0\n2 be1 32 srv31 ${s31_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s31_port} - 0 0 - - 0\n2 be1 33 srv32 ${s32_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s32_port} - 0 0 - - 0\n2 be1 34 srv33 ${s33_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s33_port} - 0 0 - - 0\n2 be1 35 srv34 ${s34_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s34_port} - 0 0 - - 0\n2 be1 36 srv35 ${s35_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s35_port} - 0 0 - - 0\n2 be1 37 srv36 ${s36_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s36_port} - 0 0 - - 0\n2 be1 38 srv37 ${s37_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s37_port} - 0 0 - - 0\n2 be1 39 srv38 ${s38_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s38_port} - 0 0 - - 0\n2 be1 40 srv39 ${s39_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s39_port} - 0 0 - - 0\n" +} + diff --git a/reg-tests/checks/40be_2srv_odd_health_checks.vtc b/reg-tests/checks/40be_2srv_odd_health_checks.vtc new file mode 100644 index 0000000..cbd4fc0 --- /dev/null +++ b/reg-tests/checks/40be_2srv_odd_health_checks.vtc @@ -0,0 +1,645 @@ +varnishtest "Health-checks" +feature ignore_unknown_macro + +#REQUIRE_VERSION=2.4 +#EXCLUDE_TARGETS=freebsd,osx,generic +#REGTEST_TYPE=slow + +# This script start 40 servers named s0 up to s39. +# For 0 <= i <= 19: +# - s(i) and s(i+1) belong to backend be(2*i+1), +# - fe(2*i+1) backend is configured to used be(2*i+1) backend. +# - only s(2*i+1) servers have health-checks enabled, +# - we start 20 clients named s(2*i+1) which connect to fe(2*i+1) frontend, +# - so that to ensure that health-checks do not consume any connection +# (any varnishtest server without -repeat <n> with n > 1 accepts +# only one connection). +# - we take care of sending the clients to the unchecked servers using the +# "first" lb algo so that servers always receive a valid request + +syslog S1 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv1 succeeded, reason: Layer4 check passed, check duration: [[:digit:]]+ms, status: 1/1 UP" +} -start + +syslog S3 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be3/srv3 succeeded, reason: Layer4 check passed, check duration: [[:digit:]]+ms, status: 1/1 UP" +} -start + +syslog S5 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be5/srv5 succeeded, reason: Layer4 check passed, check duration: [[:digit:]]+ms, status: 1/1 UP" +} -start + +syslog S7 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be7/srv7 succeeded, reason: Layer4 check passed, check duration: [[:digit:]]+ms, status: 1/1 UP" +} -start + +syslog S9 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be9/srv9 succeeded, reason: Layer4 check passed, check duration: [[:digit:]]+ms, status: 1/1 UP" +} -start + +syslog S11 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be11/srv11 succeeded, reason: Layer4 check passed, check duration: [[:digit:]]+ms, status: 1/1 UP" +} -start + +syslog S13 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be13/srv13 succeeded, reason: Layer4 check passed, check duration: [[:digit:]]+ms, status: 1/1 UP" +} -start + +syslog S15 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be15/srv15 succeeded, reason: Layer4 check passed, check duration: [[:digit:]]+ms, status: 1/1 UP" +} -start + +syslog S17 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be17/srv17 succeeded, reason: Layer4 check passed, check duration: [[:digit:]]+ms, status: 1/1 UP" +} -start + +syslog S19 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be19/srv19 succeeded, reason: Layer4 check passed, check duration: [[:digit:]]+ms, status: 1/1 UP" +} -start + +syslog S21 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be21/srv21 succeeded, reason: Layer4 check passed, check duration: [[:digit:]]+ms, status: 1/1 UP" +} -start + +syslog S23 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be23/srv23 succeeded, reason: Layer4 check passed, check duration: [[:digit:]]+ms, status: 1/1 UP" +} -start + +syslog S25 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be25/srv25 succeeded, reason: Layer4 check passed, check duration: [[:digit:]]+ms, status: 1/1 UP" +} -start + +syslog S27 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be27/srv27 succeeded, reason: Layer4 check passed, check duration: [[:digit:]]+ms, status: 1/1 UP" +} -start + +syslog S29 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be29/srv29 succeeded, reason: Layer4 check passed, check duration: [[:digit:]]+ms, status: 1/1 UP" +} -start + +syslog S31 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be31/srv31 succeeded, reason: Layer4 check passed, check duration: [[:digit:]]+ms, status: 1/1 UP" +} -start + +syslog S33 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be33/srv33 succeeded, reason: Layer4 check passed, check duration: [[:digit:]]+ms, status: 1/1 UP" +} -start + +syslog S35 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be35/srv35 succeeded, reason: Layer4 check passed, check duration: [[:digit:]]+ms, status: 1/1 UP" +} -start + +syslog S37 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be37/srv37 succeeded, reason: Layer4 check passed, check duration: [[:digit:]]+ms, status: 1/1 UP" +} -start + +syslog S39 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be39/srv39 succeeded, reason: Layer4 check passed, check duration: [[:digit:]]+ms, status: 1/1 UP" +} -start + +server s0 { + rxreq + txresp +} -start + +server s2 { + rxreq + txresp +} -start + +server s4 { + rxreq + txresp +} -start + +server s6 { + rxreq + txresp +} -start + +server s8 { + rxreq + txresp +} -start + +server s10 { + rxreq + txresp +} -start + +server s12 { + rxreq + txresp +} -start + +server s14 { + rxreq + txresp +} -start + +server s16 { + rxreq + txresp +} -start + +server s18 { + rxreq + txresp +} -start + +server s20 { + rxreq + txresp +} -start + +server s22 { + rxreq + txresp +} -start + +server s24 { + rxreq + txresp +} -start + +server s26 { + rxreq + txresp +} -start + +server s28 { + rxreq + txresp +} -start + +server s30 { + rxreq + txresp +} -start + +server s32 { + rxreq + txresp +} -start + +server s34 { + rxreq + txresp +} -start + +server s36 { + rxreq + txresp +} -start + +server s38 { + rxreq + txresp +} -start + +server s1 {} -start +server s3 {} -start +server s5 {} -start +server s7 {} -start +server s9 {} -start +server s11 {} -start +server s13 {} -start +server s15 {} -start +server s17 {} -start +server s19 {} -start +server s21 {} -start +server s23 {} -start +server s25 {} -start +server s27 {} -start +server s29 {} -start +server s31 {} -start +server s33 {} -start +server s35 {} -start +server s37 {} -start +server s39 {} -start + +haproxy h1 -conf { + defaults + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + balance first + default-server no-check inter 20ms downinter 1s rise 1 fall 1 + + backend be1 + option log-health-checks + log ${S1_addr}:${S1_port} daemon + server srv0 ${s0_addr}:${s0_port} + server srv1 ${s1_addr}:${s1_port} check + + backend be3 + option log-health-checks + log ${S3_addr}:${S3_port} daemon + server srv2 ${s2_addr}:${s2_port} + server srv3 ${s3_addr}:${s3_port} check + + backend be5 + option log-health-checks + log ${S5_addr}:${S5_port} daemon + server srv4 ${s4_addr}:${s4_port} + server srv5 ${s5_addr}:${s5_port} check + + backend be7 + option log-health-checks + log ${S7_addr}:${S7_port} daemon + server srv6 ${s6_addr}:${s6_port} + server srv7 ${s7_addr}:${s7_port} check + + backend be9 + option log-health-checks + log ${S9_addr}:${S9_port} daemon + server srv8 ${s8_addr}:${s8_port} + server srv9 ${s9_addr}:${s9_port} check + + backend be11 + option log-health-checks + log ${S11_addr}:${S11_port} daemon + server srv10 ${s10_addr}:${s10_port} + server srv11 ${s11_addr}:${s11_port} check + + backend be13 + option log-health-checks + log ${S13_addr}:${S13_port} daemon + server srv12 ${s12_addr}:${s12_port} + server srv13 ${s13_addr}:${s13_port} check + + backend be15 + option log-health-checks + log ${S15_addr}:${S15_port} daemon + server srv14 ${s14_addr}:${s14_port} + server srv15 ${s15_addr}:${s15_port} check + + backend be17 + option log-health-checks + log ${S17_addr}:${S17_port} daemon + server srv16 ${s16_addr}:${s16_port} + server srv17 ${s17_addr}:${s17_port} check + + backend be19 + option log-health-checks + log ${S19_addr}:${S19_port} daemon + server srv18 ${s18_addr}:${s18_port} + server srv19 ${s19_addr}:${s19_port} check + + backend be21 + option log-health-checks + log ${S21_addr}:${S21_port} daemon + server srv20 ${s20_addr}:${s20_port} + server srv21 ${s21_addr}:${s21_port} check + + backend be23 + option log-health-checks + log ${S23_addr}:${S23_port} daemon + server srv22 ${s22_addr}:${s22_port} + server srv23 ${s23_addr}:${s23_port} check + + backend be25 + option log-health-checks + log ${S25_addr}:${S25_port} daemon + server srv24 ${s24_addr}:${s24_port} + server srv25 ${s25_addr}:${s25_port} check + + backend be27 + option log-health-checks + log ${S27_addr}:${S27_port} daemon + server srv26 ${s26_addr}:${s26_port} + server srv27 ${s27_addr}:${s27_port} check + + backend be29 + option log-health-checks + log ${S29_addr}:${S29_port} daemon + server srv28 ${s28_addr}:${s28_port} + server srv29 ${s29_addr}:${s29_port} check + + backend be31 + option log-health-checks + log ${S31_addr}:${S31_port} daemon + server srv30 ${s30_addr}:${s30_port} + server srv31 ${s31_addr}:${s31_port} check + + backend be33 + option log-health-checks + log ${S33_addr}:${S33_port} daemon + server srv32 ${s32_addr}:${s32_port} + server srv33 ${s33_addr}:${s33_port} check + + backend be35 + option log-health-checks + log ${S35_addr}:${S35_port} daemon + server srv34 ${s34_addr}:${s34_port} + server srv35 ${s35_addr}:${s35_port} check + + backend be37 + option log-health-checks + log ${S37_addr}:${S37_port} daemon + server srv36 ${s36_addr}:${s36_port} + server srv37 ${s37_addr}:${s37_port} check + + backend be39 + option log-health-checks + log ${S39_addr}:${S39_port} daemon + server srv38 ${s38_addr}:${s38_port} + server srv39 ${s39_addr}:${s39_port} check + + frontend fe1 + bind "fd@${fe1}" + use_backend be1 + + frontend fe3 + bind "fd@${fe3}" + use_backend be3 + + frontend fe5 + bind "fd@${fe5}" + use_backend be5 + + frontend fe7 + bind "fd@${fe7}" + use_backend be7 + + frontend fe9 + bind "fd@${fe9}" + use_backend be9 + + frontend fe11 + bind "fd@${fe11}" + use_backend be11 + + frontend fe13 + bind "fd@${fe13}" + use_backend be13 + + frontend fe15 + bind "fd@${fe15}" + use_backend be15 + + frontend fe17 + bind "fd@${fe17}" + use_backend be17 + + frontend fe19 + bind "fd@${fe19}" + use_backend be19 + + frontend fe21 + bind "fd@${fe21}" + use_backend be21 + + frontend fe23 + bind "fd@${fe23}" + use_backend be23 + + frontend fe25 + bind "fd@${fe25}" + use_backend be25 + + frontend fe27 + bind "fd@${fe27}" + use_backend be27 + + frontend fe29 + bind "fd@${fe29}" + use_backend be29 + + frontend fe31 + bind "fd@${fe31}" + use_backend be31 + + frontend fe33 + bind "fd@${fe33}" + use_backend be33 + + frontend fe35 + bind "fd@${fe35}" + use_backend be35 + + frontend fe37 + bind "fd@${fe37}" + use_backend be37 + + frontend fe39 + bind "fd@${fe39}" + use_backend be39 +} -start + +# This is a sort of synchronization: after having waited for all the syslog +# servers we are sure that all the health-checks have succeeded. +syslog S1 -wait +syslog S3 -wait +syslog S5 -wait +syslog S7 -wait +syslog S9 -wait +syslog S11 -wait +syslog S13 -wait +syslog S15 -wait +syslog S17 -wait +syslog S19 -wait +syslog S21 -wait +syslog S23 -wait +syslog S25 -wait +syslog S27 -wait +syslog S29 -wait +syslog S31 -wait +syslog S33 -wait +syslog S35 -wait +syslog S37 -wait +syslog S39 -wait + +client c1 -connect ${h1_fe1_sock} { + txreq + rxresp + expect resp.status == 200 +} -start + +client c3 -connect ${h1_fe3_sock} { + txreq + rxresp + expect resp.status == 200 +} -start + +client c5 -connect ${h1_fe5_sock} { + txreq + rxresp + expect resp.status == 200 +} -start + +client c7 -connect ${h1_fe7_sock} { + txreq + rxresp + expect resp.status == 200 +} -start + +client c9 -connect ${h1_fe9_sock} { + txreq + rxresp + expect resp.status == 200 +} -start + +client c11 -connect ${h1_fe11_sock} { + txreq + rxresp + expect resp.status == 200 +} -start + +client c13 -connect ${h1_fe13_sock} { + txreq + rxresp + expect resp.status == 200 +} -start + +client c15 -connect ${h1_fe15_sock} { + txreq + rxresp + expect resp.status == 200 +} -start + +client c17 -connect ${h1_fe17_sock} { + txreq + rxresp + expect resp.status == 200 +} -start + +client c19 -connect ${h1_fe19_sock} { + txreq + rxresp + expect resp.status == 200 +} -start + +client c21 -connect ${h1_fe21_sock} { + txreq + rxresp + expect resp.status == 200 +} -start + +client c23 -connect ${h1_fe23_sock} { + txreq + rxresp + expect resp.status == 200 +} -start + +client c25 -connect ${h1_fe25_sock} { + txreq + rxresp + expect resp.status == 200 +} -start + +client c27 -connect ${h1_fe27_sock} { + txreq + rxresp + expect resp.status == 200 +} -start + +client c29 -connect ${h1_fe29_sock} { + txreq + rxresp + expect resp.status == 200 +} -start + +client c31 -connect ${h1_fe31_sock} { + txreq + rxresp + expect resp.status == 200 +} -start + +client c33 -connect ${h1_fe33_sock} { + txreq + rxresp + expect resp.status == 200 +} -start + +client c35 -connect ${h1_fe35_sock} { + txreq + rxresp + expect resp.status == 200 +} -start + +client c37 -connect ${h1_fe37_sock} { + txreq + rxresp + expect resp.status == 200 +} -start + +client c39 -connect ${h1_fe39_sock} { + txreq + rxresp + expect resp.status == 200 +} -start + +client c1 -wait +client c3 -wait +client c5 -wait +client c7 -wait +client c9 -wait +client c11 -wait +client c13 -wait +client c15 -wait +client c17 -wait +client c19 -wait +client c21 -wait +client c23 -wait +client c25 -wait +client c27 -wait +client c29 -wait +client c31 -wait +client c33 -wait +client c35 -wait +client c37 -wait +client c39 -wait + +server s0 -wait +server s2 -wait +server s4 -wait +server s6 -wait +server s8 -wait +server s10 -wait +server s12 -wait +server s14 -wait +server s16 -wait +server s18 -wait +server s20 -wait +server s22 -wait +server s24 -wait +server s26 -wait +server s28 -wait +server s30 -wait +server s32 -wait +server s34 -wait +server s36 -wait +server s38 -wait + + +haproxy h1 -cli { + send "show servers state" + # output produced using the command below (warning, a bug inserts a "be0" every other line: + # for ((i=0;i<40;i++)); do id=$((i/2+2)); be=$((i|1)); si=$(((i&1)+1)); + # if ((i&1)); then chk="6 ([[:digit:]]+ ){3}"; else chk="1 0 1 0 ";fi; + # printf "%d be%d %d srv%d \${s%d_addr} 2 0 1 1 [[:digit:]]+ %s0 0 0 - \${s%d_port} - 0 0 - - 0\n" "$id" "$be" "$si" "$i" "$i" "$chk" "$i" "$i" ; + # done|grep -v be0|sed 's,$,\\n,'| tr -d '\n' + expect ~ "# be_id be_name srv_id srv_name srv_addr srv_op_state srv_admin_state srv_uweight srv_iweight srv_time_since_last_change srv_check_status srv_check_result srv_check_health srv_check_state srv_agent_state bk_f_forced_id srv_f_forced_id srv_fqdn srv_port srvrecord srv_use_ssl srv_check_port srv_check_addr srv_agent_addr srv_agent_port\n2 be1 1 srv0 ${s0_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s0_port} - 0 0 - - 0\n2 be1 2 srv1 ${s1_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s1_port} - 0 0 - - 0\n3 be3 1 srv2 ${s2_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s2_port} - 0 0 - - 0\n3 be3 2 srv3 ${s3_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s3_port} - 0 0 - - 0\n4 be5 1 srv4 ${s4_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s4_port} - 0 0 - - 0\n4 be5 2 srv5 ${s5_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s5_port} - 0 0 - - 0\n5 be7 1 srv6 ${s6_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s6_port} - 0 0 - - 0\n5 be7 2 srv7 ${s7_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s7_port} - 0 0 - - 0\n6 be9 1 srv8 ${s8_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s8_port} - 0 0 - - 0\n6 be9 2 srv9 ${s9_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s9_port} - 0 0 - - 0\n7 be11 1 srv10 ${s10_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s10_port} - 0 0 - - 0\n7 be11 2 srv11 ${s11_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s11_port} - 0 0 - - 0\n8 be13 1 srv12 ${s12_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s12_port} - 0 0 - - 0\n8 be13 2 srv13 ${s13_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s13_port} - 0 0 - - 0\n9 be15 1 srv14 ${s14_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s14_port} - 0 0 - - 0\n9 be15 2 srv15 ${s15_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s15_port} - 0 0 - - 0\n10 be17 1 srv16 ${s16_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s16_port} - 0 0 - - 0\n10 be17 2 srv17 ${s17_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s17_port} - 0 0 - - 0\n11 be19 1 srv18 ${s18_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s18_port} - 0 0 - - 0\n11 be19 2 srv19 ${s19_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s19_port} - 0 0 - - 0\n12 be21 1 srv20 ${s20_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s20_port} - 0 0 - - 0\n12 be21 2 srv21 ${s21_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s21_port} - 0 0 - - 0\n13 be23 1 srv22 ${s22_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s22_port} - 0 0 - - 0\n13 be23 2 srv23 ${s23_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s23_port} - 0 0 - - 0\n14 be25 1 srv24 ${s24_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s24_port} - 0 0 - - 0\n14 be25 2 srv25 ${s25_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s25_port} - 0 0 - - 0\n15 be27 1 srv26 ${s26_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s26_port} - 0 0 - - 0\n15 be27 2 srv27 ${s27_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s27_port} - 0 0 - - 0\n16 be29 1 srv28 ${s28_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s28_port} - 0 0 - - 0\n16 be29 2 srv29 ${s29_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s29_port} - 0 0 - - 0\n17 be31 1 srv30 ${s30_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s30_port} - 0 0 - - 0\n17 be31 2 srv31 ${s31_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s31_port} - 0 0 - - 0\n18 be33 1 srv32 ${s32_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s32_port} - 0 0 - - 0\n18 be33 2 srv33 ${s33_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s33_port} - 0 0 - - 0\n19 be35 1 srv34 ${s34_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s34_port} - 0 0 - - 0\n19 be35 2 srv35 ${s35_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s35_port} - 0 0 - - 0\n20 be37 1 srv36 ${s36_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s36_port} - 0 0 - - 0\n20 be37 2 srv37 ${s37_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s37_port} - 0 0 - - 0\n21 be39 1 srv38 ${s38_addr} 2 0 1 1 [[:digit:]]+ 1 0 1 0 0 0 0 - ${s38_port} - 0 0 - - 0\n21 be39 2 srv39 ${s39_addr} 2 0 1 1 [[:digit:]]+ 6 ([[:digit:]]+ ){3}0 0 0 - ${s39_port} - 0 0 - - 0\n" +} + diff --git a/reg-tests/checks/4be_1srv_health_checks.vtc b/reg-tests/checks/4be_1srv_health_checks.vtc new file mode 100644 index 0000000..88b631a --- /dev/null +++ b/reg-tests/checks/4be_1srv_health_checks.vtc @@ -0,0 +1,201 @@ +varnishtest "Health-check test" +feature ignore_unknown_macro + +#REQUIRE_VERSION=2.4 +#EXCLUDE_TARGETS=freebsd +#REGTEST_TYPE=slow + +# This script test health-checks for four backends with one server by backend. +# A syslog server is attached to each backend to check the syslog messages +# in the righ order. + +# First, we check a health-check has passed for all the servers thanks to the syslog +# messages. Then each server is disabled. The health-check status are checked. +# Then each server is re-enabled. Finally health-check status +# verifications for each server terminate the execution of this script. + +# Note that the CLI is synchronized with the syslog servers so that +# to be sure to receive the passed health-checks status messages before +# disabling the servers. Same thing, when we check that the servers are down +# before enabling the servers. + +# Cyclic barrier to synchronize the CLI with the syslog servers +barrier b1 cond 5 -cyclic + +# These servers are there only for the health-check test. +server s1 { +} -start + +server s2 { +} -start + +server s3 { +} -start + +server s4 { +} -start + +syslog S1 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv1 succeeded.+reason: Layer4 check passed.+check duration: [[:digit:]]+ms.+status: 1/1 UP" + barrier b1 sync + recv alert + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Server be1/srv1 is going DOWN for maintenance. 0 active and 0 backup servers left. [01] sessions active, 0 requeued, 0 remaining in queue." + recv emerg + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: backend be1 has no server available!" + barrier b1 sync + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: (Server be1/srv1 is UP/READY \\(leaving forced maintenance\\).|Health check for server be1/srv1 succeeded.+reason: Layer4 check passed.+check duration: [[:digit:]]+ms.+status: 1/1 UP)" + barrier b1 sync +} -start + +syslog S2 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be2/srv2 succeeded.+reason: Layer4 check passed.+check duration: [[:digit:]]+ms.+status: 1/1 UP" + barrier b1 sync + recv alert + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Server be2/srv2 is going DOWN for maintenance. 0 active and 0 backup servers left. [01] sessions active, 0 requeued, 0 remaining in queue." + recv emerg + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: backend be2 has no server available!" + barrier b1 sync + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: (Server be2/srv2 is UP/READY \\(leaving forced maintenance\\).|Health check for server be2/srv2 succeeded.+reason: Layer4 check passed.+check duration: [[:digit:]]+ms.+status: 1/1 UP)" + barrier b1 sync +} -start + +syslog S3 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be3/srv3 succeeded.+reason: Layer4 check passed.+check duration: [[:digit:]]+ms.+status: 1/1 UP" + barrier b1 sync + recv alert + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Server be3/srv3 is going DOWN for maintenance. 0 active and 0 backup servers left. [01] sessions active, 0 requeued, 0 remaining in queue." + recv emerg + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: backend be3 has no server available!" + barrier b1 sync + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: (Server be3/srv3 is UP/READY \\(leaving forced maintenance\\).|Health check for server be3/srv3 succeeded.+reason: Layer4 check passed.+check duration: [[:digit:]]+ms.+status: 1/1 UP)" + barrier b1 sync +} -start + +syslog S4 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be4/srv4 succeeded.+reason: Layer4 check passed.+check duration: [[:digit:]]+ms.+status: 1/1 UP" + barrier b1 sync + recv alert + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Server be4/srv4 is going DOWN for maintenance. 0 active and 0 backup servers left. [01] sessions active, 0 requeued, 0 remaining in queue." + recv emerg + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: backend be4 has no server available!" + barrier b1 sync + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: (Server be4/srv4 is UP/READY \\(leaving forced maintenance\\).|Health check for server be4/srv4 succeeded.+reason: Layer4 check passed.+check duration: [[:digit:]]+ms.+status: 1/1 UP)" + barrier b1 sync +} -start + + +haproxy h1 -conf { + defaults + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + default-server check inter 200ms downinter 100s rise 1 fall 1 + + frontend fe1 + bind "fd@${fe1}" + use_backend be1 + + frontend fe2 + bind "fd@${fe2}" + use_backend be2 + + frontend fe3 + bind "fd@${fe3}" + use_backend be3 + + frontend fe4 + bind "fd@${fe4}" + use_backend be4 + + backend be1 + option log-health-checks + log ${S1_addr}:${S1_port} daemon + server srv1 ${s1_addr}:${s1_port} + + backend be2 + option log-health-checks + log ${S2_addr}:${S2_port} daemon + server srv2 ${s2_addr}:${s2_port} + + backend be3 + option log-health-checks + log ${S3_addr}:${S3_port} daemon + server srv3 ${s3_addr}:${s3_port} + + backend be4 + option log-health-checks + log ${S4_addr}:${S4_port} daemon + server srv4 ${s4_addr}:${s4_port} +} -start + +haproxy h1 -cli { + barrier b1 sync + send "show servers state" + expect ~ "# be_id be_name srv_id srv_name srv_addr srv_op_state srv_admin_state srv_uweight srv_iweight srv_time_since_last_change srv_check_status srv_check_result srv_check_health srv_check_state srv_agent_state bk_f_forced_id srv_f_forced_id srv_fqdn srv_port srvrecord srv_use_ssl srv_check_port srv_check_addr srv_agent_addr srv_agent_port\n6 be1 1 srv1 ${s1_addr} 2 0 1 1 [[:digit:]]+ 6 3 1 [67] 0 0 0 - ${s1_port} - 0 0 - - 0\n7 be2 1 srv2 ${s2_addr} 2 0 1 1 [[:digit:]]+ 6 3 1 [67] 0 0 0 - ${s2_port} - 0 0 - - 0\n8 be3 1 srv3 ${s3_addr} 2 0 1 1 [[:digit:]]+ 6 3 1 [67] 0 0 0 - ${s3_port} - 0 0 - - 0\n9 be4 1 srv4 ${s4_addr} 2 0 1 1 [[:digit:]]+ 6 3 1 [67] 0 0 0 - ${s4_port} - 0 0 - - 0" +} + +haproxy h1 -cli { + send "disable server be1/srv1" + expect ~ .* +} + +haproxy h1 -cli { + send "disable server be2/srv2" + expect ~ .* +} + +haproxy h1 -cli { + send "disable server be3/srv3" + expect ~ .* +} + +haproxy h1 -cli { + send "disable server be4/srv4" + expect ~ .* +} + +haproxy h1 -cli { + barrier b1 sync + send "show servers state" + expect ~ "# be_id be_name srv_id srv_name srv_addr srv_op_state srv_admin_state srv_uweight srv_iweight srv_time_since_last_change srv_check_status srv_check_result srv_check_health srv_check_state srv_agent_state bk_f_forced_id srv_f_forced_id srv_fqdn srv_port srvrecord srv_use_ssl srv_check_port srv_check_addr srv_agent_addr srv_agent_port\n6 be1 1 srv1 ${s1_addr} 0 1 1 1 [[:digit:]]+ 6 3 [01] 1[45] 0 0 0 - ${s1_port} - 0 0 - - 0\n7 be2 1 srv2 ${s2_addr} 0 1 1 1 [[:digit:]]+ 6 3 [01] 1[45] 0 0 0 - ${s2_port} - 0 0 - - 0\n8 be3 1 srv3 ${s3_addr} 0 1 1 1 [[:digit:]]+ 6 3 [01] 1[45] 0 0 0 - ${s3_port} - 0 0 - - 0\n9 be4 1 srv4 ${s4_addr} 0 1 1 1 [[:digit:]]+ 6 3 [01] 1[45] 0 0 0 - ${s4_port} - 0 0 - - 0" +} + +haproxy h1 -cli { + send "enable server be1/srv1" + expect ~ .* +} + +haproxy h1 -cli { + send "enable server be2/srv2" + expect ~ .* +} + +haproxy h1 -cli { + send "enable server be3/srv3" + expect ~ .* +} + +haproxy h1 -cli { + send "enable server be4/srv4" + expect ~ .* +} + +haproxy h1 -cli { + barrier b1 sync + send "show servers state" + expect ~ "# be_id be_name srv_id srv_name srv_addr srv_op_state srv_admin_state srv_uweight srv_iweight srv_time_since_last_change srv_check_status srv_check_result srv_check_health srv_check_state srv_agent_state bk_f_forced_id srv_f_forced_id srv_fqdn srv_port srvrecord srv_use_ssl srv_check_port srv_check_addr srv_agent_addr srv_agent_port\n6 be1 1 srv1 ${s1_addr} 2 0 1 1 [[:digit:]]+ 6 [03] 1 [67] 0 0 0 - ${s1_port} - 0 0 - - 0\n7 be2 1 srv2 ${s2_addr} 2 0 1 1 [[:digit:]]+ 6 [03] 1 [67] 0 0 0 - ${s2_port} - 0 0 - - 0\n8 be3 1 srv3 ${s3_addr} 2 0 1 1 [[:digit:]]+ 6 [03] 1 [67] 0 0 0 - ${s3_port} - 0 0 - - 0\n9 be4 1 srv4 ${s4_addr} 2 0 1 1 [[:digit:]]+ 6 [03] 1 [67] 0 0 0 - ${s4_port} - 0 0 - - 0" +} + +syslog S1 -wait +syslog S2 -wait +syslog S3 -wait +syslog S4 -wait + diff --git a/reg-tests/checks/4be_1srv_smtpchk_httpchk_layer47errors.vtc b/reg-tests/checks/4be_1srv_smtpchk_httpchk_layer47errors.vtc new file mode 100644 index 0000000..3c4fcd8 --- /dev/null +++ b/reg-tests/checks/4be_1srv_smtpchk_httpchk_layer47errors.vtc @@ -0,0 +1,99 @@ +varnishtest "Check: smptchk option" +feature ignore_unknown_macro + +#EXCLUDE_TARGETS=freebsd,osx,generic +#REGTEST_TYPE=slow + +barrier b cond 3 + +syslog S1 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv1 succeeded.+reason: Layer7 check passed.+code: 221.+check duration: [[:digit:]]+ms.+status: 1/1 UP." + barrier b sync + recv + expect ~ "Health check for server be1/srv1 failed.+reason: Layer7 timeout.+check duration: [[:digit:]]+ms.+status: 0/1 DOWN" +} -start + +syslog S2 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be2/srv2 succeeded.+reason: Layer7 check passed.+code: 200.+.+check duration: [[:digit:]]+ms.+status: 1/1 UP." + barrier b sync + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be2/srv2 failed.+reason: Layer7 timeout.+check duration: [[:digit:]]+ms.+status: 0/1 DOWN" +} -start + +syslog S3 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be3/srv3 failed.+reason: Layer4 connection problem.+info: \"General socket error \\(Network is unreachable\\)\".+check duration: [[:digit:]]+ms.+status: 0/1 DOWN." +} -start + +syslog S4 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be4/srv4 failed.+reason: Layer4 connection problem.+info: \"Connection refused\".+check duration: [[:digit:]]+ms.+status: 0/1 DOWN." +} -start + +server s1 { + send "2" + send "2" + send "0" + send "\r\n" + recv 16 + send "2" + send "4" + send "8" + send "\r\n" + recv 6 + send "2" + send "2" + send "1" + send " ok\r\n" +} -start + +server s2 { + rxreq + txresp +} -start + +haproxy h1 -conf { + defaults + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + option log-health-checks + default-server inter 200ms downinter 100ms rise 1 fall 1 + + backend be1 + option smtpchk + log ${S1_addr}:${S1_port} daemon + server srv1 ${s1_addr}:${s1_port} check + + backend be2 + mode tcp + log ${S2_addr}:${S2_port} daemon + option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www + server srv2 ${s2_addr}:${s2_port} check + + backend be3 + log ${S3_addr}:${S3_port} daemon + server srv3 255.255.255.255:11111 check + + backend be4 + log ${S4_addr}:${S4_port} daemon + server srv4 localhost:11111 check +} -start + +haproxy h1 -cli { + barrier b sync + send "show servers state" + expect ~ .* +} + +server s1 -wait +server s2 -wait + +syslog S1 -wait +syslog S2 -wait +syslog S3 -wait +syslog S4 -wait + + diff --git a/reg-tests/checks/agent-check.vtc b/reg-tests/checks/agent-check.vtc new file mode 100644 index 0000000..5cf51c6 --- /dev/null +++ b/reg-tests/checks/agent-check.vtc @@ -0,0 +1,42 @@ +varnishtest "Health-checks: agent-check" +#REGTEST_TYPE=slow +feature ignore_unknown_macro + +barrier b1 cond 2 -cyclic +barrier b2 cond 2 -cyclic + +server s1 { + barrier b1 sync + recv 5 + send "75%,maxconn:30,maint,down\n" + expect_close + barrier b2 sync +} -start + + +haproxy h1 -conf { + defaults + mode tcp + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + + backend be1 + log ${S1_addr}:${S1_port} daemon + option log-health-checks + server srv ${s1_addr}:${s1_port} weight 100 agent-check agent-addr ${s1_addr} agent-port ${s1_port} agent-send "pouet" agent-inter 100ms +} -start + +haproxy h1 -cli { + send "show servers state" + expect ~ "be1 1 srv 127.0.0.1 2 0 100 100 [[:digit:]]+ 1 0 [[:digit:]] 0 [[:digit:]]+ 0 0 - ${s1_port} -" + send "show stat" + expect ~ "be1,srv,0,0,0,0,," + + barrier b1 sync + barrier b2 sync + send "show servers state" + expect ~ "be1 1 srv 127.0.0.1 0 1 75 100 [[:digit:]]+ 1 0 [[:digit:]] 0 [[:digit:]]+ 0 0 - ${s1_port} -" + send "show stat" + expect ~ "be1,srv,0,0,0,0,30" +} diff --git a/reg-tests/checks/common.pem b/reg-tests/checks/common.pem new file mode 120000 index 0000000..a4433d5 --- /dev/null +++ b/reg-tests/checks/common.pem @@ -0,0 +1 @@ +../ssl/common.pem
\ No newline at end of file diff --git a/reg-tests/checks/http-check-expect.vtc b/reg-tests/checks/http-check-expect.vtc new file mode 100644 index 0000000..637eec6 --- /dev/null +++ b/reg-tests/checks/http-check-expect.vtc @@ -0,0 +1,64 @@ +varnishtest "Health-checks: some http-check expect tests" +feature ignore_unknown_macro +#REQUIRE_VERSION=2.2 +#REGTEST_TYPE=slow +# This script tests http-check expect rules. + +server s1 { + rxreq + expect req.method == OPTIONS + expect req.url == / + expect req.proto == HTTP/1.0 + txresp -status 202 \ + -hdr "x-test1: true, next value" \ + -hdr "x-test2: true, begin-value, value-end, value-sub-string, value-reg-123ABC" \ + -hdr "x-begin-test: 1" \ + -hdr "x-test-end: 1" \ + -hdr "x-sub-test: 1" \ + -hdr "x-reg-test1: 1" \ + -hdr "x-hdr-name: x-test1" +} -start + +syslog S1 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv succeeded.*code: 202" +} -start + +haproxy h1 -conf { + defaults + mode http + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + option log-health-checks + + backend be1 + log ${S1_addr}:${S1_port} len 2048 local0 + option httpchk + http-check expect status 200-399 + + http-check expect hdr name "x-test1" + http-check expect hdr name -m str "X-Test2" + http-check expect hdr name -m beg "X-Begin-" + http-check expect hdr name -m end "-End" + http-check expect hdr name -m sub "-Sub-" + http-check expect hdr name -m reg "^[a-z]+-Reg-[a-z]+[0-9]\$" + http-check set-var(check.hdr_name) res.fhdr(x-hdr-name) + http-check expect hdr name-lf -m str "%[var(check.hdr_name)]" + http-check expect hdr name-lf -m str "%[res.fhdr(x-hdr-name)]" + + http-check expect fhdr name "x-test1" value "true, next value" + http-check expect hdr name "x-test2" value -m str "true" + http-check expect hdr name -m beg "x-test" value -m beg "begin-" + http-check expect hdr name -m beg "x-test" value -m end "-end" + http-check expect hdr name -m beg "x-test" value -m sub "-sub-" + http-check expect hdr name -m beg "x-test" value -m reg "^value-reg-[A-Z0-9]+\$" + http-check expect fhdr name -m beg "x-test" value -m reg "value-reg-[A-Z0-9]+" + http-check set-var(check.hdr_value) str(x-test1) + http-check expect hdr name -m beg "x-" value-lf -m str "%[var(check.hdr_value)]" + http-check expect fhdr name -m beg "x-" value-lf -m str "%[res.fhdr(x-hdr-name)]" + + server srv ${s1_addr}:${s1_port} check inter 100ms rise 1 fall 1 +} -start + +syslog S1 -wait diff --git a/reg-tests/checks/http-check-send.vtc b/reg-tests/checks/http-check-send.vtc new file mode 100644 index 0000000..0970ee4 --- /dev/null +++ b/reg-tests/checks/http-check-send.vtc @@ -0,0 +1,168 @@ +varnishtest "Health-checks: http-check send test" +#REGTEST_TYPE=slow +#REQUIRE_VERSION=2.4 +feature ignore_unknown_macro + +# This script tests HTTP health-checks and more particularly the "http-check +# send" directive. + +server s1 { + rxreq + expect req.method == OPTIONS + expect req.url == / + expect req.proto == HTTP/1.0 + txresp +} -start + +server s2 { + rxreq + expect req.method == GET + expect req.url == /test + expect req.proto == HTTP/1.1 + expect req.http.connection == "close" + txresp +} -start + +server s3 { + rxreq + expect req.method == OPTIONS + expect req.url == / + expect req.proto == HTTP/1.0 + expect req.http.hdr == <undef> + expect req.http.host == <undef> + expect req.http.x-test == <undef> + expect req.bodylen == 0 + txresp +} -start + +server s4 { + rxreq + expect req.method == GET + expect req.url == /status + expect req.proto == HTTP/1.1 + expect req.http.connection == "close" + expect req.http.hdr == <undef> + expect req.http.host == "my-www-host" + expect req.http.x-test == true + expect req.http.content-length == 4 + expect req.bodylen == 4 + expect req.body == "test" + txresp +} -start + +server s5 { + rxreq + expect req.method == OPTIONS + expect req.url == / + expect req.proto == HTTP/1.0 + expect req.http.hdr == <undef> + expect req.http.host == "other-www-host" + expect req.http.x-test == <undef> + expect req.http.x-new-test == true + expect req.http.content-length == 10 + expect req.bodylen == 10 + expect req.body == "other test" + txresp +} -start + +server s6 { + rxreq + expect req.method == GET + expect req.url == / + expect req.proto == HTTP/1.1 + expect req.http.host == "ws-host" + expect req.http.connection == "upgrade" + expect req.http.upgrade == "raw-proto" + txresp \ + -status 101 \ + -hdr "connection: upgrade" \ + -hdr "upgrade: raw-proto" +} -start + + +syslog S1 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv succeeded.*code: 200" +} -start + +syslog S2 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be2/srv succeeded.*code: 200" +} -start + +syslog S3 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be3/srv succeeded.*code: 200" +} -start + +syslog S4 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be4/srv succeeded.*code: 200" +} -start + +syslog S5 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be5/srv succeeded.*code: 200" +} -start + +syslog S6 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be6_ws/srv succeeded.*code: 101" +} -start + + +haproxy h1 -conf { + defaults + mode http + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + option httpchk + option log-health-checks + + backend be1 + log ${S1_addr}:${S1_port} len 2048 local0 + server srv ${s1_addr}:${s1_port} check inter 200ms rise 1 fall 1 + + backend be2 + log ${S2_addr}:${S2_port} len 2048 local0 + option httpchk GET /test HTTP/1.1 + server srv ${s2_addr}:${s2_port} check inter 200ms rise 1 fall 1 + + defaults + mode http + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + option httpchk GET /status HTTP/1.1\r\nHdr:\ must-be-removed + option log-health-checks + http-check send hdr Host "my-www-host" hdr X-test true body "test" + + backend be3 + option httpchk + log ${S3_addr}:${S3_port} len 2048 local0 + server srv ${s3_addr}:${s3_port} check inter 200ms rise 1 fall 1 + + backend be4 + log ${S4_addr}:${S4_port} len 2048 local0 + server srv ${s4_addr}:${s4_port} check inter 200ms rise 1 fall 1 + + backend be5 + log ${S5_addr}:${S5_port} len 2058 local0 + http-check send hdr Host "other-www-host" hdr X-New-Test true body "other test" + server srv ${s5_addr}:${s5_port} check inter 200ms rise 1 fall 1 + + backend be6_ws + log ${S6_addr}:${S6_port} len 2048 local0 + http-check send meth GET uri / ver HTTP/1.1 hdr host ws-host hdr connection upgrade hdr upgrade raw-proto + http-check expect status 101 + server srv ${s6_addr}:${s6_port} check inter 200ms rise 1 fall 1 + +} -start + +syslog S1 -wait +syslog S2 -wait +syslog S3 -wait +syslog S4 -wait +syslog S5 -wait +syslog S6 -wait diff --git a/reg-tests/checks/http-check.vtc b/reg-tests/checks/http-check.vtc new file mode 100644 index 0000000..3353060 --- /dev/null +++ b/reg-tests/checks/http-check.vtc @@ -0,0 +1,157 @@ +varnishtest "Health-checks: some http-check tests" +feature ignore_unknown_macro +#REQUIRE_VERSION=2.2 +#REGTEST_TYPE=slow +# This script tests HTTP health-checks. + +server s1 { + rxreq + expect req.method == OPTIONS + expect req.url == / + expect req.proto == HTTP/1.0 + txresp +} -start + +server s2 { + rxreq + expect req.method == GET + expect req.url == /status + expect req.proto == HTTP/1.1 + txresp +} -start + +server s3 { + rxreq + expect req.method == GET + expect req.url == /status + expect req.proto == HTTP/1.1 + txresp +} -start + +server s4 { + rxreq + expect req.method == GET + expect req.url == /req1 + expect req.proto == HTTP/1.1 + expect req.http.x-test == "server=srv" + expect req.http.x-haproxy-server-state ~ "UP.+name=be4/srv" + expect req.bodylen == 0 + txresp + + accept + rxreq + expect req.method == GET + expect req.url == /req2 + expect req.proto == HTTP/1.1 + expect req.http.x-test == "server=" + expect req.http.x-haproxy-server-state ~ "UP.+name=be4/srv" + expect req.http.content-length == 17 + expect req.bodylen == 17 + expect req.body == "health-check body" + txresp + + accept + rxreq + expect req.method == GET + expect req.url == /req3 + expect req.proto == HTTP/1.0 + expect req.http.x-test == <undef> + expect req.http.x-haproxy-server-state ~ "UP.+name=be4/srv" + expect req.bodylen == 0 + txresp + + accept + rxreq + expect req.method == GET + expect req.url == / + expect req.proto == HTTP/1.0 + expect req.http.x-test == <undef> + expect req.http.x-haproxy-server-state ~ "UP.+name=be4/srv" + expect req.bodylen == 23 + expect req.body == "health-check on be4-srv" + txresp + +} -start + +syslog S1 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be[0-9]/srv succeeded.*code: 200" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be[0-9]/srv succeeded.*code: 200" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be[0-9]/srv succeeded.*code: 200" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be[0-9]/srv succeeded.*code: 200" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be[0-9]/srv succeeded.*code: 200" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be[0-9]/srv succeeded.*code: 200" +} -start + +haproxy h1 -conf { + defaults + mode http + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + option log-health-checks + + backend be1 + log ${S1_addr}:${S1_port} len 2048 local0 + option httpchk + server srv ${s1_addr}:${s1_port} check inter 100ms rise 1 fall 1 + + backend be2 + log ${S1_addr}:${S1_port} len 2048 local0 + option httpchk GET /status HTTP/1.1 + server srv ${s2_addr}:${s2_port} check inter 100ms rise 1 fall 1 + + backend be3 + log ${S1_addr}:${S1_port} len 2048 local0 + option httpchk + http-check send meth GET uri /status ver HTTP/1.1 + server srv ${s3_addr}:${s3_port} check inter 100ms rise 1 fall 1 + + backend be4 + mode tcp + log ${S1_addr}:${S1_port} len 2048 local0 + option httpchk + http-check send-state + http-check connect addr ${s4_addr}:${s4_port} + http-check set-var(check.server) "str(srv)" + http-check set-var(check.path) "str(/req1)" + http-check send meth GET uri-lf "%[var(check.path)]" ver HTTP/1.1 hdr x-test "server=%[var(check.server)]" + http-check expect status 200 + http-check connect addr ${s4_addr} port ${s4_port} + http-check unset-var(check.server) + http-check set-var(check.path) "str(/req2)" + http-check send meth GET uri-lf "%[var(check.path)]" ver HTTP/1.1 hdr x-test "server=%[var(check.server)]" body "health-check body" + http-check expect rstatus "^2[0-9]{2}" + http-check connect addr ${s4_addr} port ${s4_port} + http-check set-var(check.path) "str(/req3)" + http-check send meth GET uri-lf "%[var(check.path)]" + http-check expect rstatus "^2[0-9]{2}" + http-check connect addr ${s4_addr} port ${s4_port} + http-check unset-var(check.path) + http-check send meth GET uri-lf "%[var(check.path)]" body-lf "health-check on %[be_name]-%[srv_name]" + ## implicit expect rule + server srv ${s1_addr}:${s1_port} check inter 100ms rise 1 fall 1 + + backend be5 + log ${S1_addr}:${S1_port} len 2048 local0 + option httpchk + server srv ${h1_li1_addr}:${h1_li1_port} proto h2 check inter 100ms rise 1 fall 1 + + backend be6 + log ${S1_addr}:${S1_port} len 2048 local0 + option httpchk GET /status HTTP/1.1 + server srv ${h1_li1_addr}:${h1_li1_port} check check-proto h2 inter 100ms rise 1 fall 1 + + listen li1 + mode http + bind "fd@${li1}" proto h2 + http-request return status 200 + +} -start + +syslog S1 -wait diff --git a/reg-tests/checks/http-monitor-uri.vtc b/reg-tests/checks/http-monitor-uri.vtc new file mode 100644 index 0000000..b6c8ccb --- /dev/null +++ b/reg-tests/checks/http-monitor-uri.vtc @@ -0,0 +1,56 @@ +varnishtest "Test the HTTP directive monitor-uri" +#REQUIRE_VERSION=2.2 + +# This config tests the HTTP directive monitor-uri. Especially the path matching +# when an absolute-form uri is received from the client. But also the +# case-sensitivity of the matching. + +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe1}" + monitor-uri /health + + frontend fe2 + bind "fd@${fe2}" + monitor-uri http://www.haproxy.org/health +} -start + +client c1 -connect ${h1_fe1_sock} { + txreq -req GET -url /health + rxresp + expect resp.status == 200 +} -run + +client c2 -connect ${h1_fe1_sock} { + txreq -req GET -url http://www.haproxy.org/health \ + -hdr "Host: www.haproxy.org" + rxresp + expect resp.status == 200 +} -run + +client c3 -connect ${h1_fe1_sock} { + txreq -req GET -url /hEAlth + rxresp + expect resp.status == 503 +} -run + +client c4 -connect ${h1_fe2_sock} { + txreq -req GET -url http://www.haproxy.org/health \ + -hdr "Host: www.haproxy.org" + rxresp + expect resp.status == 200 +} -run + +client c5 -connect ${h1_fe2_sock} { + txreq -req GET -url /health + rxresp + expect resp.status == 503 +} -run diff --git a/reg-tests/checks/ldap-check.vtc b/reg-tests/checks/ldap-check.vtc new file mode 100644 index 0000000..a0e5509 --- /dev/null +++ b/reg-tests/checks/ldap-check.vtc @@ -0,0 +1,96 @@ +varnishtest "Health-checks: LDAP health-check" +#REQUIRE_VERSION=2.2 +#REGTEST_TYPE=slow +feature ignore_unknown_macro + +# This scripts tests health-checks for LDAP application, enabled using +# "option ldap-check" line. A intermediate listener is used to validate +# the request because it is impossible with VTEST to read and match raw +# text. + +server s1 { + recv 14 + sendhex "300C020101 61 070A01 00 04000400" +} -start + +server s2 { + recv 14 + sendhex "300C020101 60 070A01 00 04000400" +} -start + +server s3 { + recv 14 + sendhex "300C020101 61 070A01 01 04000400" +} -start + +server s4 { + recv 14 + sendhex "308400000010020101 61 84000000070A01" + delay 0.1 + sendhex "00 04000400" +} -start + +syslog S1 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv succeeded, reason: Layer7 check passed.+info: \"Success\".+check duration: [[:digit:]]+ms, status: 1/1 UP." +} -start + +syslog S2 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be2/srv failed, reason: Layer7 invalid response.+info: \"Not LDAPv3 protocol\".+check duration: [[:digit:]]+ms, status: 0/1 DOWN." +} -start + +syslog S3 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be3/srv failed, reason: Layer7 wrong status.+code: 1.+info: \"See RFC: http://tools.ietf.org/html/rfc4511#section-4.1.9\".+check duration: [[:digit:]]+ms, status: 0/1 DOWN." +} -start + +syslog S4 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be4/srv succeeded, reason: Layer7 check passed.+info: \"Success\".+check duration: [[:digit:]]+ms, status: 1/1 UP." +} -start + +haproxy h1 -conf { + defaults + mode tcp + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + + backend be1 + log ${S1_addr}:${S1_port} daemon + option log-health-checks + option ldap-check + server srv ${h1_ldap1_addr}:${h1_ldap1_port} check inter 1s rise 1 fall 1 + + backend be2 + log ${S2_addr}:${S2_port} daemon + option log-health-checks + option ldap-check + server srv ${s2_addr}:${s2_port} check inter 1s rise 1 fall 1 + + backend be3 + log ${S3_addr}:${S3_port} daemon + option log-health-checks + option ldap-check + server srv ${s3_addr}:${s3_port} check inter 1s rise 1 fall 1 + + backend be4 + log ${S4_addr}:${S4_port} daemon + option log-health-checks + option ldap-check + server srv ${s4_addr}:${s4_port} check inter 1s rise 1 fall 1 + + listen ldap1 + bind "fd@${ldap1}" + tcp-request inspect-delay 100ms + tcp-request content accept if { req.len eq 14 } { req.payload(0,14) -m bin "300C020101600702010304008000" } + tcp-request content reject + server srv ${s1_addr}:${s1_port} + +} -start + +syslog S1 -wait +syslog S2 -wait +syslog S3 -wait +syslog S4 -wait diff --git a/reg-tests/checks/mysql-check.vtc b/reg-tests/checks/mysql-check.vtc new file mode 100644 index 0000000..b2348c3 --- /dev/null +++ b/reg-tests/checks/mysql-check.vtc @@ -0,0 +1,123 @@ +varnishtest "Health-checks: MySQL health-check" +#REQUIRE_VERSION=2.2 +#REGTEST_TYPE=slow +feature ignore_unknown_macro + +# This scripts tests health-checks for MySQL application, enabled using +# "option mysql-check" line. A intermediate listener is used to validate +# the request because it is impossible with VTEST to read and match raw +# text. + +server s1 { + sendhex "4A0000000A382E302E3139000A0000006F3C025E6249410D00FFFFFF0200FFC715000000000000000000007C182159106E2761144322200063616368696E675F736861325F70617373776F726400" + expect_close +} -start + +server s2 { + sendhex "4A0000000A382E302E3139000A0000006F3C025E6249410D00FFFFFF0200FFC715000000000000000000007C182159106E2761144322200063616368696E675F736861325F70617373776F726400" + recv 20 + sendhex "03000002000000" +} -start + +server s3 { + sendhex "4A0000000A382E302E3139000A0000006F3C025E6249410D00FFFFFF0200FFC715000000000000000000007C182159106E2761144322200063616368696E675F736861325F70617373776F726400" + recv 47 + sendhex "0700000200000002000000" +} -start + +server s4 { + sendhex "4A0000000A382E302E3139000A0000006F3C025E6249410D00FFFFFF0200FFC715000000000000000000007C182159106E2761144322200063616368696E675F736861325F70617373776F726400" + recv 21 + sendhex "67000002FFE304436C69656E7420646F6573206E6F7420737570706F72742061757468656E7469636174696F6E2070726F746F636F6C20726571756573746564206279207365727665723B20636F6E736964657220757067726164696E67204D7953514C20636C69656E74" +} -start + +server s5 { + sendhex "4A0000000A382E302E3139000A0000006F3C025E6249410D00FFFFFF0200FFC715000000000000000000007C182159106E2761144322200063616368696E675F736861325F70617373776F726400" + recv 48 + sendhex "67000002FFE304436C69656E7420646F6573206E6F7420737570706F72742061757468656E7469636174696F6E2070726F746F636F6C20726571756573746564206279207365727665723B20636F6E736964657220757067726164696E67204D7953514C20636C69656E74" +} -start + +syslog S1 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv succeeded, reason: Layer7 check passed.+info: \"8.0.19\".+check duration: [[:digit:]]+ms, status: 1/1 UP." +} -start + +syslog S2 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be2/srv succeeded, reason: Layer7 check passed.+info: \"8.0.19\".+check duration: [[:digit:]]+ms, status: 1/1 UP." +} -start + +syslog S3 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be3/srv succeeded, reason: Layer7 check passed.+info: \"8.0.19\".+check duration: [[:digit:]]+ms, status: 1/1 UP." +} -start + +syslog S4 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be4/srv failed, reason: Layer7 wrong status.+code: 1251.+info: \"Client does not support authentication protocol requested by server; consider upgrading MySQL client\".+check duration: [[:digit:]]+ms, status: 0/1 DOWN." +} -start + +syslog S5 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be5/srv failed, reason: Layer7 wrong status.+code: 1251.+info: \"Client does not support authentication protocol requested by server; consider upgrading MySQL client\".+check duration: [[:digit:]]+ms, status: 0/1 DOWN." +} -start + + +haproxy h1 -conf { + defaults + mode tcp + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + + backend be1 + log ${S1_addr}:${S1_port} daemon + option log-health-checks + option mysql-check + server srv ${s1_addr}:${s1_port} check inter 1s rise 1 fall 1 + + backend be2 + log ${S2_addr}:${S2_port} daemon + option log-health-checks + option mysql-check user user pre-41 + server srv ${h1_mysql1_addr}:${h1_mysql1_port} check inter 1s rise 1 fall 1 + + backend be3 + log ${S3_addr}:${S3_port} daemon + option log-health-checks + option mysql-check user user + server srv ${h1_mysql2_addr}:${h1_mysql2_port} check inter 1s rise 1 fall 1 + + backend be4 + log ${S4_addr}:${S4_port} daemon + option log-health-checks + option mysql-check user pouet + server srv ${s4_addr}:${s4_port} check inter 1s rise 1 fall 1 + + backend be5 + log ${S5_addr}:${S5_port} daemon + option log-health-checks + option mysql-check user pouet post-41 + server srv ${s5_addr}:${s5_port} check inter 1s rise 1 fall 1 + + listen mysql1 + bind "fd@${mysql1}" + tcp-request inspect-delay 100ms + tcp-request content accept if { req.len eq 20 } { req.payload(0,20) -m bin "0B00000100800000017573657200000100000001" } + tcp-request content reject + server srv ${s2_addr}:${s2_port} + + listen mysql2 + bind "fd@${mysql2}" + tcp-request inspect-delay 100ms + tcp-request content accept if { req.len eq 47 } { req.payload(0,47) -m bin "2600000100820000008000012100000000000000000000000000000000000000000000007573657200000100000001" } + tcp-request content reject + server srv ${s3_addr}:${s3_port} + +} -start + +syslog S1 -wait +syslog S2 -wait +syslog S3 -wait +syslog S4 -wait +syslog S5 -wait diff --git a/reg-tests/checks/pgsql-check.vtc b/reg-tests/checks/pgsql-check.vtc new file mode 100644 index 0000000..2c9c65b --- /dev/null +++ b/reg-tests/checks/pgsql-check.vtc @@ -0,0 +1,93 @@ +varnishtest "Health-checks: PostgreSQL health-check" +#REQUIRE_VERSION=2.2 +#REGTEST_TYPE=slow +feature ignore_unknown_macro + +# This scripts tests health-checks for PostgreSQL application, enabled using +# "option pgsql-check" line. A intermediate listener is used to validate +# the request because it is impossible with VTEST to read and match raw +# text. + +server s1 { + recv 23 + sendhex "520000000800000000" +} -start + +server s2 { + recv 23 + sendhex "450000000B53464154414C00" +} -start + +server s3 { + recv 23 + send "Not a PostgreSQL response" +} -start + +server s4 { + recv 23 + sendhex "52000000170000000A534352414D2D5348412D3235360000" +} -start + +syslog S1 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv succeeded, reason: Layer7 check passed.+info: \"PostgreSQL server is ok\".+check duration: [[:digit:]]+ms, status: 1/1 UP." +} -start + +syslog S2 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be2/srv failed, reason: Layer7 invalid response.+info: \"FATAL\".+check duration: [[:digit:]]+ms, status: 0/1 DOWN." +} -start + +syslog S3 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be3/srv failed, reason: Layer7 wrong status.+info: \"PostgreSQL unknown error\".+check duration: [[:digit:]]+ms, status: 0/1 DOWN." +} -start + +syslog S4 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be4/srv succeeded, reason: Layer7 check passed.+info: \"PostgreSQL server is ok\".+check duration: [[:digit:]]+ms, status: 1/1 UP." +} -start + +haproxy h1 -conf { + defaults + mode tcp + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + + backend be1 + log ${S1_addr}:${S1_port} daemon + option log-health-checks + option pgsql-check user postgres + server srv ${h1_pgsql_addr}:${h1_pgsql_port} check inter 1s rise 1 fall 1 + + backend be2 + log ${S2_addr}:${S2_port} daemon + option log-health-checks + option pgsql-check user postgres + server srv ${s2_addr}:${s2_port} check inter 1s rise 1 fall 1 + + backend be3 + log ${S3_addr}:${S3_port} daemon + option log-health-checks + option pgsql-check user postgres + server srv ${s3_addr}:${s3_port} check inter 1s rise 1 fall 1 + + backend be4 + log ${S4_addr}:${S4_port} daemon + option log-health-checks + option pgsql-check user postgres + server srv ${s4_addr}:${s4_port} check inter 1s rise 1 fall 1 + + listen pgsql1 + bind "fd@${pgsql}" + tcp-request inspect-delay 100ms + tcp-request content accept if { req.len eq 23 } { req.payload(0,23) -m bin "00000017000300007573657200706f7374677265730000" } + tcp-request content reject + server srv ${s1_addr}:${s1_port} +} -start + +syslog S1 -wait +syslog S2 -wait +syslog S3 -wait +syslog S4 -wait diff --git a/reg-tests/checks/redis-check.vtc b/reg-tests/checks/redis-check.vtc new file mode 100644 index 0000000..78b6ed3 --- /dev/null +++ b/reg-tests/checks/redis-check.vtc @@ -0,0 +1,61 @@ +varnishtest "Health-checks: Redis health-check" +#REQUIRE_VERSION=2.2 +#REGTEST_TYPE=slow +feature ignore_unknown_macro + +# This scripts tests health-checks for Redis application, enabled using +# "option redis-check" line. A intermediate listener is used to validate +# the request because it is impossible with VTEST to read and match raw +# text. + +server s1 { + recv 14 + send "+PONG\r\n" +} -start + +server s2 { + recv 14 + send "-Error message\r\n" +} -start + +syslog S1 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv succeeded, reason: Layer7 check passed.+info: \"Redis server is ok\".+check duration: [[:digit:]]+ms, status: 1/1 UP." +} -start + +syslog S2 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be2/srv failed, reason: Layer7 wrong status.+info: \"-Error message\".+check duration: [[:digit:]]+ms, status: 0/1 DOWN." +} -start + + +haproxy h1 -conf { + defaults + mode tcp + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + + backend be1 + log ${S1_addr}:${S1_port} daemon + option log-health-checks + option redis-check + server srv ${h1_redis_addr}:${h1_redis_port} check inter 1s rise 1 fall 1 + + backend be2 + log ${S2_addr}:${S2_port} daemon + option log-health-checks + option redis-check + server srv ${s2_addr}:${s2_port} check inter 1s rise 1 fall 1 + + listen redis1 + bind "fd@${redis}" + tcp-request inspect-delay 100ms + tcp-request content accept if { req.len eq 14 } { req.payload(0,14) -m str "*1\r\n\$4\r\nPING\r\n" } + tcp-request content reject + server srv ${s1_addr}:${s1_port} + +} -start + +syslog S1 -wait +syslog S2 -wait diff --git a/reg-tests/checks/smtp-check.vtc b/reg-tests/checks/smtp-check.vtc new file mode 100644 index 0000000..723f5f0 --- /dev/null +++ b/reg-tests/checks/smtp-check.vtc @@ -0,0 +1,110 @@ +varnishtest "Health-checks: SMTP health-check" +#REQUIRE_VERSION=2.2 +#REGTEST_TYPE=slow +feature ignore_unknown_macro + +# This scripts tests health-checks for SMTP servers, enabled using +# "option smtpchk" line. + +server s1 { + send "220 smtp-check.vtc SMTP Server\r\n" + recv 16 + send "250 smtp-check.vtc\r\n" + recv 6 + send "221 smtp-check.vtc closing\r\n" +} -start + +server s2 { + send "220 smtp-check.vtc SMTP Server\r\n" + recv 17 + send "250-smtp-check.vtc\r\n" + send "250-KEYWORD\r\n" + send "250 LAST KEYWORD\r\n" + recv 6 + send "221 smtp-check.vtc closing\r\n" +} -start + +server s3 { + send "I'm not a SMTP server\r\n" +} -start + +server s4 { + send "421 Try again later\r\n" +} -start + +server s5 { + send "220 smtp-check.vtc SMTP Server\r\n" + recv 16 + send "512 DNS error\r\n" +} -start + +syslog S1 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv succeeded, reason: Layer7 check passed.+code: 221.+info: \"smtp-check.vtc closing\".+check duration: [[:digit:]]+ms, status: 1/1 UP." +} -start + +syslog S2 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be2/srv succeeded, reason: Layer7 check passed.+code: 221.+info: \"smtp-check.vtc closing\".+check duration: [[:digit:]]+ms, status: 1/1 UP." +} -start + +syslog S3 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be3/srv failed, reason: Layer7 invalid response.+info: \"I'm not a SMTP server\".+check duration: [[:digit:]]+ms, status: 0/1 DOWN." +} -start + +syslog S4 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be4/srv failed, reason: Layer7 wrong status.+code: 421.+info: \"Try again later\".+check duration: [[:digit:]]+ms, status: 0/1 DOWN." +} -start + +syslog S5 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be5/srv failed, reason: Layer7 wrong status.+code: 512.+info: \"DNS error\".+check duration: [[:digit:]]+ms, status: 0/1 DOWN." +} -start + + +haproxy h1 -conf { + defaults + mode tcp + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + + backend be1 + log ${S1_addr}:${S1_port} daemon + option log-health-checks + option smtpchk + server srv ${s1_addr}:${s1_port} check inter 1s rise 1 fall 1 + + backend be2 + log ${S2_addr}:${S2_port} daemon + option log-health-checks + option smtpchk EHLO domain.tld + server srv ${s2_addr}:${s2_port} check inter 1s rise 1 fall 1 + + backend be3 + log ${S3_addr}:${S3_port} daemon + option log-health-checks + option smtpchk + server srv ${s3_addr}:${s3_port} check inter 1s rise 1 fall 1 + + backend be4 + log ${S4_addr}:${S4_port} daemon + option log-health-checks + option smtpchk + server srv ${s4_addr}:${s4_port} check inter 1s rise 1 fall 1 + + backend be5 + log ${S5_addr}:${S5_port} daemon + option log-health-checks + option smtpchk EHLO domain.tld + server srv ${s5_addr}:${s5_port} check inter 1s rise 1 fall 1 + +} -start + +syslog S1 -wait +syslog S2 -wait +syslog S3 -wait +syslog S4 -wait +syslog S5 -wait diff --git a/reg-tests/checks/spop-check.vtc b/reg-tests/checks/spop-check.vtc new file mode 100644 index 0000000..93cef59 --- /dev/null +++ b/reg-tests/checks/spop-check.vtc @@ -0,0 +1,94 @@ +varnishtest "Health-checks: SPOP health-check" +#REQUIRE_VERSION=2.2 +#REGTEST_TYPE=slow +feature ignore_unknown_macro + +# This scripts tests health-checks for SPOE agent, enabled using +# "option spop-check" line. A intermediate listener is used to validate +# the request because it is impossible with VTEST to read and match raw +# text. + +server s1 { + recv 82 + sendhex "00000036 65 00000001 0000 0776657273696F6E 0803322E30 0E6D61782D6672616D652D73697A65 03FCF0 060C6361706162696C6974696573 0800" +} -start + +server s2 { + recv 82 + sendhex "00000000" +} -start + +server s3 { + recv 82 + sendhex "00000007 65 00000000 0000" +} -start + +server s4 { + recv 82 + sendhex "00000014 65 00000001 0000 0776657273696F6E 0803312E30" +} -start + +syslog S1 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv succeeded, reason: Layer7 check passed.+info: \"SPOA server is ok\".+check duration: [[:digit:]]+ms, status: 1/1 UP." +} -start + +syslog S2 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be2/srv failed, reason: Layer7 invalid response.+info: \"invalid frame received\".+check duration: [[:digit:]]+ms, status: 0/1 DOWN." +} -start + +syslog S3 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be3/srv failed, reason: Layer7 invalid response.+info: \"fragmentation not supported\".+check duration: [[:digit:]]+ms, status: 0/1 DOWN." +} -start + +syslog S4 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be4/srv failed, reason: Layer7 invalid response.+info: \"unsupported version\".+check duration: [[:digit:]]+ms, status: 0/1 DOWN." +} -start + +haproxy h1 -conf { + defaults + mode tcp + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + + backend be1 + log ${S1_addr}:${S1_port} daemon + option log-health-checks + option spop-check + server srv ${h1_spop1_addr}:${h1_spop1_port} check inter 1s rise 1 fall 1 + + backend be2 + log ${S2_addr}:${S2_port} daemon + option log-health-checks + option spop-check + server srv ${s2_addr}:${s2_port} check inter 1s rise 1 fall 1 + + backend be3 + log ${S3_addr}:${S3_port} daemon + option log-health-checks + option spop-check + server srv ${s3_addr}:${s3_port} check inter 1s rise 1 fall 1 + + backend be4 + log ${S4_addr}:${S4_port} daemon + option log-health-checks + option spop-check + server srv ${s4_addr}:${s4_port} check inter 1s rise 1 fall 1 + + listen spop1 + bind "fd@${spop1}" + tcp-request inspect-delay 100ms + tcp-request content accept if { req.len eq 82 } { req.payload(0,4) -m bin "0000004E" } #{ req.payload(4,4) -m bin "00000001" } { req.payload(8,2) -m bin "0000" } { req.payload(12,17) -m str "supported-version" } + tcp-request content reject + server srv ${s1_addr}:${s1_port} + +} -start + +syslog S1 -wait +syslog S2 -wait +syslog S3 -wait +syslog S4 -wait diff --git a/reg-tests/checks/ssl-hello-check.vtc b/reg-tests/checks/ssl-hello-check.vtc new file mode 100644 index 0000000..49abc0b --- /dev/null +++ b/reg-tests/checks/ssl-hello-check.vtc @@ -0,0 +1,76 @@ +varnishtest "Health-checks: ssl-hello health-check" +#REQUIRE_OPTION=OPENSSL +#REQUIRE_VERSION=2.2 +#REGTEST_TYPE=slow +feature ignore_unknown_macro + +# This scripts tests health-checks for SSL application, enabled using +# "option ssl-hello-chk" line. + +syslog S1 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv succeeded, reason: Layer6 check passed.+check duration: [[:digit:]]+ms, status: 1/1 UP." +} -start + + +syslog S2 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be2/srv failed, reason: Layer6 invalid response.+info: \"TCPCHK got an empty response at step 2\".+check duration: [[:digit:]]+ms, status: 0/1 DOWN." +} -start + +syslog S3 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be3/srv failed, reason: Layer6 invalid response.+check duration: [[:digit:]]+ms, status: 0/1 DOWN." +} -start + +haproxy htst -conf { + global + tune.ssl.default-dh-param 2048 + + defaults + mode tcp + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe1}" ssl crt ${testdir}/common.pem + + frontend fe2 + bind "fd@${fe2}" + + frontend fe3 + mode http + bind "fd@${fe3}" + +} -start + +haproxy h1 -conf { + defaults + mode tcp + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + + backend be1 + log ${S1_addr}:${S1_port} daemon + option log-health-checks + option ssl-hello-chk + server srv ${htst_fe1_addr}:${htst_fe1_port} check inter 1s rise 1 fall 1 + + backend be2 + log ${S2_addr}:${S2_port} daemon + option log-health-checks + option ssl-hello-chk + server srv ${htst_fe2_addr}:${htst_fe2_port} check inter 1s rise 1 fall 1 + + backend be3 + log ${S3_addr}:${S3_port} daemon + option log-health-checks + option ssl-hello-chk + server srv ${htst_fe3_addr}:${htst_fe3_port} check inter 1s rise 1 fall 1 +} -start + +syslog S1 -wait +syslog S2 -wait +syslog S3 -wait diff --git a/reg-tests/checks/tcp-check-ssl.vtc b/reg-tests/checks/tcp-check-ssl.vtc new file mode 100644 index 0000000..6ac1782 --- /dev/null +++ b/reg-tests/checks/tcp-check-ssl.vtc @@ -0,0 +1,118 @@ +varnishtest "Health-checks: tcp-check health-check with ssl options" +#REQUIRE_OPTION=OPENSSL +#REQUIRE_VERSION=2.2 +#REGTEST_TYPE=slow +feature ignore_unknown_macro + +syslog S_ok -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be[0-9]+/srv succeeded, reason: Layer6 check passed.+check duration: [[:digit:]]+ms, status: 1/1 UP." + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be[0-9]+/srv succeeded, reason: Layer6 check passed.+check duration: [[:digit:]]+ms, status: 1/1 UP." + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be[0-9]+/srv succeeded, reason: Layer6 check passed.+check duration: [[:digit:]]+ms, status: 1/1 UP." + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be[0-9]+/srv succeeded, reason: Layer6 check passed.+check duration: [[:digit:]]+ms, status: 1/1 UP." + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be[0-9]+/srv succeeded, reason: Layer6 check passed.+check duration: [[:digit:]]+ms, status: 1/1 UP." +} -start + +syslog S3 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be3/srv failed, reason: Layer6 invalid response.+info: \"(Connection closed during SSL handshake|SSL handshake failure)\".+check duration: [[:digit:]]+ms, status: 0/1 DOWN." +} -start + +syslog S4 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be4/srv failed, reason: Layer6 invalid response.+info: \"(Connection closed during SSL handshake|SSL handshake failure) at step 1 of tcp-check \\(connect\\)\".+check duration: [[:digit:]]+ms, status: 0/1 DOWN." +} -start + + +haproxy htst -conf { + global + tune.ssl.default-dh-param 2048 + + defaults + mode tcp + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + + listen li1 + bind "fd@${li1}" + tcp-request inspect-delay 100ms + tcp-request content reject if { req.ssl_hello_type 0 } + tcp-request content accept if { req.ssl_sni check.haproxy.org } + tcp-request content accept if { req.ssl_sni connect.haproxy.org } + tcp-request content reject + server fe1 ${htst_fe1_addr}:${htst_fe1_port} + + listen li2 + bind "fd@${li2}" + tcp-request inspect-delay 100ms + tcp-request content reject if { req.ssl_hello_type 0 } + tcp-request content accept if { req.ssl_alpn h2 } + tcp-request content accept if { req.ssl_alpn http/1.1 } + tcp-request content reject + server fe1 ${htst_fe1_addr}:${htst_fe1_port} + + frontend fe1 + bind "fd@${fe1}" ssl crt ${testdir}/common.pem + +} -start + +haproxy h1 -conf { + defaults + mode tcp + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + + backend be1 + log ${S_ok_addr}:${S_ok_port} daemon + option log-health-checks + server srv ${htst_li1_addr}:${htst_li1_port} check check-ssl check-sni check.haproxy.org inter 1s rise 1 fall 1 verify none + + backend be2 + log ${S_ok_addr}:${S_ok_port} daemon + option log-health-checks + option tcp-check + tcp-check connect ssl sni connect.haproxy.org + server srv ${htst_li1_addr}:${htst_li1_port} check inter 1s rise 1 fall 1 verify none + + backend be3 + log ${S3_addr}:${S3_port} daemon + option log-health-checks + server srv ${htst_li1_addr}:${htst_li1_port} check check-ssl check-sni bad.haproxy.org inter 1s rise 1 fall 1 verify none + + backend be4 + log ${S4_addr}:${S4_port} daemon + option log-health-checks + option tcp-check + tcp-check connect ssl sni bad.haproxy.org + server srv ${htst_li1_addr}:${htst_li1_port} check inter 1s rise 1 fall 1 verify none + + backend be5 + log ${S_ok_addr}:${S_ok_port} daemon + option log-health-checks + option tcp-check + tcp-check connect default + server srv ${htst_li1_addr}:${htst_li1_port} check check-ssl check-sni check.haproxy.org inter 1s rise 1 fall 1 verify none + + backend be6 + log ${S_ok_addr}:${S_ok_port} daemon + option log-health-checks + server srv ${htst_li2_addr}:${htst_li2_port} check check-ssl check-alpn "h2,http/1.1" inter 1s rise 1 fall 1 verify none + + backend be7 + log ${S_ok_addr}:${S_ok_port} daemon + option log-health-checks + option tcp-check + tcp-check connect ssl alpn "h2,http/1.1" + server srv ${htst_li2_addr}:${htst_li2_port} check inter 1s rise 1 fall 1 verify none + +} -start + +syslog S_ok -wait +syslog S3 -wait +syslog S4 -wait diff --git a/reg-tests/checks/tcp-check_min-recv.vtc b/reg-tests/checks/tcp-check_min-recv.vtc new file mode 100644 index 0000000..81f93e0 --- /dev/null +++ b/reg-tests/checks/tcp-check_min-recv.vtc @@ -0,0 +1,68 @@ +varnishtest "tcp-check negative bounded regex match" +#EXCLUDE_TARGETS=freebsd,osx,generic +#REGTEST_TYPE=slow +#REQUIRE_VERSION=2.2 +# This test use a negative expect rule and verify that setting a required +# minimum amount of data to match. +feature ignore_unknown_macro + +syslog S1 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv1 failed, reason: Layer7 timeout.*at step 2 of tcp-check" +} -start + +syslog S2 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be2/srv1 succeeded" +} -start + +server s1 { + send "valid" + delay 0.2 + expect_close +} -start + +server s2 { + send "valid" + recv 10 + send "valid" + delay 0.2 + expect_close +} -start + +haproxy h1 -conf { + defaults + mode tcp + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout check "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + + backend be1 + # must fail fast + timeout check 1 + timeout server 1 + log ${S1_addr}:${S1_port} len 2048 local0 + option tcp-check + option log-health-checks + tcp-check connect + tcp-check expect !rstring "^error" comment "negative check" + tcp-check expect string "valid" comment "positive check" + tcp-check send "0123456789" + tcp-check expect string "valid" comment "positive check" + server srv1 ${s1_addr}:${s1_port} check inter 200ms rise 1 fall 1 + + backend be2 + log ${S2_addr}:${S2_port} len 2048 local0 + option tcp-check + option log-health-checks + tcp-check connect + tcp-check expect min-recv 5 !rstring "^error" comment "negative check" + tcp-check expect string "valid" comment "positive check" + tcp-check send "0123456789" + tcp-check expect string "valid" comment "positive check" + server srv1 ${s2_addr}:${s2_port} check inter 200ms rise 1 fall 1 +} -start + +syslog S1 -wait +syslog S2 -wait diff --git a/reg-tests/checks/tcp-check_multiple_ports.vtc b/reg-tests/checks/tcp-check_multiple_ports.vtc new file mode 100644 index 0000000..356ddf6 --- /dev/null +++ b/reg-tests/checks/tcp-check_multiple_ports.vtc @@ -0,0 +1,48 @@ +varnishtest "tcp-check multiple ports" +#EXCLUDE_TARGETS=freebsd,osx,generic +#REGTEST_TYPE=slow +# This test uses multiple tcp-check connect rules to perform health checking on +# a target. It relies on port 1 being unbound on the local system. +feature ignore_unknown_macro + +syslog S1 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv1 failed.*Connection refused at step 2 of tcp-check.*connect port 1" +} -start + +syslog S2 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be2/srv1 failed.*Connection refused at step 1 of tcp-check.*connect port 1" +} -start + +server s1 { +} -start + +haproxy h1 -conf { + defaults + mode tcp + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout check "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + #default-server check inter 200ms rise 1 fall 1 + + backend be1 + log ${S1_addr}:${S1_port} len 2048 local0 + option tcp-check + option log-health-checks + tcp-check connect port ${s1_port} + tcp-check connect port 1 + server srv1 ${s1_addr}:${s1_port} check inter 200ms rise 1 fall 1 + + backend be2 + log ${S2_addr}:${S2_port} len 2048 local0 + option tcp-check + option log-health-checks + tcp-check connect port 1 + tcp-check connect port ${s1_port} + server srv1 ${s1_addr}:${s1_port} check inter 200ms rise 1 fall 1 +} -start + +syslog S1 -wait +syslog S2 -wait diff --git a/reg-tests/checks/tcp-checks-socks4.vtc b/reg-tests/checks/tcp-checks-socks4.vtc new file mode 100644 index 0000000..04c23ec --- /dev/null +++ b/reg-tests/checks/tcp-checks-socks4.vtc @@ -0,0 +1,61 @@ +varnishtest "Health-checks: basic HTTP health-check though a socks4 proxy" +#REQUIRE_VERSION=2.0 +#REGTEST_TYPE=slow +feature ignore_unknown_macro + +# This scripts tests a simple HTTP health-checks though a socks4 proxy. + +server s1 { +} -start + +server socks { + ## get socks4 request + recv 16 + + ## send socks4 response : + ## constant(1): 0x00 + ## statut(1) : 0x5a (success) + ## padding(6) : ignored + sendhex "005A000000000000" + + rxreq + expect req.method == OPTIONS + expect req.url == / + expect req.proto == HTTP/1.0 + txresp +} -start + +syslog S1 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv succeeded, reason: Layer7 check passed.+code: 200.+check duration: [[:digit:]]+ms, status: 1/1 UP." +} -start + +haproxy h1 -conf { + defaults + mode tcp + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + + backend be1 + log ${S1_addr}:${S1_port} daemon + option log-health-checks + option httpchk + server srv ${s1_addr}:${s1_port} socks4 ${h1_socks_addr}:${h1_socks_port} check-via-socks4 check inter 1s rise 1 fall 1 + + listen socks + bind "fd@${socks}" + tcp-request inspect-delay 500ms + ## Accept socks4 request on 16 bytes : + ## version(1) : 0x04 + ## command(1) : 0x01 + ## port(2) : ${s1_port} + ## addr(4) : ${s1_addr} + ## user-id : "HAProxy\0" + tcp-request content accept if { req.len eq 16 } { req.payload(0,1) -m bin "04" } { req.payload(1,1) -m bin "01" } { req.payload(2,2),hex,hex2i eq ${s1_port} } { req.payload(4,4),hex,hex2i -m ip ${s1_addr} } { req.payload(8,8) -m bin "484150726F787900" } + tcp-request content reject + server srv ${socks_addr}:${socks_port} + +} -start + +syslog S1 -wait diff --git a/reg-tests/checks/tls_health_checks.vtc b/reg-tests/checks/tls_health_checks.vtc new file mode 100644 index 0000000..1989d65 --- /dev/null +++ b/reg-tests/checks/tls_health_checks.vtc @@ -0,0 +1,118 @@ +varnishtest "Health-check test over TLS/SSL" +#REQUIRE_OPTIONS=OPENSSL +#REGTEST_TYPE=slow +feature ignore_unknown_macro + + +# This script tests health-checks for a TLS/SSL backend with "option httpchk" +# and "check-ssl" option enabled attached to h2 haproxy process. This haproxy +# h2 process is chained to h1 other one. +# +server s1 { + rxreq + expect req.method == OPTIONS + expect req.url == * + expect req.proto == HTTP/1.1 + txresp +} -start + +server s2 { +} -start + +server s3 { + rxreq + expect req.method == OPTIONS + expect req.url == * + expect req.proto == HTTP/1.1 + txresp +} -start + +syslog S1 -level notice { + recv info + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* fe1~ be1/srv1 .* 200 [[:digit:]]+ - - ---- .* \"OPTIONS \\* HTTP/1.1\"" +} -start + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + + defaults + mode http + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + + backend be1 + server srv1 ${s1_addr}:${s1_port} + + backend be2 + server srv2 ${s2_addr}:${s2_port} + + backend be3 + server srv3 ${s3_addr}:${s3_port} + + frontend fe1 + option httplog + log ${S1_addr}:${S1_port} len 2048 local0 debug err + bind "fd@${fe1}" ssl crt ${testdir}/common.pem + use_backend be1 + + frontend fe2 + option tcplog + bind "fd@${fe2}" ssl crt ${testdir}/common.pem + use_backend be2 + + frontend fe3 + option httplog + bind "fd@${fe3}" ssl crt ${testdir}/common.pem + use_backend be3 +} -start + +syslog S2 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h2_pid}\\]: Health check for server be2/srv1 succeeded, reason: Layer7 check passed.+code: 200.+check duration: [[:digit:]]+ms, status: 1/1 UP." +} -start + +syslog S4 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h2_pid}\\]: Health check for server be4/srv2 succeeded, reason: Layer6 check passed.+check duration: [[:digit:]]+ms, status: 1/1 UP." +} -start + +syslog S6 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h2_pid}\\]: Health check for server be6/srv3 succeeded, reason: Layer7 check passed.+code: 200.+check duration: [[:digit:]]+ms, status: 1/1 UP." +} -start + +haproxy h2 -conf { + global + tune.ssl.default-dh-param 2048 + + defaults + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + default-server downinter 1s inter 500 rise 1 fall 1 + + backend be2 + option log-health-checks + option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www + log ${S2_addr}:${S2_port} daemon + server srv1 ${h1_fe1_addr}:${h1_fe1_port} ssl crt ${testdir}/common.pem verify none check + + backend be4 + option log-health-checks + log ${S4_addr}:${S4_port} daemon + server srv2 ${h1_fe2_addr}:${h1_fe2_port} ssl crt ${testdir}/common.pem verify none check-ssl check + + backend be6 + option log-health-checks + option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www + log ${S6_addr}:${S6_port} daemon + server srv3 127.0.0.1:80 crt ${testdir}/common.pem verify none check check-ssl port ${h1_fe3_port} addr ${h1_fe3_addr}:80 +} -start + +syslog S1 -wait + +syslog S2 -wait +syslog S4 -wait +syslog S6 -wait diff --git a/reg-tests/compression/basic.vtc b/reg-tests/compression/basic.vtc new file mode 100644 index 0000000..76ad43d --- /dev/null +++ b/reg-tests/compression/basic.vtc @@ -0,0 +1,378 @@ +varnishtest "Basic compression test" + +#REQUIRE_VERSION=1.9 +#REQUIRE_OPTION=ZLIB|SLZ + +feature ignore_unknown_macro + +server s1 { + # client c1 - request 1 + rxreq + expect req.url == "/c1.1" + expect req.http.accept-encoding == "<undef>" + txresp \ + -hdr "Content-Type: text/plain" \ + -bodylen 100 + + # client c1 - request 2 + rxreq + expect req.url == "/c1.2" + expect req.http.user-agent == "Mozilla/4" + expect req.http.accept-encoding == "gzip" + txresp \ + -hdr "Content-Type: text/plain" \ + -bodylen 100 + + # client c1 - request 3 + rxreq + expect req.url == "/c1.3" + expect req.proto == "HTTP/1.0" + expect req.http.accept-encoding == "gzip" + txresp -bodylen 100 + + # client c1 - request 4 + rxreq + expect req.url == "/c1.4" + expect req.http.accept-encoding == "gzip" + txresp \ + -proto "HTTP/1.0" \ + -hdr "Connection: keep-alive" \ + -hdr "Content-Type: text/plain" \ + -bodylen 100 + + # client c1 - request 5 + rxreq + expect req.url == "/c1.5" + expect req.method == "HEAD" + expect req.http.accept-encoding == "gzip" + txresp -nolen \ + -hdr "Content-Length: 100" \ + -hdr "Content-Type: text/plain" \ + + # client c1 - request 6 + rxreq + expect req.url == "/c1.6" + expect req.http.accept-encoding == "gzip" + txresp \ + -status 400 \ + -hdr "Content-Type: text/plain" \ + -bodylen 100 + + # client c1 - request 7 + rxreq + expect req.url == "/c1.7" + expect req.http.accept-encoding == "gzip" + txresp \ + -hdr "Content-Type: text/plain" \ + -hdr "Content-Encoding: something" \ + -body "FOO" + + # client c1 - request 8 + rxreq + expect req.url == "/c1.8" + expect req.http.accept-encoding == "gzip" + txresp \ + -hdr "Content-Type: text/plain" \ + -hdr "Cache-Control: no-transform" \ + -bodylen 100 + + # client c1 - request 9 + rxreq + expect req.url == "/c1.9" + expect req.http.accept-encoding == "gzip" + txresp \ + -hdr "Content-Type: text/css" \ + -bodylen 100 + + # client c1 - request 10 + rxreq + expect req.url == "/c1.10" + expect req.http.accept-encoding == "gzip" + txresp \ + -hdr "Content-Type: multipart/mixed; boundary=\"aaa\"" \ + -bodylen 100 + + # Close the connection with HAProxy and wait for a new one + # (C1 has finished and C2 will start) + accept + + # client c2 - request 1 + rxreq + expect req.url == "/c2.1" + expect req.http.accept-encoding == "gzip" + txresp \ + -hdr "Content-Type: text/plain" \ + -bodylen 100 + + # client c2 - request 2 + rxreq + expect req.url == "/c2.2" + expect req.http.accept-encoding == "gzip" + txresp -nolen \ + -hdr "Content-Type: text/plain" \ + -hdr "Transfer-Encoding: chunked" + chunkedlen 1 + chunkedlen 1 + chunkedlen 2 + chunkedlen 3 + chunkedlen 5 + chunkedlen 8 + chunkedlen 13 + chunkedlen 21 + chunkedlen 34 + chunkedlen 55 + chunkedlen 89 + chunkedlen 144 + chunkedlen 233 + chunkedlen 0 + + # Close the connection with HAProxy and wait for a new one + # (C2 has finished and C3 will start) + accept + + # client c3 - request 1 + rxreq + expect req.url == "/c3.1" + expect req.http.accept-encoding == "<undef>" + txresp \ + -hdr "Content-Type: text/plain" \ + -bodylen 50000 + + # client c3 - request 2 + rxreq + expect req.url == "/c3.2" + expect req.http.accept-encoding == "<undef>" + txresp -nolen \ + -hdr "Content-Type: text/plain" \ + -hdr "Transfer-Encoding: chunked" + chunkedlen 1000 + chunkedlen 1000 + chunkedlen 1000 + chunkedlen 1000 + chunkedlen 1000 + chunkedlen 5000 + chunkedlen 10000 + chunkedlen 30000 + chunkedlen 0 + + # Close the connection with HAProxy and wait for a new one + # (C3 has finished and C4 will start) + accept + + # client c4 - request 1 + rxreq + expect req.url == "/c4.1" + expect req.http.accept-encoding == "<undef>" + txresp \ + -hdr "Content-Type: text/plain" \ + -bodylen 100 + + # client c4 - request 2 + rxreq + expect req.url == "/c4.2" + expect req.http.accept-encoding == "<undef>" + txresp \ + -hdr "Content-Type: text/plain" \ + -bodylen 100 +} -start + + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe-gzip + bind "fd@${fe_gzip}" + default_backend be-gzip + + frontend fe-identity + bind "fd@${fe_identity}" + default_backend be-identity + + frontend fe-gzip-deflate + bind "fd@${fe_gzip_deflate}" + default_backend be-gzip-defalte + + backend be-gzip + compression algo gzip + compression type text/html text/plain + server www ${s1_addr}:${s1_port} + + backend be-identity + compression algo identity + server www ${s1_addr}:${s1_port} + + backend be-gzip-defalte + compression algo gzip deflate + compression offload + server www ${s1_addr}:${s1_port} + +} -start + +# No compression expected because not supported by the client or because +# something in the request or response headers forbids it. +client c1 -connect ${h1_fe_gzip_sock} { + # 1. no "Accept-Encoding header" + txreq -url "/c1.1" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "<undef>" + expect resp.http.transfer-encoding == "<undef>" + expect resp.bodylen == 100 + + # 2. Buggy User-Agent + txreq -url "/c1.2" \ + -hdr "Accept-Encoding: gzip" \ + -hdr "User-Agent: Mozilla/4" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "<undef>" + expect resp.http.transfer-encoding == "<undef>" + expect resp.bodylen == 100 + + # 3. HTTP/1.0 request + txreq -url "/c1.3" \ + -proto "HTTP/1.0" \ + -hdr "Accept-Encoding: gzip" \ + -hdr "Connection: keep-alive" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "<undef>" + expect resp.http.transfer-encoding == "<undef>" + expect resp.bodylen == 100 + + # 4. HTTP/1.0 response + txreq -url "/c1.4" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.proto == "HTTP/1.0" + expect resp.http.content-encoding == "<undef>" + expect resp.http.transfer-encoding == "<undef>" + expect resp.bodylen == 100 + + # 5. HEAD method + txreq -req "HEAD" -url "/c1.5" \ + -hdr "Accept-Encoding: gzip" + rxresp -no_obj + expect resp.status == 200 + expect resp.http.content-length == "100" + expect resp.http.content-encoding == "<undef>" + expect resp.http.transfer-encoding == "<undef>" + + # 6. Response status code != 20[0-3] + txreq -url "/c1.6" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 400 + expect resp.http.content-encoding == "<undef>" + expect resp.http.transfer-encoding == "<undef>" + expect resp.bodylen == 100 + + # 7. Response alerady compressed by the server (with "Accept-Encoding") + txreq -url "/c1.7" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "something" + expect resp.http.transfer-encoding == "<undef>" + expect resp.bodylen == 3 + expect resp.body == "FOO" + + # 8. Response with "Cache-Control: no-transform" + txreq -url "/c1.8" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "<undef>" + expect resp.http.transfer-encoding == "<undef>" + expect resp.http.cache-control == "no-transform" + expect resp.bodylen == 100 + + # 9. Response with uncompressable content-type + txreq -url "/c1.9" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "<undef>" + expect resp.http.transfer-encoding == "<undef>" + expect resp.http.content-type == "text/css" + expect resp.bodylen == 100 + + # 10. Response with uncompressable content-type + txreq -url "/c1.10" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "<undef>" + expect resp.http.transfer-encoding == "<undef>" + expect resp.http.content-type == "multipart/mixed; boundary=\"aaa\"" + expect resp.bodylen == 100 +} -run + +# GZIP Compression expected (small body) +client c2 -connect ${h1_fe_gzip_sock} { + # 1. response from the server with a small body with a C-L + txreq -url "/c2.1" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.http.transfer-encoding == "chunked" + gunzip + expect resp.bodylen == 100 + + # 2. response from the server with a small chunked body + txreq -url "/c2.2" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.http.transfer-encoding == "chunked" + gunzip + expect resp.bodylen == 609 +} -run + +# Identity compression expect (Huge body) +# Identity is used because of a limitation of vtest (the uncompressed body size +# must be lower than 10 times of the compressed one) +client c3 -connect ${h1_fe_identity_sock} { + # 1. response from the server with a huge body with a C-L + txreq -url "/c3.1" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "<undef>" + expect resp.http.transfer-encoding == "chunked" + expect resp.bodylen == 50000 + + # 2. response from the server with a huge chunked body + txreq -url "/c3.2" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "<undef>" + expect resp.http.transfer-encoding == "chunked" + expect resp.bodylen == 50000 +} -run + + +# Compression expected with priority +client c4 -connect ${h1_fe_gzip_deflate_sock} { + # 1. response from the server with a small body with a C-L + txreq -url "/c4.1" \ + -hdr "Accept-Encoding: *;q=0, gzip;q=0.750, deflate;q=0.500" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.http.transfer-encoding == "chunked" + + # 2. response from the server with a small body with a C-L + txreq -url "/c4.2" \ + -hdr "Accept-Encoding: *;q=0, gzip;q=0.500, deflate;q=0.750" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "deflate" + expect resp.http.transfer-encoding == "chunked" +} -run diff --git a/reg-tests/compression/common.pem b/reg-tests/compression/common.pem new file mode 120000 index 0000000..a4433d5 --- /dev/null +++ b/reg-tests/compression/common.pem @@ -0,0 +1 @@ +../ssl/common.pem
\ No newline at end of file diff --git a/reg-tests/compression/etags_conversion.vtc b/reg-tests/compression/etags_conversion.vtc new file mode 100644 index 0000000..c5684a2 --- /dev/null +++ b/reg-tests/compression/etags_conversion.vtc @@ -0,0 +1,231 @@ +varnishtest "Compression converts strong ETags to weak ETags" + +#REQUIRE_VERSION=1.9 +#REQUIRE_OPTION=ZLIB|SLZ + +feature ignore_unknown_macro + +server s1 { + rxreq + expect req.url == "/strong" + expect req.http.accept-encoding == "gzip" + txresp \ + -hdr "Content-Type: text/plain" \ + -hdr "ETag: \"123\"" \ + -bodylen 100 + + rxreq + expect req.url == "/weak" + expect req.http.accept-encoding == "gzip" + txresp \ + -hdr "Content-Type: text/plain" \ + -hdr "ETag: W/\"456\"" \ + -bodylen 100 + + rxreq + expect req.url == "/weak-incorrect-quoting" + expect req.http.accept-encoding == "gzip" + txresp \ + -hdr "Content-Type: text/plain" \ + -hdr "ETag: \"W/789\"" \ + -bodylen 100 + + rxreq + expect req.url == "/empty-strong" + expect req.http.accept-encoding == "gzip" + txresp \ + -hdr "Content-Type: text/plain" \ + -hdr "ETag: \"\"" \ + -bodylen 100 + + rxreq + expect req.url == "/empty-weak" + expect req.http.accept-encoding == "gzip" + txresp \ + -hdr "Content-Type: text/plain" \ + -hdr "ETag: W/\"\"" \ + -bodylen 100 + + rxreq + expect req.url == "/invalid1" + expect req.http.accept-encoding == "gzip" + txresp \ + -hdr "Content-Type: text/plain" \ + -hdr "ETag: \"invalid" \ + -bodylen 100 + + rxreq + expect req.url == "/invalid2" + expect req.http.accept-encoding == "gzip" + txresp \ + -hdr "Content-Type: text/plain" \ + -hdr "ETag: invalid\"" \ + -bodylen 100 + + rxreq + expect req.url == "/invalid3" + expect req.http.accept-encoding == "gzip" + txresp \ + -hdr "Content-Type: text/plain" \ + -hdr "ETag: invalid" \ + -bodylen 100 + + rxreq + expect req.url == "/invalid4" + expect req.http.accept-encoding == "gzip" + txresp \ + -hdr "Content-Type: text/plain" \ + -hdr "ETag: W/\"invalid" \ + -bodylen 100 + + rxreq + expect req.url == "/invalid5" + expect req.http.accept-encoding == "gzip" + txresp \ + -hdr "Content-Type: text/plain" \ + -hdr "ETag: W/invalid\"" \ + -bodylen 100 + + rxreq + expect req.url == "/invalid6" + expect req.http.accept-encoding == "gzip" + txresp \ + -hdr "Content-Type: text/plain" \ + -hdr "ETag: W/invalid" \ + -bodylen 100 + + rxreq + expect req.url == "/multiple" + expect req.http.accept-encoding == "gzip" + txresp \ + -hdr "Content-Type: text/plain" \ + -hdr "ETag: \"one\"" \ + -hdr "ETag: \"two\"" \ + -bodylen 100 +} -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 + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe-gzip + bind "fd@${fe_gzip}" + default_backend be-gzip + + backend be-gzip + compression algo gzip + compression type text/html text/plain + server www ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe_gzip_sock} { + txreq -url "/strong" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.http.etag == "W/\"123\"" + gunzip + expect resp.bodylen == 100 + + txreq -url "/weak" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.http.etag == "W/\"456\"" + gunzip + expect resp.bodylen == 100 + + txreq -url "/weak-incorrect-quoting" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.http.etag == "W/\"W/789\"" + gunzip + expect resp.bodylen == 100 + + txreq -url "/empty-strong" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.http.etag == "W/\"\"" + gunzip + expect resp.bodylen == 100 + + txreq -url "/empty-weak" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.http.etag == "W/\"\"" + gunzip + expect resp.bodylen == 100 + + txreq -url "/invalid1" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "<undef>" + expect resp.http.etag == "\"invalid" + expect resp.bodylen == 100 + + txreq -url "/invalid2" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "<undef>" + expect resp.http.etag == "invalid\"" + expect resp.bodylen == 100 + + txreq -url "/invalid3" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "<undef>" + expect resp.http.etag == "invalid" + expect resp.bodylen == 100 + + txreq -url "/invalid4" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "<undef>" + expect resp.http.etag == "W/\"invalid" + expect resp.bodylen == 100 + + txreq -url "/invalid5" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "<undef>" + expect resp.http.etag == "W/invalid\"" + expect resp.bodylen == 100 + + txreq -url "/invalid6" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "<undef>" + expect resp.http.etag == "W/invalid" + expect resp.bodylen == 100 + + txreq -url "/multiple" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "<undef>" + expect resp.bodylen == 100 +} -run diff --git a/reg-tests/compression/lua_validation.lua b/reg-tests/compression/lua_validation.lua new file mode 100644 index 0000000..2cc874b --- /dev/null +++ b/reg-tests/compression/lua_validation.lua @@ -0,0 +1,19 @@ + +local data = "abcdefghijklmnopqrstuvwxyz" +local responseblob = "" +for i = 1,10000 do + responseblob = responseblob .. "\r\n" .. i .. data:sub(1, math.floor(i % 27)) +end + +http01applet = function(applet) + local response = responseblob + applet:set_status(200) + applet:add_header("Content-Type", "application/javascript") + applet:add_header("Content-Length", string.len(response)*10) + applet:start_response() + for i = 1,10 do + applet:send(response) + end +end + +core.register_service("fileloader-http01", "http", http01applet) diff --git a/reg-tests/compression/lua_validation.vtc b/reg-tests/compression/lua_validation.vtc new file mode 100644 index 0000000..b10cbd9 --- /dev/null +++ b/reg-tests/compression/lua_validation.vtc @@ -0,0 +1,59 @@ +# Checks that compression doesn't cause corruption.. + +varnishtest "Compression validation" +#REQUIRE_OPTIONS=ZLIB|SLZ,LUA,OPENSSL +#REGTEST_TYPE=slow + +feature ignore_unknown_macro + +haproxy h1 -conf { +global +# log stdout format short daemon + lua-load ${testdir}/lua_validation.lua + +defaults + mode http + log global + option httplog + +frontend main-https + bind "fd@${fe1}" ssl crt ${testdir}/common.pem + compression algo gzip + compression type text/html text/plain application/json application/javascript + compression offload + use_backend TestBack if TRUE + +backend TestBack + server LocalSrv ${h1_fe2_addr}:${h1_fe2_port} + +listen fileloader + mode http + bind "fd@${fe2}" + http-request use-service lua.fileloader-http01 +} -start + +shell { + HOST=${h1_fe1_addr} + if [ "${h1_fe1_addr}" = "::1" ] ; then + HOST="\[::1\]" + fi + + md5=$(command -v md5 || command -v md5sum) + + if [ -z $md5 ] ; then + echo "MD5 checksum utility not found" + exit 1 + fi + + expectchecksum="4d9c62aa5370b8d5f84f17ec2e78f483" + + for opt in "" "--limit-rate 300K" "--limit-rate 500K" ; do + checksum=$(curl --max-time 15 --compressed -k "https://$HOST:${h1_fe1_port}" $opt | $md5 | cut -d ' ' -f1) + if [ "$checksum" != "$expectchecksum" ] ; then + echo "Expecting checksum $expectchecksum" + echo "Received checksum: $checksum" + exit 1; + fi + done + +} -run diff --git a/reg-tests/compression/vary.vtc b/reg-tests/compression/vary.vtc new file mode 100644 index 0000000..8219c73 --- /dev/null +++ b/reg-tests/compression/vary.vtc @@ -0,0 +1,192 @@ +varnishtest "Compression sets Vary header" + +#REQUIRE_VERSION=1.9 +#REQUIRE_OPTION=ZLIB|SLZ + +feature ignore_unknown_macro + +server s1 { + rxreq + expect req.url == "/plain/accept-encoding-gzip" + expect req.http.accept-encoding == "gzip" + txresp \ + -hdr "Content-Type: text/plain" \ + -bodylen 100 + + rxreq + expect req.url == "/plain/accept-encoding-invalid" + expect req.http.accept-encoding == "invalid" + txresp \ + -hdr "Content-Type: text/plain" \ + -bodylen 100 + + rxreq + expect req.url == "/plain/accept-encoding-null" + expect req.http.accept-encoding == "<undef>" + txresp \ + -hdr "Content-Type: text/plain" \ + -bodylen 100 + + rxreq + expect req.url == "/html/accept-encoding-gzip" + expect req.http.accept-encoding == "gzip" + txresp \ + -hdr "Content-Type: text/html" \ + -bodylen 100 + + rxreq + expect req.url == "/html/accept-encoding-invalid" + expect req.http.accept-encoding == "invalid" + txresp \ + -hdr "Content-Type: text/html" \ + -bodylen 100 + + + rxreq + expect req.url == "/html/accept-encoding-null" + expect req.http.accept-encoding == "<undef>" + txresp \ + -hdr "Content-Type: text/html" \ + -bodylen 100 + + rxreq + expect req.url == "/dup-etag/accept-encoding-gzip" + expect req.http.accept-encoding == "gzip" + txresp \ + -hdr "Content-Type: text/plain" \ + -hdr "ETag: \"123\"" \ + -hdr "ETag: \"123\"" \ + -bodylen 100 +} -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 + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe-gzip + bind "fd@${fe_gzip}" + default_backend be-gzip + + backend be-gzip + compression algo gzip + compression type text/plain + server www ${s1_addr}:${s1_port} + + frontend fe-nothing + bind "fd@${fe_nothing}" + default_backend be-nothing + + backend be-nothing + server www ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe_gzip_sock} { + txreq -url "/plain/accept-encoding-gzip" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.http.vary == "Accept-Encoding" + gunzip + expect resp.bodylen == 100 + + txreq -url "/plain/accept-encoding-invalid" \ + -hdr "Accept-Encoding: invalid" + rxresp + expect resp.status == 200 + expect resp.http.vary == "<undef>" + expect resp.bodylen == 100 + + txreq -url "/plain/accept-encoding-null" + rxresp + expect resp.status == 200 + expect resp.http.vary == "<undef>" + expect resp.bodylen == 100 + + txreq -url "/html/accept-encoding-gzip" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.vary == "<undef>" + expect resp.bodylen == 100 + + txreq -url "/html/accept-encoding-invalid" \ + -hdr "Accept-Encoding: invalid" + rxresp + expect resp.status == 200 + expect resp.http.vary == "<undef>" + expect resp.bodylen == 100 + + txreq -url "/html/accept-encoding-null" + rxresp + expect resp.status == 200 + expect resp.http.vary == "<undef>" + expect resp.bodylen == 100 + + txreq -url "/dup-etag/accept-encoding-gzip" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.vary == "<undef>" + expect resp.bodylen == 100 +} -run + +# This Client duplicates c1, against the "nothing" frontend, ensuring no Vary header is ever set. +client c2 -connect ${h1_fe_nothing_sock} { + txreq -url "/plain/accept-encoding-gzip" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.vary == "<undef>" + expect resp.bodylen == 100 + + txreq -url "/plain/accept-encoding-invalid" \ + -hdr "Accept-Encoding: invalid" + rxresp + expect resp.status == 200 + expect resp.http.vary == "<undef>" + expect resp.bodylen == 100 + + txreq -url "/plain/accept-encoding-null" + rxresp + expect resp.status == 200 + expect resp.http.vary == "<undef>" + expect resp.bodylen == 100 + + txreq -url "/html/accept-encoding-gzip" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.vary == "<undef>" + expect resp.bodylen == 100 + + txreq -url "/html/accept-encoding-invalid" \ + -hdr "Accept-Encoding: invalid" + rxresp + expect resp.status == 200 + expect resp.http.vary == "<undef>" + expect resp.bodylen == 100 + + txreq -url "/html/accept-encoding-null" + rxresp + expect resp.status == 200 + expect resp.http.vary == "<undef>" + expect resp.bodylen == 100 + + txreq -url "/dup-etag/accept-encoding-gzip" \ + -hdr "Accept-Encoding: gzip" + rxresp + expect resp.status == 200 + expect resp.http.vary == "<undef>" + expect resp.bodylen == 100 +} -run diff --git a/reg-tests/connection/cli_src_dst.vtc b/reg-tests/connection/cli_src_dst.vtc new file mode 100644 index 0000000..6809d39 --- /dev/null +++ b/reg-tests/connection/cli_src_dst.vtc @@ -0,0 +1,290 @@ +varnishtest "Test multi-level client source and destination addresses" + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe1}" + tcp-request connection set-src ipv4(10.0.0.1) + tcp-request connection set-dst ipv4(10.0.0.2) + + tcp-request session set-var(sess.sess_fc_src) fc_src + tcp-request session set-var(sess.sess_fc_dst) fc_dst + tcp-request session set-var(sess.sess_src) src + tcp-request session set-var(sess.sess_dst) dst + + tcp-request inspect-delay 100ms + tcp-request content set-var(txn.strm_fc_src) fc_src + tcp-request content set-var(txn.strm_fc_dst) fc_dst + tcp-request content set-var(txn.strm_src) src + tcp-request content set-var(txn.strm_dst) dst + + http-after-response set-header sess-fc-src %[var(sess.sess_fc_src)] + http-after-response set-header sess-src %[var(sess.sess_src)] + http-after-response set-header sess-fc-dst %[var(sess.sess_fc_dst)] + http-after-response set-header sess-dst %[var(sess.sess_dst)] + http-after-response set-header strm-fc-src %[var(txn.strm_fc_src)] + http-after-response set-header strm-src %[var(txn.strm_src)] + http-after-response set-header strm-fc-dst %[var(txn.strm_fc_dst)] + http-after-response set-header strm-dst %[var(txn.strm_dst)] + + default_backend be + + frontend fe2 + bind "fd@${fe2}" + tcp-request connection set-src ipv4(10.0.0.1) + tcp-request connection set-dst ipv4(10.0.0.2) + + tcp-request session set-src ipv4(10.1.0.1) + tcp-request session set-dst ipv4(10.1.0.2) + tcp-request session set-var(sess.sess_fc_src) fc_src + tcp-request session set-var(sess.sess_fc_dst) fc_dst + tcp-request session set-var(sess.sess_src) src + tcp-request session set-var(sess.sess_dst) dst + + tcp-request inspect-delay 100ms + tcp-request content set-var(txn.strm_fc_src) fc_src + tcp-request content set-var(txn.strm_fc_dst) fc_dst + tcp-request content set-var(txn.strm_src) src + tcp-request content set-var(txn.strm_dst) dst + + http-after-response set-header sess-fc-src %[var(sess.sess_fc_src)] + http-after-response set-header sess-src %[var(sess.sess_src)] + http-after-response set-header sess-fc-dst %[var(sess.sess_fc_dst)] + http-after-response set-header sess-dst %[var(sess.sess_dst)] + http-after-response set-header strm-fc-src %[var(txn.strm_fc_src)] + http-after-response set-header strm-src %[var(txn.strm_src)] + http-after-response set-header strm-fc-dst %[var(txn.strm_fc_dst)] + http-after-response set-header strm-dst %[var(txn.strm_dst)] + + default_backend be + + frontend fe3 + bind "fd@${fe3}" + tcp-request connection set-src ipv4(10.0.0.1) + tcp-request connection set-dst ipv4(10.0.0.2) + + tcp-request session set-src ipv4(10.1.0.1) + tcp-request session set-dst ipv4(10.1.0.2) + tcp-request session set-var(sess.sess_fc_src) fc_src + tcp-request session set-var(sess.sess_fc_dst) fc_dst + tcp-request session set-var(sess.sess_src) src + tcp-request session set-var(sess.sess_dst) dst + + tcp-request inspect-delay 100ms + tcp-request content set-src ipv4(10.2.0.1) + tcp-request content set-dst ipv4(10.2.0.2) + tcp-request content set-var(txn.strm_fc_src) fc_src + tcp-request content set-var(txn.strm_fc_dst) fc_dst + tcp-request content set-var(txn.strm_src) src + tcp-request content set-var(txn.strm_dst) dst + + http-after-response set-header sess-fc-src %[var(sess.sess_fc_src)] + http-after-response set-header sess-src %[var(sess.sess_src)] + http-after-response set-header sess-fc-dst %[var(sess.sess_fc_dst)] + http-after-response set-header sess-dst %[var(sess.sess_dst)] + http-after-response set-header strm-fc-src %[var(txn.strm_fc_src)] + http-after-response set-header strm-src %[var(txn.strm_src)] + http-after-response set-header strm-fc-dst %[var(txn.strm_fc_dst)] + http-after-response set-header strm-dst %[var(txn.strm_dst)] + + + frontend fe4 + bind "fd@${fe4}" + + tcp-request connection set-src ipv4(10.0.0.1) + tcp-request connection set-dst ipv4(10.0.0.2) + + tcp-request session set-var(sess.sess_fc_src) fc_src + tcp-request session set-var(sess.sess_fc_dst) fc_dst + tcp-request session set-var(sess.sess_src) src + tcp-request session set-var(sess.sess_dst) dst + + http-request set-src hdr(x-forwarded-for) + http-request set-dst hdr(x-original-to) + http-request set-var(txn.strm_fc_src) fc_src + http-request set-var(txn.strm_fc_dst) fc_dst + http-request set-var(txn.strm_src) src + http-request set-var(txn.strm_dst) dst + + http-after-response set-header sess-fc-src %[var(sess.sess_fc_src)] + http-after-response set-header sess-src %[var(sess.sess_src)] + http-after-response set-header sess-fc-dst %[var(sess.sess_fc_dst)] + http-after-response set-header sess-dst %[var(sess.sess_dst)] + http-after-response set-header strm-fc-src %[var(txn.strm_fc_src)] + http-after-response set-header strm-src %[var(txn.strm_src)] + http-after-response set-header strm-fc-dst %[var(txn.strm_fc_dst)] + http-after-response set-header strm-dst %[var(txn.strm_dst)] + + default_backend be + + backend be + http-request return status 200 + + listen li1 + bind "fd@${li1}" + + tcp-request connection set-src ipv4(10.0.0.1) + tcp-request connection set-dst ipv4(10.0.0.2) + + http-request set-src ipv4(192.168.0.1) + http-request set-dst ipv4(192.168.0.2) + + http-after-response set-header li1-fc-src %[fc_src] + http-after-response set-header li1-src %[src] + http-after-response set-header li1-fc-dst %[fc_dst] + http-after-response set-header li1-dst %[dst] + + + server srv ${h1_li3_addr}:${h1_li3_port} send-proxy + + listen li2 + bind "fd@${li2}" + + tcp-request connection set-src ipv4(10.0.0.1) + tcp-request connection set-dst ipv4(10.0.0.2) + + http-request set-src ipv4(192.168.0.1) + http-request set-dst ipv4(192.168.0.2) + + http-after-response set-header li2-fc-src %[fc_src] + http-after-response set-header li2-src %[src] + http-after-response set-header li2-fc-dst %[fc_dst] + http-after-response set-header li2-dst %[dst] + + server srv ${h1_li3_addr}:${h1_li3_port} send-proxy-v2 + + listen li3 + bind "fd@${li3}" accept-proxy + + tcp-request connection set-src ipv4(10.1.0.1) + tcp-request connection set-dst ipv4(10.1.0.2) + + http-after-response set-header li3-fc-src %[fc_src] + http-after-response set-header li3-src %[src] + http-after-response set-header li3-fc-dst %[fc_dst] + http-after-response set-header li3-dst %[dst] + + http-request return status 200 + +} -start + + +client c1 -connect ${h1_fe1_sock} { + txreq + rxresp + expect resp.http.sess-fc-src == 10.0.0.1 + expect resp.http.sess-src == 10.0.0.1 + expect resp.http.strm-fc-src == 10.0.0.1 + expect resp.http.strm-src == 10.0.0.1 + + expect resp.http.sess-fc-dst == 10.0.0.2 + expect resp.http.sess-dst == 10.0.0.2 + expect resp.http.strm-fc-dst == 10.0.0.2 + expect resp.http.strm-dst == 10.0.0.2 +} -run + +client c2 -connect ${h1_fe2_sock} { + txreq + rxresp + expect resp.http.sess-fc-src == 10.0.0.1 + expect resp.http.sess-src == 10.1.0.1 + expect resp.http.strm-fc-src == 10.0.0.1 + expect resp.http.strm-src == 10.1.0.1 + + expect resp.http.sess-fc-dst == 10.0.0.2 + expect resp.http.sess-dst == 10.1.0.2 + expect resp.http.strm-fc-dst == 10.0.0.2 + expect resp.http.strm-dst == 10.1.0.2 +} -run + +client c3 -connect ${h1_fe3_sock} { + txreq + rxresp + expect resp.http.sess-fc-src == 10.0.0.1 + expect resp.http.sess-src == 10.1.0.1 + expect resp.http.strm-fc-src == 10.0.0.1 + expect resp.http.strm-src == 10.2.0.1 + + expect resp.http.sess-fc-dst == 10.0.0.2 + expect resp.http.sess-dst == 10.1.0.2 + expect resp.http.strm-fc-dst == 10.0.0.2 + expect resp.http.strm-dst == 10.2.0.2 +} -run + +client c4 -connect ${h1_fe4_sock} { + txreq \ + -hdr "x-forwarded-for: 192.168.0.1" \ + -hdr "x-original-to: 192.168.0.2" + rxresp + expect resp.http.sess-fc-src == 10.0.0.1 + expect resp.http.sess-src == 10.0.0.1 + expect resp.http.strm-fc-src == 10.0.0.1 + expect resp.http.strm-src == 192.168.0.1 + + expect resp.http.sess-fc-dst == 10.0.0.2 + expect resp.http.sess-dst == 10.0.0.2 + expect resp.http.strm-fc-dst == 10.0.0.2 + expect resp.http.strm-dst == 192.168.0.2 + + txreq \ + -hdr "x-forwarded-for: 192.168.1.1" \ + -hdr "x-original-to: 192.168.1.2" + rxresp + expect resp.http.sess-fc-src == 10.0.0.1 + expect resp.http.sess-src == 10.0.0.1 + expect resp.http.strm-fc-src == 10.0.0.1 + expect resp.http.strm-src == 192.168.1.1 + + expect resp.http.sess-fc-dst == 10.0.0.2 + expect resp.http.sess-dst == 10.0.0.2 + expect resp.http.strm-fc-dst == 10.0.0.2 + expect resp.http.strm-dst == 192.168.1.2 + + txreq + rxresp + expect resp.http.sess-fc-src == 10.0.0.1 + expect resp.http.sess-src == 10.0.0.1 + expect resp.http.strm-fc-src == 10.0.0.1 + expect resp.http.strm-src == 10.0.0.1 + + expect resp.http.sess-fc-dst == 10.0.0.2 + expect resp.http.sess-dst == 10.0.0.2 + expect resp.http.strm-fc-dst == 10.0.0.2 + expect resp.http.strm-dst == 10.0.0.2 +} -run + +client c5 -connect ${h1_li1_sock} { + txreq + rxresp + expect resp.http.li1-fc-src == 10.0.0.1 + expect resp.http.li1-src == 192.168.0.1 + expect resp.http.li1-fc-dst == 10.0.0.2 + expect resp.http.li1-dst == 192.168.0.2 + + expect resp.http.li3-fc-src == 10.1.0.1 + expect resp.http.li3-src == 192.168.0.1 + expect resp.http.li3-fc-dst == 10.1.0.2 + expect resp.http.li3-dst == 192.168.0.2 +} -run + +client c6 -connect ${h1_li2_sock} { + txreq + rxresp + expect resp.http.li2-fc-src == 10.0.0.1 + expect resp.http.li2-src == 192.168.0.1 + expect resp.http.li2-fc-dst == 10.0.0.2 + expect resp.http.li2-dst == 192.168.0.2 + + expect resp.http.li3-fc-src == 10.1.0.1 + expect resp.http.li3-src == 192.168.0.1 + expect resp.http.li3-fc-dst == 10.1.0.2 + expect resp.http.li3-dst == 192.168.0.2 +} -run diff --git a/reg-tests/connection/common.pem b/reg-tests/connection/common.pem new file mode 120000 index 0000000..a4433d5 --- /dev/null +++ b/reg-tests/connection/common.pem @@ -0,0 +1 @@ +../ssl/common.pem
\ No newline at end of file diff --git a/reg-tests/connection/dispatch.vtc b/reg-tests/connection/dispatch.vtc new file mode 100644 index 0000000..8696b50 --- /dev/null +++ b/reg-tests/connection/dispatch.vtc @@ -0,0 +1,42 @@ +varnishtest "Validate proper operation of the 'dispatch' mode" +feature ignore_unknown_macro + +server s1 { + rxreq + txresp +} -start + +server s2 { + rxreq + txresp +} -start + +haproxy h1 -conf { +defaults + log global + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + +listen fe_tcp + bind "fd@${fe_tcp}" + mode tcp + dispatch ${s1_addr}:${s1_port} + +listen fe_http + bind "fd@${fe_http}" + mode http + dispatch ${s2_addr}:${s2_port} +} -start + +client c1 -connect ${h1_fe_tcp_sock} { + txreq -url "/" + rxresp + expect resp.status == 200 +} -run + +client c2 -connect ${h1_fe_http_sock} { + txreq -url "/" + rxresp + expect resp.status == 200 +} -run diff --git a/reg-tests/connection/http_reuse_aggressive.vtc b/reg-tests/connection/http_reuse_aggressive.vtc new file mode 100644 index 0000000..71f4cee --- /dev/null +++ b/reg-tests/connection/http_reuse_aggressive.vtc @@ -0,0 +1,45 @@ +varnishtest "Test the http-reuse aggressive mode" + +#REQUIRE_VERSION=2.2 + +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + + listen sender + bind "fd@${feS}" + http-reuse aggressive + server srv ${h1_feR_addr}:${h1_feR_port} + + listen receiver + bind "fd@${feR}" + http-request return status 200 + http-after-response set-header http_first_request %[http_first_req] +} -start + +# bootstrap +client c1 -connect ${h1_feS_sock} { + txreq + rxresp + expect resp.http.http_first_request == "1" +} -run + +# first request should not be reused as no safe connection for the moment +client c2 -connect ${h1_feS_sock} { + txreq + rxresp + expect resp.http.http_first_request == "1" + + txreq + rxresp + expect resp.http.http_first_request == "0" +} -run + +# first request must be reused with the safe connection +client c3 -connect ${h1_feS_sock} { + txreq + rxresp + expect resp.http.http_first_request == "0" +} -run diff --git a/reg-tests/connection/http_reuse_always.vtc b/reg-tests/connection/http_reuse_always.vtc new file mode 100644 index 0000000..136fe4e --- /dev/null +++ b/reg-tests/connection/http_reuse_always.vtc @@ -0,0 +1,43 @@ +varnishtest "Test the http-reuse always mode" + +#REQUIRE_VERSION=2.2 + +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + + listen sender + bind "fd@${feS}" + http-reuse always + server srv ${h1_feR_addr}:${h1_feR_port} + + listen receiver + bind "fd@${feR}" + http-request return status 200 + http-after-response set-header http_first_request %[http_first_req] +} -start + +# bootstrap +client c1 -connect ${h1_feS_sock} { + txreq + rxresp + expect resp.http.http_first_request == "1" +} -run + +client c2 -connect ${h1_feS_sock} { + txreq + rxresp + expect resp.http.http_first_request == "0" + + txreq + rxresp + expect resp.http.http_first_request == "0" +} -run + +client c3 -connect ${h1_feS_sock} { + txreq + rxresp + expect resp.http.http_first_request == "0" +} -run diff --git a/reg-tests/connection/http_reuse_be_transparent.vtc b/reg-tests/connection/http_reuse_be_transparent.vtc new file mode 100644 index 0000000..1cadb35 --- /dev/null +++ b/reg-tests/connection/http_reuse_be_transparent.vtc @@ -0,0 +1,81 @@ +varnishtest "Test the proper interaction between http-reuse and backend in transparent mode" + +# If backend is used with the transparent mode, the connection are considered +# as private and should only be reused for requests of the same session. +# This is similar to the http-reuse never mode + +#REQUIRE_VERSION=2.4 + +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + + listen sender + bind "fd@${feS}" + http-request set-header client-id %[req.hdr(client-id)] if { req.hdr(client-id) -m found } + option transparent + http-request set-dst-port int(${h1_feR_port}) + + listen receiver + bind "fd@${feR}" + http-request set-var(sess.client_id) req.hdr(client-id) + http-request return status 200 + http-after-response set-header http_first_request %[http_first_req] + http-after-response set-header client-id %[var(sess.client_id)] +} -start + +client c1 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c1" + rxresp + expect resp.http.http_first_request == "1" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" +} -run + +client c2 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c2" + rxresp + expect resp.http.http_first_request == "1" + expect resp.http.client-id == "c2" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c2" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c2" +} -run + +client c3 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c3" + rxresp + expect resp.http.http_first_request == "1" + expect resp.http.client-id == "c3" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c3" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c3" +} -run + diff --git a/reg-tests/connection/http_reuse_conn_hash.vtc b/reg-tests/connection/http_reuse_conn_hash.vtc new file mode 100644 index 0000000..991e86f --- /dev/null +++ b/reg-tests/connection/http_reuse_conn_hash.vtc @@ -0,0 +1,163 @@ +varnishtest "Test the http-reuse with special connection parameters" +#REQUIRE_VERSION=2.4 +#REQUIRE_OPTIONS=OPENSSL + +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + + # sni + listen sender-sni + bind "fd@${feS_sni}" + server srv2 ${h1_feR_ssl_addr}:${h1_feR_ssl_port} ssl sni "req.hdr(x-sni)" verify none pool-low-conn 2 + + # set-dst + # specify dst1_addr for server, which should be identical to dst2_addr + # port is specified by the client in header x-dst-port + listen sender-set-dst + bind "fd@${feS_dst}" + http-request set-dst-port hdr(x-dst-port) + server srv2 ${h1_feR_dst1_addr}:0 pool-low-conn 2 + + # proxy protocol + # must use reuse always as consecutive requests are from different client + listen sender-proxy + bind "fd@${feS_proxy}" accept-proxy + http-reuse always + server srv2 ${h1_feR_proxy_addr}:${h1_feR_proxy_port} send-proxy pool-low-conn 2 + + listen receiver + bind "fd@${feR_ssl}" ssl crt ${testdir}/common.pem + bind "fd@${feR_proxy}" accept-proxy + http-request return status 200 + http-after-response set-header http_first_request %[http_first_req] + + listen receiver-dst1 + bind "fd@${feR_dst1}" + http-request return status 200 hdr "x-dst" "dst1" + http-after-response set-header http_first_request %[http_first_req] + + listen receiver-dst2 + bind "fd@${feR_dst2}" + http-request return status 200 hdr "x-dst" "dst2" + http-after-response set-header http_first_request %[http_first_req] +} -start + +# http-reuse with sni parameters +client c_sni -connect ${h1_feS_sni_sock} { + # first request + txreq \ + -hdr "x-sni: www.custom.com" + rxresp + expect resp.http.http_first_request == "1" + + # second request with same sni, connection must be reused + txreq \ + -hdr "x-sni: www.custom.com" + rxresp + expect resp.http.http_first_request == "0" + + # third request with a different sni, a new connection must be used + txreq \ + -hdr "x-sni: www.custom2.com" + rxresp + expect resp.http.http_first_request == "1" + + # fourth request, reuse sni2 + txreq \ + -hdr "x-sni: www.custom2.com" + rxresp + expect resp.http.http_first_request == "0" +} -run + +# http-reuse with destination address +client c_dst1 -connect ${h1_feS_dst_sock} { + txreq \ + -hdr "x-dst-port: ${h1_feR_dst1_port}" + rxresp + expect resp.status == 200 + expect resp.http.x-dst == "dst1" + expect resp.http.http_first_request == "1" + + txreq \ + -hdr "x-dst-port: ${h1_feR_dst1_port}" + rxresp + expect resp.status == 200 + expect resp.http.x-dst == "dst1" + expect resp.http.http_first_request == "0" + + txreq \ + -hdr "x-dst-port: ${h1_feR_dst2_port}" + rxresp + expect resp.status == 200 + expect resp.http.x-dst == "dst2" + expect resp.http.http_first_request == "1" + + txreq \ + -hdr "x-dst-port: ${h1_feR_dst1_port}" + rxresp + expect resp.status == 200 + expect resp.http.x-dst == "dst1" + expect resp.http.http_first_request == "0" + + txreq \ + -hdr "x-dst-port: ${h1_feR_dst2_port}" + rxresp + expect resp.status == 200 + expect resp.http.x-dst == "dst2" + expect resp.http.http_first_request == "0" +} -run + +## first request with proxy protocol +client c_proxy -connect ${h1_feS_proxy_sock} -proxy1 "127.0.0.1:40000 ${h1_feS_proxy_addr}:${h1_feS_proxy_port}" { + txreq + rxresp + expect resp.status == 200 + expect resp.http.http_first_request == "1" + + txreq + rxresp + expect resp.status == 200 + expect resp.http.http_first_request == "0" +} -run + +## second request with different proxy protocol +# this have the nice effect to fill the server pool to 2 connection +# (pool-low-conn value) to allow takeover on multi thread run +client c_proxy -connect ${h1_feS_proxy_sock} -proxy1 "127.0.0.1:50000 ${h1_feS_proxy_addr}:${h1_feS_proxy_port}" { + txreq + rxresp + expect resp.status == 200 + expect resp.http.http_first_request == "1" +} -run + +## third request, reuse same proxy protocol entry +client c_proxy -connect ${h1_feS_proxy_sock} -proxy1 "127.0.0.1:40000 ${h1_feS_proxy_addr}:${h1_feS_proxy_port}" { + txreq + rxresp + expect resp.status == 200 + expect resp.http.http_first_request == "0" +} -run + +## fourth request with different proxy protocol entry, no reuse +client c_proxy -connect ${h1_feS_proxy_sock} -proxy1 "127.0.0.1:60000 ${h1_feS_proxy_addr}:${h1_feS_proxy_port}" { + txreq + rxresp + expect resp.status == 200 + expect resp.http.http_first_request == "1" +} -run + +## fifth request, reuse proxy protocol +client c_proxy -connect ${h1_feS_proxy_sock} -proxy1 "127.0.0.1:50000 ${h1_feS_proxy_addr}:${h1_feS_proxy_port}" { + txreq + rxresp + expect resp.status == 200 + expect resp.http.http_first_request == "0" + + txreq + rxresp + expect resp.status == 200 + expect resp.http.http_first_request == "0" +} -run diff --git a/reg-tests/connection/http_reuse_dispatch.vtc b/reg-tests/connection/http_reuse_dispatch.vtc new file mode 100644 index 0000000..a419727 --- /dev/null +++ b/reg-tests/connection/http_reuse_dispatch.vtc @@ -0,0 +1,79 @@ +varnishtest "Test the proper interaction between http-reuse and dispatch mode" + +# With dispatch, the connection are considered as private and should only be +# reused for requests of the same session +# This is similar to the http-reuse never mode + +#REQUIRE_VERSION=2.4 + +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + + listen sender + bind "fd@${feS}" + http-request set-header client-id %[req.hdr(client-id)] if { req.hdr(client-id) -m found } + dispatch ${h1_feR_addr}:${h1_feR_port} + + listen receiver + bind "fd@${feR}" + http-request set-var(sess.client_id) req.hdr(client-id) + http-request return status 200 + http-after-response set-header http_first_request %[http_first_req] + http-after-response set-header client-id %[var(sess.client_id)] +} -start + +client c1 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c1" + rxresp + expect resp.http.http_first_request == "1" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" +} -run + +client c2 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c2" + rxresp + expect resp.http.http_first_request == "1" + expect resp.http.client-id == "c2" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c2" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c2" +} -run + +client c3 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c3" + rxresp + expect resp.http.http_first_request == "1" + expect resp.http.client-id == "c3" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c3" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c3" +} -run diff --git a/reg-tests/connection/http_reuse_never.vtc b/reg-tests/connection/http_reuse_never.vtc new file mode 100644 index 0000000..fc74631 --- /dev/null +++ b/reg-tests/connection/http_reuse_never.vtc @@ -0,0 +1,79 @@ +varnishtest "Test the http-reuse never mode" + +#REQUIRE_VERSION=2.2 + +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + + # limit idle pool to one connection + # this is to mirror http-reuse safe test, but in this case to ensure that + # connection are never reused as expected + listen sender + bind "fd@${feS}" + http-reuse never + http-request set-header client-id %[req.hdr(client-id)] if { req.hdr(client-id) -m found } + server srv ${h1_feR_addr}:${h1_feR_port} pool-max-conn 1 + + listen receiver + bind "fd@${feR}" + http-request set-var(sess.client_id) req.hdr(client-id) + http-request return status 200 + http-after-response set-header http_first_request %[http_first_req] + http-after-response set-header client-id %[var(sess.client_id)] +} -start + +client c1 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c1" + rxresp + expect resp.http.http_first_request == "1" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" +} -run + +client c2 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c2" + rxresp + expect resp.http.http_first_request == "1" + expect resp.http.client-id == "c2" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c2" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c2" +} -run + +client c3 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c3" + rxresp + expect resp.http.http_first_request == "1" + expect resp.http.client-id == "c3" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c3" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c3" +} -run diff --git a/reg-tests/connection/http_reuse_safe.vtc b/reg-tests/connection/http_reuse_safe.vtc new file mode 100644 index 0000000..fa00dd4 --- /dev/null +++ b/reg-tests/connection/http_reuse_safe.vtc @@ -0,0 +1,78 @@ +varnishtest "Test the http-reuse safe mode" + +#REQUIRE_VERSION=2.2 + +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + + # limit idle pool to one connection + # this forces connection reuse for the transaction after the first one + listen sender + bind "fd@${feS}" + http-reuse safe + http-request set-header client-id %[req.hdr(client-id)] if { req.hdr(client-id) -m found } + server srv ${h1_feR_addr}:${h1_feR_port} pool-max-conn 1 + + listen receiver + bind "fd@${feR}" + http-request set-var(sess.client_id) req.hdr(client-id) + http-request return status 200 + http-after-response set-header http_first_request %[http_first_req] + http-after-response set-header client-id %[var(sess.client_id)] +} -start + +client c1 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c1" + rxresp + expect resp.http.http_first_request == "1" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" +} -run + +client c2 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c2" + rxresp + expect resp.http.http_first_request == "1" + expect resp.http.client-id == "c2" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" +} -run + +client c3 -connect ${h1_feS_sock} { + txreq \ + -hdr "client-id: c3" + rxresp + expect resp.http.http_first_request == "1" + expect resp.http.client-id == "c3" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" + + txreq + rxresp + expect resp.http.http_first_request == "0" + expect resp.http.client-id == "c1" +} -run diff --git a/reg-tests/connection/proxy_protocol_random_fail.vtc b/reg-tests/connection/proxy_protocol_random_fail.vtc new file mode 100644 index 0000000..bcaa03c --- /dev/null +++ b/reg-tests/connection/proxy_protocol_random_fail.vtc @@ -0,0 +1,60 @@ +#commit b406b87 +# BUG/MEDIUM: connection: don't store recv() result into trash.data +# +# Cyril Bonté discovered that the proxy protocol randomly fails since +# commit 843b7cb ("MEDIUM: chunks: make the chunk struct's fields match +# the buffer struct"). This is because we used to store recv()'s return +# code into trash.data which is now unsigned, so it never compares as +# negative against 0. Let's clean this up and test the result itself +# without storing it first. + +varnishtest "PROXY protocol random failures" +#REQUIRE_OPTIONS=OPENSSL + +feature ignore_unknown_macro + +#REGTEST_TYPE=broken + +syslog Slog_1 -repeat 8 -level info { + recv + expect ~ "Connect from .* to ${h1_ssl_addr}:${h1_ssl_port}" + recv + expect ~ "ssl-offload-http/http .* \"POST (https://.*:${h1_ssl_port})?/[1-8] HTTP/(2\\.0|1\\.1)\"" +} -start + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + stats bind-process 1 + log ${Slog_1_addr}:${Slog_1_port} len 2048 local0 debug err + + defaults + mode http + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + log global + + listen http + bind unix@"${tmpdir}/http.socket" accept-proxy name ssl-offload-http + option forwardfor + + listen ssl-offload-http + option httplog + bind "fd@${ssl}" ssl crt ${testdir}/common.pem ssl no-sslv3 alpn h2,http/1.1 + server http unix@"${tmpdir}/http.socket" send-proxy +} -start + + +shell { + HOST=${h1_ssl_addr} + if [ "$HOST" = "::1" ] ; then + HOST="\[::1\]" + fi + for i in 1 2 3 4 5 6 7 8 ; do + urls="$urls https://$HOST:${h1_ssl_port}/$i" + done + curl -i -k -d 'x=x' $urls & wait $! +} + +syslog Slog_1 -wait diff --git a/reg-tests/connection/proxy_protocol_send_unique_id.vtc b/reg-tests/connection/proxy_protocol_send_unique_id.vtc new file mode 100644 index 0000000..4f6b848 --- /dev/null +++ b/reg-tests/connection/proxy_protocol_send_unique_id.vtc @@ -0,0 +1,42 @@ +varnishtest "Check that the unique ID TLV is properly sent" + +#REQUIRE_VERSION=2.2 + +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + log global + unique-id-format %{+X}o\ TEST-%[req.hdr(in)] + + listen sender + bind "fd@${feS}" + + unique-id-header unique_id + + server example ${h1_feR_addr}:${h1_feR_port} send-proxy-v2 proxy-v2-options unique-id + + listen receiver + bind "fd@${feR}" accept-proxy + + http-request set-var(txn.http_unique_id) req.hdr(unique_id) + http-request set-var(txn.proxy_unique_id) fc_pp_unique_id + http-after-response set-header http_unique_id %[var(txn.http_unique_id)] + http-after-response set-header proxy_unique_id %[var(txn.proxy_unique_id)] + http-request return status 200 +} -start + +# Validate that a correct header passes +client c1 -connect ${h1_feS_sock} { + txreq -url "/" \ + -hdr "in: foo" + rxresp + expect resp.http.http_unique_id == "TEST-foo" + expect resp.http.proxy_unique_id == "TEST-foo" + txreq -url "/" \ + -hdr "in: bar" + rxresp + expect resp.http.http_unique_id == "TEST-bar" + expect resp.http.proxy_unique_id == "TEST-bar" +} -run diff --git a/reg-tests/connection/proxy_protocol_send_unique_id_alpn.vtc b/reg-tests/connection/proxy_protocol_send_unique_id_alpn.vtc new file mode 100644 index 0000000..87e590a --- /dev/null +++ b/reg-tests/connection/proxy_protocol_send_unique_id_alpn.vtc @@ -0,0 +1,33 @@ +varnishtest "Check that the unique ID TLV is properly sent for servers with ALPN option" + +#REQUIRE_VERSION=2.2 +#REQUIRE_OPTIONS=OPENSSL + +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + log global + unique-id-format %{+X}o\ TEST-%[req.hdr(in)] + + listen sender + bind "fd@${feS}" + + server example ${h1_feR_addr}:${h1_feR_port} send-proxy-v2 proxy-v2-options unique-id ssl alpn XXX verify none + + listen receiver + bind "fd@${feR}" ssl crt ${testdir}/common.pem accept-proxy + + http-request set-var(txn.proxy_unique_id) fc_pp_unique_id + http-after-response set-header proxy_unique_id %[var(txn.proxy_unique_id)] + http-request return status 200 +} -start + +# Validate that a correct header passes +client c1 -connect ${h1_feS_sock} { + txreq -url "/" \ + -hdr "in: foo" + rxresp + expect resp.http.proxy_unique_id == "TEST-foo" +} -run diff --git a/reg-tests/connection/proxy_protocol_tlv_validation.vtc b/reg-tests/connection/proxy_protocol_tlv_validation.vtc new file mode 100644 index 0000000..8c7d734 --- /dev/null +++ b/reg-tests/connection/proxy_protocol_tlv_validation.vtc @@ -0,0 +1,142 @@ +varnishtest "Check that the TLVs are properly validated" + +#REQUIRE_VERSION=2.4 + +feature ignore_unknown_macro + +# We need one HAProxy for each test, because apparently the connection by +# the client is reused, leading to connection resets. + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend a + bind "fd@${fe1}" accept-proxy + http-after-response set-header echo %[fc_pp_authority,hex] + http-request return status 200 +} -start + +# Validate that a correct header passes +client c1 -connect ${h1_fe1_sock} { + # PROXY v2 signature + sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a" + # version + PROXY + sendhex "21" + # TCP4 + sendhex "11" + # length of the address (12) + length of the TLV (8) + sendhex "00 14" + # 127.0.0.1 42 127.0.0.1 1337 + sendhex "7F 00 00 01 7F 00 00 01 00 2A 05 39" + # PP2_TYPE_AUTHORITY + length of the value + "12345" + sendhex "02 00 05 31 32 33 34 35" + + txreq -url "/" + rxresp + expect resp.http.echo == "3132333435" +} -run + +haproxy h2 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend a + bind "fd@${fe1}" accept-proxy + http-after-response set-header echo %[fc_pp_authority,hex] + http-request return status 200 +} -start + +# Validate that a TLV after the end of the PROXYv2 header is not parsed +# and handle by the HTTP parser, leading to a 400 bad request error +client c2 -connect ${h2_fe1_sock} { + # PROXY v2 signature + sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a" + # version + PROXY + sendhex "21" + # TCP4 + sendhex "11" + # length of the address (12) + length of the TLV (8) + sendhex "00 14" + # 127.0.0.1 42 127.0.0.1 1337 + sendhex "7F 00 00 01 7F 00 00 01 00 2A 05 39" + # PP2_TYPE_AUTHORITY + length of the value + "12345" + sendhex "02 00 05 31 32 33 34 35" + # after the end of the PROXYv2 header: PP2_TYPE_AUTHORITY + length of the value + "54321" + sendhex "02 00 05 35 34 33 32 31" + + txreq -url "/" + rxresp + expect resp.status == 400 + expect resp.http.echo == <undef> +} -run + +haproxy h3 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend a + bind "fd@${fe1}" accept-proxy + http-after-response set-header echo %[fc_pp_authority,hex] + http-request return status 200 +} -start + +# Validate that a TLV length exceeding the PROXYv2 length fails +client c3 -connect ${h3_fe1_sock} { + # PROXY v2 signature + sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a" + # version + PROXY + sendhex "21" + # TCP4 + sendhex "11" + # length of the address (12) + too small length of the TLV (8) + sendhex "00 14" + # 127.0.0.1 42 127.0.0.1 1337 + sendhex "7F 00 00 01 7F 00 00 01 00 2A 05 39" + # PP2_TYPE_AUTHORITY + length of the value + "1234512345" + sendhex "02 00 0A 31 32 33 34 35 31 32 33 34 35" + + txreq -url "/" + expect_close +} -run + +haproxy h4 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend a + bind "fd@${fe1}" accept-proxy + http-after-response set-header echo %[fc_pp_authority,hex] + http-request return status 200 +} -start + +# Validate that TLVs not ending with the PROXYv2 header fail +client c4 -connect ${h4_fe1_sock} { + # PROXY v2 signature + sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a" + # version + PROXY + sendhex "21" + # TCP4 + sendhex "11" + # length of the address (12) + too big length of the TLV (8) + sendhex "00 14" + # 127.0.0.1 42 127.0.0.1 1337 + sendhex "7F 00 00 01 7F 00 00 01 00 2A 05 39" + # PP2_TYPE_AUTHORITY + length of the value + "1234" + sendhex "02 00 04 31 32 33 34" + + txreq -url "/" + expect_close +} -run diff --git a/reg-tests/connection/tcp_to_http_upgrade.vtc b/reg-tests/connection/tcp_to_http_upgrade.vtc new file mode 100644 index 0000000..093ba48 --- /dev/null +++ b/reg-tests/connection/tcp_to_http_upgrade.vtc @@ -0,0 +1,162 @@ +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 { + 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 + +# To be sure no other request was received by the server +client c_end -connect ${s1_sock} { + txreq + rxresp +} -run diff --git a/reg-tests/contrib/prometheus.vtc b/reg-tests/contrib/prometheus.vtc new file mode 100644 index 0000000..a481240 --- /dev/null +++ b/reg-tests/contrib/prometheus.vtc @@ -0,0 +1,113 @@ +varnishtest "prometheus exporter test" + +#REQUIRE_VERSION=2.4 +#REQUIRE_SERVICES=prometheus-exporter + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp +} -start + +server s2 { + rxreq + txresp +} -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + option socket-stats + + listen stats + bind "fd@${stats}" + http-request use-service prometheus-exporter if { path /metrics } + + frontend fe + bind "fd@${fe}" + default_backend be + + backend be + stick-table type ip size 1m expire 10s store http_req_rate(10s) + option httpchk + server s1 ${s1_addr}:${s1_port} + server s2 ${s2_addr}:${s2_port} check inter 5s maxqueue 10 maxconn 12 pool-max-conn 42 +} -start + +client c1 -connect ${h1_stats_sock} { + txreq -url "/metrics" + rxresp + # test general metrics + expect resp.status == 200 + expect resp.body ~ ".*haproxy_process.*" + expect resp.body ~ ".*haproxy_frontend.*" + expect resp.body ~ ".*haproxy_listener.*" + expect resp.body ~ ".*haproxy_backend.*" + expect resp.body ~ ".*haproxy_server.*" + expect resp.body ~ ".*haproxy_sticktable.*" + + # test expected NaN values + expect resp.body ~ ".*haproxy_server_check_failures_total{proxy=\"be\",server=\"s1\"} NaN.*" + expect resp.body ~ ".*haproxy_server_check_up_down_total{proxy=\"be\",server=\"s1\"} NaN.*" + expect resp.body ~ ".*haproxy_server_check_failures_total{proxy=\"be\",server=\"s2\"} 0.*" + expect resp.body ~ ".*haproxy_server_check_up_down_total{proxy=\"be\",server=\"s2\"} 0.*" + + expect resp.body ~ ".*haproxy_server_queue_limit{proxy=\"be\",server=\"s1\"} NaN.*" + expect resp.body ~ ".*haproxy_server_queue_limit{proxy=\"be\",server=\"s2\"} 10.*" + + expect resp.body ~ ".*haproxy_server_limit_sessions{proxy=\"be\",server=\"s1\"} NaN.*" + expect resp.body ~ ".*haproxy_server_limit_sessions{proxy=\"be\",server=\"s2\"} 12.*" + + expect resp.body ~ ".*haproxy_backend_downtime_seconds_total{proxy=\"stats\"} NaN.*" + expect resp.body ~ ".*haproxy_backend_downtime_seconds_total{proxy=\"be\"} 0.*" + expect resp.body ~ ".*haproxy_server_downtime_seconds_total{proxy=\"be\",server=\"s1\"} NaN.*" + expect resp.body ~ ".*haproxy_server_downtime_seconds_total{proxy=\"be\",server=\"s2\"} 0.*" + + expect resp.body ~ ".*haproxy_server_current_throttle{proxy=\"be\",server=\"s1\"} NaN.*" + + expect resp.body ~ ".*haproxy_server_idle_connections_limit{proxy=\"be\",server=\"s1\"} NaN.*" + expect resp.body ~ ".*haproxy_server_idle_connections_limit{proxy=\"be\",server=\"s2\"} 42.*" + + # test well known labels presence + expect resp.body ~ ".*haproxy_process_build_info{version=\".*\"} 1.*" + expect resp.body ~ ".*haproxy_frontend_http_responses_total{proxy=\"stats\",code=\"4xx\"} 0.*" + expect resp.body ~ ".*haproxy_frontend_status{proxy=\"fe\",state=\"UP\"} 1.*" + expect resp.body ~ ".*haproxy_listener_status{proxy=\"stats\",listener=\"sock-1\",state=\"WAITING\"} 0.*" + expect resp.body ~ ".*haproxy_backend_status{proxy=\"be\",state=\"UP\"} 1.*" + expect resp.body ~ ".*haproxy_server_status{proxy=\"be\",server=\"s1\",state=\"DOWN\"} 0.*" + expect resp.body ~ ".*haproxy_server_check_status{proxy=\"be\",server=\"s2\",state=\"HANA\"} 0.*" + + # test scope + txreq -url "/metrics?scope=" + rxresp + expect resp.status == 200 + expect resp.bodylen == 0 + + txreq -url "/metrics?scope=server" + rxresp + expect resp.status == 200 + expect resp.body !~ ".*haproxy_process.*" + expect resp.body !~ ".*haproxy_frontend.*" + expect resp.body !~ ".*haproxy_listener.*" + expect resp.body !~ ".*haproxy_backend.*" + expect resp.body ~ ".*haproxy_server.*" + expect resp.body !~ ".*haproxy_sticktable.*" + + txreq -url "/metrics?scope=frontend&scope=backend" + rxresp + expect resp.status == 200 + expect resp.body !~ ".*haproxy_process.*" + expect resp.body ~ ".*haproxy_frontend.*" + expect resp.body !~ ".*haproxy_listener.*" + expect resp.body ~ ".*haproxy_backend.*" + expect resp.body !~ ".*haproxy_server.*" + expect resp.body !~ ".*haproxy_sticktable.*" + + txreq -url "/metrics?scope" + rxresp + expect resp.status == 400 +} -run diff --git a/reg-tests/converter/add_item.vtc b/reg-tests/converter/add_item.vtc new file mode 100644 index 0000000..474ad7b --- /dev/null +++ b/reg-tests/converter/add_item.vtc @@ -0,0 +1,50 @@ +varnishtest "be2dec converter Test" + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.6-dev0)'" +feature ignore_unknown_macro + +server s1 { + rxreq + txresp -hdr "Connection: close" +} -repeat 3 -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + + #### requests + http-request set-var(txn.input) req.hdr(input) + http-request set-var(txn.var) str("var_content") + + http-response set-header add_item-1 "%[var(txn.input),add_item(',',txn.var,_suff_)]" + http-response set-header add_item-2 "%[var(txn.input),add_item(',',txn.var)]" + http-response set-header add_item-3 "%[var(txn.input),add_item(',',,_suff_)]" + + default_backend be + + backend be + server s1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe_sock} { + txreq -url "/" \ + -hdr "input:" + rxresp + expect resp.status == 200 + expect resp.http.add_item-1 == "var_content_suff_" + expect resp.http.add_item-2 == "var_content" + expect resp.http.add_item-3 == "_suff_" + txreq -url "/" \ + -hdr "input: input_string" + rxresp + expect resp.status == 200 + expect resp.http.add_item-1 == "input_string,var_content_suff_" + expect resp.http.add_item-2 == "input_string,var_content" + expect resp.http.add_item-3 == "input_string,_suff_" +} -run diff --git a/reg-tests/converter/be2dec.vtc b/reg-tests/converter/be2dec.vtc new file mode 100644 index 0000000..a0b7104 --- /dev/null +++ b/reg-tests/converter/be2dec.vtc @@ -0,0 +1,56 @@ +varnishtest "be2dec converter Test" + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature ignore_unknown_macro + +server s1 { + rxreq + txresp -hdr "Connection: close" +} -repeat 3 -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + + #### requests + http-request set-var(txn.input) req.hdr(input) + + http-response set-header be2dec-1 "%[var(txn.input),be2dec(:,1)]" + http-response set-header be2dec-2 "%[var(txn.input),be2dec(-,3)]" + http-response set-header be2dec-3 "%[var(txn.input),be2dec(::,3,1)]" + + default_backend be + + backend be + server s1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe_sock} { + txreq -url "/" \ + -hdr "input:" + rxresp + expect resp.status == 200 + expect resp.http.be2dec-1 == "" + expect resp.http.be2dec-2 == "" + expect resp.http.be2dec-3 == "" + txreq -url "/" \ + -hdr "input: 0123456789" + rxresp + expect resp.status == 200 + expect resp.http.be2dec-1 == "48:49:50:51:52:53:54:55:56:57" + expect resp.http.be2dec-2 == "3158322-3355701-3553080-57" + expect resp.http.be2dec-3 == "3158322::3355701::3553080" + txreq -url "/" \ + -hdr "input: abcdefghijklmnopqrstuvwxyz" + rxresp + expect resp.status == 200 + expect resp.http.be2dec-1 == "97:98:99:100:101:102:103:104:105:106:107:108:109:110:111:112:113:114:115:116:117:118:119:120:121:122" + expect resp.http.be2dec-2 == "6382179-6579558-6776937-6974316-7171695-7369074-7566453-7763832-31098" + expect resp.http.be2dec-3 == "6382179::6579558::6776937::6974316::7171695::7369074::7566453::7763832" +} -run diff --git a/reg-tests/converter/be2hex.vtc b/reg-tests/converter/be2hex.vtc new file mode 100644 index 0000000..4cf3dc1 --- /dev/null +++ b/reg-tests/converter/be2hex.vtc @@ -0,0 +1,60 @@ +varnishtest "be2hex converter Test" + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature ignore_unknown_macro + +server s1 { + rxreq + txresp -hdr "Connection: close" +} -repeat 3 -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + + #### requests + http-request set-var(txn.input) req.hdr(input) + + http-response set-header be2hex "%[var(txn.input),be2hex,lower]" + http-response set-header be2hex-1 "%[var(txn.input),be2hex(:,1),lower]" + http-response set-header be2hex-2 "%[var(txn.input),be2hex(--,3),lower]" + http-response set-header be2hex-3 "%[var(txn.input),be2hex(.,3,1),lower]" + + default_backend be + + backend be + server s1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe_sock} { + txreq -url "/" \ + -hdr "input:" + rxresp + expect resp.status == 200 + expect resp.http.be2hex == "" + expect resp.http.be2hex-1 == "" + expect resp.http.be2hex-2 == "" + expect resp.http.be2hex-3 == "" + txreq -url "/" \ + -hdr "input: 0123456789" + rxresp + expect resp.status == 200 + expect resp.http.be2hex == "30313233343536373839" + expect resp.http.be2hex-1 == "30:31:32:33:34:35:36:37:38:39" + expect resp.http.be2hex-2 == "303132--333435--363738--39" + expect resp.http.be2hex-3 == "303132.333435.363738" + txreq -url "/" \ + -hdr "input: abcdefghijklmnopqrstuvwxyz" + rxresp + expect resp.status == 200 + expect resp.http.be2hex == "6162636465666768696a6b6c6d6e6f707172737475767778797a" + expect resp.http.be2hex-1 == "61:62:63:64:65:66:67:68:69:6a:6b:6c:6d:6e:6f:70:71:72:73:74:75:76:77:78:79:7a" + expect resp.http.be2hex-2 == "616263--646566--676869--6a6b6c--6d6e6f--707172--737475--767778--797a" + expect resp.http.be2hex-3 == "616263.646566.676869.6a6b6c.6d6e6f.707172.737475.767778" +} -run diff --git a/reg-tests/converter/digest.vtc b/reg-tests/converter/digest.vtc new file mode 100644 index 0000000..e911ff4 --- /dev/null +++ b/reg-tests/converter/digest.vtc @@ -0,0 +1,57 @@ +varnishtest "digest converter Test" + +#REQUIRE_VERSION=2.2 +#REQUIRE_OPTION=OPENSSL + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp -hdr "Connection: close" +} -repeat 2 -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + + #### requests + http-request set-var(txn.hash) req.hdr(hash) + + http-response set-header SHA1 "%[var(txn.hash),digest(sha1),hex,lower]" + http-response set-header SHA224 "%[var(txn.hash),digest(sha224),hex,lower]" + http-response set-header SHA256 "%[var(txn.hash),digest(sha256),hex,lower]" + http-response set-header SHA384 "%[var(txn.hash),digest(sha384),hex,lower]" + http-response set-header SHA512 "%[var(txn.hash),digest(sha512),hex,lower]" + + default_backend be + + backend be + server s1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe_sock} { + txreq -url "/" \ + -hdr "Hash: 1" + rxresp + expect resp.status == 200 + expect resp.http.sha1 == "356a192b7913b04c54574d18c28d46e6395428ab" + expect resp.http.sha224 == "e25388fde8290dc286a6164fa2d97e551b53498dcbf7bc378eb1f178" + expect resp.http.sha256 == "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b" + expect resp.http.sha384 == "47f05d367b0c32e438fb63e6cf4a5f35c2aa2f90dc7543f8a41a0f95ce8a40a313ab5cf36134a2068c4c969cb50db776" + expect resp.http.sha512 == "4dff4ea340f0a823f15d3f4f01ab62eae0e5da579ccb851f8db9dfe84c58b2b37b89903a740e1ee172da793a6e79d560e5f7f9bd058a12a280433ed6fa46510a" + txreq -url "/" \ + -hdr "Hash: 2" + rxresp + expect resp.status == 200 + expect resp.http.sha1 == "da4b9237bacccdf19c0760cab7aec4a8359010b0" + expect resp.http.sha224 == "58b2aaa0bfae7acc021b3260e941117b529b2e69de878fd7d45c61a9" + expect resp.http.sha256 == "d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35" + expect resp.http.sha384 == "d063457705d66d6f016e4cdd747db3af8d70ebfd36badd63de6c8ca4a9d8bfb5d874e7fbd750aa804dcaddae7eeef51e" + expect resp.http.sha512 == "40b244112641dd78dd4f93b6c9190dd46e0099194d5a44257b7efad6ef9ff4683da1eda0244448cb343aa688f5d3efd7314dafe580ac0bcbf115aeca9e8dc114" +} -run diff --git a/reg-tests/converter/field.vtc b/reg-tests/converter/field.vtc new file mode 100644 index 0000000..1243728 --- /dev/null +++ b/reg-tests/converter/field.vtc @@ -0,0 +1,39 @@ +varnishtest "field converter Test" + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp -hdr "Connection: close" +} -repeat 3 -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + + #### requests + http-request set-var(txn.uri) path + http-response set-header Found %[var(txn.uri),field(3,/)] if { var(txn.uri),field(3,/) -m found } + + default_backend be + + backend be + server s1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe_sock} { + txreq -url "/foo/bar/baz" + rxresp + expect resp.status == 200 + expect resp.http.found == "bar" + txreq -url "/foo" + rxresp + expect resp.status == 200 + expect resp.http.found == "<undef>" +} -run diff --git a/reg-tests/converter/fix.vtc b/reg-tests/converter/fix.vtc new file mode 100644 index 0000000..8206da3 --- /dev/null +++ b/reg-tests/converter/fix.vtc @@ -0,0 +1,235 @@ +varnishtest "fix converters Test" +#REQUIRE_VERSION=2.4 + +feature ignore_unknown_macro + +server s1 { + # Valid FIX-4.0 logon + recv 92 + # 8=FIX|4.0|9=66|35=A|34=1|49=EXECUTOR|52=20201029-10:54:19|56=CLIENT1|98=0|108=30|10=147| + sendhex "383d4649582e342e3001393d36360133353d410133343d310134393d4558454355544f520135323d32303230313032392d31303a35343a31390135363d434c49454e54310139383d30013130383d33300131303d31343701" + close + + # Valid FIX-4.1 logon + accept + recv 98 + # 8=FIX.4.1|9=72|35=A|34=1|49=EXECUTOR|52=20201029-12:43:07|56=CLIENT1|98=0|108=30|141=Y|10=187| + sendhex "383d4649582e342e3101393d37320133353d410133343d310134393d4558454355544f520135323d32303230313032392d31323a34333a30370135363d434c49454e54310139383d30013130383d3330013134313d590131303d31383701" + close + + # Valid FIX-4.2 logon + accept + recv 98 + # 8=FIX.4.2|9=79|35=A|34=1|49=EXECUTOR|52=20201029-12:55:12.101414|56=CLIENT1|98=0|108=30|141=Y|10=027| + sendhex "383d4649582e342e3201393d37390133353d410133343d310134393d4558454355544f520135323d32303230313032392d31323a35353a31322e3130313431340135363d434c49454e54310139383d30013130383d3330013134313d590131303d30323701" + close + + # Valid FIX-4.3 logon + accept + recv 125 + # 8=FIX.4.3|9=79|35=A|34=1|49=EXECUTOR|52=20201029-12:58:50.891371|56=CLIENT1|98=0|108=30|141=Y|10=051| + sendhex "383d4649582e342e3301393d37390133353d410133343d310134393d4558454355544f520135323d32303230313032392d31323a35383a35302e3839313337310135363d434c49454e54310139383d30013130383d3330013134313d590131303d30353101" + close + + # Valid FIX-4.4 logon + accept + recv 125 + # 8=FIX.4.4|9=79|35=A|34=1|49=EXECUTOR|52=20201029-13:02:44.535360|56=CLIENT1|98=0|108=30|141=Y|10=038| + sendhex "383d4649582e342e3401393d37390133353d410133343d310134393d4558454355544f520135323d32303230313032392d31333a30323a34342e3533353336300135363d434c49454e54310139383d30013130383d3330013134313d590131303d30333801" + close + + # Valid FIX-5.0 logon + accept + recv 140 + # 8=FIXT.1.1|9=86|35=A|34=1|49=EXECUTOR|52=20201029-13:13:22.626384|56=CLIENT1|98=0|108=30|141=Y|1137=7|10=184| + sendhex "383d464958542e312e3101393d38360133353d410133343d310134393d4558454355544f520135323d32303230313032392d31333a31333a32322e3632363338340135363d434c49454e54310139383d30013130383d3330013134313d5901313133373d370131303d31383401" +} -start + +server s2 { + # Valid FIX-4.4 logon + recv 125 + # 8=FIX.4.4|9=79|35=A|34=1|49=EXECUTOR|52=20201029-13:02:44.535360|56=CLIENT1|98=0|108=30|141=Y|10=038| + sendhex "383d4649582e342e3401393d37390133353d410133343d310134393d4558454355544f520135323d32303230313032392d31333a30323a34342e3533353336300135363d434c49454e54310139383d30013130383d3330013134313d590131303d30333801" + +} -start + +haproxy h1 -conf { + defaults + mode tcp + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe1}" + tcp-request inspect-delay 1s + tcp-request content reject unless { req.payload(0,0),fix_is_valid } + default_backend be1 + + frontend fe2 + bind "fd@${fe2}" + tcp-request inspect-delay 1s + tcp-request content reject unless { req.payload(0,0),fix_is_valid } + tcp-request content set-var(req.fix_vsn) req.payload(0,0),fix_tag_value(BeginString) + tcp-request content set-var(req.fix_len) req.payload(0,0),fix_tag_value(BodyLength) + tcp-request content set-var(req.fix_type) req.payload(0,0),fix_tag_value(MsgType) + tcp-request content set-var(req.fix_sender) req.payload(0,0),fix_tag_value(SenderCompID) + tcp-request content set-var(req.fix_target) req.payload(0,0),fix_tag_value(TargetCompID) + tcp-request content set-var(req.fix_chksum) req.payload(0,0),fix_tag_value(CheckSum) + tcp-request content reject if ! { var(req.fix_vsn) -m str "FIX.4.4" } || ! { var(req.fix_len) -m str "102" } + tcp-request content reject if ! { var(req.fix_type) -m str "A" } || ! { var(req.fix_sender) -m str "CLIENT1" } + tcp-request content reject if ! { var(req.fix_target) -m str "EXECUTOR" } || ! { var(req.fix_chksum) -m str "252" } + default_backend be2 + + backend be1 + server s1 ${s1_addr}:${s1_port} + tcp-response inspect-delay 1s + tcp-response content reject unless { res.payload(0,0),fix_is_valid } + + backend be2 + server s2 ${s2_addr}:${s2_port} + tcp-response inspect-delay 1s + tcp-response content reject unless { res.payload(0,0),fix_is_valid } + tcp-response content set-var(res.fix_vsn) res.payload(0,0),fix_tag_value(8) + tcp-response content set-var(res.fix_len) res.payload(0,0),fix_tag_value(9) + tcp-response content set-var(res.fix_type) res.payload(0,0),fix_tag_value(35) + tcp-response content set-var(res.fix_sender) res.payload(0,0),fix_tag_value(49) + tcp-response content set-var(res.fix_target) res.payload(0,0),fix_tag_value(56) + tcp-response content set-var(res.fix_chksum) res.payload(0,0),fix_tag_value(10) + tcp-response content reject if ! { var(res.fix_vsn) -m str "FIX.4.4" } || ! { var(res.fix_len) -m str "79" } + tcp-response content reject if ! { var(res.fix_type) -m str "A" } || ! { var(res.fix_sender) -m str "EXECUTOR" } + tcp-response content reject if ! { var(res.fix_target) -m str "CLIENT1" } || ! { var(res.fix_chksum) -m str "038" } +} -start + +client c1_4_0 -connect ${h1_fe1_sock} { + # Valid FIX-4.0 logon + # 8=FIX|4.0|9=70|35=A|49=CLIENT1|56=EXECUTOR|34=1|52=20201029-10:54:19.617|98=0|108=30|10=090| + sendhex "383d4649582e342e3001393d37300133353d410134393d434c49454e54310135363d4558454355544f520133343d310135323d32303230313032392d31303a35343a31392e3631370139383d30013130383d33300131303d30393001" + recv 88 + expect_close +} -run + +client c1_4_1 -connect ${h1_fe1_sock} { + # Valid FIX-4.1 logon + # 8=FIX.4.1|9=76|35=A|49=CLIENT1|56=EXECUTOR|34=1|52=20201029-12:43:07.940|98=0|108=30|141=Y|10=138| + sendhex "383d4649582e342e3101393d37360133353d410134393d434c49454e54310135363d4558454355544f520133343d310135323d32303230313032392d31323a34333a30372e3934300139383d30013130383d3330013134313d590131303d31333801" + recv 94 + expect_close +} -run + +client c1_4_2 -connect ${h1_fe1_sock} { + # Valid FIX-4.2 logon + # 8=FIX.4.2|9=76|35=A|49=CLIENT1|56=EXECUTOR|34=1|52=20201029-12:55:12.100|98=0|108=30|141=Y|10=126| + sendhex "383d4649582e342e3201393d37360133353d410134393d434c49454e54310135363d4558454355544f520133343d310135323d32303230313032392d31323a35353a31322e3130300139383d30013130383d3330013134313d590131303d31323601" + recv 101 + expect_close +} -run + +client c1_4_3 -connect ${h1_fe1_sock} { + # Valid FIX-4.3 logon + # 8=FIX.4.3|9=102|35=A|49=CLIENT1|56=EXECUTOR|34=1|52=20201029-12:58:50.889|98=0|108=30|141=Y|553=Username|554=Password|10=012| + sendhex "383d4649582e342e3301393d3130320133353d410134393d434c49454e54310135363d4558454355544f520133343d310135323d32303230313032392d31323a35383a35302e3838390139383d30013130383d3330013134313d59013535333d557365726e616d65013535343d50617373776f72640131303d30313201" + recv 101 + expect_close +} -run + +client c1_4_4 -connect ${h1_fe1_sock} { + # Valid FIX-4.4 logon + # 8=FIX.4.4|9=102|35=A|49=CLIENT1|56=EXECUTOR|34=1|52=20201029-13:02:44.528|98=0|108=30|141=Y|553=Username|554=Password|10=252| + sendhex "383d4649582e342e3401393d3130320133353d410134393d434c49454e54310135363d4558454355544f520133343d310135323d32303230313032392d31333a30323a34342e3532380139383d30013130383d3330013134313d59013535333d557365726e616d65013535343d50617373776f72640131303d32353201" + recv 101 + expect_close +} -run + +client c1_5_0 -connect ${h1_fe1_sock} { + # Valid FIX-5.0 logon + # 8=FIXT.1.1|9=116|35=A|49=CLIENT1|56=EXECUTOR|34=1|52=20201029-13:13:22.624|1128=7|98=0|108=30|141=Y|553=Username|554=Password|1137=7|10=204| + sendhex "383d464958542e312e3101393d3131360133353d410134393d434c49454e54310135363d4558454355544f520133343d310135323d32303230313032392d31333a31333a32322e36323401313132383d370139383d30013130383d3330013134313d59013535333d557365726e616d65013535343d50617373776f726401313133373d370131303d32303401" + recv 109 + expect_close +} -run + +client c2_1 -connect ${h1_fe1_sock} { + # InValid FIX-4.4: Empty TagName (missing EncryptMethod <98> tag name) + # 8=FIX.4.4|9=100|35=A|49=CLIENT1|56=EXECUTOR|34=1|52=20201029-13:02:44.528|=0|108=30|141=Y|553=Username|554=Password|10=252| + sendhex "383d4649582e342e3401393d3130300133353d410134393d434c49454e54310135363d4558454355544f520133343d310135323d32303230313032392d31333a30323a34342e353238013d30013130383d3330013134313d59013535333d557365726e616d65013535343d50617373776f72640131303d32353201" + expect_close +} -run + +client c2_2 -connect ${h1_fe1_sock} { + # InValid FIX-4.4: Empty TagValue (missing EncryptMethod <98> tag value) + # 8=FIX.4.4|9=101|35=A|49=CLIENT1|56=EXECUTOR|34=1|52=20201029-13:02:44.528|98=|108=30|141=Y|553=Username|554=Password|10=252| + sendhex "383d4649582e342e3401393d3130310133353d410134393d434c49454e54310135363d4558454355544f520133343d310135323d32303230313032392d31333a30323a34342e3532380139383d013130383d3330013134313d59013535333d557365726e616d65013535343d50617373776f72640131303d32353201" + expect_close +} -run + +client c2_3 -connect ${h1_fe1_sock} { + # InValid FIX-4.4: Empty Tag no delimiter (missing delimiter for EncryptMethod <98> tag) + # 8=FIX.4.4|9=101|35=A|49=CLIENT1|56=EXECUTOR|34=1|52=20201029-13:02:44.528|98|108=30|141=Y|553=Username|554=Password|10=252| + sendhex "383d4649582e342e3401393d3130300133353d410134393d434c49454e54310135363d4558454355544f520133343d310135323d32303230313032392d31333a30323a34342e353238013938013130383d3330013134313d59013535333d557365726e616d65013535343d50617373776f72640131303d32353201" + expect_close +} -run + +client c2_4 -connect ${h1_fe1_sock} { + # Invalid FIX-4.4: First tag != BeginString + # 9=102|8=FIX.4.4|35=A|49=CLIENT1|56=EXECUTOR|34=1|52=20201029-13:02:44.528|98=0|108=30|141=Y|553=Username|554=Password|10=252| + sendhex "393d31303201383d4649582e342e340133353d410134393d434c49454e54310135363d4558454355544f520133343d310135323d32303230313032392d31333a30323a34342e3532380139383d30013130383d3330013134313d59013535333d557365726e616d65013535343d50617373776f72640131303d32353201" + expect_close +} -run + +client c2_5 -connect ${h1_fe1_sock} { + # Invalid FIX-4.4: Second tag != BodyLength + # 8=FIX.4.4|35=A|9=102|49=CLIENT1|56=EXECUTOR|34=1|52=20201029-13:02:44.528|98=0|108=30|141=Y|553=Username|554=Password|10=252| + sendhex "383d4649582e342e340133353d4101393d3130320134393d434c49454e54310135363d4558454355544f520133343d310135323d32303230313032392d31333a30323a34342e3532380139383d30013130383d3330013134313d59013535333d557365726e616d65013535343d50617373776f72640131303d32353201" + expect_close +} -run + +client c2_6 -connect ${h1_fe1_sock} { + # Invalid FIX-4.4: Third tag != MsgType + # 8=FIX.4.4|9=102|49=CLIENT1|35=A|56=EXECUTOR|34=1|52=20201029-13:02:44.528|98=0|108=30|141=Y|553=Username|554=Password|10=252| + sendhex "383d4649582e342e3401393d3130320134393d434c49454e54310133353d410135363d4558454355544f520133343d310135323d32303230313032392d31333a30323a34342e3532380139383d30013130383d3330013134313d59013535333d557365726e616d65013535343d50617373776f72640131303d32353201" + expect_close +} -run + +client c2_7 -connect ${h1_fe1_sock} { + # Invalid FIX-4.4: Bad body length (too short 100 != 102) + # 8=FIX.4.4|9=100|35=A|49=CLIENT1|56=EXECUTOR|34=1|52=20201029-13:02:44.528|98=0|108=30|141=Y|553=Username|554=Password|10=252| + sendhex "383d4649582e342e3401393d3130300133353d410134393d434c49454e54310135363d4558454355544f520133343d310135323d32303230313032392d31333a30323a34342e3532380139383d30013130383d3330013134313d59013535333d557365726e616d65013535343d50617373776f72640131303d32353201" + expect_close +} -run + +client c2_8 -connect ${h1_fe1_sock} { + # Invalid FIX-4.4: Bad body length (too long 105 != 102) + # 8=FIX.4.4|9=105|35=A|49=CLIENT1|56=EXECUTOR|34=1|52=20201029-13:02:44.528|98=0|108=30|141=Y|553=Username|554=Password|10=252|XXX + sendhex "383d4649582e342e3401393d3130350133353d410134393d434c49454e54310135363d4558454355544f520133343d310135323d32303230313032392d31333a30323a34342e3532380139383d30013130383d3330013134313d59013535333d557365726e616d65013535343d50617373776f72640131303d32353201585858" + expect_close +} -run + +client c2_9 -connect ${h1_fe1_sock} { + # Invalid FIX-4.4: Too short checksum value (< 3 digit) + # 8=FIX.4.4|9=102|35=A|49=CLIENT1|56=EXECUTOR|34=1|52=20201029-13:02:44.528|98=0|108=30|141=Y|553=Username|554=Password|10=25| + sendhex "383d4649582e342e3401393d3130320133353d410134393d434c49454e54310135363d4558454355544f520133343d310135323d32303230313032392d31333a30323a34342e3532380139383d30013130383d3330013134313d59013535333d557365726e616d65013535343d50617373776f72640131303d323501" + expect_close +} -run + +client c2_10 -connect ${h1_fe1_sock} { + # Invalid FIX-4.4: Too long checksum value (> 3 digit) + # 8=FIX.4.4|9=102|35=A|49=CLIENT1|56=EXECUTOR|34=1|52=20201029-13:02:44.528|98=0|108=30|141=Y|553=Username|554=Password|10=2520| + sendhex "383d4649582e342e3401393d3130320133353d410134393d434c49454e54310135363d4558454355544f520133343d310135323d32303230313032392d31333a30323a34342e3532380139383d30013130383d3330013134313d59013535333d557365726e616d65013535343d50617373776f72640131303d3235323001" + expect_close +} -run + +client c2_11 -connect ${h1_fe1_sock} { + # Invalid FIX-4.4: invalid checksum value (253 != 252) + # 8=FIX.4.4|9=102|35=A|49=CLIENT1|56=EXECUTOR|34=1|52=20201029-13:02:44.528|98=0|108=30|141=Y|553=Username|554=Password|10=253| + sendhex "383d4649582e342e3401393d3130320133353d410134393d434c49454e54310135363d4558454355544f520133343d310135323d32303230313032392d31333a30323a34342e3532380139383d30013130383d3330013134313d59013535333d557365726e616d65013535343d50617373776f72640131303d32353301" + expect_close +} -run + + +client c3_1 -connect ${h1_fe2_sock} { + # 8=FIX.4.4|9=102|35=A|49=CLIENT1|56=EXECUTOR|34=1|52=20201029-13:02:44.528|98=0|108=30|141=Y|553=Username|554=Password|10=252| + sendhex "383d4649582e342e3401393d3130320133353d410134393d434c49454e54310135363d4558454355544f520133343d310135323d32303230313032392d31333a30323a34342e3532380139383d30013130383d3330013134313d59013535333d557365726e616d65013535343d50617373776f72640131303d32353201" + recv 101 + expect_close +} -run diff --git a/reg-tests/converter/hmac.vtc b/reg-tests/converter/hmac.vtc new file mode 100644 index 0000000..230a44d --- /dev/null +++ b/reg-tests/converter/hmac.vtc @@ -0,0 +1,55 @@ +varnishtest "HMAC converter Test" + +#REQUIRE_VERSION=2.2 +#REQUIRE_OPTION=OPENSSL + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp -hdr "Connection: close" +} -repeat 2 -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + + #### requests + http-request set-var(txn.hash) req.hdr(hash) + http-request set-var(txn.key) str(my_super_secret_long_key),base64 + + http-response set-header SHA1-short "%[var(txn.hash),hmac(sha1,a2V5),hex,lower]" + http-response set-header SHA1-long "%[var(txn.hash),hmac(sha1,txn.key),hex,lower]" + http-response set-header SHA256-short "%[var(txn.hash),hmac(sha256,a2V5),hex,lower]" + http-response set-header SHA256-long "%[var(txn.hash),hmac(sha256,txn.key),hex,lower]" + + default_backend be + + backend be + server s1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe_sock} { + txreq -url "/" \ + -hdr "Hash: 1" + rxresp + expect resp.status == 200 + expect resp.http.sha1-short == "e23feb105f9622241bf23db1638cd2b4208b1f53" + expect resp.http.sha1-long == "87b10ddcf39e26f6bd7c3b0e38e0125997b255be" + expect resp.http.sha256-short == "6da91fb91517be1f5cdcf3af91d7d40c717dd638a306157606fb2e584f7ae926" + expect resp.http.sha256-long == "2fb3de6a462c54d1803f946b52202f3a8cd46548ffb3f789b4ac11a4361ffef2" + txreq -url "/" \ + -hdr "Hash: 2" + rxresp + expect resp.status == 200 + expect resp.http.sha1-short == "311219c4a80c5ef81b1cee5505236c1d0ab1922c" + expect resp.http.sha1-long == "c5758af565ba4b87b3db49c8b32d4a94d430cb78" + expect resp.http.sha256-short == "ae7b3ee87b8c9214f714df1c2042c7a985b9d711e9938a063937ad1636775a88" + expect resp.http.sha256-long == "c073191a2ebf29f510444b92c187d62199d84b58f58dceeadb91994c170a9a16" +} -run diff --git a/reg-tests/converter/iif.vtc b/reg-tests/converter/iif.vtc new file mode 100644 index 0000000..f412daf --- /dev/null +++ b/reg-tests/converter/iif.vtc @@ -0,0 +1,46 @@ +varnishtest "iif converter Test" +#REQUIRE_VERSION=2.3 + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp -hdr "Connection: close" +} -repeat 3 -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + + #### requests + http-request set-var(txn.iif) req.hdr_cnt(count),iif(ok,ko) + http-response set-header iif %[var(txn.iif)] + + default_backend be + + backend be + server s1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.iif == "ko" + txreq \ + -hdr "count: 1" + rxresp + expect resp.status == 200 + expect resp.http.iif == "ok" + txreq \ + -hdr "count: 1,2" + rxresp + expect resp.status == 200 + expect resp.http.iif == "ok" +} -run diff --git a/reg-tests/converter/json.vtc b/reg-tests/converter/json.vtc new file mode 100644 index 0000000..1f37c9f --- /dev/null +++ b/reg-tests/converter/json.vtc @@ -0,0 +1,40 @@ +varnishtest "json converter test" + + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp +} -repeat 2 -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + + http-response set-header json0 "%[str(foo 1/2),json]" + # bad UTF-8 sequence + http-response set-header json1 "%[str(\xE0),json(utf8)]" + # bad UTF-8 sequence, but removes them + http-response set-header json2 "%[str(-\xE0-),json(utf8s)]" + + default_backend be + + backend be + server s1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe_sock} { + txreq -url "/" + rxresp + expect resp.http.json0 == "foo 1\\/2" + expect resp.http.json1 == "" + expect resp.http.json2 == "--" + expect resp.status == 200 +} -run diff --git a/reg-tests/converter/json_query.vtc b/reg-tests/converter/json_query.vtc new file mode 100644 index 0000000..f78c393 --- /dev/null +++ b/reg-tests/converter/json_query.vtc @@ -0,0 +1,101 @@ +varnishtest "JSON Query converters Test" +#REQUIRE_VERSION=2.4 + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp -hdr "Connection: close" +} -repeat 8 -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 + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + option http-buffer-request + + frontend fe + bind "fd@${fe}" + tcp-request inspect-delay 1s + + http-request set-var(sess.header_json) req.hdr(Authorization),json_query('$.iss') + http-request set-var(sess.pay_json) req.body,json_query('$.iss') + http-request set-var(sess.pay_int) req.body,json_query('$.integer',"int"),add(1) + http-request set-var(sess.pay_neg_int) req.body,json_query('$.negativ-integer',"int"),add(1) + http-request set-var(sess.pay_double) req.body,json_query('$.double') + http-request set-var(sess.pay_boolean_true) req.body,json_query('$.boolean-true') + http-request set-var(sess.pay_boolean_false) req.body,json_query('$.boolean-false') + http-request set-var(sess.pay_mykey) req.body,json_query('$.my\\.key') + + http-response set-header x-var_header %[var(sess.header_json)] + http-response set-header x-var_body %[var(sess.pay_json)] + http-response set-header x-var_body_int %[var(sess.pay_int)] + http-response set-header x-var_body_neg_int %[var(sess.pay_neg_int)] + http-response set-header x-var_body_double %[var(sess.pay_double)] + http-response set-header x-var_body_boolean_true %[var(sess.pay_boolean_true)] + http-response set-header x-var_body_boolean_false %[var(sess.pay_boolean_false)] + http-response set-header x-var_body_mykey %[var(sess.pay_mykey)] + + default_backend be + + backend be + server s1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe_sock} { + txreq -url "/" \ + -hdr "Authorization: {\"iss\":\"kubernetes.io/serviceaccount\"}" + rxresp + expect resp.status == 200 + expect resp.http.x-var_header ~ "kubernetes.io/serviceaccount" + + txreq -url "/" \ + -body "{\"iss\":\"kubernetes.io/serviceaccount\"}" + rxresp + expect resp.status == 200 + expect resp.http.x-var_body ~ "kubernetes.io/serviceaccount" + + txreq -url "/" \ + -body "{\"integer\":4}" + rxresp + expect resp.status == 200 + expect resp.http.x-var_body_int ~ "5" + + txreq -url "/" \ + -body "{\"integer\":-4}" + rxresp + expect resp.status == 200 + expect resp.http.x-var_body_int ~ "-3" + + txreq -url "/" \ + -body "{\"double\":4.5}" + rxresp + expect resp.status == 200 + expect resp.http.x-var_body_double ~ "4.5" + + txreq -url "/" \ + -body "{\"boolean-true\":true}" + rxresp + expect resp.status == 200 + expect resp.http.x-var_body_boolean_true == 1 + + txreq -url "/" \ + -body "{\"boolean-false\":false}" + rxresp + expect resp.status == 200 + expect resp.http.x-var_body_boolean_false == 0 + + txreq -url "/" \ + -body "{\"my.key\":\"myvalue\"}" + rxresp + expect resp.status == 200 + expect resp.http.x-var_body_mykey ~ "myvalue" +} -run
\ No newline at end of file diff --git a/reg-tests/converter/mqtt.vtc b/reg-tests/converter/mqtt.vtc new file mode 100644 index 0000000..fc3daca --- /dev/null +++ b/reg-tests/converter/mqtt.vtc @@ -0,0 +1,238 @@ +varnishtest "mqtt converters Test" +#REQUIRE_VERSION=2.4 + +feature ignore_unknown_macro + +server s1 { + # MQTT 3.1.1 CONNECT packet (id: test_subaaaaaa... [len = 200]) + recv 215 + sendhex "20020000" + close + + # MQTT 3.1.1 CONNECT packet (id: <empty> - username: test - passwd: passwd) + accept + recv 28 + sendhex "20020000" + close + + # MQTT 3.1.1 CONNECT packet (id: test_sub - username: test - passwd: passwd - will_topic: willtopic - will_payload: willpayload) + accept + recv 60 + sendhex "20020000" + close + + # MQTT 5.0 CONNECT packet (id: test_sub) + accept + recv 26 + sendhex "200600000322000a" + + # MQTT 5.0 CONNECT packet (id: test_sub - username: test - passwd: passwd) + accept + recv 40 + sendhex "200600000322000a" + + # MQTT 5.0 complex CONNECT/CONNACK packet + accept + recv 128 + sendhex "20250000221100000078217fff24012501270000ffff22000a2600016100016226000163000164" + close + + # Invalid MQTT 3.1.1 CONNACK packet with invalid flags (!= 0x00) + accept + recv 22 + sendhex "21020000" + expect_close + + # MQTT 3.1 CONNECT packet (id: test_sub - username: test - passwd: passwd) + accept + recv 38 + sendhex "20020000" +} -start + +server s2 { + # MQTT 5.0 complex CONNECT packet + recv 128 + sendhex "20250000221100000078217fff24012501270000ffff22000a2600016100016226000163000164" +} -start + +haproxy h1 -conf { + defaults + mode tcp + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe1}" + tcp-request inspect-delay 1s + tcp-request content reject unless { req.payload(0,0),mqtt_is_valid } + default_backend be1 + + frontend fe2 + bind "fd@${fe2}" + tcp-request inspect-delay 1s + tcp-request content reject unless { req.payload(0,0),mqtt_is_valid } + tcp-request content set-var(req.flags) req.payload(0,0),mqtt_field_value(connect,flags) + tcp-request content set-var(req.protoname) req.payload(0,0),mqtt_field_value(connect,protocol_name) + tcp-request content set-var(req.protovsn) req.payload(0,0),mqtt_field_value(connect,protocol_version) + tcp-request content set-var(req.clientid) req.payload(0,0),mqtt_field_value(connect,client_identifier) + tcp-request content set-var(req.willtopic) req.payload(0,0),mqtt_field_value(connect,will_topic) + tcp-request content set-var(req.willbody) req.payload(0,0),mqtt_field_value(connect,will_payload) + tcp-request content set-var(req.user) req.payload(0,0),mqtt_field_value(connect,username) + tcp-request content set-var(req.pass) req.payload(0,0),mqtt_field_value(connect,password) + tcp-request content set-var(req.maxpktsz) req.payload(0,0),mqtt_field_value(connect,39) + tcp-request content set-var(req.reqpbinfo) req.payload(0,0),mqtt_field_value(connect,23) + tcp-request content set-var(req.ctype) req.payload(0,0),mqtt_field_value(connect,3) + tcp-request content set-var(req.willrsptopic) req.payload(0,0),mqtt_field_value(connect,8) + tcp-request content reject if ! { var(req.protoname) -m str "MQTT" } || ! { var(req.protovsn) -m str "5" } + tcp-request content reject if ! { var(req.flags) -m str "238" } || ! { var(req.clientid) -m str "test_sub" } + tcp-request content reject if ! { var(req.user) -m str "test" } || ! { var(req.pass) -m str "passwd" } + tcp-request content reject if ! { var(req.willtopic) -m str "willtopic" } || ! { var(req.willbody) -m str "willpayload" } + tcp-request content reject if ! { var(req.maxpktsz) -m str "20" } || ! { var(req.reqpbinfo) -m str "1" } + tcp-request content reject if ! { var(req.ctype) -m str "text/plain" } || ! { var(req.willrsptopic) -m str "willrsptopic" } + default_backend be2 + + backend be1 + server s1 ${s1_addr}:${s1_port} + tcp-response inspect-delay 1s + tcp-response content reject unless { res.payload(0,0),mqtt_is_valid } + + backend be2 + server s2 ${s2_addr}:${s2_port} + tcp-response inspect-delay 1s + tcp-response content reject unless { res.payload(0,0),mqtt_is_valid } + tcp-response content set-var(res.flags) res.payload(0,0),mqtt_field_value(connack,flags) + tcp-response content set-var(res.protovsn) res.payload(0,0),mqtt_field_value(connack,protocol_version) + tcp-response content set-var(res.rcode) res.payload(0,0),mqtt_field_value(connack,reason_code) + tcp-response content set-var(res.sessexpint) res.payload(0,0),mqtt_field_value(connack,17) + tcp-response content set-var(res.recvmax) res.payload(0,0),mqtt_field_value(connack,33) + tcp-response content set-var(res.maxqos) res.payload(0,0),mqtt_field_value(connack,36) + tcp-response content set-var(res.retainavail) res.payload(0,0),mqtt_field_value(connack,37) + tcp-response content set-var(res.maxpktsz) res.payload(0,0),mqtt_field_value(connack,39) + tcp-response content set-var(res.topicaliasmax) res.payload(0,0),mqtt_field_value(connack,34) + tcp-response content reject if ! { var(res.protovsn) -m str "5" } || ! { var(res.flags) -m str "0" } + tcp-response content reject if ! { var(res.rcode) -m str "0" } || ! { var(res.sessexpint) -m str "120" } + tcp-response content reject if ! { var(res.recvmax) -m str "32767" } || ! { var(res.maxqos) -m str "1" } + tcp-response content reject if ! { var(res.retainavail) -m str "1" } || ! { var(res.maxpktsz) -m str "65535" } + tcp-response content reject if ! { var(res.topicaliasmax) -m str "10" } +} -start + +client c1_311_1 -connect ${h1_fe1_sock} { + # Valid MQTT 3.1.1 CONNECT packet (id: test_sub) + sendhex "10d40100044d5154540402003c00c8746573745f737562616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161" + recv 4 + expect_close +} -run + +client c1_311_2 -connect ${h1_fe1_sock} { + # Valid MQTT 3.1.1 CONNECT packet (id: <empty> - username: test - passwd: passwd) + sendhex "101a00044d51545404c2003c00000004746573740006706173737764" + recv 4 + expect_close +} -run + +client c1_311_3 -connect ${h1_fe1_sock} { + # Valid MQTT 3.1.1 CONNECT packet (id: test_sub - username: test - passwd: passwd - will_topic: willtopic - will_payload: willpayload) + sendhex "103a00044d51545404ee003c0008746573745f737562000977696c6c746f706963000b77696c6c7061796c6f61640004746573740006706173737764" + recv 4 + expect_close +} -run + +client c1_50_1 -connect ${h1_fe1_sock} { + # Valid MQTT 5.0 CONNECT packet (id: test_sub) + sendhex "101800044d5154540502003c032100140008746573745f737562" + recv 8 + expect_close +} -run + +client c1_50_2 -connect ${h1_fe1_sock} { + # Valid MQTT 5.0 CONNECT packet (id: test_sub - username: test - passwd: passwd) + sendhex "102600044d51545405c2003c032100140008746573745f7375620004746573740006706173737764" + recv 8 + expect_close +} -run + +client c1_50_3 -connect ${h1_fe1_sock} { + # Valid MQTT 5.0 complex CONNECT/CONNACK packet + sendhex "107e00044d51545405ee003c182700000014170126000161000162260001630001642100140008746573745f7375622a03000a746578742f706c61696e08000c77696c6c727370746f7069632600016500016626000167000168000977696c6c746f706963000b77696c6c7061796c6f61640004746573740006706173737764" + recv 39 + expect_close +} -run + +client c2_311_1 -connect ${h1_fe1_sock} { + # Invalid MQTT 3.1.1 PINREQ + sendhex "d000" + expect_close +} -run + +client c2_311_2 -connect ${h1_fe1_sock} { + # Invalid MQTT 3.1.1 CONNECT packet with invalid flags (!= 0x00) + sendhex "111400044d5154540402003c0008746573745f737562" + expect_close +} -run + +client c2_311_3 -connect ${h1_fe1_sock} { + # Invalid MQTT 3.1.1 CONNACK packet with invalid flags (!= 0x00) + sendhex "101400044d5154540402003c0008746573745f737562" + expect_close +} -run + +client c2_311_4 -connect ${h1_fe1_sock} { + # Invalid MQTT 3.1.1 CONNECT with too long remaing_length ( > 4 bytes) + sendhex "10ffffffff1400044d5154540402003c0008746573745f737562" + expect_close +} -run + +client c2_311_4 -connect ${h1_fe1_sock} { + # Invalid MQTT 3.1.1 CONNECT with not matching ( 0x13 != 0x14) + sendhex "101300044d5154540402003c000874657374a5f737562" + expect_close +} -run + +client c2_311_4 -connect ${h1_fe1_sock} { + # Invalid MQTT 3.1.1 CONNECT with not matching ( 0x18 != 0x14) + sendhex "101800044d5154540402003c000874657374a5f737562ffffffff" + expect_close +} -run + + +client c2_50_1 -connect ${h1_fe2_sock} { + # complex MQTT 5.0 CONNECT/CONNACK packet + # - CONNECT : + # client-id : test_sub + # username : test + # password : passwd + # will-topic : willtopic + # will-payload: willpayload + # connect props: + # maximum-packet-size : 20 + # request-problem-information: 1 + # user-property : name=a value=b + # user-property : name=c value=d + # will props: + # content-type : text/plain + # response-topic: willrsptopic + # user-property : name=e value=f + # user-property : name=g value=h + # - CONNACK : + # flags : 0x00 + # reason-code: 0x00 + # connack props: + # session-Expiry-interval: 120 + # receive-maximum : 32767 + # maximum-qos : 1 + # retain-available : 1 + # maximum-packet-size : 65535 + # topic-alias-maximum : 10 + # user-property : name=a value=b + # user-property : name=c value=d + sendhex "107e00044d51545405ee003c182700000014170126000161000162260001630001642100140008746573745f7375622a03000a746578742f706c61696e08000c77696c6c727370746f7069632600016500016626000167000168000977696c6c746f706963000b77696c6c7061796c6f61640004746573740006706173737764" + recv 39 + expect_close +} -run + +client c3_31_1 -connect ${h1_fe1_sock} { + # Valid MQTT 3.1 CONNECT packet (id: test_sub - username: test - passwd: passwd) + sendhex "102400064d514973647003c200000008746573745f7375620004746573740006706173737764" + recv 4 +} -run
\ No newline at end of file diff --git a/reg-tests/converter/secure_memcmp.vtc b/reg-tests/converter/secure_memcmp.vtc new file mode 100644 index 0000000..6ff74e6 --- /dev/null +++ b/reg-tests/converter/secure_memcmp.vtc @@ -0,0 +1,143 @@ +varnishtest "secure_memcmp converter Test" + +#REQUIRE_VERSION=2.2 +#REQUIRE_OPTION=OPENSSL + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp -hdr "Connection: close" +} -repeat 4 -start + +server s2 { + rxreq + txresp -hdr "Connection: close" +} -repeat 7 -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 + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + # This frontend matches two base64 encoded values and does not need to + # handle null bytes. + + bind "fd@${fe}" + + #### requests + http-request set-var(txn.hash) req.hdr(hash) + http-request set-var(txn.raw) req.hdr(raw) + + acl is_match var(txn.raw),sha1,base64,secure_memcmp(txn.hash) + + http-response set-header Match true if is_match + http-response set-header Match false if !is_match + + default_backend be + + frontend fe2 + # This frontend matches two binary values, needing to handle null + # bytes. + bind "fd@${fe2}" + + #### requests + http-request set-var(txn.hash) req.hdr(hash),b64dec + http-request set-var(txn.raw) req.hdr(raw) + + acl is_match var(txn.raw),sha1,secure_memcmp(txn.hash) + + http-response set-header Match true if is_match + http-response set-header Match false if !is_match + + default_backend be2 + + backend be + server s1 ${s1_addr}:${s1_port} + + backend be2 + server s2 ${s2_addr}:${s2_port} +} -start + +client c1 -connect ${h1_fe_sock} { + txreq -url "/" \ + -hdr "Raw: 1" \ + -hdr "Hash: NWoZK3kTsExUV00Ywo1G5jlUKKs=" + rxresp + expect resp.status == 200 + expect resp.http.match == "true" + txreq -url "/" \ + -hdr "Raw: 2" \ + -hdr "Hash: 2kuSN7rMzfGcB2DKt67EqDWQELA=" + rxresp + expect resp.status == 200 + expect resp.http.match == "true" + txreq -url "/" \ + -hdr "Raw: 2" \ + -hdr "Hash: 2kuSN7rMzfGcB2DKt67EqDWQELX=" + rxresp + expect resp.status == 200 + expect resp.http.match == "false" + txreq -url "/" \ + -hdr "Raw: 3" \ + -hdr "Hash: 2kuSN7rMzfGcB2DKt67EqDWQELA=" + rxresp + expect resp.status == 200 + expect resp.http.match == "false" +} -run + +client c2 -connect ${h1_fe2_sock} { + txreq -url "/" \ + -hdr "Raw: 1" \ + -hdr "Hash: NWoZK3kTsExUV00Ywo1G5jlUKKs=" + rxresp + expect resp.status == 200 + expect resp.http.match == "true" + txreq -url "/" \ + -hdr "Raw: 2" \ + -hdr "Hash: 2kuSN7rMzfGcB2DKt67EqDWQELA=" + rxresp + expect resp.status == 200 + expect resp.http.match == "true" + txreq -url "/" \ + -hdr "Raw: 2" \ + -hdr "Hash: 2kuSN7rMzfGcB2DKt67EqDWQELX=" + rxresp + expect resp.status == 200 + expect resp.http.match == "false" + txreq -url "/" \ + -hdr "Raw: 3" \ + -hdr "Hash: 2kuSN7rMzfGcB2DKt67EqDWQELA=" + rxresp + expect resp.status == 200 + expect resp.http.match == "false" + + # Test for values with leading nullbytes. + txreq -url "/" \ + -hdr "Raw: 6132845" \ + -hdr "Hash: AAAAVaeL9nNcSok1j6sd40EEw8s=" + rxresp + expect resp.status == 200 + expect resp.http.match == "true" + txreq -url "/" \ + -hdr "Raw: 49177200" \ + -hdr "Hash: AAAA9GLglTNv2JoMv2n/w9Xadhc=" + rxresp + expect resp.status == 200 + expect resp.http.match == "true" + txreq -url "/" \ + -hdr "Raw: 6132845" \ + -hdr "Hash: AAAA9GLglTNv2JoMv2n/w9Xadhc=" + rxresp + expect resp.status == 200 + expect resp.http.match == "false" +} -run diff --git a/reg-tests/converter/sha2.vtc b/reg-tests/converter/sha2.vtc new file mode 100644 index 0000000..e90e274 --- /dev/null +++ b/reg-tests/converter/sha2.vtc @@ -0,0 +1,57 @@ +varnishtest "sha2 converter Test" + +#REQUIRE_VERSION=2.1 +#REQUIRE_OPTION=OPENSSL + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp +} -repeat 2 -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + + #### requests + http-request set-var(txn.hash) req.hdr(hash) + + http-response set-header SHA2 "%[var(txn.hash),sha2,hex,lower]" + http-response set-header SHA2-224 "%[var(txn.hash),sha2(224),hex,lower]" + http-response set-header SHA2-256 "%[var(txn.hash),sha2(256),hex,lower]" + http-response set-header SHA2-384 "%[var(txn.hash),sha2(384),hex,lower]" + http-response set-header SHA2-512 "%[var(txn.hash),sha2(512),hex,lower]" + + default_backend be + + backend be + server s1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe_sock} { + txreq -url "/" \ + -hdr "Hash: 1" + rxresp + expect resp.status == 200 + expect resp.http.sha2 == "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b" + expect resp.http.sha2-224 == "e25388fde8290dc286a6164fa2d97e551b53498dcbf7bc378eb1f178" + expect resp.http.sha2-256 == "6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b" + expect resp.http.sha2-384 == "47f05d367b0c32e438fb63e6cf4a5f35c2aa2f90dc7543f8a41a0f95ce8a40a313ab5cf36134a2068c4c969cb50db776" + expect resp.http.sha2-512 == "4dff4ea340f0a823f15d3f4f01ab62eae0e5da579ccb851f8db9dfe84c58b2b37b89903a740e1ee172da793a6e79d560e5f7f9bd058a12a280433ed6fa46510a" + txreq -url "/" \ + -hdr "Hash: 2" + rxresp + expect resp.status == 200 + expect resp.http.sha2 == "d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35" + expect resp.http.sha2-224 == "58b2aaa0bfae7acc021b3260e941117b529b2e69de878fd7d45c61a9" + expect resp.http.sha2-256 == "d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35" + expect resp.http.sha2-384 == "d063457705d66d6f016e4cdd747db3af8d70ebfd36badd63de6c8ca4a9d8bfb5d874e7fbd750aa804dcaddae7eeef51e" + expect resp.http.sha2-512 == "40b244112641dd78dd4f93b6c9190dd46e0099194d5a44257b7efad6ef9ff4683da1eda0244448cb343aa688f5d3efd7314dafe580ac0bcbf115aeca9e8dc114" +} -run diff --git a/reg-tests/converter/url_dec.vtc b/reg-tests/converter/url_dec.vtc new file mode 100644 index 0000000..d5e317b --- /dev/null +++ b/reg-tests/converter/url_dec.vtc @@ -0,0 +1,37 @@ +varnishtest "url_dec converter Test" + + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp +} -repeat 2 -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + + http-request set-var(txn.url) url + http-response set-header url_dec0 "%[var(txn.url),url_dec]" + http-response set-header url_dec1 "%[var(txn.url),url_dec(1)]" + + default_backend be + + backend be + server s1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe_sock} { + txreq -url "/bla+%20?foo%3Dbar%2B42+42%20" + rxresp + expect resp.http.url_dec0 == "/bla+ ?foo=bar+42 42 " + expect resp.http.url_dec1 == "/bla ?foo=bar+42 42 " + expect resp.status == 200 +} -run diff --git a/reg-tests/converter/url_enc.vtc b/reg-tests/converter/url_enc.vtc new file mode 100644 index 0000000..74acac8 --- /dev/null +++ b/reg-tests/converter/url_enc.vtc @@ -0,0 +1,43 @@ +varnishtest "url_enc converter test" + +#REQUIRE_VERSION=2.4 + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp +} -repeat 2 -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + + http-request set-var(txn.url0) "str(foo=bar+42 42 )" + http-request set-var(txn.url1) "var(txn.url0),url_enc" + http-request set-var(txn.url2) "var(txn.url1),url_dec" + http-request set-var(txn.url3) "var(txn.url2),url_enc(query)" + http-response set-header url_enc0 "%[var(txn.url1)]" + http-response set-header url_dec "%[var(txn.url2)]" + http-response set-header url_enc1 "%[var(txn.url3)]" + + default_backend be + + backend be + server s1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe_sock} { + txreq -url "/" + rxresp + expect resp.http.url_enc0 == "foo%3Dbar%2B42%2042%20" + expect resp.http.url_dec == "foo=bar+42 42 " + expect resp.http.url_enc1 == "foo%3Dbar%2B42%2042%20" + expect resp.status == 200 +} -run diff --git a/reg-tests/filters/random-forwarding.vtc b/reg-tests/filters/random-forwarding.vtc new file mode 100644 index 0000000..87e29a6 --- /dev/null +++ b/reg-tests/filters/random-forwarding.vtc @@ -0,0 +1,139 @@ +varnishtest "Filtering test with several filters and random forwarding (via trace filter)" + +#REQUIRE_VERSION=2.4 +#REQUIRE_OPTION=ZLIB|SLZ +#REGTEST_TYPE=slow + +feature ignore_unknown_macro + +barrier b1 cond 2 -cyclic + +server s1 { + rxreq + expect req.url == "/" + expect req.bodylen == 1048576 + expect req.http.accept-encoding == "<undef>" + txresp \ + -hdr "Content-Type: text/plain" \ + -bodylen 1048576 + + rxreq + expect req.url == "127.0.0.1:80" + txresp \ + -hdr "Content-Length: 0" + recv 36000 + send_n 1000 "0123456789abcdefghijklmnopqrstuvwxyz" + barrier b1 sync + + accept + rxreq + expect req.url == "/" + txresp -nolen \ + -hdr "Content-Type: text/plain" \ + -bodylen 20480 + close + + accept + rxreq + expect req.url == "/" + txresp -nolen + close + + accept + rxreq + expect req.url == "/" + expect req.bodylen == 20480 + txresp -nolen \ + -hdr "Content-Type: text/plain" \ + -bodylen 20480 + +} -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe1}" + + compression offload + compression algo gzip + + filter trace name "BEFORE" random-forwarding quiet + filter compression + filter trace name "AFTER" random-forwarding quiet + default_backend be1 + + backend be1 + server www ${s1_addr}:${s1_port} + + listen li1 + mode tcp + bind "fd@${li1}" + # Validate nothing is blocked in TCP mode + filter compression + server www ${s1_addr}:${s1_port} + + +} -start + +client c1 -connect ${h1_fe1_sock} { + txreq -url "/" \ + -hdr "Accept-Encoding: gzip" \ + -hdr "Content-Type: text/plain" \ + -bodylen 1048576 + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "gzip" + expect resp.http.transfer-encoding == "chunked" + gunzip + expect resp.bodylen == 1048576 + + txreq -method "CONNECT" -url "127.0.0.1:80" -nolen + rxresp + expect resp.status == 200 + send_n 1000 "0123456789abcdefghijklmnopqrstuvwxyz" + recv 36000 + barrier b1 sync +} -run + +client c2 -connect ${h1_fe1_sock} { + txreq -url "/" \ + -hdr "Accept-Encoding: gzip" \ + -hdr "Content-Type: text/plain" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "<undef>" + expect resp.http.transfer-encoding == "<undef>" + expect resp.http.content-length == "<undef>" + expect resp.bodylen == 20480 +} -run + +client c3 -connect ${h1_fe1_sock} { + txreq -url "/" \ + -hdr "Accept-Encoding: gzip" \ + -hdr "Content-Type: text/plain" + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "<undef>" + expect resp.http.transfer-encoding == "<undef>" + expect resp.http.content-length == "<undef>" + expect resp.bodylen == 0 +} -run + +client c4 -connect ${h1_li1_sock} { + txreq -url "/" \ + -hdr "Accept-Encoding: gzip" \ + -hdr "Content-Type: text/plain" \ + -bodylen 20480 + rxresp + expect resp.status == 200 + expect resp.http.content-encoding == "<undef>" + expect resp.http.transfer-encoding == "<undef>" + expect resp.http.content-length == "<undef>" + expect resp.bodylen == 20480 + expect_close +} -run diff --git a/reg-tests/http-capture/multiple_headers.vtc b/reg-tests/http-capture/multiple_headers.vtc new file mode 100644 index 0000000..1ae210b --- /dev/null +++ b/reg-tests/http-capture/multiple_headers.vtc @@ -0,0 +1,91 @@ +varnishtest "Tests for 'capture (request|response) header" +feature ignore_unknown_macro + +# This script checks that the last occurrences of "fooresp" and "fooreq" header +# are correctly captured and added to the logs. +# Note that varnishtest does not support more than MAX_HDR header. + +syslog S -level info { + recv + expect ~ "[^:\\[ ]\\[${h_pid}\\]: .* .* fe be/srv .* 200 1[0-9]{4} - - ---- .* .* {HPhx8n59qjjNBLjP} {htb56qDdCcbRVTfS} \"GET / HTTP/1\\.1\"" +} -start + +server s { + rxreq + txresp -hdr "fooresp: HnFDGJ6KvhSG5QjX" -hdr "fooresp: 8dp7vBMQjTMkVwtG" \ + -hdr "fooresp: NTpxWmvsNKGxvH6K" -hdr "fooresp: sPKNNJ5VRBDz9qXP" \ + -hdr "fooresp: HnFDGJ6KvhSG5QjX" -hdr "fooresp: 8dp7vBMQjTMkVwtG" \ + -hdr "fooresp: VSNnccbGkvfM9JK9" -hdr "fooresp: 9D5cjwtK3LCxmg4F" \ + -hdr "fooresp: dsbxGqlBPRWGP3vX" -hdr "fooresp: xf6VK6GXlgdj5mwc" \ + -hdr "fooresp: 8jzM3clRKtdL2WWb" -hdr "fooresp: v7ZHrTPjDR6lm6Bg" \ + -hdr "fooresp: FQT6th9whMqQ7Z6C" -hdr "fooresp: KM22HH6lRBw6SHQT" \ + -hdr "fooresp: PmRHphHXmTV9kZNS" -hdr "fooresp: CkGRbTJrD5nSVpFk" \ + -hdr "fooresp: KQ9mzmMHpmmZ2SXP" -hdr "fooresp: W5FqfFDN6dqBxjK7" \ + -hdr "fooresp: bvcxNPK4gpnTvn3z" -hdr "fooresp: BSXRLSWMsgQN54cC" \ + -hdr "fooresp: ZX9ttTnlbXtJK55d" -hdr "fooresp: KH9StjMHF73NqzL8" \ + -hdr "fooresp: W2q2m6MvMLcnXsX7" -hdr "fooresp: wtrjnJgFzHDvMg5r" \ + -hdr "fooresp: Vpk2c2DsbWf2Gtwh" -hdr "fooresp: sCcW2qpRhFHHRDpH" \ + -hdr "fooresp: P4mltXtvxLsnPcNS" -hdr "fooresp: TXgdSKNMmsJ8x9zq" \ + -hdr "fooresp: n5t8pdZgnGFXZDd3" -hdr "fooresp: pD84GCtkWZqWbCM9" \ + -hdr "fooresp: wx2FPxsGqSRjNVws" -hdr "fooresp: TXmtBCqPTVGFc3NK" \ + -hdr "fooresp: 4DrFTLxpcPk2n3Zv" -hdr "fooresp: vrcFr9MWpqJWhK4h" \ + -hdr "fooresp: HMsCHMZnHT3q8qD2" -hdr "fooresp: HsCXQGTxDpsMf4z6" \ + -hdr "fooresp: 9rb2vjvvd2SzCQVT" -hdr "fooresp: qn5C2fZTWHVp7NkC" \ + -hdr "fooresp: ZVd5ltcngZFHXfvr" -hdr "fooresp: j6BZVdV8fkz5tgjR" \ + -hdr "fooresp: 6qfVwfHqdfntQjmP" -hdr "fooresp: RRr9nTnwjG6d2x7X" \ + -hdr "fooresp: RJXtWtdJRTss6JgZ" -hdr "fooresp: zzHZWm6bqXDN9k47" \ + -hdr "fooresp: htb56qDdCcbRVTfS" \ + -bodylen 16384 +} -start + +haproxy h -conf { + defaults + mode http + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + + backend be + server srv ${s_addr}:${s_port} + + frontend fe + option httplog + log ${S_addr}:${S_port} local0 debug err + capture request header fooreq len 25 + capture response header fooresp len 25 + + bind "fd@${fe}" + use_backend be +} -start + +client c1 -connect ${h_fe_sock} { + txreq -hdr "fooreq: c8Ck8sx8qfXk5pSS" -hdr "fooreq: TGNXbG2DF3TmLWK3" \ + -hdr "fooreq: mBxq9Cgr8GN6hkt6" -hdr "fooreq: MHZ6VBCPgs564KfR" \ + -hdr "fooreq: BCCwX2kL9BSMCqvt" -hdr "fooreq: 8rXw87xVTphpRQb7" \ + -hdr "fooreq: gJ3Tp9kXQlqLC8Qp" -hdr "fooreq: dFnLs6wpMl2M5N7c" \ + -hdr "fooreq: r3f9WgQ8Brqw37Kj" -hdr "fooreq: dbJzSSdCqV3ZVtXK" \ + -hdr "fooreq: 5HxHd6g4n2Rj2CNG" -hdr "fooreq: HNqQSNfkt6q4zK26" \ + -hdr "fooreq: rzqNcfskPR7vW4jG" -hdr "fooreq: 9c7txWhsdrwmkR6d" \ + -hdr "fooreq: 3v8Nztg9l9vLSKJm" -hdr "fooreq: lh4WDxMX577h4z3l" \ + -hdr "fooreq: mFtHj5SKDvfcGzfq" -hdr "fooreq: PZ5B5wRM9D7GLm7W" \ + -hdr "fooreq: fFpN4zCkLTxzp5Dz" -hdr "fooreq: J5XMdfCCHmmwkr2f" \ + -hdr "fooreq: KqssZ3SkZnZJF8mz" -hdr "fooreq: HrGgsnBnslKN7Msz" \ + -hdr "fooreq: d8TQltZ39xFZBNx2" -hdr "fooreq: mwDt2k2tvqM8x5kQ" \ + -hdr "fooreq: 7Qh6tM7s7z3P8XCl" -hdr "fooreq: S3mTVbbPhJbLR7n2" \ + -hdr "fooreq: zr7hMDvrrwfvpmTT" -hdr "fooreq: lV9TnZX2CtSnr4k8" \ + -hdr "fooreq: bMdJx8pVDG2nWFNg" -hdr "fooreq: FkGvB2cBwNrB3cm4" \ + -hdr "fooreq: 5ckNn3m6m8r2CXLF" -hdr "fooreq: sk4pJGTSZ5HMPJP5" \ + -hdr "fooreq: HgVgQ73zhLwX6Wzq" -hdr "fooreq: T5k2QbFKvCVJlz4c" \ + -hdr "fooreq: SKcNPw8CXGKhtxNP" -hdr "fooreq: n9fFrcR2kRQJrCpZ" \ + -hdr "fooreq: hrJ2MXCdcSCDhQ6n" -hdr "fooreq: 9xsWQ8srzLDvG9F4" \ + -hdr "fooreq: GNcP9NBTFJkg4hbk" -hdr "fooreq: Vg8B8MNwz4T7q5Tj" \ + -hdr "fooreq: XXns3qPCzZmt9j4G" -hdr "fooreq: hD7TnP43bcPHm5g2" \ + -hdr "fooreq: wZbxVq7MwmfBSqb5" -hdr "fooreq: HPhx8n59qjjNBLjP" \ + -bodylen 16384 + rxresp + expect resp.status == 200 +} -start + +server s -wait +syslog S -wait + diff --git a/reg-tests/http-cookies/cookie_insert_indirect.vtc b/reg-tests/http-cookies/cookie_insert_indirect.vtc new file mode 100644 index 0000000..6b86360 --- /dev/null +++ b/reg-tests/http-cookies/cookie_insert_indirect.vtc @@ -0,0 +1,54 @@ +varnishtest "HTTP cookie basic test" +feature ignore_unknown_macro + +# This script tests "cookie <name> insert indirect" directive. +# The client sends a wrong "SRVID=s2" cookie. +# haproxy removes it. +# The server replies with "SRVID=S1" after having checked that +# no cookies were sent by haproxy. +# haproxy replies "SRVID=server-one" to the client. +# We log the HTTP request to a syslog server and check their "--II" +# (invalid, insert) flags. + +syslog S1 -level notice { + recv info + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* fe1 be1/srv1 .* --II .* \"GET / HTTP/1\\.1\"" +} -start + +server s1 { + rxreq + expect req.http.cookie == <undef> + txresp -hdr "Cookie: SRVID=S1" +} -start + +haproxy h1 -conf { + global + log ${S1_addr}:${S1_port} len 2048 local0 debug err + + defaults + mode http + option httplog + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + log global + + backend be1 + cookie SRVID insert indirect + server srv1 ${s1_addr}:${s1_port} cookie server-one + + frontend fe1 + option httplog + bind "fd@${fe1}" + use_backend be1 +} -start + +client c1 -connect ${h1_fe1_sock} { + txreq -hdr "Cookie: SRVID=s2" + rxresp + expect resp.http.Set-Cookie ~ "^SRVID=server-one;.*" +} -start + + +client c1 -wait +syslog S1 -wait diff --git a/reg-tests/http-cookies/h2_cookie_concat.vtc b/reg-tests/http-cookies/h2_cookie_concat.vtc new file mode 100644 index 0000000..e2e6d81 --- /dev/null +++ b/reg-tests/http-cookies/h2_cookie_concat.vtc @@ -0,0 +1,42 @@ +varnishtest "HTTP/2 cookie concatenation" +feature ignore_unknown_macro + +server s1 { + rxreq + expect req.http.cookie == "c1=foo; c2=bar; c3=baz" + txresp +} -start + +haproxy h1 -conf { + defaults + mode http + + frontend fe1 + bind "fd@${fe1}" proto h2 + use_backend be1 + + backend be1 + server srv1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe1_sock} { + txpri + stream 0 { + txsettings + rxsettings + txsettings -ack + rxsettings + expect settings.ack == true + } -run + + stream 1 { + txreq \ + -req "GET" \ + -scheme "http" \ + -url "/" \ + -hdr "cookie" "c1=foo" \ + -hdr "cookie" "c2=bar" \ + -hdr "cookie" "c3=baz" + rxhdrs + } -run +} -run diff --git a/reg-tests/http-errorfiles/errorfiles.vtc b/reg-tests/http-errorfiles/errorfiles.vtc new file mode 100644 index 0000000..1ace744 --- /dev/null +++ b/reg-tests/http-errorfiles/errorfiles.vtc @@ -0,0 +1,51 @@ +varnishtest "Test the errofile directive in proxy sections" + +# This config tests the errorfile directive in proxy sections (including the +# defaults section). + +feature ignore_unknown_macro + + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + errorfile 400 ${testdir}/errors/400.http + errorfile 403 ${testdir}/errors/403.http + errorfile 408 /dev/null + + frontend fe1 + bind "fd@${fe1}" + + errorfile 403 ${testdir}/errors/403-1.http + errorfile 500 /dev/null + + http-request deny deny_status 400 if { path /400 } + http-request deny deny_status 403 if { path /403 } + http-request deny deny_status 408 if { path /408 } + http-request deny deny_status 500 if { path /500 } + +} -start + +client c1r1 -connect ${h1_fe1_sock} { + txreq -req GET -url /400 + rxresp + expect resp.status == 400 + expect resp.http.x-err-type == "default" +} -run +client c1r2 -connect ${h1_fe1_sock} { + txreq -req GET -url /403 + rxresp + expect resp.status == 403 + expect resp.http.x-err-type == "errors-1" +} -run +client c1r3 -connect ${h1_fe1_sock} { + txreq -req GET -url /408 + expect_close +} -run +client c1r4 -connect ${h1_fe1_sock} { + txreq -req GET -url /500 + expect_close +} -run diff --git a/reg-tests/http-errorfiles/errors/400-1.http b/reg-tests/http-errorfiles/errors/400-1.http new file mode 100644 index 0000000..86a2e69 --- /dev/null +++ b/reg-tests/http-errorfiles/errors/400-1.http @@ -0,0 +1,9 @@ +HTTP/1.1 400 Bad request
+Cache-Control: no-cache
+Connection: close
+Content-Type: text/html
+x-err-type: errors-1
+
+<html><body><h1>400 Bad request</h1> +Your browser sent an invalid request. +</body></html> diff --git a/reg-tests/http-errorfiles/errors/400-2.http b/reg-tests/http-errorfiles/errors/400-2.http new file mode 100644 index 0000000..c108510 --- /dev/null +++ b/reg-tests/http-errorfiles/errors/400-2.http @@ -0,0 +1,9 @@ +HTTP/1.1 400 Bad request
+Cache-Control: no-cache
+Connection: close
+Content-Type: text/html
+x-err-type: errors-2
+
+<html><body><h1>400 Bad request</h1> +Your browser sent an invalid request. +</body></html> diff --git a/reg-tests/http-errorfiles/errors/400-3.http b/reg-tests/http-errorfiles/errors/400-3.http new file mode 100644 index 0000000..1fe1841 --- /dev/null +++ b/reg-tests/http-errorfiles/errors/400-3.http @@ -0,0 +1,9 @@ +HTTP/1.1 400 Bad request
+Cache-Control: no-cache
+Connection: close
+Content-Type: text/html
+x-err-type: errors-3
+
+<html><body><h1>400 Bad request</h1> +Your browser sent an invalid request. +</body></html> diff --git a/reg-tests/http-errorfiles/errors/400.http b/reg-tests/http-errorfiles/errors/400.http new file mode 100644 index 0000000..ce229aa --- /dev/null +++ b/reg-tests/http-errorfiles/errors/400.http @@ -0,0 +1,9 @@ +HTTP/1.1 400 Bad request
+Cache-Control: no-cache
+Connection: close
+Content-Type: text/html
+x-err-type: default
+
+<html><body><h1>400 Bad request</h1> +Your browser sent an invalid request. +</body></html> diff --git a/reg-tests/http-errorfiles/errors/403-1.http b/reg-tests/http-errorfiles/errors/403-1.http new file mode 100644 index 0000000..08bdf02 --- /dev/null +++ b/reg-tests/http-errorfiles/errors/403-1.http @@ -0,0 +1,9 @@ +HTTP/1.0 403 Forbidden
+Cache-Control: no-cache
+Connection: close
+Content-Type: text/html
+x-err-type: errors-1
+
+<html><body><h1>403 Forbidden</h1> +Request forbidden by administrative rules. +</body></html> diff --git a/reg-tests/http-errorfiles/errors/403-2.http b/reg-tests/http-errorfiles/errors/403-2.http new file mode 100644 index 0000000..9c07e5d --- /dev/null +++ b/reg-tests/http-errorfiles/errors/403-2.http @@ -0,0 +1,9 @@ +HTTP/1.0 403 Forbidden
+Cache-Control: no-cache
+Connection: close
+Content-Type: text/html
+x-err-type: errors-2
+
+<html><body><h1>403 Forbidden</h1> +Request forbidden by administrative rules. +</body></html> diff --git a/reg-tests/http-errorfiles/errors/403.http b/reg-tests/http-errorfiles/errors/403.http new file mode 100644 index 0000000..fd969b2 --- /dev/null +++ b/reg-tests/http-errorfiles/errors/403.http @@ -0,0 +1,9 @@ +HTTP/1.0 403 Forbidden
+Cache-Control: no-cache
+Connection: close
+Content-Type: text/html
+x-err-type: default
+
+<html><body><h1>403 Forbidden</h1> +Request forbidden by administrative rules. +</body></html> diff --git a/reg-tests/http-errorfiles/errors/404-1.http b/reg-tests/http-errorfiles/errors/404-1.http new file mode 100644 index 0000000..154ed0b --- /dev/null +++ b/reg-tests/http-errorfiles/errors/404-1.http @@ -0,0 +1,9 @@ +HTTP/1.1 404 Not Found
+Cache-Control: no-cache
+Connection: close
+Content-Type: text/html
+x-err-type: errors-1
+
+<html><body><h1>404 Not Found</h1> +The resource could not be found. +</body></html> diff --git a/reg-tests/http-errorfiles/errors/404-2.http b/reg-tests/http-errorfiles/errors/404-2.http new file mode 100644 index 0000000..e26f91d --- /dev/null +++ b/reg-tests/http-errorfiles/errors/404-2.http @@ -0,0 +1,9 @@ +HTTP/1.1 404 Not Found
+Cache-Control: no-cache
+Connection: close
+Content-Type: text/html
+x-err-type: errors-2
+
+<html><body><h1>404 Not Found</h1> +The resource could not be found. +</body></html> diff --git a/reg-tests/http-errorfiles/errors/404-3.http b/reg-tests/http-errorfiles/errors/404-3.http new file mode 100644 index 0000000..4bc1661 --- /dev/null +++ b/reg-tests/http-errorfiles/errors/404-3.http @@ -0,0 +1,9 @@ +HTTP/1.1 404 Not Found
+Cache-Control: no-cache
+Connection: close
+Content-Type: text/html
+x-err-type: errors-3
+
+<html><body><h1>404 Not Found</h1> +The resource could not be found. +</body></html> diff --git a/reg-tests/http-errorfiles/errors/404.http b/reg-tests/http-errorfiles/errors/404.http new file mode 100644 index 0000000..8dacd95 --- /dev/null +++ b/reg-tests/http-errorfiles/errors/404.http @@ -0,0 +1,9 @@ +HTTP/1.1 404 Not Found
+Cache-Control: no-cache
+Connection: close
+Content-Type: text/html
+x-err-type: default
+
+<html><body><h1>404 Not Found</h1> +The resource could not be found. +</body></html> diff --git a/reg-tests/http-errorfiles/errors/500-1.http b/reg-tests/http-errorfiles/errors/500-1.http new file mode 100644 index 0000000..4e4f7e4 --- /dev/null +++ b/reg-tests/http-errorfiles/errors/500-1.http @@ -0,0 +1,9 @@ +HTTP/1.0 500 Internal Server Error
+Cache-Control: no-cache
+Connection: close
+Content-Type: text/html
+x-err-type: errors-1
+
+<html><body><h1>500 Internal Server Error</h1> +An internal server error occurred. +</body></html> diff --git a/reg-tests/http-errorfiles/errors/500.http b/reg-tests/http-errorfiles/errors/500.http new file mode 100644 index 0000000..68a31ff --- /dev/null +++ b/reg-tests/http-errorfiles/errors/500.http @@ -0,0 +1,9 @@ +HTTP/1.0 500 Internal Server Error
+Cache-Control: no-cache
+Connection: close
+Content-Type: text/html
+x-err-type: default
+
+<html><body><h1>500 Internal Server Error</h1> +An internal server error occurred. +</body></html> diff --git a/reg-tests/http-errorfiles/errors/lf-403.txt b/reg-tests/http-errorfiles/errors/lf-403.txt new file mode 100644 index 0000000..3a3c3aa --- /dev/null +++ b/reg-tests/http-errorfiles/errors/lf-403.txt @@ -0,0 +1 @@ +The path "%[path]" is forbidden diff --git a/reg-tests/http-errorfiles/http-error.vtc b/reg-tests/http-errorfiles/http-error.vtc new file mode 100644 index 0000000..1af909b --- /dev/null +++ b/reg-tests/http-errorfiles/http-error.vtc @@ -0,0 +1,75 @@ +varnishtest "Test the http-error directive" +#REQUIRE_VERSION=2.2 + +# This config tests the http-error directive. + +feature ignore_unknown_macro + + +haproxy h1 -conf { + http-errors errors-1 + errorfile 400 ${testdir}/errors/400-1.http + errorfile 403 ${testdir}/errors/403-1.http + errorfile 404 ${testdir}/errors/404-1.http + errorfile 500 ${testdir}/errors/500-1.http + + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + errorfile 400 ${testdir}/errors/400.http + errorfile 404 ${testdir}/errors/404.http + + frontend fe1 + bind "fd@${fe1}" + + http-error status 400 + http-error status 403 default-errorfiles + http-error status 404 errorfiles errors-1 + http-error status 500 errorfile ${testdir}/errors/500.http + http-error status 200 content-type "text/plain" hdr x-path "path=%[path]" lf-string "The path is \"%[path]\"" + + http-request return status 200 default-errorfiles if { path /200 } + http-request deny deny_status 400 if { path /400 } + http-request deny deny_status 403 if { path /403 } + http-request deny deny_status 404 if { path /404 } + http-request deny deny_status 500 if { path /500 } + +} -start + +client c1r1 -connect ${h1_fe1_sock} { + txreq -req GET -url /200 + rxresp + expect resp.status == 200 + expect resp.http.x-path == "path=/200" + expect resp.http.content-type == "text/plain" + expect resp.body == "The path is \"/200\"" +} -run +client c1r2 -connect ${h1_fe1_sock} { + txreq -req GET -url /400 + rxresp + expect resp.status == 400 + expect resp.http.x-err-type == <undef> + expect resp.http.content-length == 0 +} -run +client c1r3 -connect ${h1_fe1_sock} { + txreq -req GET -url /403 + rxresp + expect resp.status == 403 + expect resp.http.x-err-type == <undef> + expect resp.http.content-length == 93 + expect resp.http.content-type == "text/html" +} -run +client c1r3 -connect ${h1_fe1_sock} { + txreq -req GET -url /404 + rxresp + expect resp.status == 404 + expect resp.http.x-err-type == "errors-1" +} -run +client c1r4 -connect ${h1_fe1_sock} { + txreq -req GET -url /500 + rxresp + expect resp.status == 500 + expect resp.http.x-err-type == "default" +} -run diff --git a/reg-tests/http-errorfiles/http_deny_errors.vtc b/reg-tests/http-errorfiles/http_deny_errors.vtc new file mode 100644 index 0000000..353045d --- /dev/null +++ b/reg-tests/http-errorfiles/http_deny_errors.vtc @@ -0,0 +1,77 @@ +varnishtest "Test the custom errors for HTTP deny rules" +#REQUIRE_VERSION=2.2 + +# This config tests the custom errors for HTTP deny rules. + +feature ignore_unknown_macro + + +haproxy h1 -conf { + http-errors errors-1 + errorfile 400 ${testdir}/errors/400-1.http + errorfile 403 ${testdir}/errors/403-1.http + errorfile 404 ${testdir}/errors/404-1.http + errorfile 500 /dev/null + + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe1}" + http-request deny deny_status 400 if { path /400 } + http-request deny deny_status 403 errorfile ${testdir}/errors/403.http if { path /403 } + http-request deny deny_status 404 errorfiles errors-1 if { path /404 } + http-request deny deny_status 500 errorfile /dev/null if { path /500-1 } + http-request deny deny_status 500 errorfiles errors-1 if { path /500-2 } + + http-request deny status 500 hdr x-err-info "path=%[path]" content-type "text/plain" string "Internal Error" if { path /int-err } + http-request deny status 403 hdr x-err-info "path=%[path]" content-type "text/plain" lf-file ${testdir}/errors/lf-403.txt if { path /forbidden } + +} -start + +client c1r1 -connect ${h1_fe1_sock} { + txreq -req GET -url /400 + rxresp + expect resp.status == 400 + expect resp.http.x-err-type == <undef> +} -run +client c1r2 -connect ${h1_fe1_sock} { + txreq -req GET -url /403 + rxresp + expect resp.status == 403 + expect resp.http.x-err-type == "default" +} -run +client c1r3 -connect ${h1_fe1_sock} { + txreq -req GET -url /404 + rxresp + expect resp.status == 404 + expect resp.http.x-err-type == "errors-1" +} -run +client c1r4 -connect ${h1_fe1_sock} { + txreq -req GET -url /500-1 + expect_close +} -run +client c1r5 -connect ${h1_fe1_sock} { + txreq -req GET -url /500-2 + expect_close +} -run +client c1r6 -connect ${h1_fe1_sock} { + txreq -req GET -url /int-err + rxresp + expect resp.status == 500 + expect resp.http.x-err-info == "path=/int-err" + expect resp.http.content-type == "text/plain" + expect resp.http.content-length == 14 + expect resp.body == "Internal Error" +} -run +client c1r7 -connect ${h1_fe1_sock} { + txreq -req GET -url /forbidden + rxresp + expect resp.status == 403 + expect resp.http.x-err-info == "path=/forbidden" + expect resp.http.content-type == "text/plain" + expect resp.body == "The path \"/forbidden\" is forbidden\n" +} -run diff --git a/reg-tests/http-errorfiles/http_errors.vtc b/reg-tests/http-errorfiles/http_errors.vtc new file mode 100644 index 0000000..6b20be7 --- /dev/null +++ b/reg-tests/http-errorfiles/http_errors.vtc @@ -0,0 +1,134 @@ +varnishtest "Test the errorfiles directive" +#REQUIRE_VERSION=2.2 + +# This config tests the errorfiles directive. + +feature ignore_unknown_macro + + +haproxy h1 -conf { + http-errors errors-1 + errorfile 400 ${testdir}/errors/400-1.http + errorfile 403 ${testdir}/errors/403-1.http + errorfile 404 ${testdir}/errors/404-1.http + errorfile 500 ${testdir}/errors/500-1.http + + http-errors errors-2 + errorfile 400 ${testdir}/errors/400-2.http + errorfile 403 ${testdir}/errors/403-2.http + errorfile 404 ${testdir}/errors/404-2.http + + http-errors errors-3 + errorfile 400 ${testdir}/errors/400-3.http + errorfile 404 ${testdir}/errors/404-3.http + + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + errorfiles errors-2 + errorfile 400 ${testdir}/errors/400.http + errorfile 404 ${testdir}/errors/404.http + + frontend fe1 + bind "fd@${fe1}" + http-request deny deny_status 400 if { path /400 } + http-request deny if { path /403 } + http-request deny deny_status 404 if { path /404 } + http-request deny deny_status 500 if { path /500 } + + frontend fe2 + bind "fd@${fe2}" + errorfiles errors-1 + errorfile 500 ${testdir}/errors/500.http + http-request deny deny_status 400 if { path /400 } + http-request deny if { path /403 } + http-request deny deny_status 404 if { path /404 } + http-request deny deny_status 500 if { path /500 } + + frontend fe3 + bind "fd@${fe3}" + errorfile 500 ${testdir}/errors/500.http + errorfiles errors-1 500 + errorfiles errors-3 400 + http-request deny deny_status 400 if { path /400 } + http-request deny if { path /403 } + http-request deny deny_status 404 if { path /404 } + http-request deny deny_status 500 if { path /500 } +} -start + +client c1r1 -connect ${h1_fe1_sock} { + txreq -req GET -url /400 + rxresp + expect resp.status == 400 + expect resp.http.x-err-type == "default" +} -run +client c1r2 -connect ${h1_fe1_sock} { + txreq -req GET -url /403 + rxresp + expect resp.status == 403 + expect resp.http.x-err-type == "errors-2" +} -run +client c1r3 -connect ${h1_fe1_sock} { + txreq -req GET -url /404 + rxresp + expect resp.status == 404 + expect resp.http.x-err-type == "default" +} -run +client c1r4 -connect ${h1_fe1_sock} { + txreq -req GET -url /500 + rxresp + expect resp.status == 500 + expect resp.http.x-err-type == <undef> +} -run + +client c2r1 -connect ${h1_fe2_sock} { + txreq -req GET -url /400 + rxresp + expect resp.status == 400 + expect resp.http.x-err-type == "errors-1" +} -run +client c2r2 -connect ${h1_fe2_sock} { + txreq -req GET -url /403 + rxresp + expect resp.status == 403 + expect resp.http.x-err-type == "errors-1" +} -run +client c2r3 -connect ${h1_fe2_sock} { + txreq -req GET -url /404 + rxresp + expect resp.status == 404 + expect resp.http.x-err-type == "errors-1" +} -run +client c2r4 -connect ${h1_fe2_sock} { + txreq -req GET -url /500 + rxresp + expect resp.status == 500 + expect resp.http.x-err-type == "default" +} -run + +client c3r1 -connect ${h1_fe3_sock} { + txreq -req GET -url /400 + rxresp + expect resp.status == 400 + expect resp.http.x-err-type == "errors-3" +} -run +client c3r2 -connect ${h1_fe3_sock} { + txreq -req GET -url /403 + rxresp + expect resp.status == 403 + expect resp.http.x-err-type == "errors-2" +} -run +client c3r3 -connect ${h1_fe3_sock} { + txreq -req GET -url /404 + rxresp + expect resp.status == 404 + expect resp.http.x-err-type == "default" +} -run +client c3r4 -connect ${h1_fe3_sock} { + txreq -req GET -url /500 + rxresp + expect resp.status == 500 + expect resp.http.x-err-type == "errors-1" +} -run diff --git a/reg-tests/http-errorfiles/http_return.vtc b/reg-tests/http-errorfiles/http_return.vtc new file mode 100644 index 0000000..8db77a9 --- /dev/null +++ b/reg-tests/http-errorfiles/http_return.vtc @@ -0,0 +1,46 @@ +varnishtest "Test the HTTP return action with errorfiles" +#REQUIRE_VERSION=2.2 + +# This config tests the HTTP return action when error files are used to reply to +# the client. + +feature ignore_unknown_macro + +haproxy h1 -conf { + http-errors errors-2 + errorfile 400 ${testdir}/errors/400-2.http + + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe1}" + errorfile 400 ${testdir}/errors/400.http + http-request return status 400 default-errorfiles if { path /def } + http-request return status 400 errorfile ${testdir}/errors/400-1.http if { path /400-1 } + http-request return status 400 errorfiles errors-2 if { path /400-2 } +} -start + +client c1 -connect ${h1_fe1_sock} { + txreq -req GET -url /def + rxresp + expect resp.status == 400 + expect resp.http.x-err-type == "default" +} -run + +client c1r2 -connect ${h1_fe1_sock} { + txreq -req GET -url /400-1 + rxresp + expect resp.status == 400 + expect resp.http.x-err-type == "errors-1" +} -run + +client c1r3 -connect ${h1_fe1_sock} { + txreq -req GET -url /400-2 + rxresp + expect resp.status == 400 + expect resp.http.x-err-type == "errors-2" +} -run diff --git a/reg-tests/http-messaging/common.pem b/reg-tests/http-messaging/common.pem new file mode 120000 index 0000000..a4433d5 --- /dev/null +++ b/reg-tests/http-messaging/common.pem @@ -0,0 +1 @@ +../ssl/common.pem
\ No newline at end of file diff --git a/reg-tests/http-messaging/h1_host_normalization.vtc b/reg-tests/http-messaging/h1_host_normalization.vtc new file mode 100644 index 0000000..5855034 --- /dev/null +++ b/reg-tests/http-messaging/h1_host_normalization.vtc @@ -0,0 +1,603 @@ +varnishtest "H1 authority validation and host normalizarion based on the scheme (rfc3982 6.3.2) or the method (connect)" + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.6-dev0)'" +feature ignore_unknown_macro + +syslog S1 -level info { + # C1 + recv + expect ~ "^.* uri: GET http://toto:poue@hostname/c1 HTTP/1.1; host: {hostname}$" + + # C2 + recv + expect ~ "^.* uri: GET http://hostname:8080/c2 HTTP/1.1; host: {hostname:8080}$" + + # C3 + recv + expect ~ "^.* uri: GET https://hostname/c3 HTTP/1.1; host: {hostname}$" + + # C4 + recv + expect ~ "^.* uri: GET https://hostname:80/c4 HTTP/1.1; host: {hostname:80}$" + + # C5 + recv + expect ~ "^.* uri: CONNECT hostname:80 HTTP/1.1; host: {hostname}$" + recv + expect ~ "^.* uri: CONNECT hostname:80 HTTP/1.1; host: {hostname}$" + recv + expect ~ "^.* uri: CONNECT hostname:80 HTTP/1.1; host: {hostname:}$" + + # C6 + recv + expect ~ "^.* uri: CONNECT hostname:443 HTTP/1.1; host: {hostname}$" + recv + expect ~ "^.* uri: CONNECT hostname:443 HTTP/1.1; host: {hostname}$" + recv + expect ~ "^.* uri: CONNECT hostname:443 HTTP/1.1; host: {hostname:}$" + + # C7 + recv + expect ~ "^.* uri: CONNECT hostname:8443 HTTP/1.1; host: {hostname:8443}$" + + # C8 + recv + expect ~ "^.* uri: <BADREQ>; host: $" + + # C9 + recv + expect ~ "^.* uri: <BADREQ>; host: $" + + # C10 + recv + expect ~ "^.* uri: <BADREQ>; host: $" + + # C11 + recv + expect ~ "^.* uri: <BADREQ>; host: $" + + # C12 + recv + expect ~ "^.* uri: <BADREQ>; host: $" + + # C13 + recv + expect ~ "^.* uri: <BADREQ>; host: $" + + # C14 + recv + expect ~ "^.* uri: <BADREQ>; host: $" + + # C15 + recv + expect ~ "^.* uri: <BADREQ>; host: $" + + # C16 + recv + expect ~ "^.* uri: <BADREQ>; host: $" + + # C17 + recv + expect ~ "^.* uri: <BADREQ>; host: $" + + # C18 + recv + expect ~ "^.* uri: <BADREQ>; host: $" + + # C19 + recv + expect ~ "^.* uri: <BADREQ>; host: $" + + # C20 + recv + expect ~ "^.* uri: GET http://hostname/c20 HTTP/1.1; host: {hostname}$" + + # C21 + recv + expect ~ "^.* uri: GET https://hostname/c21 HTTP/1.1; host: {hostname}$" + + # C22 + recv + expect ~ "^.* uri: GET http://hostname/c22 HTTP/1.1; host: {hostname:80}$" + + # C23 + recv + expect ~ "^.* uri: GET https://hostname/c23 HTTP/1.1; host: {hostname:443}$" + + # C24 + recv + expect ~ "^.* uri: GET http://hostname/c24 HTTP/1.1; host: {hostname}$" + + # C25 + recv + expect ~ "^.* uri: GET https://hostname/c25 HTTP/1.1; host: {hostname}$" + + # C26 + recv + expect ~ "^.* uri: GET http://hostname/c26 HTTP/1.1; host: {hostname:}$" + + # C27 + recv + expect ~ "^.* uri: GET https://hostname/c27 HTTP/1.1; host: {hostname:}$" + + # C28 + recv + expect ~ "^.* uri: GET http://hostname/c28 HTTP/1.1; host: {hostname}$" + + # C29 + recv + expect ~ "^.* uri: GET http://hostname/c29 HTTP/1.1; host: {hostname}$" + + # C30 + recv + expect ~ "^.* uri: GET https://hostname/c30 HTTP/1.1; host: {hostname}$" + + # C31 + recv + expect ~ "^.* uri: GET https://hostname/c31 HTTP/1.1; host: {hostname}$" + + # C32 + recv + expect ~ "^.* uri: GET http:// HTTP/1.1; host: {}$" + + # C33 + recv + expect ~ "^.* uri: GET https:// HTTP/1.1; host: {}$" + + # C34 + recv + expect ~ "^.* uri: GET http:// HTTP/1.1; host: {}$" + + # C35 + recv + expect ~ "^.* uri: GET https:// HTTP/1.1; host: {}$" +} -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + + http-request capture req.hdr(host) len 512 + log-format "uri: %r; host: %hr" + log ${S1_addr}:${S1_port} len 2048 local0 debug err + + http-request return status 200 +} -start + +# default port 80 with http scheme => should be normalized +# Be sure userinfo are skipped +client c1 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "http://toto:poue@hostname:80/c1" \ + -hdr "host: hostname:80" + + rxresp + expect resp.status == 200 +} -run + +# port 8080 with http scheme => no normalization +client c2 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "http://hostname:8080/c2" \ + -hdr "host: hostname:8080" + + rxresp + expect resp.status == 200 +} -run + +# default port 443 with https scheme => should be normalized +client c3 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "https://hostname:443/c3" \ + -hdr "host: hostname:443" + + rxresp + expect resp.status == 200 +} -run + +# port 80 with https scheme => no normalization +client c4 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "https://hostname:80/c4" \ + -hdr "host: hostname:80" + + rxresp + expect resp.status == 200 +} -run + +# CONNECT on port 80 => should be normalized +client c5 -connect ${h1_fe_sock} { + txreq \ + -req "CONNECT" \ + -url "hostname:80" \ + -hdr "host: hostname:80" + + rxresp + expect resp.status == 200 +} -run +client c5 -connect ${h1_fe_sock} { + + txreq \ + -req "CONNECT" \ + -url "hostname:80" \ + -hdr "host: hostname" + + rxresp + expect resp.status == 200 +} -run +client c5 -connect ${h1_fe_sock} { + + txreq \ + -req "CONNECT" \ + -url "hostname:80" \ + -hdr "host: hostname:" + + rxresp + expect resp.status == 200 +} -run + +# CONNECT on port 443 => should be normalized +client c6 -connect ${h1_fe_sock} { + txreq \ + -req "CONNECT" \ + -url "hostname:443" \ + -hdr "host: hostname:443" + + rxresp + expect resp.status == 200 +} -run +client c6 -connect ${h1_fe_sock} { + txreq \ + -req "CONNECT" \ + -url "hostname:443" \ + -hdr "host: hostname" + + rxresp + expect resp.status == 200 +} -run +client c6 -connect ${h1_fe_sock} { + txreq \ + -req "CONNECT" \ + -url "hostname:443" \ + -hdr "host: hostname:" + + rxresp + expect resp.status == 200 +} -run + +# CONNECT on port non-default port => no normalization +client c7 -connect ${h1_fe_sock} { + txreq \ + -req "CONNECT" \ + -url "hostname:8443" \ + -hdr "host: hostname:8443" + + rxresp + expect resp.status == 200 +} -run + +# host miss-match => error +client c8 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "http://hostname1/" \ + -hdr "host: hostname2" + + rxresp + expect resp.status == 400 +} -run + +# port miss-match => error +client c9 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "http://hostname:80/" \ + -hdr "host: hostname:81" + + rxresp + expect resp.status == 400 +} -run + +# no host port with a non-default port in abs-uri => error +client c10 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "http://hostname:8080/" \ + -hdr "host: hostname" + + rxresp + expect resp.status == 400 +} -run + +# non-default host port with a default in abs-uri => error +client c11 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "http://hostname/" \ + -hdr "host: hostname:81" + + rxresp + expect resp.status == 400 +} -run + +# miss-match between host headers => error +client c12 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "http://hostname1/" \ + -hdr "host: hostname1" \ + -hdr "host: hostname2" + + rxresp + expect resp.status == 400 +} -run + +# miss-match between host headers but with a normalization => error +client c13 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "http://hostname1/" \ + -hdr "host: hostname1:80" \ + -hdr "host: hostname1" + + rxresp + expect resp.status == 400 +} -run + +# CONNECT authoriy without port => error +client c14 -connect ${h1_fe_sock} { + txreq \ + -req "CONNECT" \ + -url "hostname" \ + -hdr "host: hostname" + + rxresp + expect resp.status == 400 +} -run + +# host miss-match with CONNECT => error +client c15 -connect ${h1_fe_sock} { + txreq \ + -req "CONNECT" \ + -url "hostname1:80" \ + -hdr "host: hostname2:80" + + rxresp + expect resp.status == 400 +} -run + +# port miss-match with CONNECT => error +client c16 -connect ${h1_fe_sock} { + txreq \ + -req "CONNECT" \ + -url "hostname:80" \ + -hdr "host: hostname:443" + + rxresp + expect resp.status == 400 +} -run + +# no host port with non-default port in CONNECT authority => error +client c17 -connect ${h1_fe_sock} { + txreq \ + -req "CONNECT" \ + -url "hostname:8080" \ + -hdr "host: hostname" + + rxresp + expect resp.status == 400 +} -run + +# no authority => error +client c18 -connect ${h1_fe_sock} { + txreq \ + -req "CONNECT" \ + -url "/" \ + -hdr "host: hostname" + + rxresp + expect resp.status == 400 +} -run + +# no authority => error +client c19 -connect ${h1_fe_sock} { + txreq \ + -req "CONNECT" \ + -url "hostname:" \ + -hdr "host: hostname" + + rxresp + expect resp.status == 400 +} -run + + +# default port 80 with http scheme but no port for host value => should be normalized +client c20 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "http://hostname:80/c20" \ + -hdr "host: hostname" + + rxresp + expect resp.status == 200 +} -run + + +# default port 443 with https scheme but no port for host value => should be normalized +client c21 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "https://hostname:443/c21" \ + -hdr "host: hostname" + + rxresp + expect resp.status == 200 +} -run + + +# http scheme, no port for the authority but default port for host value => no normalization +client c22 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "http://hostname/c22" \ + -hdr "host: hostname:80" + + rxresp + expect resp.status == 200 +} -run + +# https scheme, no port for the authority but default port for host value => no normalization +client c23 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "https://hostname/c23" \ + -hdr "host: hostname:443" + + rxresp + expect resp.status == 200 +} -run + + +# http scheme, empty port for the authority and no port for host value => should be normalized +client c24 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "http://hostname:/c24" \ + -hdr "host: hostname" + + rxresp + expect resp.status == 200 +} -run + +# https scheme, empty port for the authority and no port for host value => should be normalized +client c25 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "https://hostname:/c25" \ + -hdr "host: hostname" + + rxresp + expect resp.status == 200 +} -run + +# http scheme, no port for the authority and empty port for host value => no normalization +client c26 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "http://hostname/c26" \ + -hdr "host: hostname:" + + rxresp + expect resp.status == 200 +} -run + +# https scheme, no port for the authority and empty port for host value => no normalization +client c27 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "https://hostname/c27" \ + -hdr "host: hostname:" + + rxresp + expect resp.status == 200 +} -run + +# http scheme, default port for the authority and empty port for host value => should be normalized +client c28 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "http://hostname:80/c28" \ + -hdr "host: hostname:" + + rxresp + expect resp.status == 200 +} -run + +# http scheme, empty port for the authority and default port for host value => should be normalized +client c29 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "http://hostname:/c29" \ + -hdr "host: hostname:80" + + rxresp + expect resp.status == 200 +} -run + +# https scheme, default port for the authority and empty port for host value => should be normalized +client c30 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "https://hostname:443/c30" \ + -hdr "host: hostname:" + + rxresp + expect resp.status == 200 +} -run + +# https scheme, empty port for the authority and default port for host value => should be normalized +client c31 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "https://hostname:/c31" \ + -hdr "host: hostname:443" + + rxresp + expect resp.status == 200 +} -run + +# Strange cases +client c32 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "http://:" \ + -hdr "host: :80" + + rxresp + expect resp.status == 200 +} -run + + +client c33 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "https://:" \ + -hdr "host: :443" + + rxresp + expect resp.status == 200 +} -run + +# Strange cases +client c34 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "http://:" \ + -hdr "host: :" + + rxresp + expect resp.status == 200 +} -run + + +client c35 -connect ${h1_fe_sock} { + txreq \ + -req "GET" \ + -url "https://:" \ + -hdr "host: :" + + rxresp + expect resp.status == 200 +} -run + +syslog S1 -wait diff --git a/reg-tests/http-messaging/h1_to_h1.vtc b/reg-tests/http-messaging/h1_to_h1.vtc new file mode 100644 index 0000000..0d65366 --- /dev/null +++ b/reg-tests/http-messaging/h1_to_h1.vtc @@ -0,0 +1,275 @@ +varnishtest "HTTP request tests: H1 to H1 (HTX mode supported only for HAProxy >= 1.9)" + +# Run it with HAPROXY_PROGRAM=$PWD/haproxy varnishtest -l -k -t 1 "$1" + +feature ignore_unknown_macro + +server s1 { + ## + ## Handle GET requests + ## + rxreq + expect req.bodylen == 0 + expect req.body == "" + txresp \ + -status 200 \ + -body "response 1" + + rxreq + expect req.bodylen == 0 + expect req.body == "" + txresp \ + -status 200 \ + -body "response 2" + + rxreq + expect req.bodylen == 38 + expect req.body == "this must be delivered, like it or not" + txresp \ + -status 200 \ + -body "response 3" + + rxreq + expect req.bodylen == 0 + expect req.body == "" + txresp \ + -status 200 \ + -body "response 4" + + accept + + ## + ## Handle HEAD requests + ## + rxreq + expect req.bodylen == 0 + expect req.body == "" + txresp \ + -status 200 \ + -body "response 1" + + accept + + rxreq + expect req.bodylen == 0 + expect req.body == "" + txresp \ + -status 200 \ + -body "response 2" + + accept + + rxreq + expect req.bodylen == 38 + expect req.body == "this must be delivered, like it or not" + txresp \ + -status 200 \ + -body "response 3" + + accept + + rxreq + expect req.bodylen == 0 + expect req.body == "" + txresp \ + -status 200 \ + -body "response 4" + + accept + + ## + ## Handle POST requests + ## + # POST request without body + rxreq + expect req.bodylen == 0 + expect req.body == "" + txresp \ + -status 200 \ + -body "response 1" + + # POST request without body + rxreq + expect req.bodylen == 0 + expect req.body == "" + txresp \ + -status 200 \ + -body "response 2" + + # POST request with a body + rxreq + expect req.bodylen == 12 + expect req.body == "this is sent" + txresp \ + -status 200 \ + -body "response 3" + + # POST request without body + rxreq + expect req.bodylen == 0 + expect req.body == "" + txresp \ + -status 200 \ + -body "response 4" +} -repeat 3 -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 + mode http + 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 + +# GET requests +client c1h1 -connect ${h1_feh1_sock} { + # first request is valid + txreq \ + -req "GET" \ + -url "/test1.html" + rxresp + expect resp.status == 200 + expect resp.body == "response 1" + + # second request is valid and advertises C-L:0 + txreq \ + -req "GET" \ + -url "/test2.html" \ + -hdr "content-length: 0" + rxresp + expect resp.status == 200 + expect resp.body == "response 2" + + # third request sends a body with a GET + txreq \ + -req "GET" \ + -url "/test3.html" \ + -body "this must be delivered, like it or not" + rxresp + expect resp.status == 200 + expect resp.body == "response 3" + + # 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. + txreq \ + -req "GET" \ + -url "/test4.html" \ + -hdr "content-length: 0" \ + -hdr "connection: close" + # "this is not sent" + sendhex "74787973207973206E6F742073656E740D0A0D0A" + rxresp + expect resp.status == 200 + expect resp.body == "response 4" + + # the connection is expected to be closed and no more response must + # arrive here. + expect_close +} -run + +# HEAD requests +# Note: for now they fail with varnishtest, which expects the amount of +# data advertised in the content-length response. +client c2h1 -connect ${h1_feh1_sock} { + # first request is valid + txreq \ + -req "HEAD" \ + -url "/test11.html" + rxresp + expect resp.status == 200 + expect resp.body == "" + + # second request is valid and advertises C-L:0 + txreq \ + -req "HEAD" \ + -url "/test12.html" \ + -hdr "content-length: 0" + rxresp + expect resp.status == 200 + expect resp.body == "" + + # third request sends a body with a HEAD + txreq \ + -req "HEAD" \ + -url "/test13.html" \ + -body "this must be delivered, like it or not" + rxresp + expect resp.status == 200 + expect resp.body == "" + + # 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. + txreq \ + -req "HEAD" \ + -url "/test14.html" \ + -hdr "content-length: 0" \ + -hdr "connection: close" + # "this is not sent" + sendhex "74787973207973206E6F742073656E740D0A0D0A" + rxresp + expect resp.status == 200 + expect resp.body == "" + + # the connection is expected to be closed and no more response must + # arrive here. + expect_close +} -run + +client c3h1 -connect ${h1_feh1_sock} { + # first request is valid + txreq \ + -req "POST" \ + -url "/test21.html" + rxresp + expect resp.status == 200 + expect resp.body == "response 1" + + # second request is valid and advertises C-L:0 + txreq \ + -req "POST" \ + -url "/test22.html" \ + -hdr "content-length: 0" + rxresp + expect resp.status == 200 + expect resp.body == "response 2" + + # third request is valid and advertises (and sends) some contents + txreq \ + -req "POST" \ + -url "/test23.html" \ + -body "this is sent" + rxresp + expect resp.status == 200 + expect resp.body == "response 3" + + # 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. + txreq \ + -req "POST" \ + -url "/test24.html" \ + -hdr "content-length: 0" \ + -hdr "connection: close" + # "this is not sent" + sendhex "74787973207973206E6F742073656E740D0A0D0A" + rxresp + expect resp.status == 200 + expect resp.body == "response 4" + + # the connection is expected to be closed and no more response must + # arrive here. + expect_close +} -run diff --git a/reg-tests/http-messaging/h2_desync_attacks.vtc b/reg-tests/http-messaging/h2_desync_attacks.vtc new file mode 100644 index 0000000..112bc60 --- /dev/null +++ b/reg-tests/http-messaging/h2_desync_attacks.vtc @@ -0,0 +1,167 @@ +# This test ensures that h2 requests with invalid pseudo-headers are properly +# rejected. Also, the host header must be ignored if authority is present. This +# is necessary to avoid http/2 desync attacks through haproxy as described here +# https://portswigger.net/research/http2 + +varnishtest "h2 desync attacks" +feature ignore_unknown_macro + +server s1 { + rxreq + expect req.http.host == "hostname" + txresp +} -start + +# haproxy frontend +haproxy hap -conf { + defaults + mode http + + listen feSrvH1 + bind "fd@${feSrvH1}" + http-request return status 200 + + listen feSrvH2 + bind "fd@${feSrvH2}" proto h2 + http-request return status 200 + + listen fe1 + bind "fd@${fe1}" proto h2 + server srv-hapSrv "${hap_feSrvH1_addr}:${hap_feSrvH1_port}" + + listen fe2 + bind "fd@${fe2}" proto h2 + server srv-hapSrv "${hap_feSrvH2_addr}:${hap_feSrvH2_port}" proto h2 + + listen fe3 + bind "fd@${fe3}" proto h2 + server s1 "${s1_addr}:${s1_port}" +} -start + +# valid request +client c1 -connect ${hap_fe1_sock} { + txpri + stream 0 { + txsettings + rxsettings + txsettings -ack + rxsettings + expect settings.ack == true + } -run + + stream 1 { + txreq \ + -method "GET" \ + -scheme "http" \ + -url "/" + rxresp + expect resp.status == 200 + } -run +} -run + +# valid request +client c2 -connect ${hap_fe2_sock} { + txpri + stream 0 { + txsettings + rxsettings + txsettings -ack + rxsettings + expect settings.ack == true + } -run + + stream 1 { + txreq \ + -method "GET" \ + -scheme "http" \ + -url "/" + rxresp + expect resp.status == 200 + } -run +} -run + +# invalid path +client c3-path -connect ${hap_fe1_sock} { + txpri + stream 0 { + txsettings + rxsettings + txsettings -ack + rxsettings + expect settings.ack == true + } -run + + stream 1 { + txreq \ + -method "GET" \ + -scheme "http" \ + -url "hello-world" + rxrst + } -run +} -run + +# invalid scheme +client c4-scheme -connect ${hap_fe1_sock} { + txpri + stream 0 { + txsettings + rxsettings + txsettings -ack + rxsettings + expect settings.ack == true + } -run + + stream 1 { + txreq \ + -method "GET" \ + -scheme "http://localhost/?" \ + -url "/" + rxresp + expect resp.status == 400 + } -run +} -run + +# invalid method +client c5-method -connect ${hap_fe2_sock} { + txpri + stream 0 { + txsettings + rxsettings + txsettings -ack + rxsettings + expect settings.ack == true + } -run + + stream 1 { + txreq \ + -method "GET?" \ + -scheme "http" \ + -url "/" + rxresp + expect resp.status == 400 + } -run +} -run + +# different authority and host headers +# in this case, host should be ignored in favor of the authority +client c6-host-authority -connect ${hap_fe3_sock} { + txpri + stream 0 { + txsettings + rxsettings + txsettings -ack + rxsettings + expect settings.ack == true + } -run + + stream 1 { + txreq \ + -method "GET" \ + -scheme "http" \ + -url "/" \ + -hdr ":authority" "hostname" \ + -hdr "host" "other_host" + } -run +} -run + +server s1 -wait diff --git a/reg-tests/http-messaging/h2_to_h1.vtc b/reg-tests/http-messaging/h2_to_h1.vtc new file mode 100644 index 0000000..852ee4c --- /dev/null +++ b/reg-tests/http-messaging/h2_to_h1.vtc @@ -0,0 +1,265 @@ +varnishtest "HTTP request tests: H2 to H1 (HTX and legacy mode)" +#REQUIRE_VERSION=1.9 + +# 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 + +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 +} -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 +} -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 +} -run diff --git a/reg-tests/http-messaging/http_abortonclose.vtc b/reg-tests/http-messaging/http_abortonclose.vtc new file mode 100644 index 0000000..767a185 --- /dev/null +++ b/reg-tests/http-messaging/http_abortonclose.vtc @@ -0,0 +1,142 @@ +varnishtest "A test for the abortonclose option (H1 only)" +feature ignore_unknown_macro + +# NOTE : This test may fail if too many vtest are running in parallel because +# the port reserved for closed s1 server may be reused by another vtest + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.0-dev0)'" +#REGTEST_TYPE=slow + +# b0 : Wait s1 was detected as DOWN to be sure it is stopped +# b1 : Don't send /c4 before /c3 was received by s2 server +# b2 : Don't finish c2 before c1 and c3 before c4 (from syslog POV) +# b3 : finish c3 before s2 + +barrier b0 cond 2 -cyclic +barrier b1 cond 2 -cyclic +barrier b2 cond 2 -cyclic +barrier b3 cond 2 -cyclic + +server s1 { +} -start +server s1 -break + +server s2 { + rxreq + + # unlock c4 + barrier b1 sync + + # wait end of c3 + barrier b3 sync + + expect_close +} -start + +syslog S -level info { + recv alert + expect ~ "[^:\\[ ]*\\[[0-9]*\\]: Server check/srv1 is DOWN.*" + barrier b0 sync + + recv + expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe1 be1_1/srv1 [0-9]*/[0-9]*/-1/-1/[0-9]* 503 .* - - SC-- .* .* \"GET /c1 HTTP/1\\.1\"" + barrier b2 sync + recv + expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe1 be1_2/srv1 [0-9]*/[0-9]*/-1/-1/[0-9]* -1 .* - - CC-- .* .* \"GET /c2 HTTP/1\\.1\"" + barrier b2 sync + recv + expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe2 be2/<NOSRV> [0-9]*/[0-9]*/-1/-1/[0-9]* -1 .* - - CQ-- .* .* \"GET /c4 HTTP/1\\.1\"" + barrier b2 sync + recv + expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe2 be2/srv1 [0-9]*/[0-9]*/[0-9]*/-1/[0-9]* 400 .* - - CH-- .* .* \"GET /c3 HTTP/1\\.1\"" +} -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 + mode http + option abortonclose + retries 1 + timeout client 10s + timeout server 10s + timeout connect 100ms + timeout queue 5s + + frontend fe1 + option httplog + log ${S_addr}:${S_port} local0 debug err + bind "fd@${fe1}" + use_backend be1_1 if { path /c1 } + use_backend be1_2 if { path /c2 } + + frontend fe2 + option httplog + log ${S_addr}:${S_port} local0 debug err + bind "fd@${fe2}" + use_backend be2 + + backend be1_1 + server srv1 ${s1_addr}:${s1_port} + + backend be1_2 + timeout connect 1s + retries 10 + server srv1 ${s1_addr}:${s1_port} + + backend be2 + server srv1 ${s2_addr}:${s2_port} maxconn 1 + + backend check + server srv1 ${s1_addr}:${s1_port} check + log ${S_addr}:${S_port} local0 debug alert +} -start + +# Wait s1 was detected as DOWN +barrier b0 sync + +# No server, wait all connection retries : SC-- +client c1 -connect ${h1_fe1_sock} { + txreq -url /c1 + rxresp + expect resp.status == 503 +} -run + +# Wait c1 log entry +barrier b2 sync + +# No server, abort during connections retries : CC-- +client c2 -connect ${h1_fe1_sock} { + txreq -url /c2 +} -run + +# Wait c2 log entry +barrier b2 sync + +# server with maxconn=1, abort waiting the server reply : CH-- +client c3 -connect ${h1_fe2_sock} { + txreq -url /c3 + + # Wait c4 log entry + barrier b2 sync +} -start + +# server with maxconn=1, abort waiting in the queue (c3 still attached) : CQ-- +client c4 -connect ${h1_fe2_sock} { + # Wait s2 receives c3 request + barrier b1 sync + + txreq -url /c4 + delay .2 +} -run + +client c3 -wait + +# unlock s2 +barrier b3 sync + +syslog S -wait diff --git a/reg-tests/http-messaging/http_bodyless_response.vtc b/reg-tests/http-messaging/http_bodyless_response.vtc new file mode 100644 index 0000000..9e0ce1c --- /dev/null +++ b/reg-tests/http-messaging/http_bodyless_response.vtc @@ -0,0 +1,127 @@ +varnishtest "A test to be sure payload is skipped for bodyless responses" +feature ignore_unknown_macro + +#REQUIRE_VERSION=2.4 + +server s1 { + rxreq + txresp \ + -status 200 \ + -body "skipped data" + + rxreq + txresp \ + -status 200 \ + -bodylen 20000 + + rxreq + txresp \ + -status 200 \ + -nolen -hdr "Transfer-Encoding: chunked" + chunkedlen 15 + chunkedlen 1024 + chunkedlen 4048 + chunkedlen 0 + + rxreq + txresp \ + -status 200 \ + -body "last response" +} -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 + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen fe1 + bind "fd@${fe1}" + # Rewrite the method to be sure to get the response payload + # on the server side + http-request set-method GET + server s1 ${s1_addr}:${s1_port} + + listen int + bind "fd@${int}" proto h2 + # Rewrite the method to be sure to get the response payload + # on the server side + http-request set-method GET + server s1 ${s1_addr}:${s1_port} + #server s1 ${h1_fe1_addr}:${h1_fe1_port} + + listen fe2 + bind "fd@${fe2}" + server s1 ${h1_int_addr}:${h1_int_port} proto h2 +} -start + +client c1 -connect ${h1_fe1_sock} { + txreq \ + -req "HEAD" \ + -url "/req1" + rxresp + expect resp.status == 200 + expect resp.body == "" + + txreq \ + -req "HEAD" \ + -url "/req2" + rxresp + expect resp.status == 200 + expect resp.body == "" + + txreq \ + -req "HEAD" \ + -url "/req3" + rxresp + expect resp.status == 200 + expect resp.body == "" + + # The last one have a body and validate the connection was not closed + # unexpectedly and no payload was received for previous requests + txreq \ + -req "GET" \ + -url "/req4" + rxresp + expect resp.status == 200 + expect resp.body == "last response" +} -run + +client c2 -connect ${h1_fe2_sock} { + txreq \ + -req "HEAD" \ + -url "/req1" + rxresp + expect resp.status == 200 + expect resp.body == "" + + txreq \ + -req "HEAD" \ + -url "/req2" + rxresp + expect resp.status == 200 + expect resp.body == "" + + txreq \ + -req "HEAD" \ + -url "/req3" + rxresp + expect resp.status == 200 + expect resp.body == "" + + # The last one have a body and validate the connection was not closed + # unexpectedly and no payload was received for previous requests + txreq \ + -req "GET" \ + -url "/req4" + rxresp + expect resp.status == 200 + expect resp.body == "last response" +} -run diff --git a/reg-tests/http-messaging/http_msg_full_on_eom.vtc b/reg-tests/http-messaging/http_msg_full_on_eom.vtc new file mode 100644 index 0000000..2edba7d --- /dev/null +++ b/reg-tests/http-messaging/http_msg_full_on_eom.vtc @@ -0,0 +1,62 @@ +varnishtest "cannot add the HTX EOM block because the buffer is full" +feature ignore_unknown_macro + +#REQUIRE_VERSION=2.2 +#REQUIRE_VERSION_BELOW=2.4 +#REGTEST_TYPE=devel + +# This test checks that an HTTP message is properly processed when we failed to +# add the HTX EOM block in an HTX message during the parsing because the buffer +# is full. Some space must be released in the buffer to make it possible. This +# requires an extra pass in the H1 multiplexer. Here, we must be sure the mux is +# called while there is no more incoming data. + +server s1 { + rxreq + expect req.bodylen == 15200 + txresp -bodylen 15220 +} -start + +syslog S -level info { + recv + expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe1 be1/srv1 [0-9]*/[0-9]*/[0-9]*/[0-9]*/[0-9]* 200 .* - - ---- .* .* \"GET / HTTP/1\\.1\"" +} -start + +haproxy h1 -conf { + global + tune.bufsize 16384 + tune.maxrewrite 1024 + + defaults + mode http + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + + backend be1 + tcp-response inspect-delay 100ms + tcp-response content accept if { res.len gt 15272 } + tcp-response content reject + + http-response deny if { internal.htx.has_eom -m bool } or { internal.htx.free_data gt 1024 } + server srv1 ${s1_addr}:${s1_port} + + frontend fe1 + option httplog + option http-buffer-request + log ${S_addr}:${S_port} local0 debug err + bind "fd@${fe1}" + http-request deny if ! { req.body_len eq 15200 } or { internal.htx.has_eom -m bool } or { internal.htx.free_data gt 1024 } + use_backend be1 +} -start + +haproxy h1 -cli { + send "trace h1 sink stderr; trace h1 level developer; trace h1 verbosity complete; trace h1 start now" +} + +client c1 -connect ${h1_fe1_sock} { + txreq -bodylen 15200 + rxresp + expect resp.status == 200 + expect resp.bodylen == 15220 +} -run diff --git a/reg-tests/http-messaging/http_request_buffer.vtc b/reg-tests/http-messaging/http_request_buffer.vtc new file mode 100644 index 0000000..15ec540 --- /dev/null +++ b/reg-tests/http-messaging/http_request_buffer.vtc @@ -0,0 +1,135 @@ +varnishtest "A test for http-request-buffer option" +feature ignore_unknown_macro + + +# This test checks HTTP request buffering feature. +# We run one server s1 which can serve only one client (no -repeat argument here). +# c1 client uses a malformed request which is not transferred to s1 server +# thanks to "http-buffer-request". If this was the case, c2 client +# could not connect to s1 server and this would lead to make this test fail. + +barrier b1 cond 2 -cyclic + +server s1 { + rxreq + expect req.bodylen == 257 + txresp + + accept + + rxreq + expect req.bodylen == 2 + txresp +} -start + +syslog S -level info { + recv + expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe1 fe1/<NOSRV> .* 408 .* - - cR-- .* .* \"GET /this-is-a-long-url-this-is-a-long-url-this-is-a-long-url-this-is-a-long-url-this-is-a-long-url-this-is-a-long-url-this-is-a-long-url HTTP/1\\.1\"" + barrier b1 sync + + recv + expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe1 be1/srv1 [0-9]*/[0-9]*/[0-9]*/[0-9]*/[0-9]* 200 .* - - ---- .* .* \"GET / HTTP/1\\.1\"" + barrier b1 sync + + recv + expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe2 be1/srv1 [0-9]*/[0-9]*/[0-9]*/[0-9]*/[0-9]* 200 .* - - ---- .* .* \"POST /1 HTTP/1\\.1\"" + barrier b1 sync + + recv + expect ~ "[^:\\[ ]*\\[[0-9]*\\]: .* .* fe2 be1/<NOSRV> [0-9]*/-1/-1/-1/[0-9]* -1 .* - - CR-- .* .* \"POST /2 HTTP/1\\.1\"" +} -start + +haproxy h1 -conf { + defaults + mode http + timeout client 100 + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + + backend be1 + server srv1 ${s1_addr}:${s1_port} + + frontend fe1 + option httplog + option http-buffer-request + log ${S_addr}:${S_port} local0 debug err + bind "fd@${fe1}" + use_backend be1 + + frontend fe2 + timeout client 10s + option httplog + option http-buffer-request + log ${S_addr}:${S_port} local0 debug err + bind "fd@${fe2}" + use_backend be1 +} -start + +# 1 byte of the payload is missing. +# ==> The request must timed out with a 408 response +client c1 -connect ${h1_fe1_sock} { + send "GET" + send " " + send "/this-is-a-long-url" + send "-this-is-a-long-url" + send "-this-is-a-long-url" + send "-this-is-a-long-url" + send "-this-is-a-long-url" + send "-this-is-a-long-url" + send "-this-is-a-long-url" + send " HTT" + send "P/1.1" + send "\r" + send "\n" + send "Content-Length: 209\r\n\r\n" + send "abcdefghijklmnopqrstuvwxyz" + send "abcdefghijklmnopqrstuvwxyz" + send "abcdefghijklmnopqrstuvwxyz" + send "abcdefghijklmnopqrstuvwxyz" + send "abcdefghijklmnopqrstuvwxyz" + send "abcdefghijklmnopqrstuvwxyz" + send "abcdefghijklmnopqrstuvwxyz" + send "abcdefghijklmnopqrstuvwxyz" + rxresp + expect resp.status == 408 +} -run + +# Wait matching on log message +barrier b1 sync + +# Payload is fully sent +# ==> Request must be sent to the server. A 200 must be received +client c2 -connect ${h1_fe1_sock} { + txreq -bodylen 257 + rxresp + expect resp.status == 200 +} -run + +# Wait matching on log message +barrier b1 sync + +# Payload is fully sent in 2 steps (with a small delay, smaller than the client +# timeout) and split on a chunk size. +# ==> Request must be sent to the server. A 200 must be received +client c3 -connect ${h1_fe2_sock} { + send "POST /1 HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n1\r\n1\r\n1" + delay 0.01 + send "\r\n1\r\n0\r\n\r\n" + rxresp + expect resp.status == 200 +} -run + +# Wait matching on log message +barrier b1 sync + +# Last CRLF of the request payload is missing but payload is sent in 2 steps +# (with a small delay, smaller than the client timeout) and split on a chunk +# size. The client aborts before sending the last CRLF. +# ==> Request must be handled as an error with 'CR--' termination state. +client c4 -connect ${h1_fe2_sock} { + send "POST /2 HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n1\r\n1\r\n1" + delay 0.01 + send "\r\n1\r\n0\r\n" +} -run + +syslog S -wait diff --git a/reg-tests/http-messaging/http_splicing.vtc b/reg-tests/http-messaging/http_splicing.vtc new file mode 100644 index 0000000..2456cdd --- /dev/null +++ b/reg-tests/http-messaging/http_splicing.vtc @@ -0,0 +1,75 @@ +# This reg-test checks splicing support for the H1 multiplexer + +varnishtest "A test to validate h1 splicing support" + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.6-dev0)'" +feature cmd "$HAPROXY_PROGRAM -cc 'feature(LINUX_SPLICE)'" +feature ignore_unknown_macro + +#REGTEST_TYPE=slow + +server s1 { + rxreq + expect req.http.content-length == "1048576" + expect req.bodylen == 1048576 + txresp -status 200 -bodylen 1048576 +} -start + +server s2 { + rxreq + txresp -status 200 -nolen -bodylen 1048576 +} -start + +haproxy h1 -conf { + global + log stderr len 4096 local0 debug + + defaults + mode http + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + option splice-request + option splice-response + log global + option httplog + + listen li1 + bind "fd@${li1}" + id 10 + server srv1 ${s1_addr}:${s1_port} + + listen li2 + bind "fd@${li2}" + id 20 + server srv2 ${s2_addr}:${s2_port} +} -start + + +client c1 -connect ${h1_li1_sock} { + txreq -method POST -url "/" -bodylen 1048576 + rxresp + expect resp.status == 200 + expect resp.http.content-length == "1048576" + expect resp.bodylen == 1048576 +} -run + +client c2 -connect ${h1_li2_sock} { + txreq -url "/" + rxresp + expect resp.status == 200 + expect resp.http.content-length == <undef> + expect resp.bodylen == 1048576 +} -run + +haproxy h1 -cli { + send "show stat typed" + expect ~ "F.10.0.[[:digit:]]+.h1_spliced_bytes_in.1:MCP:u64:[1-9][[:digit:]]+\nF.10.0.[[:digit:]]+.h1_spliced_bytes_out.1:MCP:u64:[1-9][[:digit:]]+" + send "show stat typed" + expect ~ "B.10.0.[[:digit:]]+.h1_spliced_bytes_in.1:MCP:u64:[1-9][[:digit:]]+\nB.10.0.[[:digit:]]+.h1_spliced_bytes_out.1:MCP:u64:[1-9][[:digit:]]+" + + send "show stat typed" + expect ~ "F.20.0.[[:digit:]]+.h1_spliced_bytes_in.1:MCP:u64:0\nF.20.0.[[:digit:]]+.h1_spliced_bytes_out.1:MCP:u64:[1-9][[:digit:]]+" + send "show stat typed" + expect ~ "B.20.0.[[:digit:]]+.h1_spliced_bytes_in.1:MCP:u64:[1-9][[:digit:]]+\nB.20.0.[[:digit:]]+.h1_spliced_bytes_out.1:MCP:u64:0" +} diff --git a/reg-tests/http-messaging/http_transfer_encoding.vtc b/reg-tests/http-messaging/http_transfer_encoding.vtc new file mode 100644 index 0000000..322dfe2 --- /dev/null +++ b/reg-tests/http-messaging/http_transfer_encoding.vtc @@ -0,0 +1,202 @@ +varnishtest "A test to validate Transfer-Encoding header conformance to the spec" + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature ignore_unknown_macro + +server s1 { + rxreq + expect req.http.content-length == <undef> + expect req.http.transfer-encoding == "chunked" + expect req.bodylen == 0 + expect req.body == "" + txresp -status 200 + + accept + rxreq + expect req.http.content-length == <undef> + expect req.http.transfer-encoding == "chunked" + expect req.bodylen == 0 + expect req.body == "" + txresp -status 200 + + accept + rxreq + send "HTTP/1.0 200 Ok\r\n" + send "Transfer-Encoding: chunked\r\n\r\n" + send "0\r\n\r\n" + + accept + rxreq + send "HTTP/1.1 200 Ok\r\n" + send "Transfer-Encoding: chunked\r\n" + send "Content-Length: 30\r\n\r\n" + send "0\r\n\r\nResponse splitting attach" + + accept + rxreq + expect req.url == "/1" + expect req.http.transfer-encoding == "chunked" + expect req.http.te == "trailers" + txresp + + rxreq + expect req.url == "/2" + expect req.http.transfer-encoding == "chunked" + expect req.http.te == <undef> + txresp + + rxreq + expect req.url == "/3" + expect req.http.transfer-encoding == "chunked" + expect req.http.te == <undef> + txresp +} -start + +server s2 { + rxreq + txresp -nolen \ + -hdr "Transfer-Encoding: chunked, chunked" \ + -body "0\r\n\r\n" + + accept + rxreq + txresp -nolen \ + -hdr "Transfer-Encoding: chunked, gzip, chunked" \ + -body "0\r\n\r\n" + + accept + rxreq + txresp -nolen \ + -hdr "Transfer-Encoding: chunked, gzip" \ + -body "0\r\n\r\n" + + accept + rxreq + txresp \ + -hdr "Transfer-Encoding: gzip" +} -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen fe1 + bind "fd@${fe1}" + server s1 ${s1_addr}:${s1_port} + + listen fe2 + bind "fd@${fe2}" + server s2 ${s2_addr}:${s2_port} +} -start + +client c1 -connect ${h1_fe1_sock} { + txreq -method POST -nolen \ + -hdr "Transfer-Encoding: chunked" \ + -hdr "Content-Length: 31" \ + -body "0\r\n\r\nGET /smuggled HTTP/1.1\r\n\r\n" + rxresp + expect resp.status == 200 + expect resp.http.connection == "close" + expect_close +} -run + +client c2 -connect ${h1_fe1_sock} { + send "POST / HTTP/1.0\r\n" + send "Transfer-Encoding: chunked\r\n\r\n" + send "0\r\n\r\n" + rxresp + expect resp.status == 200 + expect_close +} -run + +client c3 -connect ${h1_fe1_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.content-length == <undef> + expect resp.http.transfer-encoding == "chunked" + expect resp.bodylen == 0 + expect resp.body == "" + expect_close +} -run + +client c4 -connect ${h1_fe1_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.content-length == <undef> + expect resp.http.transfer-encoding == "chunked" + expect resp.bodylen == 0 + expect resp.body == "" +} -run + +client c5 -connect ${h1_fe1_sock} { + txreq -method POST -url "/1" -nolen \ + -hdr "Transfer-Encoding: chunked" \ + -hdr "TE: trailers, gzip" \ + -body "0\r\n\r\n" + rxresp + expect resp.status == 200 + + txreq -method POST -url "/2" -nolen \ + -hdr "Transfer-Encoding: chunked" \ + -hdr "TE: gzip" \ + -body "0\r\n\r\n" + rxresp + expect resp.status == 200 + + txreq -method POST -url "/3" -nolen \ + -hdr "Transfer-Encoding: chunked" \ + -hdr "TE: trailers;q=0.5" \ + -body "0\r\n\r\n" + rxresp + expect resp.status == 200 +} -run + +client c6 -connect ${h1_fe1_sock} { + txreq -nolen \ + -hdr "Transfer-Encoding: chunked, chunked" \ + -body "0\r\n\r\n" + rxresp + expect resp.status == 400 +} -run + +client c7 -connect ${h1_fe1_sock} { + txreq -nolen \ + -hdr "Transfer-Encoding: chunked, gzip, chunked" \ + -body "0\r\n\r\n" + rxresp + expect resp.status == 400 +} -run + +client c8 -connect ${h1_fe1_sock} { + txreq -nolen \ + -hdr "Transfer-Encoding: chunked, gzip" \ + -body "0\r\n\r\n" + rxresp + expect resp.status == 400 +} -run + +client c9 -connect ${h1_fe1_sock} { + txreq \ + -hdr "Transfer-Encoding: gzip" + rxresp + expect resp.status == 400 +} -run + +client c10 -connect ${h1_fe1_sock} { + txreq -nolen \ + -hdr "Transfer-Encoding: gzip, chunked" \ + -body "0\r\n\r\n" + rxresp + expect resp.status == 422 +} -run + +client c11 -connect ${h1_fe2_sock} { + txreq + rxresp + expect resp.status == 502 +} -run -repeat 4 diff --git a/reg-tests/http-messaging/http_wait_for_body.vtc b/reg-tests/http-messaging/http_wait_for_body.vtc new file mode 100644 index 0000000..a9f8191 --- /dev/null +++ b/reg-tests/http-messaging/http_wait_for_body.vtc @@ -0,0 +1,171 @@ +varnishtest "A test for the wait-for-body HTTP action" +feature ignore_unknown_macro + +#REQUIRE_VERSION=2.4 +#REGTEST_TYPE=slow + +server s1 { + rxreq + expect req.bodylen == 1001 + txresp + + rxreq + expect req.bodylen == 1001 + txresp +} -start + + +server s2 { + rxreq + send "HTTP/1.1 200 OK\r\n" + send "Content-Length: 1001\r\n\r\n" + delay 0.01 + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + + expect_close + accept + + rxreq + send "HTTP/1.1 200 OK\r\n" + send "Content-Length: 1001\r\n\r\n" + delay 0.01 + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + delay 0.01 + send "1" + + rxreq + send "HTTP/1.1 201 OK\r\n" + send "Content-Length: 1001\r\n\r\n" + delay 0.01 + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + delay 0.1 + send "1" +} -start + +haproxy h1 -conf { + defaults + mode http + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe1}" + http-request wait-for-body time 100ms if { path /a } + http-request wait-for-body time 100ms at-least 1000 if { path /b } + use_backend be1 + + backend be1 + server srv1 ${s1_addr}:${s1_port} + + frontend fe2 + bind "fd@${fe2}" + use_backend be2 + + backend be2 + http-response wait-for-body time 100ms if { status eq 200 } + http-response wait-for-body time 100ms at-least 1000 if { status eq 201 } + server srv1 ${s2_addr}:${s2_port} +} -start + + +client c1 -connect ${h1_fe1_sock} { + send "GET /a HTTP/1.1\r\n" + send "Content-Length: 1001\r\n\r\n" + delay 0.01 + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + rxresp + expect resp.status == 408 +} -run + +client c2 -connect ${h1_fe1_sock} { + send "GET /a HTTP/1.1\r\n" + send "Content-Length: 1001\r\n\r\n" + delay 0.01 + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + delay 0.01 + send "1" + rxresp + expect resp.status == 200 + + send "GET /b HTTP/1.1\r\n" + send "Content-Length: 1001\r\n\r\n" + delay 0.01 + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + send "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789=====================================\n" + delay 0.1 + send "1" + rxresp + expect resp.status == 200 +} -run + +client c3 -connect ${h1_fe2_sock} { + txreq + rxresp + expect resp.status == 504 +} -run + +client c4 -connect ${h1_fe2_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.bodylen == 1001 + + txreq + rxresp + expect resp.status == 201 + expect resp.bodylen == 1001 +} -run diff --git a/reg-tests/http-messaging/protocol_upgrade.vtc b/reg-tests/http-messaging/protocol_upgrade.vtc new file mode 100644 index 0000000..ebb6328 --- /dev/null +++ b/reg-tests/http-messaging/protocol_upgrade.vtc @@ -0,0 +1,228 @@ +# 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 "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + # 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 diff --git a/reg-tests/http-messaging/scheme_based_normalize.vtc b/reg-tests/http-messaging/scheme_based_normalize.vtc new file mode 100644 index 0000000..3edbafb --- /dev/null +++ b/reg-tests/http-messaging/scheme_based_normalize.vtc @@ -0,0 +1,125 @@ +varnishtest "scheme based normalization (rfc3982 6.3.2)" + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature ignore_unknown_macro + +syslog S1 -level info { + recv + expect ~ "^.* uri: GET http://hostname/ HTTP/2.0; host: {hostname}$" + + recv + expect ~ "^.* uri: GET http://hostname:8080/ HTTP/2.0; host: {hostname:8080}$" + + recv + expect ~ "^.* uri: GET https://hostname/ HTTP/2.0; host: {hostname}$" + + recv + expect ~ "^.* uri: GET https://hostname:80/ HTTP/2.0; host: {hostname:80}$" +} -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" proto h2 + + http-request capture req.hdr(host) len 512 + log-format "uri: %r; host: %hr" + log ${S1_addr}:${S1_port} len 2048 local0 debug err + + http-request return status 200 +} -start + +# default port 80 with http scheme => should be normalized +client c1 -connect ${h1_fe_sock} { + txpri + stream 0 { + txsettings + rxsettings + txsettings -ack + rxsettings + expect settings.ack == true + } -run + + stream 1 { + txreq \ + -req "GET" \ + -scheme "http" \ + -url "/" \ + -hdr ":authority" "hostname:80" + rxhdrs + expect resp.status == 200 + } -run +} -run + +# port 8080 with http scheme => no normalization +client c2 -connect ${h1_fe_sock} { + txpri + stream 0 { + txsettings + rxsettings + txsettings -ack + rxsettings + expect settings.ack == true + } -run + + stream 1 { + txreq \ + -req "GET" \ + -scheme "http" \ + -url "/" \ + -hdr ":authority" "hostname:8080" + rxhdrs + expect resp.status == 200 + } -run +} -run + +# default port 443 with https scheme => should be normalized +client c3 -connect ${h1_fe_sock} { + txpri + stream 0 { + txsettings + rxsettings + txsettings -ack + rxsettings + expect settings.ack == true + } -run + + stream 1 { + txreq \ + -req "GET" \ + -scheme "https" \ + -url "/" \ + -hdr ":authority" "hostname:443" + rxhdrs + expect resp.status == 200 + } -run +} -run + +# port 80 with https scheme => no normalization +client c4 -connect ${h1_fe_sock} { + txpri + stream 0 { + txsettings + rxsettings + txsettings -ack + rxsettings + expect settings.ack == true + } -run + + stream 1 { + txreq \ + -req "GET" \ + -scheme "https" \ + -url "/" \ + -hdr ":authority" "hostname:80" + rxhdrs + expect resp.status == 200 + } -run +} -run + +syslog S1 -wait diff --git a/reg-tests/http-messaging/srv_ws.vtc b/reg-tests/http-messaging/srv_ws.vtc new file mode 100644 index 0000000..b26908e --- /dev/null +++ b/reg-tests/http-messaging/srv_ws.vtc @@ -0,0 +1,180 @@ +# This reg-test checks websocket support in regards with the server keyword +# 'ws' + +varnishtest "h2 backend websocket management via server keyword" + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL)'" +feature ignore_unknown_macro + +# haproxy server +haproxy hapsrv -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + bind "fd@${fessl}" ssl crt ${testdir}/common.pem alpn h2,http/1.1 + capture request header sec-websocket-key len 128 + http-request set-var(txn.ver) req.ver + use_backend be + + backend be + # define websocket ACL + acl ws_handshake hdr(upgrade) -m str websocket + + # handle non-ws streams + http-request return status 200 if !ws_handshake + + # handle ws streams + #capture request header sec-websocket-key len 128 + http-request return status 200 hdr connection upgrade hdr upgrade websocket hdr sec-websocket-accept "%[capture.req.hdr(0),concat(258EAFA5-E914-47DA-95CA-C5AB0DC85B11,,),sha1,base64]" if ws_handshake + http-after-response set-status 101 if { status eq 200 } { res.hdr(upgrade) -m str websocket } + http-after-response set-header x-backend-protocol "%[var(txn.ver)]" +} -start + +# haproxy LB +haproxy hap -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + # proto X ws h1 -> websocket on h1 + listen li + bind "fd@${li}" + server hap_srv ${hapsrv_fe_addr}:${hapsrv_fe_port} proto h2 ws h1 + + # proto X ws h2 -> websocket on h2 + listen lih2 + bind "fd@${lih2}" + server hap_srv ${hapsrv_fe_addr}:${hapsrv_fe_port} proto h2 ws h2 + + # alpn h2,http/1.1 ws h2 -> websocket on h2 + listen lisslh2 + bind "fd@${lisslh2}" + server hap_srv ${hapsrv_fessl_addr}:${hapsrv_fessl_port} ssl verify none alpn h2,http/1.1 ws h2 + http-response set-header x-alpn "%[ssl_bc_alpn]" + + # ws auto -> websocket on h1 + listen liauto + bind "fd@${liauto}" + server hap_srv ${hapsrv_fe_addr}:${hapsrv_fe_port} + + # alpn h2,http/1.1 ws auto -> websocket on h1 + listen lissl + bind "fd@${lissl}" + server hap_srv ${hapsrv_fessl_addr}:${hapsrv_fessl_port} ssl verify none alpn h2,http/1.1 ws auto + http-response set-header x-alpn "%[ssl_bc_alpn]" + # alpn h2,http/1.1 ws auto -> websocket on h1 + listen lisslauto + bind "fd@${lisslauto}" + server hap_srv ${hapsrv_fessl_addr}:${hapsrv_fessl_port} ssl verify none alpn h2,http/1.1 + http-response set-header x-alpn "%[ssl_bc_alpn]" + + # proto h2 ws auto -> websocket on h2 + listen liauto2 + bind "fd@${liauto2}" + server hap_srv ${hapsrv_fe_addr}:${hapsrv_fe_port} proto h2 + + # alpn h2 ws auto -> websocket on h2 + listen lisslauto2 + bind "fd@${lisslauto2}" + server hap_srv ${hapsrv_fessl_addr}:${hapsrv_fessl_port} ssl verify none alpn h2 ws auto + http-response set-header x-alpn "%[ssl_bc_alpn]" +} -start + +client c1 -connect ${hap_li_sock} { + txreq \ + -req "GET" \ + -url "/" \ + -hdr "host: 127.0.0.1" \ + -hdr "connection: upgrade" \ + -hdr "upgrade: websocket" \ + -hdr "sec-websocket-key: dGhlIHNhbXBsZSBub25jZQ==" + rxresp + expect resp.status == 101 + expect resp.http.x-backend-protocol == "1.1" +} -run + +client c1.2 -connect ${hap_lih2_sock} { + txreq \ + -req "GET" \ + -url "/" \ + -hdr "host: 127.0.0.1" \ + -hdr "connection: upgrade" \ + -hdr "upgrade: websocket" \ + -hdr "sec-websocket-key: dGhlIHNhbXBsZSBub25jZQ==" + rxresp + expect resp.status == 101 + expect resp.http.x-backend-protocol == "2.0" +} -run + +client c1.3 -connect ${hap_liauto_sock} { + txreq \ + -req "GET" \ + -url "/" \ + -hdr "host: 127.0.0.1" \ + -hdr "connection: upgrade" \ + -hdr "upgrade: websocket" \ + -hdr "sec-websocket-key: dGhlIHNhbXBsZSBub25jZQ==" + rxresp + expect resp.status == 101 + expect resp.http.x-backend-protocol == "1.1" +} -run + +client c1.4 -connect ${hap_liauto2_sock} { + txreq \ + -req "GET" \ + -url "/" \ + -hdr "host: 127.0.0.1" \ + -hdr "connection: upgrade" \ + -hdr "upgrade: websocket" \ + -hdr "sec-websocket-key: dGhlIHNhbXBsZSBub25jZQ==" + rxresp + expect resp.status == 101 + expect resp.http.x-backend-protocol == "2.0" +} -run + +client c2 -connect ${hap_lisslauto_sock} { + txreq \ + -req "GET" \ + -url "/" \ + -hdr "host: 127.0.0.1" \ + -hdr "connection: upgrade" \ + -hdr "upgrade: websocket" \ + -hdr "sec-websocket-key: dGhlIHNhbXBsZSBub25jZQ==" + rxresp + expect resp.status == 101 + expect resp.http.x-alpn == "http/1.1" +} -run + +client c2.2 -connect ${hap_lisslauto2_sock} { + txreq \ + -req "GET" \ + -url "/" \ + -hdr "host: 127.0.0.1" \ + -hdr "connection: upgrade" \ + -hdr "upgrade: websocket" \ + -hdr "sec-websocket-key: dGhlIHNhbXBsZSBub25jZQ==" + rxresp + expect resp.status == 101 + expect resp.http.x-alpn == "h2" +} -run + +client c2.3 -connect ${hap_lisslh2_sock} { + txreq \ + -req "GET" \ + -url "/" \ + -hdr "host: 127.0.0.1" \ + -hdr "connection: upgrade" \ + -hdr "upgrade: websocket" \ + -hdr "sec-websocket-key: dGhlIHNhbXBsZSBub25jZQ==" + rxresp + expect resp.status == 101 + expect resp.http.x-alpn == "h2" +} -run diff --git a/reg-tests/http-messaging/websocket.vtc b/reg-tests/http-messaging/websocket.vtc new file mode 100644 index 0000000..5f4b960 --- /dev/null +++ b/reg-tests/http-messaging/websocket.vtc @@ -0,0 +1,205 @@ +# This reg-test is uses to test respect of the websocket protocol according to +# rfc6455. +# +# In particular, a request/response without a websocket key must be rejected by +# haproxy. Note that in the tested case (h1 on both sides), haproxy does not +# validate the key of the server but only checks its presence. +# +# For the case h2 client/h1 server, haproxy would add the key and validates it. +# However, there is no way to check this case quickly at the moment using vtest. + +varnishtest "WebSocket test" + +feature ignore_unknown_macro + +#REQUIRE_VERSION=2.4 + +# valid websocket server +server s1 { + rxreq + expect req.method == "GET" + expect req.http.connection == "upgrade" + expect req.http.upgrade == "websocket" + expect req.http.sec-websocket-key == "dGhlIHNhbXBsZSBub25jZQ==" + + txresp \ + -status 101 \ + -hdr "connection: upgrade" \ + -hdr "upgrade: websocket" \ + -hdr "sec-websocket-accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=" +} -repeat 2 -start + +# non-conformant server: no websocket key +server s2 { + rxreq + expect req.method == "GET" + expect req.http.connection == "upgrade" + expect req.http.upgrade == "websocket" + + txresp \ + -status 101 \ + -hdr "connection: upgrade" \ + -hdr "upgrade: websocket" +} -start + +# haproxy instance used as a server +# generate a http/1.1 websocket response with the valid key +haproxy hap_srv -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen fe1 + bind "fd@${fe1}" + + # reject if the request does not contains a websocket key + acl ws_handshake hdr(sec-websocket-key) -m found + http-request reject unless ws_handshake + + # return a valid websocket handshake response + capture request header sec-websocket-key len 128 + http-request return status 200 hdr connection upgrade hdr upgrade websocket hdr sec-websocket-accept "%[capture.req.hdr(0),concat(258EAFA5-E914-47DA-95CA-C5AB0DC85B11,,),sha1,base64]" + http-after-response set-status 101 if { status eq 200 } +} -start + +# haproxy instance used as a server +# generate a http/1.1 websocket response with an invalid key +haproxy hap_srv_bad_key -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen fe1 + bind "fd@${fe1}" + + # reject if the request does not contains a websocket key + acl ws_handshake hdr(sec-websocket-key) -m found + http-request reject unless ws_handshake + + # return an invalid websocket handshake response + capture request header sec-websocket-key len 128 + http-request return status 200 hdr connection upgrade hdr upgrade websocket hdr sec-websocket-accept "invalid_key" + http-after-response set-status 101 if { status eq 200 } +} -start + +haproxy hap -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen fe1 + bind "fd@${fe1}" + server s1 ${s1_addr}:${s1_port} + + listen fe2 + bind "fd@${fe2}" + server s2 ${s2_addr}:${s2_port} + + listen fe3 + bind "fd@${fe3}" proto h2 + server hap_srv ${hap_srv_fe1_addr}:${hap_srv_fe1_port} + + listen fe4 + bind "fd@${fe4}" proto h2 + server hap_srv_bad_key ${hap_srv_bad_key_fe1_addr}:${hap_srv_bad_key_fe1_port} +} -start + +# standard request +client c1 -connect ${hap_fe1_sock} { + txreq \ + -req "GET" \ + -url "/" \ + -hdr "host: 127.0.0.1" \ + -hdr "connection: upgrade" \ + -hdr "upgrade: websocket" \ + -hdr "sec-websocket-key: dGhlIHNhbXBsZSBub25jZQ==" + rxresp + expect resp.status == 101 + expect resp.http.connection == "upgrade" + expect resp.http.upgrade == "websocket" + expect resp.http.sec-websocket-accept == "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=" +} -run + +# missing websocket key +client c2 -connect ${hap_fe1_sock} { + txreq \ + -req "GET" \ + -url "/" \ + -hdr "host: 127.0.0.1" \ + -hdr "connection: upgrade" \ + -hdr "upgrade: websocket" + + rxresp + expect resp.status == 400 +} -run + +# missing key on server side +client c3 -connect ${hap_fe2_sock} { + txreq \ + -req "GET" \ + -url "/" \ + -hdr "host: 127.0.0.1" \ + -hdr "connection: upgrade" \ + -hdr "upgrade: websocket" \ + -hdr "sec-websocket-key: dGhlIHNhbXBsZSBub25jZQ==" + + rxresp + expect resp.status == 502 +} -run + +# connect with http/2 on a http/1.1 websocket server +# the key must be provided by haproxy +client c4 -connect ${hap_fe3_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" "websocket" + + rxhdrs + expect resp.status == 200 + } -run +} -run + +# connect with http/2 on a http/1.1 websocket server +# however, the server will respond with an invalid key +# haproxy is responsible to reject the request and returning a 502 to the client +client c5 -connect ${hap_fe4_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" "websocket" + + rxhdrs + expect resp.status == 502 + } -run +} -run diff --git a/reg-tests/http-rules/1k.txt b/reg-tests/http-rules/1k.txt new file mode 100644 index 0000000..bbdd7e7 --- /dev/null +++ b/reg-tests/http-rules/1k.txt @@ -0,0 +1,16 @@ +s313l7hzIJ5FIXCmpr+zAyFK80lNfjOIRNZSXJJn/GQVNQsBqDl3AFcb7JQt1ler +KgBNE1LAiU02vTj4+hlW2qi4Xg1T3lshEOSSxJQN/ITQG/1KVmDiTtsjjSv8iWUj +T403xvLKQd0FB2h00N9pwd9ApbGPYF8uG1kjnNQmzJOqQ2Pz7jUkNpF+sAAQHaRD +ocjEucTsb676w8l9EqWNE+DK5IqoO2AK47bHbr4u38ZOwXjQWGw9MiUJZmVQEqdC +QZlmpFuSKQiig1SZFZlmKVidf1genz6q+4BT80IFU2UE+pWiay/HcZttwM++eG7w +n/Va7yd3D+ryK2j4rw0sOYM7Cu7AwleZeGEaCZINZmnVAWtg2OVFOTxx6jz8wNuY +VJPb3VFD72WnnBhtbik5mEqjzVJy530sQBlGlcxi3Tivq69ZnAk55RBN0LO+jWf4 +DI4189LTIfY5WroA8AQeCCQYnzyXo5O/vDmic+uwKALlQ6TXzSuCNpHO8fL1UwHH +7KBqxHi+/yYJ0431V/LAvRBpVFPYJ8iED7Md67GRVQWy8o+tgC1PmycJtS5ADQGO +Jys46KjhL9cnaS3aP1YcuuGuSUOVMA7BjqPcz7r+hqYTCZ3akaY4w7AGRCZyRf8e +finlAkgFpzKSFwaa2M6H3vUE14WzHC0hJ/bO2epjlcOeoMcgBVn5uUMYMVroAK0+ +vI9jg1RDV17oHberVmWj8VAXolDNS0pW2rt+JbqHsAVDDk/Ex3NJWFSYByHFyglQ +cjYMwrzIsWC09ykW6WhUN6IsopLlDk7O2jcKaHxZ6WaFiVxIGFkepfNhf4wYZ6O9 +tjwMuOqTQtSjdP3MbbVEM6VpAkJW/Si1jmSW02ObMcdEpxJHTB9fC30waMM7e+T4 +FT/AlwB49un/3yYU2iUndW+wenoED9UkdbZ7uvjyu+UgQ3bMaQhX9Z9eHxhfi6Gy +aRM2IJVeEpk5w0ifAQxrL4Wp+dFbzfGN1yPkI2UAo6WbWi63D
\ No newline at end of file diff --git a/reg-tests/http-rules/acl_cli_spaces.vtc b/reg-tests/http-rules/acl_cli_spaces.vtc new file mode 100644 index 0000000..e61176a --- /dev/null +++ b/reg-tests/http-rules/acl_cli_spaces.vtc @@ -0,0 +1,79 @@ +varnishtest "haproxy ACL, CLI and mCLI spaces" +feature ignore_unknown_macro + +#REQUIRE_VERSION=2.0 + +server s1 { + rxreq + expect req.method == "GET" + txresp +} -repeat 2 -start + +haproxy h1 -W -S -conf { + defaults + mode http + log global + option httplog + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe1}" + + http-request deny if { req.hdr(user-agent) -i -m str -f ${testdir}/agents.acl } + + default_backend be1 + + backend be1 + server s1 ${s1_addr}:${s1_port} + +} -start + +client c1 -connect ${h1_fe1_sock} { + txreq -hdr "User-Agent: Mon User Agent" + rxresp + expect resp.status == 200 +} -run + +haproxy h1 -cli { + send "add acl ${testdir}/agents.acl Mon\\ User\\ Agent\\;" + expect ~ .* + + send "show acl ${testdir}/agents.acl" + expect ~ ".*Mon User Agent.*" +} + +client c1 -connect ${h1_fe1_sock} { + txreq -hdr "User-Agent: Mon User Agent;" + rxresp + expect resp.status == 403 +} -run + + +haproxy h1 -cli { + send "del acl ${testdir}/agents.acl Mon\\ User\\ Agent\\;" + expect ~ .* + + send "show acl ${testdir}/agents.acl" + expect ~ .* +} + +client c1 -connect ${h1_fe1_sock} { + txreq -hdr "User-Agent: Mon User Agent;" + rxresp + expect resp.status == 200 +} -run + + +# Try it with the master CLI +haproxy h1 -mcli { + send "@1 add acl ${testdir}/agents.acl Mon\\ User\\ Agent\\;;@1 show acl ${testdir}/agents.acl" + expect ~ ".*Mon User Agent;.*" +} + +client c1 -connect ${h1_fe1_sock} { + txreq -hdr "User-Agent: Mon User Agent;" + rxresp + expect resp.status == 403 +} -run diff --git a/reg-tests/http-rules/agents.acl b/reg-tests/http-rules/agents.acl new file mode 100644 index 0000000..345e6ae --- /dev/null +++ b/reg-tests/http-rules/agents.acl @@ -0,0 +1 @@ +Test diff --git a/reg-tests/http-rules/converters_ipmask_concat_strcmp_field_word.map b/reg-tests/http-rules/converters_ipmask_concat_strcmp_field_word.map new file mode 100644 index 0000000..9a3e8e6 --- /dev/null +++ b/reg-tests/http-rules/converters_ipmask_concat_strcmp_field_word.map @@ -0,0 +1 @@ +^(.+)_(.+)$ \2_\1 diff --git a/reg-tests/http-rules/converters_ipmask_concat_strcmp_field_word.vtc b/reg-tests/http-rules/converters_ipmask_concat_strcmp_field_word.vtc new file mode 100644 index 0000000..97469b5 --- /dev/null +++ b/reg-tests/http-rules/converters_ipmask_concat_strcmp_field_word.vtc @@ -0,0 +1,218 @@ +varnishtest "Minimal tests for 1.9 converters: ipmask,concat,strcmp,field,word" +feature ignore_unknown_macro + +# concat,strcmp,ipmask(ipv6mask) need 1.9 +#REQUIRE_VERSION=1.9 + +# ipmask tests server +server s1 { + rxreq + expect req.method == "GET" + expect req.http.srciphdr == "192.168.1.101" + expect req.http.srcmask1 == "192.168.1.0" + expect req.http.srcmask2 == "192.168.0.0" + expect req.http.srcmask3 == "192.0.0.0" + + expect req.http.test1mask128 ~ "2001:db8:[0:]*:1" + expect req.http.test2mask64 ~ "2001:db8:[0:]+" + expect req.http.test2mask128 ~ "2001:db8:[0:]*:bad:c0f:ffff" + expect req.http.test2mask120 ~ "2001:db8:[0:]*:bad:c0f:ff00" + expect req.http.test2maskff00 ~ "2001:db8:[0:]*:bad:c0f:ff00" + expect req.http.test2maskfee0 ~ "2001:db8:[0:]*:bad:c0f:fee0" + + expect req.http.test3mask64 ~ "2001:db8:c001:c01a:[0:]+" + expect req.http.test3mask64v2 ~ "2001:db8:c001:c01a:[0:]+" + expect req.http.test3mask64v3 ~ "2001:db8:c001:c01a:[0:]+" + expect req.http.test3maskff ~ "2001:db8:c001:c01a:[0:]*:ffff:10:[0:]+" + expect req.http.test3maskv2 ~ "2001:db8:c001:c01a:c001:c001:[0:]+" + + expect req.http.test4mask32 == "192.168.1.101" + + expect req.http.test5mask24 == "192.168.1.0" + expect req.http.test6mask24 == "192.168.1.0" + expect req.http.test6mask25 == "192.168.1.128" + txresp +} -start + +# concat,strcmp,field,word tests server +server s2 { + rxreq + expect req.method == "GET" + expect req.http.fieldconcat == "f1_f2_f3__f5" + expect req.http.fieldconcat2 == "f1_f2_f3__f5" + expect req.http.fieldconcat3 == "f1_f2_f3__f5" + expect req.http.fieldstrcmp == "0" + + # field tests + expect req.http.fieldtest1 == "f5" + expect req.http.fieldtest2 == "f2_f3__f5" + expect req.http.fieldtest3 == "f2_f3" + expect req.http.fieldtest4 == "f2_f3_" + expect req.http.fieldtest5 == "f1_f2_f3" + expect req.http.okfieldtest == "ok" + expect req.http.qsfieldtest == "IT_IS" + expect req.http.qsfieldconcat == "IT_IS_ok" + expect req.http.fieldtest1strcmp == "0" + + # word tests + expect req.http.wordtest1 == "f5" + expect req.http.wordtest2 == "f2_f3__f5" + expect req.http.wordtest3 == "f3__f5" + expect req.http.wordtest4 == "f1_f2_f3" + expect req.http.wordtest5 == "f1_f2" + expect req.http.okwordtest == "OK" + expect req.http.qswordtest == "Yes_It" + expect req.http.qswordregmtest == "It_Yes" + expect req.http.wordtest1strcmp == "0" + txresp +} -start + + +# ipmask tests with accept-proxy bind +haproxy h1 -conf { + defaults + mode http + log global + option httplog + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + # accept-proxy so test client can send src ip + bind "fd@${fe1}" accept-proxy + + # ipmask tests w/src + http-request set-header Srciphdr %[src] + http-request set-header Srcmask1 %[src,ipmask(24)] # 192.168.1.0 + http-request set-header Srcmask2 %[src,ipmask(16)] # 192.168.0.0 + http-request set-header Srcmask3 %[src,ipmask(8)] # 192.0.0.0 + + # ipmask tests from headers + http-request set-header Test1mask128 %[req.hdr_ip(Addr1),ipmask(24,128)] + + http-request set-header Test2mask64 %[req.hdr_ip(Addr2),ipmask(24,64)] + http-request set-header Test2mask128 %[req.hdr_ip(Addr2),ipmask(24,128)] + http-request set-header Test2mask120 %[req.hdr_ip(Addr2),ipmask(24,120)] + http-request set-header Test2maskff00 %[req.hdr_ip(Addr2),ipmask(24,ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00)] + http-request set-header Test2maskfee0 %[req.hdr_ip(Addr2),ipmask(24,ffff:ffff:ffff:ffff:ffff:ffff:ffff:fee0)] + + http-request set-header Test3mask64 %[req.hdr_ip(Addr3),ipmask(24,64)] + http-request set-header Test3mask64v2 %[req.hdr_ip(Addr3),ipmask(24,ffff:ffff:ffff:ffff:0:0:0:0)] + http-request set-header Test3mask64v3 %[req.hdr_ip(Addr3),ipmask(24,ffff:ffff:ffff:ffff::)] + http-request set-header Test3maskff %[req.hdr_ip(Addr3),ipmask(24,ffff:ffff:ffff:ffff:0:ffff:ffff:0)] + http-request set-header Test3maskv2 %[req.hdr_ip(Addr3),ipmask(24,ffff:ffff:ffff:ffff:c001:c001:0000:0000)] + + # ipv4 mask applied to ipv4 mapped address + http-request set-header Test4mask32 %[req.hdr_ip(Addr4),ipmask(32,64)] + + http-request set-header Test5mask24 %[req.hdr_ip(Addr5),ipmask(24)] + + http-request set-header Test6mask24 %[req.hdr_ip(Addr6),ipmask(24)] + http-request set-header Test6mask25 %[req.hdr_ip(Addr6),ipmask(25)] + + # track addr/mask in stick table + http-request track-sc0 src,ipmask(24) table be1 + http-request track-sc1 hdr_ip(Addr4),ipmask(32) table be1 + http-request track-sc2 hdr_ip(Addr3),ipmask(24,64) table be1 + + default_backend be1 + + backend be1 + stick-table type ipv6 size 20 expire 360s store gpc0,conn_cnt + server s1 ${s1_addr}:${s1_port} +} -start + +# concat,strcmp,word,field haproxy +haproxy h2 -conf { + defaults + mode http + log global + option httplog + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe2 + bind "fd@${fe2}" + + # concat f1_f2 + _ + f3__f5 tests + http-request set-var(sess.field1) hdr(Field1) + http-request set-var(sess.field2) hdr(Field2) + http-request set-var(sess.fieldhdr) hdr(Fieldhdr) + http-request set-var(sess.fieldconcat) hdr(Field1),concat(_,sess.field2,) + http-request set-header Fieldconcat2 %[var(sess.field1),concat(_,sess.field2,)] + http-request set-header Fieldconcat3 %[hdr(Field1),concat(_,sess.field2,)] + http-request set-header Fieldconcat %[var(sess.fieldconcat)] + http-request set-header Fieldstrcmp %[hdr(Fieldhdr),strcmp(sess.fieldconcat)] + http-request deny unless { hdr(Fieldhdr),strcmp(sess.fieldconcat) eq 0 } + + # field tests + http-request set-header Fieldtest1 %[hdr(Fieldhdr),field(5,_)] #f5 + http-request set-var(sess.fieldtest1var) hdr(Fieldtest1) + http-request set-var(sess.okfield) path,lower,field(4,/,1) #ok + http-request set-header Okfieldtest %[var(sess.okfield)] #ok + http-request set-var(sess.qsfield) url_param(qs),upper,field(2,_,2) #IT_IS + http-request set-header Qsfieldtest %[var(sess.qsfield)] #IT_IS + http-request set-header Qsfieldconcat %[var(sess.qsfield),concat(_,sess.okfield,)] #IT_IS_ok + http-request set-header Fieldtest2 %[var(sess.fieldhdr),field(2,_,0)] #f2_f3__f5 + http-request set-header Fieldtest3 %[var(sess.fieldconcat),field(2,_,2)] #f2_f3 + http-request set-header Fieldtest4 %[hdr(Fieldconcat2),field(-2,_,3)] #f2_f3_ + http-request set-header Fieldtest5 %[hdr(Fieldconcat3),field(-3,_,0)] #f1_f2_f3 + http-request set-header Fieldtest1strcmp %[str(f5),strcmp(sess.fieldtest1var)] + http-request deny unless { str(f5),strcmp(sess.fieldtest1var) eq 0 } + http-request deny unless { str(ok),strcmp(sess.okfield) eq 0 } + http-request deny unless { str(IT_IS),strcmp(sess.qsfield) eq 0 } + + # word tests + http-request set-header Wordtest1 %[hdr(Fieldhdr),word(4,_)] #f5 + http-request set-var(sess.wordtest1var) hdr(Wordtest1) + http-request set-var(sess.okword) path,upper,word(3,/,1) #OK + http-request set-header Okwordtest %[var(sess.okword)] #OK + http-request set-var(sess.qsword) url_param(qs),word(1,_,2) #Yes_It + http-request set-header Qswordtest %[var(sess.qsword)] #Yes_It + http-request set-header Qswordregmtest %[var(sess.qsword),map_regm(${testdir}/converters_ipmask_concat_strcmp_field_word.map)] #It_Yes + http-request set-header Wordtest2 %[var(sess.fieldhdr),word(2,_,0)] #f2_f3__f5 + http-request set-header Wordtest3 %[var(sess.fieldconcat),word(3,_,2)] #f3__f5 + http-request set-header Wordtest4 %[hdr(Fieldconcat2),word(-2,_,3)] #f1_f2_f3 + http-request set-header Wordtest5 %[hdr(Fieldconcat3),word(-3,_,0)] #f1_f2 + http-request set-header Wordtest1strcmp %[str(f5),strcmp(sess.wordtest1var)] + http-request deny unless { str(f5),strcmp(sess.wordtest1var) eq 0 } + http-request deny unless { str(OK),strcmp(sess.okword) eq 0 } + http-request deny unless { str(Yes_It),strcmp(sess.qsword) eq 0 } + + default_backend be2 + + backend be2 + server s2 ${s2_addr}:${s2_port} +} -start + +# ipmask tests +client c1 -connect ${h1_fe1_sock} -proxy2 "192.168.1.101:1234 127.0.0.1:2345" { + txreq -hdr "Addr1: 2001:db8::1" \ + -hdr "Addr2: 2001:db8::bad:c0f:ffff" \ + -hdr "Addr3: 2001:db8:c001:c01a:ffff:ffff:10:ffff" \ + -hdr "Addr4: ::FFFF:192.168.1.101" \ + -hdr "Addr5: 192.168.1.2" \ + -hdr "Addr6: 192.168.1.255" + rxresp + expect resp.status == 200 +} -run + +# cli show be1 stick table +haproxy h1 -cli { + send "show table be1" + expect ~ "^# table: be1, type: ipv6, size:20, used:3\\n0x[a-f0-9]+: key=::ffff:192\\.168\\.1\\.0 use=0 exp=[[:digit:]]+ gpc0=0 conn_cnt=1\\n0x[a-f0-9]+: key=::ffff:192\\.168\\.1\\.101 use=0 exp=[[:digit:]]+ gpc0=0 conn_cnt=1\\n0x[a-f0-9]+: key=2001:db8:c001:c01a:[0:]+ use=0 exp=[[:digit:]]+ gpc0=0 conn_cnt=1\\n" +} + +# concat,strcmp,word,field tests +client c2 -connect ${h2_fe2_sock} { + txreq -req GET \ + -url /is/this/Ok/or/not?qs=Yes_It_Is \ + -hdr "Fieldhdr: f1_f2_f3__f5" \ + -hdr "Field1: f1_f2" \ + -hdr "Field2: f3__f5" + rxresp + expect resp.status == 200 +} -run + diff --git a/reg-tests/http-rules/default_rules.vtc b/reg-tests/http-rules/default_rules.vtc new file mode 100644 index 0000000..cc726ab --- /dev/null +++ b/reg-tests/http-rules/default_rules.vtc @@ -0,0 +1,159 @@ +varnishtest "Test declaration of HTTP rules in default sections" + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature ignore_unknown_macro + +server s1 { + rxreq + expect req.http.x-frontend == "fe" + expect req.http.x-backend == "be" + expect req.http.x-test1-frt == "def_front" + expect req.http.x-test1-bck == "def_back" + txresp +} -start + +server s2 { + rxreq + txresp +} -start + +haproxy h1 -conf { + defaults common + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + defaults def_front from common + http-request set-header x-frontend "%[fe_name]" + http-request set-var(txn.test1) "str(def_front)" + http-response set-header x-frontend "%[fe_name]" + http-response set-var(txn.test2) "str(def_front)" + http-after-response set-var(txn.test3) "str(def_front)" + + defaults def_back from common + http-request set-header x-backend "%[be_name]" + http-request set-var(txn.test1) "str(def_back)" + http-response set-header x-backend "%[be_name]" + http-response set-var(txn.test2) "str(def_back)" + http-after-response set-var(txn.test3) "str(def_back)" + + frontend fe from def_front + bind "fd@${feh1}" + + http-request set-header x-test1-frt "%[var(txn.test1)]" + http-response set-header x-test2-frt "%[var(txn.test2)]" + http-after-response set-header x-test3-frt "%[var(txn.test3)]" + + default_backend be + + backend be from def_back + http-request set-header x-test1-bck "%[var(txn.test1)]" + http-response set-header x-test2-bck "%[var(txn.test2)]" + http-after-response set-header x-test3-bck "%[var(txn.test3)]" + + server s1 ${s1_addr}:${s1_port} + +} -start + + +haproxy h2 -conf { + defaults common + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + defaults def_front from common + http-request allow + http-response allow + http-after-response allow + + defaults def_back from common + http-request allow + http-response allow + http-after-response allow + + frontend fe from def_front + bind "fd@${feh2}" + + http-request deny status 403 + http-response deny status 502 + http-after-response set-status 502 + + default_backend be + + backend be from def_back + http-request deny status 403 + http-response deny status 502 + http-after-response set-status 502 + + server s2 ${s2_addr}:${s2_port} + +} -start + +haproxy h3 -conf { + defaults base-http + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + http-request capture hdr(Host) len 64 # idx 0 + http-request capture hdr(X-req-1) len 32 # idx 1 + + frontend fe1 from base-http + bind "fd@${fe1h3}" + declare capture request len 32 # idx 2 + + http-request capture hdr(X-req-2) id 2 + http-request return status 200 hdr "X-Capture-1" "%[capture.req.hdr(0)]" hdr "X-Capture-2" "%[capture.req.hdr(1)]" hdr "X-Capture-3" "%[capture.req.hdr(2)]" + + frontend fe2 from base-http + bind "fd@${fe2h3}" + http-request capture hdr(X-req-2) id 1 + http-request return status 200 hdr "X-Capture-1" "%[capture.req.hdr(0)]" hdr "X-Capture-2" "%[capture.req.hdr(1)]" + +} -start + +client c1 -connect ${h1_feh1_sock} { + txreq -req GET -url / + rxresp + expect resp.status == 200 + expect resp.http.x-frontend == "fe" + expect resp.http.x-backend == "be" + expect resp.http.x-test2-bck == "def_back" + expect resp.http.x-test2-frt == "def_front" + expect resp.http.x-test3-bck == "def_back" + expect resp.http.x-test3-frt == "def_front" +} -run + +client c2 -connect ${h2_feh2_sock} { + txreq -req GET -url / + rxresp + expect resp.status == 200 +} -run + +client c3 -connect ${h3_fe1h3_sock} { + txreq -req GET -url / \ + -hdr "host: v-test" \ + -hdr "x-req-1: val1" \ + -hdr "x-req-2: val2" + rxresp + expect resp.status == 200 + expect resp.http.x-capture-1 == "v-test" + expect resp.http.x-capture-2 == "val1" + expect resp.http.x-capture-3 == "val2" +} -run + +client c4 -connect ${h3_fe2h3_sock} { + txreq -req GET -url / \ + -hdr "host: v-test" \ + -hdr "x-req-1: val1" \ + -hdr "x-req-2: val2" + rxresp + expect resp.status == 200 + expect resp.http.x-capture-1 == "v-test" + expect resp.http.x-capture-2 == "val2" + expect resp.http.x-capture-3 == "<undef>" +} -run diff --git a/reg-tests/http-rules/del_header.vtc b/reg-tests/http-rules/del_header.vtc new file mode 100644 index 0000000..0f74a60 --- /dev/null +++ b/reg-tests/http-rules/del_header.vtc @@ -0,0 +1,93 @@ +varnishtest "del-header tests" + +# This config tests various http-request/response del-header operations +# with or without specified header name matching method. + +feature ignore_unknown_macro + +server s1 { + rxreq + expect req.url == / + expect req.http.x-always == always + expect req.http.x-str1 == <undef> + expect req.http.x-str2 == <undef> + expect req.http.x-beg1 == <undef> + expect req.http.x-beg2 == <undef> + expect req.http.x-end1 == <undef> + expect req.http.x-end2 == end2 + expect req.http.x-sub1 == <undef> + expect req.http.x-sub2 == <undef> + expect req.http.x-reg1 == <undef> + expect req.http.x-reg2 == <undef> + txresp -hdr "x-always: always" \ + -hdr "x-str1: str1" \ + -hdr "x-str2: str2" \ + -hdr "x-beg1: beg1" \ + -hdr "x-beg2: beg2" \ + -hdr "x-end1: end1" \ + -hdr "x-end2: end2" \ + -hdr "x-sub1: sub1" \ + -hdr "x-sub2: sub2" \ + -hdr "x-reg1: reg1" \ + -hdr "x-reg2: reg2" + +} -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + + http-request del-header x-str1 + http-request del-header x-str2 -m str + http-request del-header x-beg -m beg + http-request del-header end1 -m end + http-request del-header sub -m sub + http-request del-header ^x.reg.$ -m reg + + http-response del-header x-str1 + http-response del-header x-str2 -m str + http-response del-header x-beg -m beg + http-response del-header end1 -m end + http-response del-header sub -m sub + http-response del-header ^x.reg.$ -m reg + + default_backend be + + backend be + server s1 ${s1_addr}:${s1_port} + +} -start + +client c1 -connect ${h1_fe_sock} { + txreq -req GET -url / \ + -hdr "x-always: always" \ + -hdr "x-str1: str1" \ + -hdr "x-str2: str2" \ + -hdr "x-beg1: beg1" \ + -hdr "x-beg2: beg2" \ + -hdr "x-end1: end1" \ + -hdr "x-end2: end2" \ + -hdr "x-sub1: sub1" \ + -hdr "x-sub2: sub2" \ + -hdr "x-reg1: reg1" \ + -hdr "x-reg2: reg2" + rxresp + expect resp.status == 200 + expect resp.http.x-always == always + expect resp.http.x-str1 == <undef> + expect resp.http.x-str2 == <undef> + expect resp.http.x-beg1 == <undef> + expect resp.http.x-beg2 == <undef> + expect resp.http.x-end1 == <undef> + expect resp.http.x-end2 == end2 + expect resp.http.x-sub1 == <undef> + expect resp.http.x-sub2 == <undef> + expect resp.http.x-reg1 == <undef> + expect resp.http.x-reg2 == <undef> +} -run diff --git a/reg-tests/http-rules/except-forwardfor-originalto.vtc b/reg-tests/http-rules/except-forwardfor-originalto.vtc new file mode 100644 index 0000000..a859160 --- /dev/null +++ b/reg-tests/http-rules/except-forwardfor-originalto.vtc @@ -0,0 +1,143 @@ +varnishtest "Test IPv4/IPv6 except param for the forwardfor and originalto options" +#REQUIRE_VERSION=2.4 + +# This config tests the except parameter for the HTTP forwardfor and originalto +# options. + +feature ignore_unknown_macro + +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 + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe1}" + http-request set-src hdr(x-src) + http-request set-dst hdr(x-dst) + use_backend be1 if { path /req1 } + use_backend be2 if { path /req2 } + use_backend be3 if { path /req3 } + use_backend be4 if { path /req4 } + use_backend be5 if { path /req5 } + + frontend fe2 + bind "fd@${fe2}" + http-request return status 200 hdr x-ff "%[req.hdr(x-forwarded-for)]" hdr x-ot "%[req.hdr(x-original-to)]" + + backend be1 + option forwardfor except 127.0.0.1 + option originalto except 127.0.0.1 + server s1 ${h1_fe2_addr}:${h1_fe2_port} + + backend be2 + option forwardfor except 10.0.0.1/25 + option originalto except 10.0.0.1/25 + server s1 ${h1_fe2_addr}:${h1_fe2_port} + + backend be3 + option forwardfor except ::1 + option originalto except ::1 + server s1 ${h1_fe2_addr}:${h1_fe2_port} + + backend be4 + option forwardfor except 2001:db8::1:0:0:1 + option originalto except 2001:db8::1:0:0:1 + server s1 ${h1_fe2_addr}:${h1_fe2_port} + + backend be5 + option forwardfor except 2001:db8:1f89::/48 + option originalto except 2001:db8:1f89::/48 + server s1 ${h1_fe2_addr}:${h1_fe2_port} +} -start + +client c1 -connect ${h1_fe1_sock} { + txreq -req GET -url /req1 \ + -hdr "x-src: 127.0.0.1" \ + -hdr "x-dst: 127.0.0.1" + rxresp + expect resp.status == 200 + expect resp.http.x-ff == <undef> + expect resp.http.x-ot == <undef> + + txreq -req GET -url /req1 \ + -hdr "x-src: 127.0.0.2" \ + -hdr "x-dst: 127.0.0.2" + rxresp + expect resp.status == 200 + expect resp.http.x-ff == "127.0.0.2" + expect resp.http.x-ot == "127.0.0.2" + + + txreq -req GET -url /req2 \ + -hdr "x-src: 10.0.0.1" \ + -hdr "x-dst: 10.0.0.1" + rxresp + expect resp.status == 200 + expect resp.http.x-ff == <undef> + expect resp.http.x-ot == <undef> + + txreq -req GET -url /req2 \ + -hdr "x-src: 10.0.0.128" \ + -hdr "x-dst: 10.0.0.128" + rxresp + expect resp.status == 200 + expect resp.http.x-ff == "10.0.0.128" + expect resp.http.x-ot == "10.0.0.128" + + txreq -req GET -url /req3 \ + -hdr "x-src: ::1" \ + -hdr "x-dst: ::1" + rxresp + expect resp.status == 200 + expect resp.http.x-ff == <undef> + expect resp.http.x-ot == <undef> + + txreq -req GET -url /req3 \ + -hdr "x-src: ::2" \ + -hdr "x-dst: ::2" + rxresp + expect resp.status == 200 + expect resp.http.x-ff == "::2" + expect resp.http.x-ot == "::2" + + txreq -req GET -url /req4 \ + -hdr "x-src: 2001:db8::1:0:0:1" \ + -hdr "x-dst: 2001:db8::1:0:0:1" + rxresp + expect resp.status == 200 + expect resp.http.x-ff == <undef> + expect resp.http.x-ot == <undef> + + txreq -req GET -url /req4 \ + -hdr "x-src: 2001:db8::1:0:0:2" \ + -hdr "x-dst: 2001:db8::1:0:0:2" + rxresp + expect resp.status == 200 + expect resp.http.x-ff == "2001:db8::1:0:0:2" + expect resp.http.x-ot == "2001:db8::1:0:0:2" + + txreq -req GET -url /req5 \ + -hdr "x-src: 2001:db8:1f89::1" \ + -hdr "x-dst: 2001:db8:1f89::1" + rxresp + expect resp.status == 200 + expect resp.http.x-ff == <undef> + expect resp.http.x-ot == <undef> + + txreq -req GET -url /req5 \ + -hdr "x-src: 2001:db8:1f90::1" \ + -hdr "x-dst: 2001:db8:1f90::1" + rxresp + expect resp.status == 200 + expect resp.http.x-ff == "2001:db8:1f90::1" + expect resp.http.x-ot == "2001:db8:1f90::1" +} -run diff --git a/reg-tests/http-rules/h1_to_h1c.vtc b/reg-tests/http-rules/h1_to_h1c.vtc new file mode 100644 index 0000000..9ae73f7 --- /dev/null +++ b/reg-tests/http-rules/h1_to_h1c.vtc @@ -0,0 +1,186 @@ +varnishtest "Composite HTTP manipulation test (H1 clear to H1 clear)" +#REQUIRE_VERSION_BELOW=1.9 + +# This config tests several http-request features and their interactions. +# It extracts some samples, places them into variables, modifies some header +# fields, appends multiple identical header fields, overwrites the start line +# using several methods, then dumps the initial list of variables and the final +# one, then applies CRC32 to these values as signatures that are easy to test. +# Then it does it again in the backend after saving the current headers into +# the same names prefixed by "fe-". Then it does the same on the response path. +# If some modifications are performed, the crc values need to be adjusted based +# on the failed logs. +# +# Run it with HAPROXY_PROGRAM=$PWD/haproxy varnishtest -l -k -t 1 "$1" + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp \ + -status 234 \ + -hdr "hdr1: val1" \ + -hdr "hdr2: val2a" \ + -hdr "hdr2: val2b" \ + -hdr "hdr3: val3a, val3b" \ + -hdr "hdr4:" \ + -body "This is a body" + + expect req.method == "GET" + expect req.http.fe-sl1-crc == 992395575 + expect req.http.fe-sl2-crc == 1270056220 + expect req.http.fe-hdr-crc == 1719311923 + expect req.http.be-sl1-crc == 2604236007 + expect req.http.be-sl2-crc == 4181358964 + expect req.http.be-hdr-crc == 3634102538 +} -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + + #### requests + http-request set-var(req.method) method + http-request set-var(req.uri) url + http-request set-var(req.path) path + http-request set-var(req.query) query + http-request set-var(req.param) url_param(qs_arg) + + http-request set-header sl1 "sl1: " + + http-request set-method "%[str(GET)]" + http-request set-uri concat(/bu/,req.uri,/eu) + http-request set-path "/bp/%[var(req.path)]/ep" + http-request set-query "bq&%[var(req.query)]&eq" + + http-request set-header sl2 "sl2: " + + http-request set-header sl1 "%[req.fhdr(sl1)] method=<%[var(req.method)]>; uri=<%[var(req.uri)]>; path=<%[var(req.path)]>;" + http-request set-header sl1 "%[req.fhdr(sl1)] query=<%[var(req.query)]>; param=<%[var(req.param)]>" + http-request set-header sl2 "%[req.fhdr(sl2)] method=<%[method]>; uri=<%[url]>; path=<%[path]>; " + http-request set-header sl2 "%[req.fhdr(sl2)] query=<%[query]>; param=<%[url_param(qs_arg)]>" + http-request set-header hdr "%[req.fhdr(hdr)] hdr1=<%[req.hdr(hdr1)]>; fhdr1=<%[req.fhdr(hdr1)]>;" + http-request set-header hdr "%[req.fhdr(hdr)] hdr2=<%[req.hdr(hdr2)]>; fhdr2=<%[req.fhdr(hdr2)]>;" + http-request set-header hdr "%[req.fhdr(hdr)] hdr3=<%[req.hdr(hdr3)]>; fhdr3=<%[req.fhdr(hdr3)]>;" + http-request set-header hdr "%[req.fhdr(hdr)] hdr4=<%[req.hdr(hdr4)]>; fhdr4=<%[req.fhdr(hdr4)]>;" + + http-request set-header sl1-crc "%[req.fhdr(sl1),crc32]" + http-request set-header sl2-crc "%[req.fhdr(sl2),crc32]" + http-request set-header hdr-crc "%[req.fhdr(hdr),crc32]" + + #### responses + http-response set-header be-sl1 "%[res.fhdr(sl1)]" + http-response set-header be-sl2 "%[res.fhdr(sl2)]" + http-response set-header be-hdr "%[res.fhdr(hdr)]" + + http-response set-header be-sl1-crc "%[res.fhdr(sl1-crc)]" + http-response set-header be-sl2-crc "%[res.fhdr(sl2-crc)]" + http-response set-header be-hdr-crc "%[res.fhdr(hdr-crc)]" + + http-response set-var(res.status) status + http-response set-header sl1 "sl1: " + + http-response set-status 200 + + http-response set-header sl2 "sl2: " + + http-response set-header sl1 "%[res.fhdr(sl1)] status=<%[var(res.status)]>;" + http-response set-header sl2 "%[res.fhdr(sl2)] status=<%[status]>;" + http-response set-header hdr "%[res.fhdr(hdr)] hdr1=<%[res.hdr(hdr1)]>; fhdr1=<%[res.fhdr(hdr1)]>;" + http-response set-header hdr "%[res.fhdr(hdr)] hdr2=<%[res.hdr(hdr2)]>; fhdr2=<%[res.fhdr(hdr2)]>;" + http-response set-header hdr "%[res.fhdr(hdr)] hdr3=<%[res.hdr(hdr3)]>; fhdr3=<%[res.fhdr(hdr3)]>;" + http-response set-header hdr "%[res.fhdr(hdr)] hdr4=<%[res.hdr(hdr4)]>; fhdr4=<%[res.fhdr(hdr4)]>;" + + http-response set-header fe-sl1-crc "%[res.fhdr(sl1),crc32]" + http-response set-header fe-sl2-crc "%[res.fhdr(sl2),crc32]" + http-response set-header fe-hdr-crc "%[res.fhdr(hdr),crc32]" + + default_backend be + + backend be + #### requests + http-request set-header fe-sl1 "%[req.fhdr(sl1)]" + http-request set-header fe-sl2 "%[req.fhdr(sl2)]" + http-request set-header fe-hdr "%[req.fhdr(hdr)]" + + http-request set-header fe-sl1-crc "%[req.fhdr(sl1-crc)]" + http-request set-header fe-sl2-crc "%[req.fhdr(sl2-crc)]" + http-request set-header fe-hdr-crc "%[req.fhdr(hdr-crc)]" + + http-request set-var(req.method) method + http-request set-var(req.uri) url + http-request set-var(req.path) path + http-request set-var(req.query) query + http-request set-var(req.param) url_param(qs_arg) + + http-request set-header sl1 "sl1: " + + http-request set-method "%[str(GET)]" + http-request set-uri concat(/bu/,req.uri,/eu) + http-request set-path "/bp/%[var(req.path)]/ep" + http-request set-query "bq&%[var(req.query)]&eq" + + http-request set-header sl2 "sl2: " + + http-request set-header sl1 "%[req.fhdr(sl1)] method=<%[var(req.method)]>; uri=<%[var(req.uri)]>; path=<%[var(req.path)]>;" + http-request set-header sl1 "%[req.fhdr(sl1)] query=<%[var(req.query)]>; param=<%[var(req.param)]>" + http-request set-header sl2 "%[req.fhdr(sl2)] method=<%[method]>; uri=<%[url]>; path=<%[path]>; " + http-request set-header sl2 "%[req.fhdr(sl2)] query=<%[query]>; param=<%[url_param(qs_arg)]>" + http-request set-header hdr "%[req.fhdr(hdr)] hdr1=<%[req.hdr(hdr1)]>; fhdr1=<%[req.fhdr(hdr1)]>;" + http-request set-header hdr "%[req.fhdr(hdr)] hdr2=<%[req.hdr(hdr2)]>; fhdr2=<%[req.fhdr(hdr2)]>;" + http-request set-header hdr "%[req.fhdr(hdr)] hdr3=<%[req.hdr(hdr3)]>; fhdr3=<%[req.fhdr(hdr3)]>;" + http-request set-header hdr "%[req.fhdr(hdr)] hdr4=<%[req.hdr(hdr4)]>; fhdr4=<%[req.fhdr(hdr4)]>;" + + http-request set-header be-sl1-crc "%[req.fhdr(sl1),crc32]" + http-request set-header be-sl2-crc "%[req.fhdr(sl2),crc32]" + http-request set-header be-hdr-crc "%[req.fhdr(hdr),crc32]" + + #### responses + http-response set-var(res.status) status + http-response set-header sl1 "sl1: " + + http-response set-status 200 + + http-response set-header sl2 "sl2: " + + http-response set-header sl1 "%[res.fhdr(sl1)] status=<%[var(res.status)]>;" + http-response set-header sl2 "%[res.fhdr(sl2)] status=<%[status]>;" + http-response set-header hdr "%[res.fhdr(hdr)] hdr1=<%[res.hdr(hdr1)]>; fhdr1=<%[res.fhdr(hdr1)]>;" + http-response set-header hdr "%[res.fhdr(hdr)] hdr2=<%[res.hdr(hdr2)]>; fhdr2=<%[res.fhdr(hdr2)]>;" + http-response set-header hdr "%[res.fhdr(hdr)] hdr3=<%[res.hdr(hdr3)]>; fhdr3=<%[res.fhdr(hdr3)]>;" + http-response set-header hdr "%[res.fhdr(hdr)] hdr4=<%[res.hdr(hdr4)]>; fhdr4=<%[res.fhdr(hdr4)]>;" + + http-response set-header sl1-crc "%[res.fhdr(sl1),crc32]" + http-response set-header sl2-crc "%[res.fhdr(sl2),crc32]" + http-response set-header hdr-crc "%[res.fhdr(hdr),crc32]" + + server s1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe_sock} { + txreq \ + -req GET \ + -url /path/to/file.extension?qs_arg=qs_value \ + -hdr "hdr1: val1" \ + -hdr "hdr2: val2a" \ + -hdr "hdr2: val2b" \ + -hdr "hdr3: val3a, val3b" \ + -hdr "hdr4:" + rxresp + + expect resp.status == 200 + expect resp.http.be-sl1-crc == 487202719 + expect resp.http.be-sl2-crc == 561949791 + expect resp.http.be-hdr-crc == 1719311923 + expect resp.http.fe-sl1-crc == 146151597 + expect resp.http.fe-sl2-crc == 561949791 + expect resp.http.fe-hdr-crc == 3634102538 + expect resp.bodylen == 14 + expect resp.body == "This is a body" +} -run diff --git a/reg-tests/http-rules/h1or2_to_h1c.vtc b/reg-tests/http-rules/h1or2_to_h1c.vtc new file mode 100644 index 0000000..9e7eb60 --- /dev/null +++ b/reg-tests/http-rules/h1or2_to_h1c.vtc @@ -0,0 +1,226 @@ +varnishtest "Composite HTTP manipulation test (H1 and H2 clear to H1 clear)" +#REQUIRE_VERSION=1.9 + +# This config tests several http-request features and their interactions. +# It extracts some samples, places them into variables, modifies some header +# fields, appends multiple identical header fields, overwrites the start line +# using several methods, then dumps the initial list of variables and the final +# one, then applies CRC32 to these values as signatures that are easy to test. +# Then it does it again in the backend after saving the current headers into +# the same names prefixed by "fe-". Then it does the same on the response path. +# If some modifications are performed, the crc values need to be adjusted based +# on the failed logs. +# +# Run it with HAPROXY_PROGRAM=$PWD/haproxy varnishtest -l -k -t 1 "$1" + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp \ + -status 234 \ + -hdr "hdr1: val1" \ + -hdr "hdr2: val2a" \ + -hdr "hdr2: val2b" \ + -hdr "hdr3: val3a, val3b" \ + -hdr "hdr4:" \ + -body "This is a body" + + expect req.method == "GET" + expect req.http.fe-sl1-crc == 992395575 + expect req.http.fe-sl2-crc == 1270056220 + expect req.http.fe-hdr-crc == 1719311923 + expect req.http.be-sl1-crc == 2604236007 + expect req.http.be-sl2-crc == 4181358964 + expect req.http.be-hdr-crc == 3634102538 +} -repeat 2 -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${feh1}" + bind "fd@${feh2}" proto h2 + + #### requests + http-request set-var(req.method) method + http-request set-var(req.uri) url + http-request set-var(req.path) path + http-request set-var(req.query) query + http-request set-var(req.param) url_param(qs_arg) + + http-request set-header sl1 "sl1: " + + http-request set-method "%[str(GET)]" + http-request set-uri %[str(),concat(/bu/,req.uri,/eu)] + http-request set-path "/bp/%[var(req.path)]/ep" + http-request set-query "bq&%[var(req.query)]&eq" + + http-request set-header sl2 "sl2: " + + http-request set-header sl1 "%[req.fhdr(sl1)] method=<%[var(req.method)]>; uri=<%[var(req.uri)]>; path=<%[var(req.path)]>;" + http-request set-header sl1 "%[req.fhdr(sl1)] query=<%[var(req.query)]>; param=<%[var(req.param)]>" + http-request set-header sl2 "%[req.fhdr(sl2)] method=<%[method]>; uri=<%[url]>; path=<%[path]>; " + http-request set-header sl2 "%[req.fhdr(sl2)] query=<%[query]>; param=<%[url_param(qs_arg)]>" + http-request set-header hdr "%[req.fhdr(hdr)] hdr1=<%[req.hdr(hdr1)]>; fhdr1=<%[req.fhdr(hdr1)]>;" + http-request set-header hdr "%[req.fhdr(hdr)] hdr2=<%[req.hdr(hdr2)]>; fhdr2=<%[req.fhdr(hdr2)]>;" + http-request set-header hdr "%[req.fhdr(hdr)] hdr3=<%[req.hdr(hdr3)]>; fhdr3=<%[req.fhdr(hdr3)]>;" + http-request set-header hdr "%[req.fhdr(hdr)] hdr4=<%[req.hdr(hdr4)]>; fhdr4=<%[req.fhdr(hdr4)]>;" + + http-request set-header sl1-crc "%[req.fhdr(sl1),crc32]" + http-request set-header sl2-crc "%[req.fhdr(sl2),crc32]" + http-request set-header hdr-crc "%[req.fhdr(hdr),crc32]" + + #### responses + http-response set-header be-sl1 "%[res.fhdr(sl1)]" + http-response set-header be-sl2 "%[res.fhdr(sl2)]" + http-response set-header be-hdr "%[res.fhdr(hdr)]" + + http-response set-header be-sl1-crc "%[res.fhdr(sl1-crc)]" + http-response set-header be-sl2-crc "%[res.fhdr(sl2-crc)]" + http-response set-header be-hdr-crc "%[res.fhdr(hdr-crc)]" + + http-response set-var(res.status) status + http-response set-header sl1 "sl1: " + + http-response set-status 200 + + http-response set-header sl2 "sl2: " + + http-response set-header sl1 "%[res.fhdr(sl1)] status=<%[var(res.status)]>;" + http-response set-header sl2 "%[res.fhdr(sl2)] status=<%[status]>;" + http-response set-header hdr "%[res.fhdr(hdr)] hdr1=<%[res.hdr(hdr1)]>; fhdr1=<%[res.fhdr(hdr1)]>;" + http-response set-header hdr "%[res.fhdr(hdr)] hdr2=<%[res.hdr(hdr2)]>; fhdr2=<%[res.fhdr(hdr2)]>;" + http-response set-header hdr "%[res.fhdr(hdr)] hdr3=<%[res.hdr(hdr3)]>; fhdr3=<%[res.fhdr(hdr3)]>;" + http-response set-header hdr "%[res.fhdr(hdr)] hdr4=<%[res.hdr(hdr4)]>; fhdr4=<%[res.fhdr(hdr4)]>;" + + http-response set-header fe-sl1-crc "%[res.fhdr(sl1),crc32]" + http-response set-header fe-sl2-crc "%[res.fhdr(sl2),crc32]" + http-response set-header fe-hdr-crc "%[res.fhdr(hdr),crc32]" + + default_backend be + + backend be + #### requests + http-request set-header fe-sl1 "%[req.fhdr(sl1)]" + http-request set-header fe-sl2 "%[req.fhdr(sl2)]" + http-request set-header fe-hdr "%[req.fhdr(hdr)]" + + http-request set-header fe-sl1-crc "%[req.fhdr(sl1-crc)]" + http-request set-header fe-sl2-crc "%[req.fhdr(sl2-crc)]" + http-request set-header fe-hdr-crc "%[req.fhdr(hdr-crc)]" + + http-request set-var(req.method) method + http-request set-var(req.uri) url + http-request set-var(req.path) path + http-request set-var(req.query) query + http-request set-var(req.param) url_param(qs_arg) + + http-request set-header sl1 "sl1: " + + http-request set-method "%[str(GET)]" + http-request set-uri %[str(),concat(/bu/,req.uri,/eu)] + http-request set-path "/bp/%[var(req.path)]/ep" + http-request set-query "bq&%[var(req.query)]&eq" + + http-request set-header sl2 "sl2: " + + http-request set-header sl1 "%[req.fhdr(sl1)] method=<%[var(req.method)]>; uri=<%[var(req.uri)]>; path=<%[var(req.path)]>;" + http-request set-header sl1 "%[req.fhdr(sl1)] query=<%[var(req.query)]>; param=<%[var(req.param)]>" + http-request set-header sl2 "%[req.fhdr(sl2)] method=<%[method]>; uri=<%[url]>; path=<%[path]>; " + http-request set-header sl2 "%[req.fhdr(sl2)] query=<%[query]>; param=<%[url_param(qs_arg)]>" + http-request set-header hdr "%[req.fhdr(hdr)] hdr1=<%[req.hdr(hdr1)]>; fhdr1=<%[req.fhdr(hdr1)]>;" + http-request set-header hdr "%[req.fhdr(hdr)] hdr2=<%[req.hdr(hdr2)]>; fhdr2=<%[req.fhdr(hdr2)]>;" + http-request set-header hdr "%[req.fhdr(hdr)] hdr3=<%[req.hdr(hdr3)]>; fhdr3=<%[req.fhdr(hdr3)]>;" + http-request set-header hdr "%[req.fhdr(hdr)] hdr4=<%[req.hdr(hdr4)]>; fhdr4=<%[req.fhdr(hdr4)]>;" + + http-request set-header be-sl1-crc "%[req.fhdr(sl1),crc32]" + http-request set-header be-sl2-crc "%[req.fhdr(sl2),crc32]" + http-request set-header be-hdr-crc "%[req.fhdr(hdr),crc32]" + + #### responses + http-response set-var(res.status) status + http-response set-header sl1 "sl1: " + + http-response set-status 200 + + http-response set-header sl2 "sl2: " + + http-response set-header sl1 "%[res.fhdr(sl1)] status=<%[var(res.status)]>;" + http-response set-header sl2 "%[res.fhdr(sl2)] status=<%[status]>;" + http-response set-header hdr "%[res.fhdr(hdr)] hdr1=<%[res.hdr(hdr1)]>; fhdr1=<%[res.fhdr(hdr1)]>;" + http-response set-header hdr "%[res.fhdr(hdr)] hdr2=<%[res.hdr(hdr2)]>; fhdr2=<%[res.fhdr(hdr2)]>;" + http-response set-header hdr "%[res.fhdr(hdr)] hdr3=<%[res.hdr(hdr3)]>; fhdr3=<%[res.fhdr(hdr3)]>;" + http-response set-header hdr "%[res.fhdr(hdr)] hdr4=<%[res.hdr(hdr4)]>; fhdr4=<%[res.fhdr(hdr4)]>;" + + http-response set-header sl1-crc "%[res.fhdr(sl1),crc32]" + http-response set-header sl2-crc "%[res.fhdr(sl2),crc32]" + http-response set-header hdr-crc "%[res.fhdr(hdr),crc32]" + http-response allow + http-response deny # must not be evaluated + + server s1 ${s1_addr}:${s1_port} +} -start + +client c1h1 -connect ${h1_feh1_sock} { + txreq \ + -req GET \ + -url /path/to/file.extension?qs_arg=qs_value \ + -hdr "hdr1: val1" \ + -hdr "hdr2: val2a" \ + -hdr "hdr2: val2b" \ + -hdr "hdr3: val3a, val3b" \ + -hdr "hdr4:" + rxresp + + expect resp.status == 200 + expect resp.http.be-sl1-crc == 487202719 + expect resp.http.be-sl2-crc == 561949791 + expect resp.http.be-hdr-crc == 1719311923 + expect resp.http.fe-sl1-crc == 146151597 + expect resp.http.fe-sl2-crc == 561949791 + expect resp.http.fe-hdr-crc == 3634102538 + expect resp.bodylen == 14 + expect resp.body == "This is a body" +} -run + +client c1h2 -connect ${h1_feh2_sock} { + txpri + stream 0 { + txsettings + rxsettings + txsettings -ack + rxsettings + expect settings.ack == true + } -run + stream 1 { + # warning: -req, -scheme, -url MUST be placed first otherwise + # the H2 protocol is invalid since they are pseudo-headers + txreq \ + -req GET \ + -scheme "https" \ + -url /path/to/file.extension?qs_arg=qs_value \ + -hdr "hdr1" "val1" \ + -hdr "hdr2" " val2a" \ + -hdr "hdr2" " val2b" \ + -hdr "hdr3" " val3a, val3b" \ + -hdr "hdr4" "" + + rxhdrs + expect resp.status == 200 + expect resp.http.be-sl1-crc == 487202719 + expect resp.http.be-sl2-crc == 561949791 + expect resp.http.be-hdr-crc == 1719311923 + expect resp.http.fe-sl1-crc == 146151597 + expect resp.http.fe-sl2-crc == 561949791 + expect resp.http.fe-hdr-crc == 3634102538 + expect resp.http.content-length == 14 + + rxdata -all + expect resp.body == "This is a body" + } -run +} -run diff --git a/reg-tests/http-rules/http_after_response.vtc b/reg-tests/http-rules/http_after_response.vtc new file mode 100644 index 0000000..7e8cc1d --- /dev/null +++ b/reg-tests/http-rules/http_after_response.vtc @@ -0,0 +1,192 @@ +varnishtest "Test HTTP response manipulation under the http-after-response rulesets" +#REQUIRE_VERSION=2.2 + +# This config tests various http-after-response rules for HTTP responses from a +# server and the stats applet, but also for internal responses +# (deny/redirect/auth/return). + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp \ + -status 234 \ + -hdr "hdr1: val1" \ + -hdr "hdr2: val2a" \ + -hdr "hdr2: val2b" \ + -hdr "hdr3: val3a, val3b" \ + -hdr "hdr4:" \ + -body "This is a body" +} -repeat 2 -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${feh1}" + + http-request deny if { path /deny } + http-request redirect location / if { path /redir } + http-request auth if { path /auth } + + http-after-response allow if { status eq 403 } + http-after-response allow if { status eq 302 } + http-after-response allow if { status eq 401 } + + http-after-response set-header be-sl1 "%[res.fhdr(sl1)]" + http-after-response set-header be-sl2 "%[res.fhdr(sl2)]" + http-after-response set-header be-hdr "%[res.fhdr(hdr)]" + + http-after-response set-header be-sl1-crc "%[res.fhdr(sl1-crc)]" + http-after-response set-header be-sl2-crc "%[res.fhdr(sl2-crc)]" + http-after-response set-header be-hdr-crc "%[res.fhdr(hdr-crc)]" + + http-after-response set-var(res.status) status + http-after-response set-header sl1 "sl1: " + + http-after-response set-status 200 + + http-after-response set-header sl2 "sl2: " + + http-after-response set-header sl1 "%[res.fhdr(sl1)] status=<%[var(res.status)]>;" + http-after-response set-header sl2 "%[res.fhdr(sl2)] status=<%[status]>;" + http-after-response set-header hdr "%[res.fhdr(hdr)] hdr1=<%[res.hdr(hdr1)]>; fhdr1=<%[res.fhdr(hdr1)]>;" + http-after-response set-header hdr "%[res.fhdr(hdr)] hdr2=<%[res.hdr(hdr2)]>; fhdr2=<%[res.fhdr(hdr2)]>;" + http-after-response set-header hdr "%[res.fhdr(hdr)] hdr3=<%[res.hdr(hdr3)]>; fhdr3=<%[res.fhdr(hdr3)]>;" + http-after-response set-header hdr "%[res.fhdr(hdr)] hdr4=<%[res.hdr(hdr4)]>; fhdr4=<%[res.fhdr(hdr4)]>;" + + http-after-response set-header fe-sl1-crc "%[res.fhdr(sl1),crc32]" + http-after-response set-header fe-sl2-crc "%[res.fhdr(sl2),crc32]" + http-after-response set-header fe-hdr-crc "%[res.fhdr(hdr),crc32]" + + default_backend be + + backend be + stats enable + stats uri /stats + + http-request return status 234 content-type "text/plain" string "This is a body" if { path /return } + + http-response deny if { capture.req.uri /deny-srv } + + http-after-response allow if { status eq 502 } + + http-after-response set-status 234 if { capture.req.uri /stats } + http-after-response add-header hdr1 val1 unless { capture.req.uri / } + http-after-response add-header hdr2 val2a unless { capture.req.uri / } + http-after-response add-header hdr2 val2b unless { capture.req.uri / } + http-after-response add-header hdr3 "val3a, val3b" unless { capture.req.uri / } + http-after-response add-header hdr4 "%[str()]" unless { capture.req.uri / } + http-after-response del-header content-type + + http-after-response set-var(res.status) status + http-after-response set-header sl1 "sl1: " + + http-after-response set-status 200 + + http-after-response set-header sl2 "sl2: " + + http-after-response set-header sl1 "%[res.fhdr(sl1)] status=<%[var(res.status)]>;" + http-after-response set-header sl2 "%[res.fhdr(sl2)] status=<%[status]>;" + http-after-response set-header hdr "%[res.fhdr(hdr)] hdr1=<%[res.hdr(hdr1)]>; fhdr1=<%[res.fhdr(hdr1)]>;" + http-after-response set-header hdr "%[res.fhdr(hdr)] hdr2=<%[res.hdr(hdr2)]>; fhdr2=<%[res.fhdr(hdr2)]>;" + http-after-response set-header hdr "%[res.fhdr(hdr)] hdr3=<%[res.hdr(hdr3)]>; fhdr3=<%[res.fhdr(hdr3)]>;" + http-after-response set-header hdr "%[res.fhdr(hdr)] hdr4=<%[res.hdr(hdr4)]>; fhdr4=<%[res.fhdr(hdr4)]>;" + + http-after-response set-header sl1-crc "%[res.fhdr(sl1),crc32]" + http-after-response set-header sl2-crc "%[res.fhdr(sl2),crc32]" + http-after-response set-header hdr-crc "%[res.fhdr(hdr),crc32]" + + server s1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_feh1_sock} { + txreq -req GET -url / + rxresp + expect resp.status == 200 + expect resp.http.be-sl1-crc == 487202719 + expect resp.http.be-sl2-crc == 561949791 + expect resp.http.be-hdr-crc == 1719311923 + expect resp.http.fe-sl1-crc == 146151597 + expect resp.http.fe-sl2-crc == 561949791 + expect resp.http.fe-hdr-crc == 3634102538 + expect resp.http.content-type == <undef> + expect resp.bodylen == 14 + expect resp.body == "This is a body" + + txreq -req GET -url /return + rxresp + expect resp.status == 200 + expect resp.http.be-sl1-crc == 487202719 + expect resp.http.be-sl2-crc == 561949791 + expect resp.http.be-hdr-crc == 1719311923 + expect resp.http.fe-sl1-crc == 146151597 + expect resp.http.fe-sl2-crc == 561949791 + expect resp.http.fe-hdr-crc == 3634102538 + expect resp.http.content-type == <undef> + expect resp.bodylen == 14 + expect resp.body == "This is a body" + + txreq -req GET -url /stats + rxresp + expect resp.status == 200 + expect resp.http.be-sl1-crc == 487202719 + expect resp.http.be-sl2-crc == 561949791 + expect resp.http.be-hdr-crc == 1719311923 + expect resp.http.fe-sl1-crc == 146151597 + expect resp.http.fe-sl2-crc == 561949791 + expect resp.http.fe-hdr-crc == 3634102538 + expect resp.http.content-type == <undef> +} -run + +client c2 -connect ${h1_feh1_sock} { + txreq -req GET -url /deny + rxresp + expect resp.status == 403 + expect resp.http.be-sl1 == <undef> + expect resp.http.be-sl2 == <undef> + expect resp.http.be-hdr == <undef> + expect resp.http.sl1 == <undef> + expect resp.http.sl2 == <undef> + expect resp.http.hdr == <undef> +} -run + +client c3 -connect ${h1_feh1_sock} { + txreq -req GET -url /redir + rxresp + expect resp.status == 302 + expect resp.http.be-sl1 == <undef> + expect resp.http.be-sl2 == <undef> + expect resp.http.be-hdr == <undef> + expect resp.http.sl1 == <undef> + expect resp.http.sl2 == <undef> + expect resp.http.hdr == <undef> +} -run + +client c4 -connect ${h1_feh1_sock} { + txreq -req GET -url /auth + rxresp + expect resp.status == 401 + expect resp.http.be-sl1 == <undef> + expect resp.http.be-sl2 == <undef> + expect resp.http.be-hdr == <undef> + expect resp.http.sl1 == <undef> + expect resp.http.sl2 == <undef> + expect resp.http.hdr == <undef> +} -run + +client c5 -connect ${h1_feh1_sock} { + txreq -req GET -url /deny-srv + rxresp + expect resp.status == 200 + expect resp.http.be-sl1 == "" + expect resp.http.be-sl2 == "" + expect resp.http.be-hdr == "" + expect resp.http.fe-sl1-crc == 3104968915 + expect resp.http.fe-sl2-crc == 561949791 + expect resp.http.fe-hdr-crc == 623352154 +} -run diff --git a/reg-tests/http-rules/http_return.vtc b/reg-tests/http-rules/http_return.vtc new file mode 100644 index 0000000..ae96775 --- /dev/null +++ b/reg-tests/http-rules/http_return.vtc @@ -0,0 +1,99 @@ +varnishtest "Test the HTTP return action" +#REQUIRE_VERSION=2.2 + +# This config tests the HTTP return action. + +feature ignore_unknown_macro + +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 + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe1}" + http-request return if { path /def-1 } + http-request return hdr "x-custom-hdr" "%[url]" if { path /def-2 } + http-request return status 403 if { path /def-3 } + http-request return content-type "text/plain" if { path /def-4 } + + http-request return content-type "text/plain" string "hello" hdr "x-custom-hdr" "%[url]" if { path /string } + http-request return content-type "text/plain" lf-string "path is %[url]" hdr "x-custom-hdr" "%[url]" if { path /lf-string } + http-request return content-type "text/plain" file /dev/null hdr "x-custom-hdr" "%[url]" if { path /empty-file } + http-request return content-type "text/plain" file ${testdir}/1k.txt hdr "x-custom-hdr" "%[url]" if { path /file } + http-request return content-type "text/plain" lf-file ${testdir}/lf-file.txt hdr "x-custom-hdr" "%[url]" if { path /lf-file } +} -start + +client c1 -connect ${h1_fe1_sock} { + txreq -req GET -url /def-1 + rxresp + expect resp.status == 200 + expect resp.http.content-length == 0 + expect resp.http.content-type == <undef> + expect resp.http.x-custom-hdr == <undef> + + txreq -req GET -url /def-2 + rxresp + expect resp.status == 200 + expect resp.http.content-length == 0 + expect resp.http.content-type == <undef> + expect resp.http.x-custom-hdr == "/def-2" + + txreq -req GET -url /def-3 + rxresp + expect resp.status == 403 + expect resp.http.content-length == 0 + expect resp.http.content-type == <undef> + + txreq -req GET -url /def-4 + rxresp + expect resp.status == 200 + expect resp.http.content-length == 0 + expect resp.http.content-type == <undef> + + txreq -req GET -url /string + rxresp + expect resp.status == 200 + expect resp.http.content-length == 5 + expect resp.http.content-type == "text/plain" + expect resp.http.x-custom-hdr == "/string" + expect resp.body == "hello" + + txreq -req GET -url /lf-string + rxresp + expect resp.status == 200 + expect resp.http.content-length == 18 + expect resp.http.content-type == "text/plain" + expect resp.http.x-custom-hdr == "/lf-string" + expect resp.body == "path is /lf-string" + + txreq -req GET -url /empty-file + rxresp + expect resp.status == 200 + expect resp.http.content-length == 0 + expect resp.http.content-type == <undef> + expect resp.http.x-custom-hdr == "/empty-file" + + txreq -req GET -url /file + rxresp + expect resp.status == 200 + expect resp.http.content-length == 1024 + expect resp.http.content-type == "text/plain" + expect resp.http.x-custom-hdr == "/file" + + txreq -req GET -url /lf-file + rxresp + expect resp.status == 200 + expect resp.http.content-length == 17 + expect resp.http.content-type == "text/plain" + expect resp.http.x-custom-hdr == "/lf-file" + expect resp.body == "path is /lf-file\n" +} -run diff --git a/reg-tests/http-rules/lf-file.txt b/reg-tests/http-rules/lf-file.txt new file mode 100644 index 0000000..7fda1d4 --- /dev/null +++ b/reg-tests/http-rules/lf-file.txt @@ -0,0 +1 @@ +path is %[url] diff --git a/reg-tests/http-rules/map_redirect-be.map b/reg-tests/http-rules/map_redirect-be.map new file mode 100644 index 0000000..c8822fc --- /dev/null +++ b/reg-tests/http-rules/map_redirect-be.map @@ -0,0 +1,4 @@ +# These entries are used for use_backend rules +test1.example.com test1_be +test1.example.invalid test1_be +test2.example.com test2_be diff --git a/reg-tests/http-rules/map_redirect.map b/reg-tests/http-rules/map_redirect.map new file mode 100644 index 0000000..c4743f6 --- /dev/null +++ b/reg-tests/http-rules/map_redirect.map @@ -0,0 +1,5 @@ +# These entries are used for http-request redirect rules +example.org https://www.example.org +subdomain.example.org https://www.subdomain.example.org + +/path/to/old/file /path/to/new/file diff --git a/reg-tests/http-rules/map_redirect.vtc b/reg-tests/http-rules/map_redirect.vtc new file mode 100644 index 0000000..f55e0d8 --- /dev/null +++ b/reg-tests/http-rules/map_redirect.vtc @@ -0,0 +1,200 @@ +varnishtest "haproxy host header: map / redirect tests" +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev5) && (feature(PCRE) || feature(PCRE2))'" +feature ignore_unknown_macro + + +server s1 { + rxreq + expect req.method == "GET" + expect req.http.host == "test1.example.com" + txresp -body "test1 ok" +} -start + +server s2 { + rxreq + expect req.method == "GET" + expect req.http.host == "test2.example.com" + txresp -body "test2 ok" +} -start + +server s3 { + rxreq + expect req.method == "GET" + expect req.http.host == "test3.example.com" + txresp -body "test3 ok" +} -start + +server s4 { + rxreq + expect req.method == "GET" + expect req.http.host == "test1.example.invalid" + txresp -body "test1 after del map ok" +} -start + +haproxy h1 -conf { + defaults + mode http + log global + option httplog + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe1}" + + # automatically redirect matching paths from maps but skip rule on no-match + http-request redirect code 301 location %[path,map_str(${testdir}/map_redirect.map)] ignore-empty + + # redirect Host: example.org / subdomain.example.org + http-request redirect prefix %[req.hdr(Host),lower,regsub(:\d+$,,),map_str(${testdir}/map_redirect.map)] code 301 if { hdr(Host),lower,regsub(:\d+$,,),map_str(${testdir}/map_redirect.map) -m found } + + # set var and redirect in be1 + http-request set-var(txn.testvar) req.hdr(Testvar),lower,regsub(:\d+$,,),map_str(${testdir}/map_redirect.map) if { hdr(Testvar),lower,regsub(:\d+$,,),map_str(${testdir}/map_redirect.map) -m found } + + # use map to select backend (no default map value) + use_backend %[req.hdr(Host),lower,map_dom(${testdir}/map_redirect-be.map)] if { hdr_dom(Host) -i test1.example.com || hdr_dom(Host) -i test2.example.com } + + # use map to select backend with default value(test3_be) + use_backend %[req.hdr(Host),lower,map_dom(${testdir}/map_redirect-be.map,test3_be)] if { hdr_dom(Host) -m end -i example.com } + + # use map(after del map test1.example.com) default value(test4_be) + use_backend %[req.hdr(Host),lower,map_dom(${testdir}/map_redirect-be.map,test4_be)] if { hdr_dom(Host) -m end -i example.invalid } + + default_backend be1 + + backend be1 + http-request redirect prefix %[var(txn.testvar)] code 301 if { var(txn.testvar) -m found } + http-request deny + + backend test1_be + server s1 ${s1_addr}:${s1_port} + + backend test2_be + server s2 ${s2_addr}:${s2_port} + + backend test3_be + server s3 ${s3_addr}:${s3_port} + + backend test4_be + server s4 ${s4_addr}:${s4_port} +} -start + +# Check map redirects +client c1 -connect ${h1_fe1_sock} { + txreq -hdr "Host: example.org:8443" + rxresp + expect resp.status == 301 + expect resp.http.location ~ "https://www.example.org" + + txreq -url /path/to/old/file + rxresp + expect resp.status == 301 + expect resp.http.location ~ "/path/to/new/file" + + # Closes connection +} -run + +client c2 -connect ${h1_fe1_sock} { + txreq -hdr "Host: subdomain.example.org" + rxresp + expect resp.status == 301 + expect resp.http.location ~ "https://www.subdomain.example.org" + # Closes connection +} -run + +client c3 -connect ${h1_fe1_sock} { + # redirect on Testvar header + txreq -hdr "Testvar: subdomain.example.org" + rxresp + expect resp.status == 301 + expect resp.http.location ~ "https://www.subdomain.example.org" + # Closes connection +} -run + +client c4 -connect ${h1_fe1_sock} { + txreq -hdr "Host: www.subdomain.example.org" + rxresp + expect resp.status == 403 + # Closes connection +} -run + +client c5 -connect ${h1_fe1_sock} { + txreq -hdr "Testvar: www.subdomain.example.org" + rxresp + expect resp.status == 403 + # Closes connection +} -run + +client c6 -connect ${h1_fe1_sock} { + txreq -hdr "Host: :8443example.org" + rxresp + expect resp.status == 403 + # Closes connection +} -run + +# Check map backend selection +client c7 -connect ${h1_fe1_sock} { + txreq -hdr "Host: test1.example.com" + rxresp + expect resp.status == 200 + expect resp.body == "test1 ok" + + txreq -hdr "Host: test2.example.com" + rxresp + expect resp.status == 200 + expect resp.body == "test2 ok" + + txreq -hdr "Host: test3.example.com" + rxresp + expect resp.status == 200 + expect resp.body == "test3 ok" +} -run + +# cli show maps +haproxy h1 -cli { + send "show map ${testdir}/map_redirect.map" + expect ~ "^0x[a-f0-9]+ example\\.org https://www\\.example\\.org\\n0x[a-f0-9]+ subdomain\\.example\\.org https://www\\.subdomain\\.example\\.org\\n0x[a-f0-9]+ /path/to/old/file /path/to/new/file\n$" + + send "show map ${testdir}/map_redirect-be.map" + expect ~ "^0x[a-f0-9]+ test1\\.example\\.com test1_be\\n0x[a-f0-9]+ test1\\.example\\.invalid test1_be\\n0x[a-f0-9]+ test2\\.example\\.com test2_be\\n$" +} + +haproxy h1 -cli { + # clear map ${testdir}/map_redirect.map + send "clear map ${testdir}/map_redirect.map" + expect ~ "^\\n" + + send "show map ${testdir}/map_redirect.map" + expect ~ "^\\n" + + # add map ${testdir}/map_redirect.map + send "add map ${testdir}/map_redirect.map site1_key site1_value" + expect ~ "^\\n" + + # add 2 more entries as payload + send "add map ${testdir}/map_redirect.map <<\nsite2_key site2_value\nsite3_key site3_value\n" + expect ~ "^\\n" + + send "show map ${testdir}/map_redirect.map" + expect ~ "^0x[a-f0-9]+ site1_key site1_value\\n0x[a-f0-9]+ site2_key site2_value\\n0x[a-f0-9]+ site3_key site3_value\\n$" + + # del map ${testdir}/map_redirect-be.map test1.example.{com,invalid} + send "del map ${testdir}/map_redirect-be.map test1.example.com" + expect ~ "^\\n" + + send "del map ${testdir}/map_redirect-be.map test1.example.invalid" + expect ~ "^\\n" + + send "show map ${testdir}/map_redirect-be.map" + expect ~ "^0x[a-f0-9]+ test2\\.example\\.com test2_be\\n$" +} + +# Check map backend after del map +client c6 -connect ${h1_fe1_sock} { + # test1.example.invalid should go to test4_be after del map + txreq -hdr "Host: test1.example.invalid" + rxresp + expect resp.status == 200 + expect resp.body == "test1 after del map ok" +} -run diff --git a/reg-tests/http-rules/map_regm_with_backref.map b/reg-tests/http-rules/map_regm_with_backref.map new file mode 100644 index 0000000..08ffcfb --- /dev/null +++ b/reg-tests/http-rules/map_regm_with_backref.map @@ -0,0 +1 @@ +^(.*)\.(.*)$ \1_AND_\2 diff --git a/reg-tests/http-rules/map_regm_with_backref.vtc b/reg-tests/http-rules/map_regm_with_backref.vtc new file mode 100644 index 0000000..c3b21fb --- /dev/null +++ b/reg-tests/http-rules/map_regm_with_backref.vtc @@ -0,0 +1,73 @@ +#commit 271022150d7961b9aa39dbfd88e0c6a4bc48c3ee +# BUG/MINOR: map: fix map_regm with backref +# +# Due to a cascade of get_trash_chunk calls the sample is +# corrupted when we want to read it. +# +# The fix consist to use a temporary chunk to copy the sample +# value and use it. + +varnishtest "map_regm get_trash_chunk test" +feature ignore_unknown_macro + +#REGTEST_TYPE=bug + +syslog S1 -level notice { + recv info + # not expecting ${h1_pid} with master-worker + expect ~ "[^:\\[ ]\\[[[:digit:]]+\\]: .* fe1 be1/s1 [[:digit:]]+/[[:digit:]]+/[[:digit:]]+/[[:digit:]]+/[[:digit:]]+ 200 [[:digit:]]+ - - ---- .* \"GET / HTTP/(1|2)(\\.1)?\"" +} -start + +server s1 { + rxreq + expect req.method == "GET" + expect req.http.x-mapped-from-header == example_AND_org + expect req.http.x-mapped-from-var == example_AND_org + txresp + + rxreq + expect req.method == "GET" + expect req.http.x-mapped-from-header == www.example_AND_org + expect req.http.x-mapped-from-var == www.example_AND_org + txresp +} -start + +haproxy h1 -conf { + global + log ${S1_addr}:${S1_port} local0 debug err + + defaults + mode http + log global + option httplog + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe1}" + # Remove port from Host header + http-request replace-value Host '(.*):.*' '\1' + # Store host header in variable + http-request set-var(txn.host) req.hdr(Host) + # This works correctly + http-request set-header X-Mapped-From-Header %[req.hdr(Host),map_regm(${testdir}/map_regm_with_backref.map,"unknown")] + # This breaks before commit 271022150d7961b9aa39dbfd88e0c6a4bc48c3ee + http-request set-header X-Mapped-From-Var %[var(txn.host),map_regm(${testdir}/map_regm_with_backref.map,"unknown")] + + default_backend be1 + + backend be1 + server s1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe1_sock} { + txreq -hdr "Host: example.org:8443" + rxresp + expect resp.status == 200 + + txreq -hdr "Host: www.example.org" + rxresp + expect resp.status == 200 +} -run + diff --git a/reg-tests/http-rules/normalize_uri.vtc b/reg-tests/http-rules/normalize_uri.vtc new file mode 100644 index 0000000..82c8107 --- /dev/null +++ b/reg-tests/http-rules/normalize_uri.vtc @@ -0,0 +1,536 @@ +varnishtest "normalize-uri tests" +#REQUIRE_VERSION=2.4 + +# This reg-test tests the http-request normalize-uri action. + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp -hdr "connection: close" +} -repeat 70 -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 + expose-experimental-directives + + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe_path_merge_slashes + bind "fd@${fe_path_merge_slashes}" + + http-request set-var(txn.before) url + http-request normalize-uri path-merge-slashes + http-request set-var(txn.after) url + + http-response add-header before %[var(txn.before)] + http-response add-header after %[var(txn.after)] + + default_backend be + + frontend fe_path_strip_dotdot + bind "fd@${fe_path_strip_dotdot}" + + http-request set-var(txn.before) url + http-request normalize-uri path-strip-dotdot + http-request set-var(txn.after) url + + http-request set-uri %[var(txn.before)] + http-request normalize-uri path-strip-dotdot full + http-request set-var(txn.after_full) url + + http-response add-header before %[var(txn.before)] + http-response add-header after %[var(txn.after)] + http-response add-header after-full %[var(txn.after_full)] + + default_backend be + + frontend fe_sort_query_by_name + bind "fd@${fe_sort_query_by_name}" + + http-request set-var(txn.before) url + http-request normalize-uri query-sort-by-name + http-request set-var(txn.after) url + + http-response add-header before %[var(txn.before)] + http-response add-header after %[var(txn.after)] + + default_backend be + + frontend fe_percent_to_uppercase + bind "fd@${fe_percent_to_uppercase}" + + http-request set-var(txn.before) url + http-request normalize-uri percent-to-uppercase + http-request set-var(txn.after) url + + http-response add-header before %[var(txn.before)] + http-response add-header after %[var(txn.after)] + + default_backend be + + frontend fe_percent_to_uppercase_strict + bind "fd@${fe_percent_to_uppercase_strict}" + + http-request set-var(txn.before) url + http-request normalize-uri percent-to-uppercase strict + http-request set-var(txn.after) url + + http-response add-header before %[var(txn.before)] + http-response add-header after %[var(txn.after)] + + default_backend be + + frontend fe_dot + bind "fd@${fe_dot}" + + http-request set-var(txn.before) url + http-request normalize-uri path-strip-dot + http-request set-var(txn.after) url + + http-response add-header before %[var(txn.before)] + http-response add-header after %[var(txn.after)] + + default_backend be + + frontend fe_percent_decode_unreserved + bind "fd@${fe_percent_decode_unreserved}" + + http-request set-var(txn.before) url + http-request normalize-uri percent-decode-unreserved + http-request set-var(txn.after) url + + http-response add-header before %[var(txn.before)] + http-response add-header after %[var(txn.after)] + + default_backend be + + frontend fe_percent_decode_unreserved_strict + bind "fd@${fe_percent_decode_unreserved_strict}" + + http-request set-var(txn.before) url + http-request normalize-uri percent-decode-unreserved strict + http-request set-var(txn.after) url + + http-response add-header before %[var(txn.before)] + http-response add-header after %[var(txn.after)] + + default_backend be + + frontend fe_fragment_strip + bind "fd@${fe_fragment_strip}" + + http-request set-var(txn.before) url + http-request normalize-uri fragment-strip + http-request set-var(txn.after) url + + http-response add-header before %[var(txn.before)] + http-response add-header after %[var(txn.after)] + + default_backend be + + frontend fe_fragment_encode + bind "fd@${fe_fragment_encode}" + + http-request set-var(txn.before) url + http-request normalize-uri fragment-encode + http-request set-var(txn.after) url + + http-response add-header before %[var(txn.before)] + http-response add-header after %[var(txn.after)] + + default_backend be + + backend be + server s1 ${s1_addr}:${s1_port} + +} -start + +client c1 -connect ${h1_fe_path_merge_slashes_sock} { + txreq -url "/foo/bar" + rxresp + expect resp.http.before == "/foo/bar" + expect resp.http.after == "/foo/bar" + + txreq -url "/foo//bar" + rxresp + expect resp.http.before == "/foo//bar" + expect resp.http.after == "/foo/bar" + + txreq -url "/foo///bar" + rxresp + expect resp.http.before == "/foo///bar" + expect resp.http.after == "/foo/bar" + + txreq -url "///foo///bar" + rxresp + expect resp.http.before == "///foo///bar" + expect resp.http.after == "/foo/bar" + + txreq -url "///foo/bar" + rxresp + expect resp.http.before == "///foo/bar" + expect resp.http.after == "/foo/bar" + + txreq -url "///foo///bar///" + rxresp + expect resp.http.before == "///foo///bar///" + expect resp.http.after == "/foo/bar/" + + txreq -url "///" + rxresp + expect resp.http.before == "///" + expect resp.http.after == "/" + + txreq -url "/foo?bar=///" + rxresp + expect resp.http.before == "/foo?bar=///" + expect resp.http.after == "/foo?bar=///" + + txreq -url "//foo?bar=///" + rxresp + expect resp.http.before == "//foo?bar=///" + expect resp.http.after == "/foo?bar=///" + + txreq -req OPTIONS -url "*" + rxresp + expect resp.http.before == "*" + expect resp.http.after == "*" +} -run + +client c2 -connect ${h1_fe_path_strip_dotdot_sock} { + txreq -url "/foo/bar" + rxresp + expect resp.http.before == "/foo/bar" + expect resp.http.after == "/foo/bar" + expect resp.http.after-full == "/foo/bar" + + txreq -url "/foo/.." + rxresp + expect resp.http.before == "/foo/.." + expect resp.http.after == "/" + expect resp.http.after-full == "/" + + txreq -url "/foo/../" + rxresp + expect resp.http.before == "/foo/../" + expect resp.http.after == "/" + expect resp.http.after-full == "/" + + txreq -url "/foo/bar/../" + rxresp + expect resp.http.before == "/foo/bar/../" + expect resp.http.after == "/foo/" + expect resp.http.after-full == "/foo/" + + txreq -url "/foo/../bar" + rxresp + expect resp.http.before == "/foo/../bar" + expect resp.http.after == "/bar" + expect resp.http.after-full == "/bar" + + txreq -url "/foo/../bar/" + rxresp + expect resp.http.before == "/foo/../bar/" + expect resp.http.after == "/bar/" + expect resp.http.after-full == "/bar/" + + txreq -url "/foo/../../bar/" + rxresp + expect resp.http.before == "/foo/../../bar/" + expect resp.http.after == "/../bar/" + expect resp.http.after-full == "/bar/" + + txreq -url "/foo//../../bar/" + rxresp + expect resp.http.before == "/foo//../../bar/" + expect resp.http.after == "/bar/" + expect resp.http.after-full == "/bar/" + + txreq -url "/foo/?bar=/foo/../" + rxresp + expect resp.http.before == "/foo/?bar=/foo/../" + expect resp.http.after == "/foo/?bar=/foo/../" + expect resp.http.after-full == "/foo/?bar=/foo/../" + + txreq -url "/foo/../?bar=/foo/../" + rxresp + expect resp.http.before == "/foo/../?bar=/foo/../" + expect resp.http.after == "/?bar=/foo/../" + expect resp.http.after-full == "/?bar=/foo/../" + + txreq -req OPTIONS -url "*" + rxresp + expect resp.http.before == "*" + expect resp.http.after == "*" + expect resp.http.after-full == "*" +} -run + +client c3 -connect ${h1_fe_sort_query_by_name_sock} { + txreq -url "/?a=a" + rxresp + expect resp.http.before == "/?a=a" + expect resp.http.after == "/?a=a" + + txreq -url "/?a=a&z=z" + rxresp + expect resp.http.before == "/?a=a&z=z" + expect resp.http.after == "/?a=a&z=z" + + txreq -url "/?z=z&a=a" + rxresp + expect resp.http.before == "/?z=z&a=a" + expect resp.http.after == "/?a=a&z=z" + + txreq -url "/?a=z&z=a" + rxresp + expect resp.http.before == "/?a=z&z=a" + expect resp.http.after == "/?a=z&z=a" + + txreq -url "/?z=a&a=z" + rxresp + expect resp.http.before == "/?z=a&a=z" + expect resp.http.after == "/?a=z&z=a" + + txreq -url "/?c&b&a&z&x&y" + rxresp + expect resp.http.before == "/?c&b&a&z&x&y" + expect resp.http.after == "/?a&b&c&x&y&z" + + txreq -url "/?a=&aa=&aaa=&aaaa=" + rxresp + expect resp.http.before == "/?a=&aa=&aaa=&aaaa=" + expect resp.http.after == "/?a=&aa=&aaa=&aaaa=" + + txreq -url "/?aaaa=&a=&aa=&aaa=" + rxresp + expect resp.http.before == "/?aaaa=&a=&aa=&aaa=" + expect resp.http.after == "/?a=&aa=&aaa=&aaaa=" + + txreq -url "/?a=5&a=3&a=1&a=2&a=4" + rxresp + expect resp.http.before == "/?a=5&a=3&a=1&a=2&a=4" + expect resp.http.after == "/?a=5&a=3&a=1&a=2&a=4" + + txreq -url "/?a=5&b=3&a=1&a=2&b=4" + rxresp + expect resp.http.before == "/?a=5&b=3&a=1&a=2&b=4" + expect resp.http.after == "/?a=5&a=1&a=2&b=3&b=4" + + txreq -url "/" + rxresp + expect resp.http.before == "/" + expect resp.http.after == "/" + + txreq -url "/?" + rxresp + expect resp.http.before == "/?" + expect resp.http.after == "/?" + + txreq -req OPTIONS -url "*" + rxresp + expect resp.http.before == "*" + expect resp.http.after == "*" +} -run + +client c4 -connect ${h1_fe_percent_to_uppercase_sock} { + txreq -url "/a?a=a" + rxresp + expect resp.http.before == "/a?a=a" + expect resp.http.after == "/a?a=a" + + txreq -url "/%aa?a=%aa" + rxresp + expect resp.http.before == "/%aa?a=%aa" + expect resp.http.after == "/%AA?a=%AA" + + txreq -url "/%zz?a=%zz" + rxresp + expect resp.status == 200 + expect resp.http.before == "/%zz?a=%zz" + expect resp.http.after == "/%zz?a=%zz" + + txreq -req OPTIONS -url "*" + rxresp + expect resp.http.before == "*" + expect resp.http.after == "*" +} -run + +client c5 -connect ${h1_fe_percent_to_uppercase_strict_sock} { + txreq -url "/a?a=a" + rxresp + expect resp.http.before == "/a?a=a" + expect resp.http.after == "/a?a=a" + + txreq -url "/%aa?a=%aa" + rxresp + expect resp.http.before == "/%aa?a=%aa" + expect resp.http.after == "/%AA?a=%AA" + + txreq -url "/%zz?a=%zz" + rxresp + expect resp.status == 400 +} -run + +client c6 -connect ${h1_fe_dot_sock} { + txreq -url "/" + rxresp + expect resp.http.before == "/" + expect resp.http.after == "/" + + txreq -url "/a/b" + rxresp + expect resp.http.before == "/a/b" + expect resp.http.after == "/a/b" + + txreq -url "/." + rxresp + expect resp.http.before == "/." + expect resp.http.after == "/" + + txreq -url "/./" + rxresp + expect resp.http.before == "/./" + expect resp.http.after == "/" + + txreq -url "/a/." + rxresp + expect resp.http.before == "/a/." + expect resp.http.after == "/a/" + + txreq -url "/a." + rxresp + expect resp.http.before == "/a." + expect resp.http.after == "/a." + + txreq -url "/.a" + rxresp + expect resp.http.before == "/.a" + expect resp.http.after == "/.a" + + txreq -url "/a/." + rxresp + expect resp.http.before == "/a/." + expect resp.http.after == "/a/" + + txreq -url "/a/./" + rxresp + expect resp.http.before == "/a/./" + expect resp.http.after == "/a/" + + txreq -url "/a/./a" + rxresp + expect resp.http.before == "/a/./a" + expect resp.http.after == "/a/a" + + txreq -url "/a/../" + rxresp + expect resp.http.before == "/a/../" + expect resp.http.after == "/a/../" + + txreq -url "/a/../a" + rxresp + expect resp.http.before == "/a/../a" + expect resp.http.after == "/a/../a" + + txreq -url "/?a=/./" + rxresp + expect resp.http.before == "/?a=/./" + expect resp.http.after == "/?a=/./" +} -run + +client c7 -connect ${h1_fe_percent_decode_unreserved_sock} { + txreq -url "/a?a=a" + rxresp + expect resp.http.before == "/a?a=a" + expect resp.http.after == "/a?a=a" + + txreq -url "/%61?%61=%61" + rxresp + expect resp.http.before == "/%61?%61=%61" + expect resp.http.after == "/a?a=a" + + txreq -url "/%3F?foo=bar" + rxresp + expect resp.http.before == "/%3F?foo=bar" + expect resp.http.after == "/%3F?foo=bar" + + txreq -url "/%%36%36" + rxresp + expect resp.status == 200 + expect resp.http.before == "/%%36%36" + expect resp.http.after == "/%66" + + txreq -req OPTIONS -url "*" + rxresp + expect resp.http.before == "*" + expect resp.http.after == "*" +} -run + +client c8 -connect ${h1_fe_percent_decode_unreserved_strict_sock} { + txreq -url "/a?a=a" + rxresp + expect resp.http.before == "/a?a=a" + expect resp.http.after == "/a?a=a" + + txreq -url "/%61?%61=%61" + rxresp + expect resp.http.before == "/%61?%61=%61" + expect resp.http.after == "/a?a=a" + + txreq -url "/%3F?foo=bar" + rxresp + expect resp.http.before == "/%3F?foo=bar" + expect resp.http.after == "/%3F?foo=bar" + + txreq -url "/%%36%36" + rxresp + expect resp.status == 400 +} -run + +client c9 -connect ${h1_fe_fragment_strip_sock} { + txreq -url "/#foo" + rxresp + expect resp.http.before == "/#foo" + expect resp.http.after == "/" + + txreq -url "/%23foo" + rxresp + expect resp.http.before == "/%23foo" + expect resp.http.after == "/%23foo" + + txreq -req OPTIONS -url "*" + rxresp + expect resp.http.before == "*" + expect resp.http.after == "*" +} -run + +client c10 -connect ${h1_fe_fragment_encode_sock} { + txreq -url "/#foo" + rxresp + expect resp.http.before == "/#foo" + expect resp.http.after == "/%23foo" + + txreq -url "/#foo/#foo" + rxresp + expect resp.http.before == "/#foo/#foo" + expect resp.http.after == "/%23foo/%23foo" + + txreq -url "/%23foo" + rxresp + expect resp.http.before == "/%23foo" + expect resp.http.after == "/%23foo" + + txreq -req OPTIONS -url "*" + rxresp + expect resp.http.before == "*" + expect resp.http.after == "*" +} -run diff --git a/reg-tests/http-rules/path_and_pathq.vtc b/reg-tests/http-rules/path_and_pathq.vtc new file mode 100644 index 0000000..31e85be --- /dev/null +++ b/reg-tests/http-rules/path_and_pathq.vtc @@ -0,0 +1,64 @@ +varnishtest "path vs pathq tests" +#REQUIRE_VERSION=2.2 + +# This config tests various http request rules (set/replace) manipulating the +# path, with or without the query-string. It also test path and pathq sample +# fetches. + +feature ignore_unknown_macro + +server s1 { + rxreq + expect req.url == /regtest/foo/fe/req1/bar?param1=val1¶m2=val2 + expect req.http.x-path == /req1 + expect req.http.x-pathq == /req1?param1=val1¶m2=val2 + expect req.http.x-query == param1=val1¶m2=val2 + expect req.http.x-url == /req1?param1=val1¶m2=val2 + txresp + + rxreq + expect req.url == http://127.0.0.1/regtest/foo/fe/req2/bar?param1=val1¶m2=val2 + expect req.http.x-path == /req2 + expect req.http.x-pathq == /req2?param1=val1¶m2=val2 + expect req.http.x-query == param1=val1¶m2=val2 + expect req.http.x-url == http://127.0.0.1/req2?param1=val1¶m2=val2 + txresp +} -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + + http-request add-header x-path %[path] + http-request add-header x-pathq %[pathq] + http-request add-header x-query %[query] + http-request add-header x-url %[url] + + http-request set-path /fe%[path] + http-request replace-path (.*) /foo\1 + http-request replace-path (.*) \1/bar + http-request set-pathq %[path]?app=regtest&%[query] + http-request replace-pathq /([^?]*)\?app=([^&]*)&?(.*) /\2/\1?\3 + + default_backend be + + backend be + server s1 ${s1_addr}:${s1_port} + +} -start + +client c1 -connect ${h1_fe_sock} { + txreq -req GET -url /req1?param1=val1¶m2=val2 + rxresp + expect resp.status == 200 + + txreq -req GET -url http://127.0.0.1/req2?param1=val1¶m2=val2 + rxresp + expect resp.status == 200 +} -run diff --git a/reg-tests/http-rules/restrict_req_hdr_names.vtc b/reg-tests/http-rules/restrict_req_hdr_names.vtc new file mode 100644 index 0000000..4b26e33 --- /dev/null +++ b/reg-tests/http-rules/restrict_req_hdr_names.vtc @@ -0,0 +1,185 @@ +varnishtest "http-restrict-req-hdr-names option tests" +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.0-dev0)'" + +# This config tests "http-restrict-req-hdr-names" option + +feature ignore_unknown_macro + +server s1 { + rxreq + expect req.http.x-my_hdr == on + txresp +} -start + +server s2 { + rxreq + expect req.http.x-my_hdr == <undef> + txresp +} -start + +server s3 { + rxreq + expect req.http.x-my_hdr == on + txresp +} -start + +server s4 { + rxreq + expect req.http.x-my_hdr == <undef> + txresp +} -start + +server s5 { + rxreq + expect req.http.x-my_hdr == on + txresp +} -start + +server s6 { + rxreq + expect req.http.x_my_hdr_with_lots_of_underscores == <undef> + txresp +} -start + +server s7 { + rxreq + expect req.http.x_my_hdr-1 == <undef> + expect req.http.x-my-hdr-2 == on + txresp +} -start + +server s8 { + rxreq + expect req.http.x-my_hdr-1 == <undef> + expect req.http.x-my_hdr-2 == <undef> + txresp +} -start + +server s9 { + rxreq + expect req.http.x-my-hdr-with-trailing-underscore_ == <undef> + txresp +} -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe1}" + use_backend be-http1 if { path /req1 } + use_backend be-http2 if { path /req2 } + use_backend be-http3 if { path /req3 } + use_backend be-fcgi1 if { path /req4 } + use_backend be-fcgi2 if { path /req5 } + use_backend be-fcgi3 if { path /req6 } + use_backend be-http4 if { path /req7 } + use_backend be-http5 if { path /req8 } + use_backend be-http6 if { path /req9 } + use_backend be-http7 if { path /req10 } + + backend be-http1 + server s1 ${s1_addr}:${s1_port} + + backend be-http2 + option http-restrict-req-hdr-names delete + server s2 ${s2_addr}:${s2_port} + + backend be-http3 + option http-restrict-req-hdr-names reject + + backend be-fcgi1 + option http-restrict-req-hdr-names preserve + server s3 ${s3_addr}:${s3_port} + + backend be-fcgi2 + option http-restrict-req-hdr-names delete + server s4 ${s4_addr}:${s4_port} + + backend be-fcgi3 + option http-restrict-req-hdr-names reject + + backend be-http4 + option http-restrict-req-hdr-names delete + server s6 ${s6_addr}:${s6_port} + + backend be-http5 + option http-restrict-req-hdr-names delete + server s7 ${s7_addr}:${s7_port} + + backend be-http6 + option http-restrict-req-hdr-names delete + server s8 ${s8_addr}:${s8_port} + + backend be-http7 + option http-restrict-req-hdr-names delete + server s9 ${s9_addr}:${s9_port} + + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + option http-restrict-req-hdr-names preserve + + frontend fe2 + bind "fd@${fe2}" + default_backend be-fcgi4 + + backend be-fcgi4 + server s5 ${s5_addr}:${s5_port} + + fcgi-app my-fcgi-app + docroot ${testdir} +} -start + +client c1 -connect ${h1_fe1_sock} { + txreq -req GET -url /req1 -hdr "X-my_hdr: on" + rxresp + expect resp.status == 200 + + txreq -req GET -url /req2 -hdr "X-my_hdr: on" + rxresp + expect resp.status == 200 + + txreq -req GET -url /req3 -hdr "X-my_hdr: on" + rxresp + expect resp.status == 403 + + txreq -req GET -url /req4 -hdr "X-my_hdr: on" + rxresp + expect resp.status == 200 + + txreq -req GET -url /req5 -hdr "X-my_hdr: on" + rxresp + expect resp.status == 200 + + txreq -req GET -url /req6 -hdr "X-my_hdr: on" + rxresp + expect resp.status == 403 + + txreq -req GET -url /req7 -hdr "X_my_hdr_with_lots_of_underscores: on" + rxresp + expect resp.status == 200 + + txreq -req GET -url /req8 -hdr "X_my_hdr-1: on" -hdr "X-my-hdr-2: on" + rxresp + expect resp.status == 200 + + txreq -req GET -url /req9 -hdr "X-my_hdr-1: on" -hdr "X-my_hdr-2: on" + rxresp + expect resp.status == 200 + + txreq -req GET -url /req10 -hdr "X-my-hdr-with-trailing-underscore_: on" + rxresp + expect resp.status == 200 +} -run + +client c2 -connect ${h1_fe2_sock} { + txreq -req GET -url /req1 -hdr "X-my_hdr: on" + rxresp + expect resp.status == 200 +} -run diff --git a/reg-tests/http-rules/strict_rw_mode.vtc b/reg-tests/http-rules/strict_rw_mode.vtc new file mode 100644 index 0000000..14e6901 --- /dev/null +++ b/reg-tests/http-rules/strict_rw_mode.vtc @@ -0,0 +1,164 @@ +varnishtest "Test the strict rewriting mode" +#REQUIRE_VERSION=2.2 + +# This config tests the strict-mode of HTTP rules. + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp \ + -status 200 + expect req.method == "GET" + expect req.url == "/req1" + expect req.http.x-hdr1 == "123456789012345678901234567890123456789012345678901234567890" + + accept + rxreq + txresp \ + -status 200 + expect req.method == "GET" + expect req.url == "/req3" + expect req.http.x-hdr1 == "123456789012345678901234567890123456789012345678901234567890" + expect req.http.x-hdr3 == <undef> +} -start + +server s2 { + rxreq + txresp \ + -status 200 \ + -hdr "x-req: /req1" \ + -bodylen 2000 + expect req.method == "GET" + expect req.url == "/req1" + + accept + rxreq + txresp \ + -status 200 \ + -hdr "x-req: /req2" \ + -bodylen 2000 + expect req.method == "GET" + expect req.url == "/req2" + + accept + rxreq + txresp \ + -status 200 \ + -hdr "x-req: /req3" \ + -bodylen 2000 + expect req.method == "GET" + expect req.url == "/req3" + + accept + rxreq + txresp \ + -status 200 \ + -hdr "x-req: /req4" \ + -bodylen 2000 + expect req.method == "GET" + expect req.url == "/req4" + +} -start + +haproxy h1 -conf { + global + tune.bufsize 2048 + tune.maxrewrite 128 + + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + option http-buffer-request + + frontend fe1 + bind "fd@${fe1}" + http-request set-header x-hdr1 123456789012345678901234567890123456789012345678901234567890 + http-request set-header x-hdr2 123456789012345678901234567890123456789012345678901234567890 if { path /req2 } + http-request strict-mode off if { path /req3 } + http-request set-header x-hdr3 123456789012345678901234567890123456789012345678901234567890 if { path /req3 } + default_backend be1 + + backend be1 + http-request set-header x-hdr3 123456789012345678901234567890123456789012345678901234567890 if { path /req4 } + server s1 ${s1_addr}:${s1_port} + + frontend fe2 + bind "fd@${fe2}" + http-response set-header x-hdr4 123456789012345678901234567890123456789012345678901234567890 if { res.hdr(x-req) /req4 } + default_backend be2 + backend be2 + http-response set-header x-hdr1 123456789012345678901234567890123456789012345678901234567890 + http-response set-header x-hdr2 123456789012345678901234567890123456789012345678901234567890 if { res.hdr(x-req) /req2 } + http-response strict-mode off if { res.hdr(x-req) /req3 } + http-response set-header x-hdr3 123456789012345678901234567890123456789012345678901234567890 if { res.hdr(-req) /req3 } + server s2 ${s2_addr}:${s2_port} + +} -start + +client c1r1 -connect ${h1_fe1_sock} { + txreq \ + -req GET \ + -url /req1 \ + -bodylen 2000 + rxresp + expect resp.status == 200 +} -run +client c1r2 -connect ${h1_fe1_sock} { + txreq \ + -req GET \ + -url /req2 \ + -bodylen 2000 + rxresp + expect resp.status == 500 +} -run +client c1r3 -connect ${h1_fe1_sock} { + txreq \ + -req GET \ + -url /req3 \ + -bodylen 2000 + rxresp + expect resp.status == 200 +} -run +client c1r4 -connect ${h1_fe1_sock} { + txreq \ + -req GET \ + -url /req4 \ + -bodylen 2000 + rxresp + expect resp.status == 500 +} -run + +client c2r1 -connect ${h1_fe2_sock} { + txreq \ + -req GET \ + -url /req1 + rxresp + expect resp.status == 200 + expect resp.http.x-hdr1 == "123456789012345678901234567890123456789012345678901234567890" +} -run +client c2r2 -connect ${h1_fe2_sock} { + txreq \ + -req GET \ + -url /req2 + rxresp + expect resp.status == 500 +} -run +client c2r3 -connect ${h1_fe2_sock} { + txreq \ + -req GET \ + -url /req3 + rxresp + expect resp.status == 200 + expect resp.http.x-hdr1 == "123456789012345678901234567890123456789012345678901234567890" + expect resp.http.x-hdr3 == <undef> +} -run +client c2r4 -connect ${h1_fe2_sock} { + txreq \ + -req GET \ + -url /req4 + rxresp + expect resp.status == 500 +} -run diff --git a/reg-tests/http-set-timeout/set_timeout.vtc b/reg-tests/http-set-timeout/set_timeout.vtc new file mode 100644 index 0000000..ebaa6a3 --- /dev/null +++ b/reg-tests/http-set-timeout/set_timeout.vtc @@ -0,0 +1,82 @@ +varnishtest "http-request set-timeout test" + +feature ignore_unknown_macro + +#REQUIRE_VERSION=2.4 + +server srv_h1 -repeat 3 { + rxreq + txresp +} -start + +syslog Slog1 -level info { + recv + expect ~ "^.*timeout: 5000 5000.*$" +} -start + +syslog Slog2 -level info { + recv + expect ~ "^.*timeout: 5000 5000.*$" +} -start + +syslog Slog3 -level info { + recv + expect ~ "^.*timeout: 5000 3000.*$" +} -start + +haproxy hap -conf { + defaults + timeout connect 5s + timeout client 5s + timeout server 5s + log global + + listen li1 + mode http + bind "fd@${li1}" + log-format "timeout: %[be_server_timeout] %[cur_server_timeout]" + log ${Slog1_addr}:${Slog1_port} len 2048 local0 debug err + server srv_h1 ${srv_h1_addr}:${srv_h1_port} + + listen li2 + mode http + bind "fd@${li2}" + log-format "timeout: %[be_server_timeout] %[cur_server_timeout]" + log ${Slog2_addr}:${Slog2_port} len 2048 local0 debug err + http-request set-timeout server 5s + server srv_h1 ${srv_h1_addr}:${srv_h1_port} + + frontend fe1 + mode http + bind "fd@${fe1}" + log-format "timeout: %[be_server_timeout] %[cur_server_timeout]" + log ${Slog3_addr}:${Slog3_port} len 2048 local0 debug err + default_backend be1 + + backend be1 + mode http + http-request set-timeout server int(3),mul(1000) + server srv_h1 ${srv_h1_addr}:${srv_h1_port} +} -start + +client c1 -connect ${hap_li1_sock} { + txreq + rxresp + expect resp.status == 200 +} -run + +client c2 -connect ${hap_li2_sock} { + txreq + rxresp + expect resp.status == 200 +} -run + +client c3 -connect ${hap_fe1_sock} { + txreq + rxresp + expect resp.status == 200 +} -run + +syslog Slog1 -wait +syslog Slog2 -wait +syslog Slog3 -wait diff --git a/reg-tests/jwt/build_token.py b/reg-tests/jwt/build_token.py new file mode 100755 index 0000000..2f368ab --- /dev/null +++ b/reg-tests/jwt/build_token.py @@ -0,0 +1,22 @@ +#!/usr/bin/python + +# JWT package can be installed via 'pip install pyjwt' command + +import sys +import jwt +import json + +if len(sys.argv) != 4: + print(sys.argv[0],"<alg> <json_to_sign> <priv_key>") + quit() + + +alg=sys.argv[1] +json_to_sign=sys.argv[2] +priv_key_file=sys.argv[3] + +with open(priv_key_file) as file: + priv_key = file.read() + +print(jwt.encode(json.loads(json_to_sign),priv_key,algorithm=alg)) + diff --git a/reg-tests/jwt/es256-public.pem b/reg-tests/jwt/es256-public.pem new file mode 100644 index 0000000..ac69e6d --- /dev/null +++ b/reg-tests/jwt/es256-public.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEjq7vv/FURryqr7ukvkrn1ek5rjCM +hOngjD17uQTZN7fo1QRIV18lPx5O2Ed5ok/j8j/hZaFOB6TNshNmthk3dA== +-----END PUBLIC KEY----- diff --git a/reg-tests/jwt/es384-public.pem b/reg-tests/jwt/es384-public.pem new file mode 100644 index 0000000..b726e12 --- /dev/null +++ b/reg-tests/jwt/es384-public.pem @@ -0,0 +1,5 @@ +-----BEGIN PUBLIC KEY----- +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEm1LU84aybo84c3LWQtaILtzzQsU9sT1b +uda6u6NBJ9FrVEAQkk5tABimCcn60bxSe7s1+oM8xLsu2RuGibQzbTuL75pEs5kx +HPQW4nmOz0zXCjvAvtQTA7vMirb/Oste +-----END PUBLIC KEY----- diff --git a/reg-tests/jwt/es512-public.pem b/reg-tests/jwt/es512-public.pem new file mode 100644 index 0000000..46520ac --- /dev/null +++ b/reg-tests/jwt/es512-public.pem @@ -0,0 +1,6 @@ +-----BEGIN PUBLIC KEY----- +MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAMJ5MagTv8l+AjWZLLJ+xxV9/iNhb +xE52xa8uMCiuBM5VHPcBLEPi1haY17abA6j0F173bK/AN7MBOpT4pAFP07IAEpF7 +QWzw+YH7hrWcT66gzfPysgpzktY+xpMFYhmLH1h9DGiJE+5t5FF5+mCg4GXi1Aez +UzHc9yLw+6meeTWKcv4= +-----END PUBLIC KEY----- diff --git a/reg-tests/jwt/jws_verify.vtc b/reg-tests/jwt/jws_verify.vtc new file mode 100644 index 0000000..d9a6328 --- /dev/null +++ b/reg-tests/jwt/jws_verify.vtc @@ -0,0 +1,379 @@ +#REGTEST_TYPE=devel + +# This reg-test uses the JSON Web Token (JWT) converters to verify a token's signature. +# It uses the http_auth_bearer sample fetch to fetch a token contained in an +# HTTP Authorization header (with the Bearer scheme) which is the common way of +# transmitting a token (see RFC6750). It then uses the jwt_header_query +# converter to get the "alg" field declared in the token's JOSE header and +# gives it to the jwt_verify converter with the appropriate certificate. +# +# All the supported algorithms are tested at least once (HMAC, RSA and ECDSA) +# and the errors codes returned by jwt_verify are tested as well. + +varnishtest "Test the 'set ssl ca-file' feature of the CLI" +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL)'" +feature cmd "command -v socat" +feature ignore_unknown_macro + +server s1 -repeat 22 { + rxreq + txresp +} -start + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + tune.ssl.capture-buffer-size 1 + stats socket "${tmpdir}/h1/stats" level admin + + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen main-fe + bind "fd@${mainfe}" + + use_backend hsXXX_be if { path_beg /hs } + use_backend rsXXX_be if { path_beg /rs } + use_backend esXXX_be if { path_beg /es } + use_backend auth_bearer_be if { path /auth_bearer } + default_backend dflt_be + + + backend hsXXX_be + http-request set-var(txn.bearer) http_auth_bearer + http-request set-var(txn.jwt_alg) var(txn.bearer),jwt_header_query('$.alg') + + http-request deny unless { var(txn.jwt_alg) -m beg "HS" } + + http-response set-header x-jwt-token %[var(txn.bearer)] + http-response set-header x-jwt-alg %[var(txn.jwt_alg)] + + http-response set-header x-jwt-verify-HS256 %[var(txn.bearer),jwt_verify(txn.jwt_alg,"hmac key hs256")] if { var(txn.jwt_alg) -m str "HS256" } + http-response set-header x-jwt-verify-HS384 %[var(txn.bearer),jwt_verify(txn.jwt_alg,"hmac key hs384")] if { var(txn.jwt_alg) -m str "HS384" } + http-response set-header x-jwt-verify-HS512 %[var(txn.bearer),jwt_verify(txn.jwt_alg,"hmac key hs512")] if { var(txn.jwt_alg) -m str "HS512" } + server s1 ${s1_addr}:${s1_port} + + backend rsXXX_be + http-request set-var(txn.bearer) http_auth_bearer + http-request set-var(txn.jwt_alg) var(txn.bearer),jwt_header_query('$.alg') + + http-request deny unless { var(txn.jwt_alg) -m beg "RS" } + + http-response set-header x-jwt-token %[var(txn.bearer)] + http-response set-header x-jwt-alg %[var(txn.jwt_alg)] + + http-response set-header x-jwt-verify-RS256 %[var(txn.bearer),jwt_verify(txn.jwt_alg,"${testdir}/rsa-public.pem")] if { var(txn.jwt_alg) -m str "RS256" } + http-response set-header x-jwt-verify-RS384 %[var(txn.bearer),jwt_verify(txn.jwt_alg,"${testdir}/rsa-public.pem")] if { var(txn.jwt_alg) -m str "RS384" } + http-response set-header x-jwt-verify-RS512 %[var(txn.bearer),jwt_verify(txn.jwt_alg,"${testdir}/rsa-public.pem")] if { var(txn.jwt_alg) -m str "RS512" } + server s1 ${s1_addr}:${s1_port} + + backend esXXX_be + http-request set-var(txn.bearer) http_auth_bearer + http-request set-var(txn.jwt_alg) var(txn.bearer),jwt_header_query('$.alg') + + http-request deny unless { var(txn.jwt_alg) -m beg "ES" } + + http-response set-header x-jwt-token %[var(txn.bearer)] + http-response set-header x-jwt-alg %[var(txn.jwt_alg)] + + http-response set-header x-jwt-verify-ES256 %[var(txn.bearer),jwt_verify(txn.jwt_alg,"${testdir}/es256-public.pem")] if { var(txn.jwt_alg) -m str "ES256" } + http-response set-header x-jwt-verify-ES384 %[var(txn.bearer),jwt_verify(txn.jwt_alg,"${testdir}/es384-public.pem")] if { var(txn.jwt_alg) -m str "ES384" } + http-response set-header x-jwt-verify-ES512 %[var(txn.bearer),jwt_verify(txn.jwt_alg,"${testdir}/es512-public.pem")] if { var(txn.jwt_alg) -m str "ES512" } + server s1 ${s1_addr}:${s1_port} + + + # This backend will only be used to test the http_auth_bearer sample fetch. + # No jwt_verify will then be performed. + backend auth_bearer_be + http-request set-var(txn.bearer) http_auth_bearer("Custom-Authorization") + + http-response set-header x-jwt-token %[var(txn.bearer)] + + server s1 ${s1_addr}:${s1_port} + + # This backend will mostly be used to test error cases (invalid tokens, algorithm and so on) + backend dflt_be + http-request set-var(txn.bearer) http_auth_bearer + http-request set-var(txn.jwt_alg) var(txn.bearer),jwt_header_query('$.alg') + + http-request set-var(txn.jwt_verify) var(txn.bearer),jwt_verify(txn.jwt_alg,"unknown_cert.pem") + + http-response set-header x-jwt-token %[var(txn.bearer)] + http-response set-header x-jwt-alg %[var(txn.jwt_alg)] + http-response set-header x-jwt-verify %[var(txn.jwt_verify)] + + server s1 ${s1_addr}:${s1_port} + +} -start + + +client c1 -connect ${h1_mainfe_sock} { + # Token content : {"alg":"HS256","typ":"JWT"} + # {"sub":"1234567890","name":"John Doe","iat":1516239022} + # HMAC key : 'hmac key hs256' + # OpenSSL cmd : openssl dgst -sha256 -mac HMAC -macopt key:'hmac key hs256' data.txt | base64 | tr -d '=\n' | tr '/+' '_-' + + txreq -url "/hs256" -hdr "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.hhj1mbYgezxFoYwinThsZQbckYHt4jJlRoQ7W8ksrFM" + rxresp + expect resp.status == 200 + expect resp.http.x-jwt-alg == "HS256" + expect resp.http.x-jwt-verify-HS256 == "1" +} -run + +client c2 -connect ${h1_mainfe_sock} { + # Token content : {"alg":"HS384","typ":"JWT"} + # {"sub":"1234567890","name":"John Doe","iat":1516239022} + # HMAC key : 'hmac key hs384' + # OpenSSL cmd : openssl dgst -sha384 -mac HMAC -macopt key:'hmac key hs384' data.txt | base64 | tr -d '=\n' | tr '/+' '_-' + + txreq -url "/hs384" -hdr "Authorization: Bearer eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.3EsbLfl6DDh5nZMkLWg3ssCurFHyOhXP28a4PDS48aPAIoYLzHchtXmNaYI8He-R" + rxresp + expect resp.status == 200 + expect resp.http.x-jwt-alg == "HS384" + expect resp.http.x-jwt-verify-HS384 == "1" +} -run + +client c3 -connect ${h1_mainfe_sock} { + # Token content : {"alg":"HS512","typ":"JWT"} + # {"sub":"1234567890","name":"John Doe","iat":1516239022} + # HMAC key : 'hmac key hs512' + # OpenSSL cmd : openssl dgst -sha512 -mac HMAC -macopt key:'hmac key hs512' data.txt | base64 | tr -d '=\n' | tr '/+' '_-' + + txreq -url "/hs512" -hdr "Authorization: Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.K4Yze5N7jeJrDbJymphaH1YsFlYph5F-U75HzBRKDybrN7WBO494EgNG77mAQj4CVci_xbTD_IsqY2umO0f47A" + rxresp + expect resp.status == 200 + expect resp.http.x-jwt-alg == "HS512" + expect resp.http.x-jwt-verify-HS512 == "1" +} -run + +# The following token is invalid (it has three extra characters at the end of the signature) +client c4 -connect ${h1_mainfe_sock} { + # Token content : {"alg":"HS512","typ":"JWT"} + # {"sub":"1234567890","name":"John Doe","iat":1516239022} + # HMAC key : 'hmac key hs512' + # OpenSSL cmd : openssl dgst -sha512 -mac HMAC -macopt key:'hmac key hs512' data.txt | base64 | tr -d '=\n' | tr '/+' '_-' + + txreq -url "/hs512" -hdr "Authorization: Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.K4Yze5N7jeJrDbJymphaH1YsFlYph5F-U75HzBRKDybrN7WBO494EgNG77mAQj4CVci_xbTD_IsqY2umO0f47AAAA" + rxresp + expect resp.status == 200 + expect resp.http.x-jwt-alg == "HS512" + expect resp.http.x-jwt-verify-HS512 == "-3" +} -run + + +client c5 -connect ${h1_mainfe_sock} { + # Token content : {"alg":"RS256","typ":"JWT"} + # {"sub":"1234567890","name":"John Doe","iat":1516239022} + # OpenSSL cmd : openssl dgst -sha256 -sign rsa-private.pem data.txt | base64 | tr -d '=\n' | tr '/+' '_-' + + txreq -url "/rs256" -hdr "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.hRqFM87JzV_YinYhdERp2E9BLhl6s7I5J37GTXAeT5fixJx-OCjTFvwKssyVo7fWAFcQMdQU7vGEXDOiWbNaMUFGIsMxx0Uflk0BeNwk6pWvNGk8KZGMtiqOv-IuPdAiaSW_xhxLHIk7eOwVefvBfk8j2hgU9yoHN87AYnl8oEnzrkzwWvEt-x-P2zB4s_VwhF0gbL1G4FsP5hxWL1HWmSFLBpvWaL5Lx3OJE7mLRLRf8TpMwEe4ROakzMpiv9Xk1H3mZth6d2a91F5Bm65MIJpJ7P2kEL3tdS62VRx8DM_SlsFuWcsqryO3CDQquMbwzAvfRgLPy8PBLRLT64wM3mZtue5GI2KUlqSYsSwKwK580b4drosLvAS75l_4jJwdwuQEvVd8Gry3DWS2mKJSMefmGfD-cdty1vvszs5sUa96Gf7Ro5DvkgXtVCKYk8KJLI62YgZd5S3M0ucP5NLBc_flUi4A2B_aSkd7NDM0ELddk0y48pcF95tejcvliGIy1GRRwevdqensXXQrFweFSZVvuKo8c9pcCBVfKTSllgL0lFGyI_vz6dUYt69I1gqWBDeGcA2XQUBJqfX3o9nkhZspA7b7QxMESatoATsM_XmfhbwsyY-sTq25XIGC4awaZHViZr1YFVD6BwNZWBCEBvW5zObiD5h5A5AgWoBv14E" + rxresp + expect resp.status == 200 + expect resp.http.x-jwt-alg == "RS256" + expect resp.http.x-jwt-verify-RS256 == "1" +} -run + +client c6 -connect ${h1_mainfe_sock} { + # Token content : {"alg":"RS384","typ":"JWT"} + # {"sub":"1234567890","name":"John Doe","iat":1516239022} + # OpenSSL cmd : openssl dgst -sha384 -sign rsa-private.pem data.txt | base64 | tr -d '=\n' | tr '/+' '_-' + + txreq -url "/rs384" -hdr "Authorization: Bearer eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.GuR-v91EMCVvvTTLiE56O0oDAKeQ5JdLqvHtrgOp2MbUtF7zCDutV0LTmMo4qDNVpvTnD3GZfTTGaVUTvW7kIQ3_1iEVAg61qVWkT9rtHHxifDX70RDBKkvNcMWyQH-dFP_FUvCmhCu7q-AzgBT6PHvs5ZqYyQvlQ1gSWZEPFi184dhvcUQrQC6CySEAdOzIryIHH2oQjN_a9lA9V9M_CH3P-AAwFE7NwUE1H1SGIYM4NHcngEZ3B4lBCHOhhgQMpfagcxQjjXv7VfeSqza6OZDpupwlOl34bb0gnFDGMh4hHSS6iHvvwCeCkclbyvKV0Vq0MaRtJuoKRF-_Oww-nKT_bfNtbF6MeOQLNRlYjGCHerWoBtjv3w2KjoLvQ5iGIFI3cEguyrrKNimpovF4Y5uINH0pWdRF99zOwVUlcJBk3RivIb--Y6s47aNFIVWimUpSn-8MSHTla20TYbcdVaZaMur09Cw500jPrOy6jFqVydSnmU6r13NkmCD5-Bl0mgwGtpZcOQExrnIcPQky12kQJAIrffVblvtkd-8FIBPBy1uBKCgkE-q9_suEvBTdvaoTocBmPcIxfPjZUVXeU3UmnRrXEz17pue0YfrwK9CUR9UoP0F5C7O5eSbAtZNm4Hpkiah0w7qugWG3esMgku3-xx0B2xwg6Ul7bAgEJFg" + rxresp + expect resp.status == 200 + expect resp.http.x-jwt-alg == "RS384" + expect resp.http.x-jwt-verify-RS384 == "1" +} -run + +client c7 -connect ${h1_mainfe_sock} { + # Token content : {"alg":"RS512","typ":"JWT"} + # {"sub":"1234567890","name":"John Doe","iat":1516239022} + # OpenSSL cmd : openssl dgst -sha512 -sign rsa-private.pem data.txt | base64 | tr -d '=\n' | tr '/+' '_-' + + txreq -url "/rs512" -hdr "Authorization: Bearer eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.dgUDvxbWXV-q9lVFDVDt6zffrAjCMkKL7UURz-vvc6utCNMEgt8jSkDWi-mt-jmttkD5mwHqUf3HxWPhfjYNmkTok_XL79F5RXhiF_cu_2oDLDc-RuXdrHaRt9xjUIyZhVJMhaMLdmpcAokQlZxc2W6aj92HKzk3EjyHwfdwfKQNgMooXNzxjE9vCHUbahyLZvtPwiqDtYUSnvN_XOpAMUilxByJStwNqdB7MaOxeAzn76nITh6DqD1bNtxBiLzA7MxYdfsUSmXHMLpkWNAhlrcEIJui9PKm9E0OLFD3M7cCqi6rVvzDxvHqXz3-fcXiSJSRrSmSTu1_ok35TT4WwA9SkHpGe2MJ3uc-8CRlYmjDTcLyXWs_d8i3iNozo6xgiwqIkty4HqScTjhXndRQdmiK-RcUfNLM0Iqm6wYgOifWj728_9GCtdjup-C2uVPdwVwuOjwLbzctZLlFqH3i5IGrCfuOOCAcc_vN3REFqSrDEi4-9qpXuh7yk5pOaiCZYr3-uVhmY5neo55_eV8N3NooDyztwkzRtB_DdbaNrqxk3WEHU79Hseg7c1mkXGm6Djqt3dkkrdpbltzRLrnGKxA4-FzccKOT_P27UYmxQSkyfpAQhfH3jpOE0n9-UYyULbMOY7ZIypXUTquJnrZM3rD_NypU7Jg8uBBGqcziZFc" + rxresp + expect resp.status == 200 + expect resp.http.x-jwt-alg == "RS512" + expect resp.http.x-jwt-verify-RS512 == "1" +} -run + +# The following token is invalid (the signature used SHA384 instead of SHA512) +client c8 -connect ${h1_mainfe_sock} { + # Token content : {"alg":"RS512","typ":"JWT"} + # {"sub":"1234567890","name":"John Doe","iat":1516239022} + # OpenSSL cmd : openssl dgst -sha512 -sign rsa-private.pem data.txt | base64 | tr -d '=\n' | tr '/+' '_-' + + txreq -url "/rs512" -hdr "Authorization: Bearer eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.GuR-v91EMCVvvTTLiE56O0oDAKeQ5JdLqvHtrgOp2MbUtF7zCDutV0LTmMo4qDNVpvTnD3GZfTTGaVUTvW7kIQ3_1iEVAg61qVWkT9rtHHxifDX70RDBKkvNcMWyQH-dFP_FUvCmhCu7q-AzgBT6PHvs5ZqYyQvlQ1gSWZEPFi184dhvcUQrQC6CySEAdOzIryIHH2oQjN_a9lA9V9M_CH3P-AAwFE7NwUE1H1SGIYM4NHcngEZ3B4lBCHOhhgQMpfagcxQjjXv7VfeSqza6OZDpupwlOl34bb0gnFDGMh4hHSS6iHvvwCeCkclbyvKV0Vq0MaRtJuoKRF-_Oww-nKT_bfNtbF6MeOQLNRlYjGCHerWoBtjv3w2KjoLvQ5iGIFI3cEguyrrKNimpovF4Y5uINH0pWdRF99zOwVUlcJBk3RivIb--Y6s47aNFIVWimUpSn-8MSHTla20TYbcdVaZaMur09Cw500jPrOy6jFqVydSnmU6r13NkmCD5-Bl0mgwGtpZcOQExrnIcPQky12kQJAIrffVblvtkd-8FIBPBy1uBKCgkE-q9_suEvBTdvaoTocBmPcIxfPjZUVXeU3UmnRrXEz17pue0YfrwK9CUR9UoP0F5C7O5eSbAtZNm4Hpkiah0w7qugWG3esMgku3-xx0B2xwg6Ul7bAgEJFg" + rxresp + expect resp.status == 200 + expect resp.http.x-jwt-alg == "RS512" + expect resp.http.x-jwt-verify-RS512 == "0" +} -run + + + +client c9 -connect ${h1_mainfe_sock} { + # Token content : {"alg":"ES256","typ":"JWT"} + # {"sub":"1234567890","name":"John Doe","iat":1516239022} + # Key gen process : openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out es256-private.pem; openssl ec -in es256-private.pem -pubout -out es256-public.pem + # Token creation : ./build_token.py ES256 '{"sub":"1234567890","name":"John Doe","iat":1516239022}' es256-private.pem + + txreq -url "/es256" -hdr "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.pNI_c5mHE3mLV0YDpstlP4l3t5XARLl6OmcKLuvF5r60m-C63mbgfKWdPjmJPMTCmX_y50YW_v2SKw0ju0tJHw" + rxresp + expect resp.status == 200 + expect resp.http.x-jwt-alg == "ES256" + expect resp.http.x-jwt-verify-ES256 == "1" +} -run + +client c10 -connect ${h1_mainfe_sock} { + # Token content : {"alg":"ES384","typ":"JWT"} + # {"sub":"1234567890","name":"John Doe","iat":1516239022} + # Key gen process : openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-384 -out es384-private.pem; openssl ec -in es384-private.pem -pubout -out es384-public.pem + # Token creation : ./build_token.py ES384 '{"sub":"1234567890","name":"John Doe","iat":1516239022}' es384-private.pem + + txreq -url "/es384" -hdr "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzM4NCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.cs59CQiCI_Pl8J-PKQ2y73L5IJascZXkf7MfRXycO1HkT9pqDW2bFr1bh7pFyPA85GaML4BPYVH_zDhcmjSMn_EIvUV8cPDuuUu69Au7n9LYGVkVJ-k7qN4DAR5eLCiU" + rxresp + expect resp.status == 200 + expect resp.http.x-jwt-alg == "ES384" + expect resp.http.x-jwt-verify-ES384 == "1" +} -run + +client c11 -connect ${h1_mainfe_sock} { + # Token content : {"alg":"ES512","typ":"JWT"} + # {"sub":"1234567890","name":"John Doe","iat":1516239022} + # Key gen process : openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-521 -out es512-private.pem; openssl ec -in es512-private.pem -pubout -out es512-public.pem + # Token creation : ./build_token.py ES512 '{"sub":"1234567890","name":"John Doe","iat":1516239022}' es512-private.pem + + txreq -url "/es512" -hdr "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzUxMiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.AJcyt0OYf2wg7SggJJVKYysLUkBQA0f0Zc0EbKgud2fQLeT65n42A9l9hhGje79VLWhEyisQmDpFXTpfFXeD_NiaAXyNnX5b8TbZALqxbjx8iIpbcObgUh_g5Gi81bKmRmfXUHW7L5iAwoNjYbUpXGipCpCD0N6-8zCrjcFD2UX01f0Y" + rxresp + expect resp.status == 200 + expect resp.http.x-jwt-alg == "ES512" + expect resp.http.x-jwt-verify-ES512 == "1" +} -run + +# The following token is invalid (too short) +client c12 -connect ${h1_mainfe_sock} { + # Token content : {"alg":"ES512","typ":"JWT"} + # {"sub":"1234567890","name":"John Doe","iat":1516239022} + # OpenSSL cmd : openssl dgst -sha512 -sign es512-private.pem data.txt | base64 | tr -d '=\n' | tr '/+' '_-' + + txreq -url "/es512" -hdr "Authorization: Bearer eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.MIGHAkEEPEgIrFKIDofBpFKX_mtya55QboGr09P6--v8uO85DwQWR0iKgMNSzYkL3K1lwyExG0Vtwfnife0lNe7Fn5TigAJCAY95NShiTn3tvleXVGCkkD0-HcribnMhd34QPGRc4rlwTkUg9umIUhxnEhPR--OohlmhJyIYGHuH8Ksm5f" + rxresp + expect resp.status == 200 + expect resp.http.x-jwt-alg == "ES512" + # Invalid token + expect resp.http.x-jwt-verify-ES512 == "-3" +} -run + + +# Unmanaged algorithm +client c13 -connect ${h1_mainfe_sock} { + # Token content : {"alg":"PS512","typ":"JWT"} + # {"sub":"1234567890","name":"John Doe","iat":1516239022} + txreq -url "/errors" -hdr "Authorization: Bearer eyJhbGciOiJQUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.MIGHAkEEPEgIrFKIDofBpFKX_mtya55QboGr09P6--v8uO85DwQWR0iKgMNSzYkL3K1lwyExG0Vtwfnife0lNe7Fn5TigAJCAY95NShiTn3tvleXVGCkkD0-HcribnMhd34QPGRc4rlwTkUg9umIUhxnEhPR--OohlmhJyIYGHuH8Ksm5f" + rxresp + expect resp.status == 200 + expect resp.http.x-jwt-alg == "PS512" + # Unmanaged algorithm + expect resp.http.x-jwt-verify == "-2" +} -run + +# Unknown algorithm +client c14 -connect ${h1_mainfe_sock} { + # Token content : {"alg":"UNKNOWN_ALG","typ":"JWT"} + # {"sub":"1234567890","name":"John Doe","iat":1516239022} + txreq -url "/errors" -hdr "Authorization: Bearer eyJhbGciOiJVTktOT1dOX0FMRyIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.MIGHAkEEPEgIrFKIDofBpFKX_mtya55QboGr09P6--v8uO85DwQWR0iKgMNSzYkL3K1lwyExG0Vtwfnife0lNe7Fn5TigAJCAY95NShiTn3tvleXVGCkkD0-HcribnMhd34QPGRc4rlwTkUg9umIUhxnEhPR--OohlmhJyIYGHuH8Ksm5f" + rxresp + expect resp.status == 200 + expect resp.http.x-jwt-alg == "UNKNOWN_ALG" + # Unmanaged algorithm + expect resp.http.x-jwt-verify == "-1" +} -run + +# Invalid token (not enough fields) +client c15 -connect ${h1_mainfe_sock} { + # Token content : {"alg":"ES512","typ":"JWT"} + # {"sub":"1234567890","name":"John Doe","iat":1516239022} + txreq -url "/errors" -hdr "Authorization: Bearer eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ" + rxresp + expect resp.status == 200 + expect resp.http.x-jwt-alg == "ES512" + # Invalid token + expect resp.http.x-jwt-verify == "-3" +} -run + +# Invalid token (too many fields) +client c16 -connect ${h1_mainfe_sock} { + # Token content : {"alg":"ES512","typ":"JWT"} + # {"sub":"1234567890","name":"John Doe","iat":1516239022} + txreq -url "/errors" -hdr "Authorization: Bearer eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.MIGHAkEEPEgIrFKIDofBpFKX_mtya55QboGr09P6--v8uO85DwQWR0iKgMNSzYkL3K1lwyExG0Vtwfnife0lNe7Fn5TigAJCAY95NShiTn3tvleXVGCkkD0-HcribnMhd34QPGRc4rlwTkUg9umIUhxnEhPR--OohlmhJyIYGHuH8Ksm5f.unexpectedextrafield" + rxresp + expect resp.status == 200 + expect resp.http.x-jwt-alg == "ES512" + # Invalid token + expect resp.http.x-jwt-verify == "-3" +} -run + +# Invalid token (empty signature) +client c17 -connect ${h1_mainfe_sock} { + # Token content : {"alg":"ES512","typ":"JWT"} + # {"sub":"1234567890","name":"John Doe","iat":1516239022} + txreq -url "/errors" -hdr "Authorization: Bearer eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ." + rxresp + expect resp.status == 200 + expect resp.http.x-jwt-alg == "ES512" + # Invalid token + expect resp.http.x-jwt-verify == "-3" +} -run + +# Unknown certificate +client c18 -connect ${h1_mainfe_sock} { + # Token content : {"alg":"ES512","typ":"JWT"} + # {"sub":"1234567890","name":"John Doe","iat":1516239022} + # Key gen process : openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-521 -out es512-private.pem; openssl ec -in es512-private.pem -pubout -out es512-public.pem + # OpenSSL cmd : openssl dgst -sha512 -sign es512-private.pem data.txt | base64 | tr -d '=\n' | tr '/+' '_-' + + txreq -url "/errors" -hdr "Authorization: Bearer eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.MIGHAkEEPEgIrFKIDofBpFKX_mtya55QboGr09P6--v8uO85DwQWR0iKgMNSzYkL3K1lwyExG0Vtwfnife0lNe7Fn5TigAJCAY95NShiTn3tvleXVGCkkD0-HcribnMhd34QPGRc4rlwTkUg9umIUhxnEhPR--OohlmhJyIYGHuH8Ksm5fSIWfRa" + rxresp + expect resp.status == 200 + expect resp.http.x-jwt-alg == "ES512" + # Unknown certificate + expect resp.http.x-jwt-verify == "-5" +} -run + + +# Test the http_auth_bearer special cases (other header than the default "Authorization" one) +client c19 -connect ${h1_mainfe_sock} { + txreq -url "/auth_bearer" -hdr "Custom-Authorization: Bearer random_value" + rxresp + expect resp.status == 200 + expect resp.http.x-jwt-token == "random_value" +} -run + +# Test the http_auth_bearer special cases (multiple spaces after the scheme) +client c20 -connect ${h1_mainfe_sock} { + txreq -url "/auth_bearer" -hdr "Custom-Authorization: Bearer random_value" + rxresp + expect resp.status == 200 + expect resp.http.x-jwt-token == "random_value" +} -run + +# Test the http_auth_bearer special cases (no value after the scheme) +client c21 -connect ${h1_mainfe_sock} { + txreq -url "/auth_bearer" -hdr "Custom-Authorization: Bearer " + rxresp + expect resp.status == 200 + expect resp.http.x-jwt-token == "" +} -run + +# Test the http_auth_bearer special cases (no value after the scheme) +client c22 -connect ${h1_mainfe_sock} { + txreq -url "/errors" -hdr "Authorization: Bearer " + rxresp + expect resp.status == 200 + expect resp.http.x-jwt-token == "" +} -run diff --git a/reg-tests/jwt/rsa-public.pem b/reg-tests/jwt/rsa-public.pem new file mode 100644 index 0000000..a87a89d --- /dev/null +++ b/reg-tests/jwt/rsa-public.pem @@ -0,0 +1,14 @@ +-----BEGIN PUBLIC KEY----- +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxCPdKRUDpwNqrka4OYaI +9bweoN/YoMYR8sddqK39S0pmzVIWZpZ51wXJU7oT4umSGAP0VpexxKNZdKnq6b9S +caIfLCazl8EaU3Wg16l5ZD/OmHggaD5iHtI3lV2JhxTFlIdLI6sGoJxaDne0oelv +tsE2dbBZBPT0OPKWyXgL2qQHCtYnqZI7d9czA61rg1PfiUqV6zh9MC7NW5mKPVS9 +5/MCIILyP4smljh5cUGkzhZaBy/mfKobTRe5xTP+DJ78wZhTAapOY/GmyQ4rFWZF +ISH2tVQ7Ic32lbxeYXycTcPxEUcijNklnFHfpZ3Hhbz9hBuCWTaujcdYVxkRfMoc +nz9InY8FCic3vgcOPrpqhZMxjeuVwUV9cjJhsWTjZeIne5P4l6DHmDIdoVJVatKR ++O4AL2q+VZ+d5euSmUe6bwrz1ufczIcRYAo1mnYD+USwjT5rGWSjG8brtfxtrzJz +QP4oqMgLH2QBEgVDKlvsHiEC2K16tTf1pSEAh9Lyo2t8Tbc1BbuuJPafixNGFEQI +J7sAwYoWNkncGOfwrPUpU13KtAGoW8hMBlLSuGb70FLbei/Qiz/YsWi86ybetN4W +MpF096lcgqa/JH8IeYvGa/MQYoavloGv05OhaGrvGRy0GV6I9elnLEaSdBROnA4k +yPaHW8jKmj04T8EBFmx5Lu0CAwEAAQ== +-----END PUBLIC KEY----- diff --git a/reg-tests/log/last_rule.vtc b/reg-tests/log/last_rule.vtc new file mode 100644 index 0000000..e695166 --- /dev/null +++ b/reg-tests/log/last_rule.vtc @@ -0,0 +1,165 @@ +varnishtest "Verify logging of last final rule" + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.6-dev0)'" +feature ignore_unknown_macro + +server s1 { + rxreq + txresp +} -repeat 15 -start + +syslog Slg_1 -level info { + recv + # /trqacc1 + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* lr=.*/h1/cfg:30" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* lr=.*/h1/cfg:31" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* lr=.*/h1/cfg:32" + recv + # /trsacc1 + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* lr=.*/h1/cfg:36" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* lr=.*/h1/cfg:37" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* lr=.*/h1/cfg:38" + recv + # /hrqvar + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* lr=.*-:-" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* lr=.*/h1/cfg:41" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* lr=.*/h1/cfg:42" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* lr=.*/h1/cfg:43" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* lr=.*/h1/cfg:44" + recv + # /hrsacc1 + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* lr=.*/h1/cfg:46" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* lr=.*/h1/cfg:47" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* lr=.*/h1/cfg:48" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* lr=.*/h1/cfg:49" +} -start + +haproxy h1 -conf { + global + nbthread 1 + + defaults + mode http + option httplog + option http-server-close + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe_1}" + log ${Slg_1_addr}:${Slg_1_port} local0 + log-format "ci:%cp [%tr] lr=%[last_rule_file]:%[last_rule_line]" + default_backend be + + backend be + # handle these URLs: + # /trqacc1, /trqrej1, /trqrej2, /trsacc1, /trsrej1, /trsrej2 + # /hrqvar, /hrqacc1, /hrqred1, /hrqrej1, /hrqrej2, + # /hrsacc1, /hrsred1, /hrsrej1, /hrsrej2 + + tcp-response inspect-delay 10s + tcp-request content set-var(txn.path) path # must have no effect + tcp-request content accept if { var(txn.path) -m beg /trqacc1 /hrqrej1 } + tcp-request content reject if { var(txn.path) -m beg /trqrej1 } + tcp-request content reject if { var(txn.path) -m beg /trqrej2 } + + tcp-response content reject unless WAIT_END + tcp-response content set-var(txn.foo) var(txn.path) # must have no effect + tcp-response content accept if { var(txn.path) -m beg /trsacc1 /hrsrej1 } + tcp-response content reject if { var(txn.path) -m beg /trsrej1 } + tcp-response content reject if { var(txn.path) -m beg /trsrej2 } + + http-request set-var(txn.bar) var(txn.path) if { path_beg /hrqvar } # must have no effect + http-request allow if { var(txn.path) -m beg /hrqacc1 /hrsrej2 } + http-request redirect location / if { var(txn.path) -m beg /hrqred1 } + http-request deny if { var(txn.path) -m beg /hrqrej1 } # accepted by tcp-rq above + http-request deny if { var(txn.path) -m beg /hrqrej2 } + + http-response allow if { var(txn.path) -m beg /hrsacc1 } + http-response redirect location / if { var(txn.path) -m beg /hrsred1 } + http-response deny if { var(txn.path) -m beg /hrsrej1 } # accepted by tcp-rs above + http-response deny if { var(txn.path) -m beg /hrsrej2 } # accepted by http-rq above + http-response deny if { var(txn.path) -m beg /hrsrej3 } + + server app1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe_1_sock} { + txreq -url /trqacc1 + rxresp + + txreq -url /trqrej1 + expect_close +} -run + +# The following client are started in background and synchronized +client c2 -connect ${h1_fe_1_sock} { + txreq -url /trqrej2 + expect_close +} -run + +client c3 -connect ${h1_fe_1_sock} { + txreq -url /trsacc1 + rxresp + expect resp.status == 200 + + txreq -url /trsrej1 + expect_close +} -run + +client c4 -connect ${h1_fe_1_sock} { + txreq -url /trsrej2 + expect_close +} -run + +client c5 -connect ${h1_fe_1_sock} { + txreq -url /hrqvar + rxresp + expect resp.status == 200 + + txreq -url /hrqacc1 + rxresp + expect resp.status == 200 + + txreq -url /hrqred1 + rxresp + expect resp.status == 302 + + txreq -url /hrqrej1 + rxresp + expect resp.status == 403 + + txreq -url /hrqrej2 + rxresp + expect resp.status == 403 + + txreq -url /hrsacc1 + rxresp + expect resp.status == 200 + + txreq -url /hrsred1 + rxresp + expect resp.status == 302 + + txreq -url /hrsrej1 + rxresp + expect resp.status == 502 + + txreq -url /hrsrej2 + rxresp + expect resp.status == 502 +} -run + +syslog Slg_1 -wait diff --git a/reg-tests/log/load_balancing.vtc b/reg-tests/log/load_balancing.vtc new file mode 100644 index 0000000..22aacae --- /dev/null +++ b/reg-tests/log/load_balancing.vtc @@ -0,0 +1,161 @@ +varnishtest "Basic log load-balancing test" +feature ignore_unknown_macro + +#REQUIRE_VERSION=2.0 + +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 + +server s1 { + rxreq + txresp +} -repeat 500 -start + +syslog Slg_1 -level info { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* \"GET /client_c1 HTTP/1.1\"" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* \"GET /client_c2 HTTP/1.1\"" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* \"GET /client_c3 HTTP/1.1\"" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* \"GET /client_c4 HTTP/1.1\"" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* \"GET /client_c5 HTTP/1.1\"" +} -repeat 50 -start + +# Here are the syslog messages received by Slg_2: +syslog Slg_2 -level info { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* \"GET /client_c6 HTTP/1.1\"" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* \"GET /client_c8 HTTP/1.1\"" +} -repeat 50 -start + +haproxy h1 -conf { + global + nbthread 1 + + defaults + mode http + option httplog + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe_1}" + log ${Slg_1_addr}:${Slg_1_port} local0 + default_backend be + + frontend fe2 + bind "fd@${fe_2}" + log ${Slg_2_addr}:${Slg_2_port} sample 1,3:5 local0 + default_backend be + + backend be + server app1 ${s1_addr}:${s1_port} +} -start + +# The following client are started in background and synchronized +client c1 -connect ${h1_fe_1_sock} { + txreq -url "/client_c1" + rxresp + expect resp.status == 200 + barrier b1 sync + barrier b5 sync +} -repeat 50 -start + +client c2 -connect ${h1_fe_1_sock} { + barrier b1 sync + txreq -url "/client_c2" + rxresp + expect resp.status == 200 + barrier b2 sync +} -repeat 50 -start + +client c3 -connect ${h1_fe_1_sock} { + barrier b2 sync + txreq -url "/client_c3" + rxresp + expect resp.status == 200 + barrier b3 sync +} -repeat 50 -start + +client c4 -connect ${h1_fe_1_sock} { + barrier b3 sync + txreq -url "/client_c4" + rxresp + expect resp.status == 200 + barrier b4 sync +} -repeat 50 -start + +client c5 -connect ${h1_fe_1_sock} { + barrier b4 sync + txreq -url "/client_c5" + rxresp + expect resp.status == 200 + barrier b5 sync +} -repeat 50 -start + +syslog Slg_1 -wait + +client c1 -wait +client c2 -wait +client c3 -wait +client c4 -wait +client c5 -wait + +# Same test as before but with fe2 frontend. +# The following client are started in background and synchronized +client c6 -connect ${h1_fe_2_sock} { + txreq -url "/client_c6" + rxresp + expect resp.status == 200 + barrier b1 sync + barrier b5 sync +} -repeat 50 -start + +client c7 -connect ${h1_fe_2_sock} { + barrier b1 sync + txreq -url "/client_c7" + rxresp + expect resp.status == 200 + barrier b2 sync +} -repeat 50 -start + +client c8 -connect ${h1_fe_2_sock} { + barrier b2 sync + txreq -url "/client_c8" + rxresp + expect resp.status == 200 + barrier b3 sync +} -repeat 50 -start + +client c9 -connect ${h1_fe_2_sock} { + barrier b3 sync + txreq -url "/client_c9" + rxresp + expect resp.status == 200 + barrier b4 sync +} -repeat 50 -start + +client c10 -connect ${h1_fe_2_sock} { + barrier b4 sync + txreq -url "/client_c10" + rxresp + expect resp.status == 200 + barrier b5 sync +} -repeat 50 -start + +syslog Slg_2 -wait + +client c6 -wait +client c7 -wait +client c8 -wait +client c9 -wait +client c10 -wait + diff --git a/reg-tests/log/log_forward.vtc b/reg-tests/log/log_forward.vtc new file mode 100644 index 0000000..3977f4c --- /dev/null +++ b/reg-tests/log/log_forward.vtc @@ -0,0 +1,57 @@ +varnishtest "Test the TCP load-forward" +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.3-dev1)'" +feature ignore_unknown_macro + +server s1 { + rxreq + txresp +} -repeat 500 -start + +syslog Slg1 -level info { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* \"GET /client_c1 HTTP/1.1\"" +} -repeat 50 -start + +haproxy h1 -conf { + defaults + mode http + option httplog + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe_1}" + log 127.0.0.1:1514 local0 +# log ${Slg1_addr}:${Slg1_port} local0 + default_backend be + + backend be + server app1 ${s1_addr}:${s1_port} + + ring myring + description "My local buffer" + format rfc5424 + maxlen 1200 + size 32764 + timeout connect 5s + timeout server 10s + # syslog tcp server + server mysyslogsrv 127.0.0.1:2514 + + log-forward syslog2tcp + dgram-bind 127.0.0.1:1514 + log ring@myring local0 # To TCP log + + log-forward syslog2local + bind 127.0.0.1:2514 + log ${Slg1_addr}:${Slg1_port} local0 # To VTest syslog +} -start + +client c1 -connect ${h1_fe_1_sock} { + txreq -url "/client_c1" + rxresp + expect resp.status == 200 +} -repeat 50 -start + +syslog Slg1 -wait diff --git a/reg-tests/log/log_uri.vtc b/reg-tests/log/log_uri.vtc new file mode 100644 index 0000000..6993b7c --- /dev/null +++ b/reg-tests/log/log_uri.vtc @@ -0,0 +1,61 @@ +varnishtest "Verify logging of relative/absolute URI path" +feature ignore_unknown_macro + +#REQUIRE_VERSION=2.4 + +server s1 { + rxreq + txresp +} -repeat 4 -start + +syslog Slg_1 -level info { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* hpo=/r/1 hp=/r/1 hu=/r/1 hq=" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* hpo=/r/2 hp=/r/2 hu=/r/2\\?q=2 hq=\\?q=2" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* hpo=/r/3 hp=http://localhost/r/3 hu=http://localhost/r/3 hq=" + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* hpo=/r/4 hp=http://localhost/r/4 hu=http://localhost/r/4\\?q=4 hq=\\?q=4" +} -start + +haproxy h1 -conf { + global + nbthread 1 + + defaults + mode http + option httplog + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe_1}" + log ${Slg_1_addr}:${Slg_1_port} local0 + log-format "ci:%cp [%tr] hpo=%HPO hp=%HP hu=%HU hq=%HQ" + default_backend be + + backend be + server app1 ${s1_addr}:${s1_port} +} -start + +# The following client are started in background and synchronized +client c1 -connect ${h1_fe_1_sock} { + txreq -url "/r/1" + rxresp + expect resp.status == 200 + txreq -url "/r/2?q=2" + rxresp + expect resp.status == 200 + txreq -url "http://localhost/r/3" -hdr "host: localhost" + rxresp + expect resp.status == 200 + txreq -url "http://localhost/r/4?q=4" -hdr "host: localhost" + rxresp + expect resp.status == 200 +} -start + +syslog Slg_1 -wait + +client c1 -wait diff --git a/reg-tests/log/wrong_ip_port_logging.vtc b/reg-tests/log/wrong_ip_port_logging.vtc new file mode 100644 index 0000000..af8ca84 --- /dev/null +++ b/reg-tests/log/wrong_ip_port_logging.vtc @@ -0,0 +1,62 @@ +# commit d02286d +# BUG/MINOR: log: pin the front connection when front ip/ports are logged +# +# Mathias Weiersmueller reported an interesting issue with logs which Lukas +# diagnosed as dating back from commit 9b061e332 (1.5-dev9). When front +# connection information (ip, port) are logged in TCP mode and the log is +# emitted at the end of the connection (eg: because %B or any log tag +# requiring LW_BYTES is set), the log is emitted after the connection is +# closed, so the address and ports cannot be retrieved anymore. +# +# It could be argued that we'd make a special case of these to immediately +# retrieve the source and destination addresses from the connection, but it +# seems cleaner to simply pin the front connection, marking it "tracked" by +# adding the LW_XPRT flag to mention that we'll need some of these elements +# at the last moment. Only LW_FRTIP and LW_CLIP are affected. Note that after +# this change, LW_FRTIP could simply be removed as it's not used anywhere. +# +# Note that the problem doesn't happen when using %[src] or %[dst] since +# all sample expressions set LW_XPRT. + +#REGTEST_TYPE=bug + +varnishtest "Wrong ip/port logging" +feature ignore_unknown_macro + +server s1 { + rxreq + delay 0.02 +} -start + +syslog Slg_1 -level notice { + recv info + expect ~ \"dip\":\"${h1_fe_1_addr}\",\"dport\":\"${h1_fe_1_port}.*\"ts\":\"[cC]D\",\" +} -start + +haproxy h1 -conf { + global + log ${Slg_1_addr}:${Slg_1_port} local0 + +defaults + log global + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client 1 + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + +frontend fe1 + bind "fd@${fe_1}" + mode tcp + log-format {\"dip\":\"%fi\",\"dport\":\"%fp\",\"c_ip\":\"%ci\",\"c_port\":\"%cp\",\"fe_name\":\"%ft\",\"be_name\":\"%b\",\"s_name\":\"%s\",\"ts\":\"%ts\",\"bytes_read\":\"%B\"} + default_backend be_app + +backend be_app + server app1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe_1_sock} { + txreq -url "/" + expect_close +} -run + +syslog Slg_1 -wait + diff --git a/reg-tests/lua/bad_http_clt_req_duration.lua b/reg-tests/lua/bad_http_clt_req_duration.lua new file mode 100644 index 0000000..2c2ab1d --- /dev/null +++ b/reg-tests/lua/bad_http_clt_req_duration.lua @@ -0,0 +1,8 @@ +core.register_service("foo.http", "http", function(applet) + core.msleep(10) + applet:start_response() +end) + +core.register_service("foo.tcp", "tcp", function(applet) + applet:send("HTTP/1.1 200 OK\r\nTransfer-encoding: chunked\r\n\r\n0\r\n\r\n") +end) diff --git a/reg-tests/lua/bad_http_clt_req_duration.vtc b/reg-tests/lua/bad_http_clt_req_duration.vtc new file mode 100644 index 0000000..5cfdf1a --- /dev/null +++ b/reg-tests/lua/bad_http_clt_req_duration.vtc @@ -0,0 +1,76 @@ +# commit 7b6cc52784526c32efda44b873a4258d3ae0b8c7 +# BUG/MINOR: lua: Bad HTTP client request duration. +# +# HTTP LUA applet callback should not update the date on which the HTTP client requests +# arrive. This was done just after the LUA applet has completed its job. +# +# This patch simply removes the affected statement. The same fix has been applied +# to TCP LUA applet callback. +# +# To reproduce this issue, as reported by Patrick Hemmer, implement an HTTP LUA applet +# which sleeps a bit before replying: +# +# core.register_service("foo", "http", function(applet) +# core.msleep(100) +# applet:set_status(200) +# applet:start_response() +# end) +# +# This had as a consequence to log %TR field with approximately the same value as +# the LUA sleep time. + +varnishtest "LUA bug" +#REQUIRE_OPTIONS=LUA +#REGTEST_TYPE=bug + +feature ignore_unknown_macro + +syslog Slog { + recv info + expect ~ "[^:\\[ ]\\[[0-9]*\\]: Ta=[0-9]* Tc=[0-9]* Td=[0-9]* Th=[0-9]* Ti=[0-9]* Tq=[0-9]* TR=[0-9]* Tr=[0-9]* Tt=[0-9]* Tw=[0-9]*$" + + recv info + expect ~ "[^:\\[ ]\\[[0-9]*\\]: Tc=[0-9]* Td=[0-9]* Th=[0-9]* Tt=[0-9]* Tw=[0-9]*$" +} -start + +haproxy h1 -conf { + global + lua-load ${testdir}/bad_http_clt_req_duration.lua + + defaults + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend f1 + mode http + bind "fd@${f1}" + log ${Slog_addr}:${Slog_port} daemon + log-format Ta=%Ta\ Tc=%Tc\ Td=%Td\ Th=%Th\ Ti=%Ti\ Tq=%Tq\ TR=%TR\ Tr=%Tr\ Tt=%Tt\ Tw=%Tw + default_backend b1 + + backend b1 + mode http + http-request use-service lua.foo.http + + frontend f2 + mode tcp + bind "fd@${f2}" + log ${Slog_addr}:${Slog_port} daemon + log-format Tc=%Tc\ Td=%Td\ Th=%Th\ Tt=%Tt\ Tw=%Tw + + tcp-request inspect-delay 1s + tcp-request content use-service lua.foo.tcp +} -start + +client c1 -connect "${h1_f1_sock}" { + txreq + rxresp +} -run + +client c2 -connect "${h1_f2_sock}" { + txreq + rxresp +} -run + +syslog Slog -wait diff --git a/reg-tests/lua/close_wait_lf.lua b/reg-tests/lua/close_wait_lf.lua new file mode 100644 index 0000000..cc897e7 --- /dev/null +++ b/reg-tests/lua/close_wait_lf.lua @@ -0,0 +1 @@ +core.register_service("donothing", "http", function(applet) end) diff --git a/reg-tests/lua/close_wait_lf.vtc b/reg-tests/lua/close_wait_lf.vtc new file mode 100644 index 0000000..7bed3fd --- /dev/null +++ b/reg-tests/lua/close_wait_lf.vtc @@ -0,0 +1,53 @@ +# commit 70d318c +# BUG/MEDIUM: lua: possible CLOSE-WAIT state with '\n' headers +# +# The Lua parser doesn't takes in account end-of-headers containing +# only '\n'. It expects always '\r\n'. If a '\n' is processes the Lua +# parser considers it miss 1 byte, and wait indefinitely for new data. +# +# When the client reaches their timeout, it closes the connection. +# This close is not detected and the connection keep in CLOSE-WAIT +# state. +# +# I guess that this patch fix only a visible part of the problem. +# If the Lua HTTP parser wait for data, the timeout server or the +# connectio closed by the client may stop the applet. + +varnishtest "possible CLOSE-WAIT with '\n' headers" +#REQUIRE_OPTIONS=LUA +#REGTEST_TYPE=bug + +feature ignore_unknown_macro + +syslog Slog -level info -repeat 100 { + recv info + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Ta=[0-9]* Tc=[0-9]* Td=[0-9]* Th=[0-9]* Ti=[0-9]* Tq=[0-9]* TR=[0-9]* Tr=[0-9]* Tt=[0-9]* Tw=[0-9]*" +} -start + +haproxy h1 -conf { + defaults + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + + global + lua-load ${testdir}/close_wait_lf.lua + + frontend frt + log ${Slog_addr}:${Slog_port} local0 debug err + log-format Ta=%Ta\ Tc=%Tc\ Td=%Td\ Th=%Th\ Ti=%Ti\ Tq=%Tq\ TR=%TR\ Tr=%Tr\ Tt=%Tt\ Tw=%Tw + mode http + bind "fd@${frt}" + http-request use-service lua.donothing +} -start + + +client c1 -connect ${h1_frt_sock} -repeat 100 { + send "GET / HTTP/1.1\n\n" +} -run + +syslog Slog -wait + +shell { + ss -pt | grep CLOSE-WAIT.*haproxy.*pid=${h1_pid} + exit $((!$?)) +} diff --git a/reg-tests/lua/common.pem b/reg-tests/lua/common.pem new file mode 120000 index 0000000..a4433d5 --- /dev/null +++ b/reg-tests/lua/common.pem @@ -0,0 +1 @@ +../ssl/common.pem
\ No newline at end of file diff --git a/reg-tests/lua/h_txn_get_priv.lua b/reg-tests/lua/h_txn_get_priv.lua new file mode 100644 index 0000000..999ea88 --- /dev/null +++ b/reg-tests/lua/h_txn_get_priv.lua @@ -0,0 +1,15 @@ +core.register_action("bug", { "http-res" }, function(txn) + data = txn:get_priv() + if not data then + data = 0 + end + data = data + 1 + print(string.format("set to %d", data)) + txn.http:res_set_status(200 + data) + txn:set_priv(data) +end) + +core.register_service("fakeserv", "http", function(applet) + applet:set_status(200) + applet:start_response() +end) diff --git a/reg-tests/lua/h_txn_get_priv.vtc b/reg-tests/lua/h_txn_get_priv.vtc new file mode 100644 index 0000000..bd8c069 --- /dev/null +++ b/reg-tests/lua/h_txn_get_priv.vtc @@ -0,0 +1,33 @@ +varnishtest "Lua: txn:get_priv() scope" +#REQUIRE_OPTIONS=LUA + +feature ignore_unknown_macro + +haproxy h1 -conf { + global + lua-load ${testdir}/h_txn_get_priv.lua + + frontend fe1 + mode http + bind "fd@${fe1}" + default_backend b1 + + http-response lua.bug + + backend b1 + mode http + http-request use-service lua.fakeserv +} -start + +client c0 -connect ${h1_fe1_sock} { + txreq -url "/" + rxresp + expect resp.status == 201 + txreq -url "/" + rxresp + expect resp.status == 201 +} + +client c0 -start + +client c0 -wait diff --git a/reg-tests/lua/httpclient_action.lua b/reg-tests/lua/httpclient_action.lua new file mode 100644 index 0000000..9a7209c --- /dev/null +++ b/reg-tests/lua/httpclient_action.lua @@ -0,0 +1,8 @@ +function test() + local httpclient = core.httpclient() + local response = httpclient:get{url="http://127.0.0.1", headers={ [ "Host" ] = { "localhost" } }} + +end + + +core.register_action("test", {"tcp-req"}, test, 0) diff --git a/reg-tests/lua/httpclient_action.vtc b/reg-tests/lua/httpclient_action.vtc new file mode 100644 index 0000000..11c7d62 --- /dev/null +++ b/reg-tests/lua/httpclient_action.vtc @@ -0,0 +1,39 @@ +varnishtest "Lua: test the httpclient when the lua action timeout" +# +# Start an httpclient from "lua.test" whose lua task will expire before the +# httpclient is ended. + + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev7)'" +feature ignore_unknown_macro + +#REQUIRE_OPTIONS=LUA + +haproxy h1 -conf { + + global + lua-load ${testdir}/httpclient_action.lua + defaults + mode tcp + timeout http-request 10s + timeout queue 1m + timeout connect 10s + timeout client 1m + timeout server 1m + timeout check 10s + + listen li1 + mode http + bind "fd@${fe1}" + tcp-request inspect-delay 10ms + tcp-request content lua.test + http-request return status 503 + +} -start + +client c0 -connect ${h1_fe1_sock} { + txreq + rxresp + expect resp.status == 503 +} -run + diff --git a/reg-tests/lua/lua_httpclient.lua b/reg-tests/lua/lua_httpclient.lua new file mode 100644 index 0000000..b5a5180 --- /dev/null +++ b/reg-tests/lua/lua_httpclient.lua @@ -0,0 +1,49 @@ + +local vtc_port = 0 +local vtc_port2 = 0 +local vtc_port3 = 0 + +core.register_service("fakeserv", "http", function(applet) + vtc_port = applet.headers["vtcport"][0] + vtc_port2 = applet.headers["vtcport2"][0] + vtc_port3 = applet.headers["vtcport3"][0] + core.Info("APPLET START") + local response = "OK" + applet:add_header("Server", "haproxy/webstats") + applet:add_header("Content-Length", string.len(response)) + applet:add_header("Content-Type", "text/html") + applet:start_response() + applet:send(response) + core.Info("APPLET DONE") +end) + +local function cron() + -- wait for until the correct port is set through the c0 request.. + while vtc_port == 0 do + core.msleep(1) + end + core.Debug('CRON port:' .. vtc_port) + + local body = "" + + for i = 0, 2000 do + body = body .. i .. ' ABCDEFGHIJKLMNOPQRSTUVWXYZ\n' + end + core.Info("First httpclient request") + local httpclient = core.httpclient() + local response = httpclient:post{url="http://127.0.0.1:" .. vtc_port, body=body} + core.Info("Received: " .. response.body) + + body = response.body + + core.Info("Second httpclient request") + local httpclient2 = core.httpclient() + local response2 = httpclient2:post{url="http://127.0.0.1:" .. vtc_port2, body=body} + + core.Info("Third httpclient request") + local httpclient3 = core.httpclient() + local response3 = httpclient3:get{url="http://127.0.0.1", dst = vtc_port3, headers={ [ "Host" ] = { "foobar.haproxy.local" } }} + +end + +core.register_task(cron) diff --git a/reg-tests/lua/lua_httpclient.vtc b/reg-tests/lua/lua_httpclient.vtc new file mode 100644 index 0000000..0a27493 --- /dev/null +++ b/reg-tests/lua/lua_httpclient.vtc @@ -0,0 +1,68 @@ +varnishtest "Lua: check httpclient functionality from a lua-task" + +# A request if first made with c0 with the port of s1 and s2 so the httpclient +# can generate its URI with it. +# +# This reg-test sends a payload with the httpclient to s1, s1 returns another +# payload. The 2nd lua httpclient sends back the payload from s1 to s2. +# + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev7)'" +feature ignore_unknown_macro + +#REQUIRE_OPTIONS=LUA + +server s1 { + rxreq + txresp -bodylen 54000 + expect req.body ~ ".*0 ABCDEFGHIJKLMNOPQRSTUVWXYZ.*" + expect req.body ~ ".*500 ABCDEFGHIJKLMNOPQRSTUVWXYZ.*" + expect req.body ~ ".*1000 ABCDEFGHIJKLMNOPQRSTUVWXYZ.*" + expect req.body ~ ".*1500 ABCDEFGHIJKLMNOPQRSTUVWXYZ.*" + expect req.body ~ ".*2000 ABCDEFGHIJKLMNOPQRSTUVWXYZ" +} -start + +server s2 { + rxreq + txresp + expect req.bodylen == 54000 +} -start + +server s3 { + rxreq + txresp -bodylen 54000 + expect req.method == "GET" + expect req.http.host == "foobar.haproxy.local" +} -start + + +haproxy h1 -conf { + global + lua-load ${testdir}/lua_httpclient.lua + + frontend fe1 + mode http + bind "fd@${fe1}" + default_backend b1 + + backend b1 + mode http + http-request use-service lua.fakeserv + + listen li1 + mode http + bind unix@${tmpdir}/srv3 + server srv3 ${s3_addr}:${s3_port} + +} -start + +client c0 -connect ${h1_fe1_sock} { + txreq -url "/" -hdr "vtcport: ${s1_port}" -hdr "vtcport2: ${s2_port}" -hdr "vtcport3: unix@${tmpdir}/srv3" + rxresp + expect resp.status == 200 +} -run + + +server s1 -wait +server s2 -wait +server s3 -wait diff --git a/reg-tests/lua/lua_socket.lua b/reg-tests/lua/lua_socket.lua new file mode 100644 index 0000000..3ad14fe --- /dev/null +++ b/reg-tests/lua/lua_socket.lua @@ -0,0 +1,44 @@ + +local vtc_port = 0 + +core.register_service("fakeserv", "http", function(applet) + vtc_port = applet.headers["vtcport"][0] + core.Info("APPLET START") + local response = "OK" + applet:add_header("Server", "haproxy/webstats") + applet:add_header("Content-Length", string.len(response)) + applet:add_header("Content-Type", "text/html") + applet:start_response() + applet:send(response) + core.Info("APPLET DONE") +end) + +local function cron() + -- wait for until the correct port is set through the c0 request.. + while vtc_port == 0 do + core.msleep(1) + end + core.Debug('CRON port:' .. vtc_port) + + local socket = core.tcp() + local success = socket:connect("127.0.0.1", vtc_port) + core.Info("SOCKET MADE ".. (success or "??")) + if success ~= 1 then + core.Info("CONNECT SOCKET FAILED?") + return + end + local request = "GET / HTTP/1.1\r\n\r\n" + core.Info("SENDING REQUEST") + socket:send(request) + local result = "" + repeat + core.Info("4") + local d = socket:receive("*a") + if d ~= nil then + result = result .. d + end + until d == nil or d == 0 + core.Info("Received: "..result) +end + +core.register_task(cron)
\ No newline at end of file diff --git a/reg-tests/lua/lua_socket.vtc b/reg-tests/lua/lua_socket.vtc new file mode 100644 index 0000000..83e06a6 --- /dev/null +++ b/reg-tests/lua/lua_socket.vtc @@ -0,0 +1,33 @@ +varnishtest "Lua: check socket functionality from a lua-task" +feature ignore_unknown_macro + +#REQUIRE_OPTIONS=LUA + +server s1 { + rxreq + txresp -bodylen 20 +} -start + +haproxy h1 -conf { + global + lua-load ${testdir}/lua_socket.lua + + frontend fe1 + mode http + bind "fd@${fe1}" + default_backend b1 + + backend b1 + mode http + http-request use-service lua.fakeserv + +} -start + +client c0 -connect ${h1_fe1_sock} { + txreq -url "/" -hdr "vtcport: ${s1_port}" + rxresp + expect resp.status == 200 +} -run + + +server s1 -wait diff --git a/reg-tests/lua/set_var.lua b/reg-tests/lua/set_var.lua new file mode 100644 index 0000000..f4d5e7a --- /dev/null +++ b/reg-tests/lua/set_var.lua @@ -0,0 +1,25 @@ +core.register_service("set_var", "http", function(applet) + local var_name = applet.headers["var"][0] + local result = applet:set_var(var_name, "value") + if result then + applet:set_status(202) + else + applet:set_status(400) + end + applet:add_header("echo", applet:get_var(var_name) or "(nil)") + applet:start_response() + applet:send("") +end) + +core.register_service("set_var_ifexist", "http", function(applet) + local var_name = applet.headers["var"][0] + local result = applet:set_var(var_name, "value", true) + if result then + applet:set_status(202) + else + applet:set_status(400) + end + applet:add_header("echo", applet:get_var(var_name) or "(nil)") + applet:start_response() + applet:send("") +end) diff --git a/reg-tests/lua/set_var.vtc b/reg-tests/lua/set_var.vtc new file mode 100644 index 0000000..0c8a4b1 --- /dev/null +++ b/reg-tests/lua/set_var.vtc @@ -0,0 +1,83 @@ +varnishtest "Lua: set_var" +#REQUIRE_VERSION=2.2 +#REQUIRE_OPTIONS=LUA + +feature ignore_unknown_macro + +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 + + global + lua-load ${testdir}/set_var.lua + + frontend fe1 + mode http + bind "fd@${fe1}" + + http-request use-service lua.set_var + + frontend fe2 + mode http + bind "fd@${fe2}" + # just make sure the variable exists + http-request set-header Dummy %[var(proc.fe2_foo)] + + http-request use-service lua.set_var_ifexist +} -start + +client c0 -connect ${h1_fe1_sock} { + # create var + txreq -url "/" \ + -hdr "Var: txn.fe1_foo" + rxresp + expect resp.status == 202 + expect resp.http.echo == "value" + + # rewrite var + txreq -url "/" \ + -hdr "Var: txn.fe1_foo" + rxresp + expect resp.status == 202 + expect resp.http.echo == "value" + + # create var under scope "proc" + txreq -url "/" \ + -hdr "Var: proc.fe1_foo" + rxresp + expect resp.status == 202 + expect resp.http.echo == "value" + + # fail to create bad scope + txreq -url "/" \ + -hdr "Var: invalid.var" + rxresp + expect resp.status == 400 + expect resp.http.echo == "(nil)" +} -run + +client c1 -connect ${h1_fe2_sock} { + # this one exists in the conf, it must succeed + txreq -url "/" \ + -hdr "Var: proc.fe2_foo" + rxresp + expect resp.status == 202 + expect resp.http.echo == "value" + + # this one does not exist in the conf, it must fail + txreq -url "/" \ + -hdr "Var: proc.fe2_bar" + rxresp + expect resp.status == 400 + expect resp.http.echo == "(nil)" + + # this one is under txn, it must succeed + txreq -url "/" \ + -hdr "Var: txn.fe2_foo" + rxresp + expect resp.status == 202 + expect resp.http.echo == "value" +} -run diff --git a/reg-tests/lua/txn_get_priv-print_r.lua b/reg-tests/lua/txn_get_priv-print_r.lua new file mode 100644 index 0000000..185614f --- /dev/null +++ b/reg-tests/lua/txn_get_priv-print_r.lua @@ -0,0 +1,96 @@ +-- Copyright 2016 Thierry Fournier + +function color(index, str) + return "\x1b[" .. index .. "m" .. str .. "\x1b[00m" +end + +function nocolor(index, str) + return str +end + +function sp(count) + local spaces = "" + while count > 0 do + spaces = spaces .. " " + count = count - 1 + end + return spaces +end + +function escape(str) + local s = "" + for i = 1, #str do + local c = str:sub(i,i) + local ascii = string.byte(c, 1) + if ascii > 126 or ascii < 20 then + s = s .. string.format("\\x%02x", ascii) + else + s = s .. c + end + end + return s +end + +function print_rr(p, indent, c, wr, hist) + local i = 0 + local nl = "" + + if type(p) == "table" then + wr(c("33", "(table)") .. " " .. c("36", tostring(p)) .. " [") + + for idx, value in ipairs(hist) do + if value == p then + wr(" " .. c("35", "/* recursion */") .. " ]") + return + end + end + hist[indent + 1] = p + + mt = getmetatable(p) + if mt ~= nil then + wr("\n" .. sp(indent+1) .. c("31", "METATABLE") .. ": ") + print_rr(mt, indent+1, c, wr, hist) + end + + for k,v in pairs(p) do + if i > 0 then + nl = "\n" + else + wr("\n") + end + wr(nl .. sp(indent+1)) + if type(k) == "number" then + wr(c("32", tostring(k))) + else + wr("\"" .. c("32", escape(tostring(k))) .. "\"") + end + wr(": ") + print_rr(v, indent+1, c, wr, hist) + i = i + 1 + end + if i == 0 then + wr(" " .. c("35", "/* empty */") .. " ]") + else + wr("\n" .. sp(indent) .. "]") + end + + hist[indent + 1] = nil + + elseif type(p) == "string" then + wr(c("33", "(string)") .. " \"" .. c("36", escape(p)) .. "\"") + else + wr(c("33", "(" .. type(p) .. ")") .. " " .. c("36", tostring(p))) + end +end + +function print_r(p, col, wr) + if col == nil then col = true end + if wr == nil then wr = function(msg) io.stdout:write(msg) end end + local hist = {} + if col == true then + print_rr(p, 0, color, wr, hist) + else + print_rr(p, 0, nocolor, wr, hist) + end + wr("\n") +end diff --git a/reg-tests/lua/txn_get_priv-thread.vtc b/reg-tests/lua/txn_get_priv-thread.vtc new file mode 100644 index 0000000..9538363 --- /dev/null +++ b/reg-tests/lua/txn_get_priv-thread.vtc @@ -0,0 +1,69 @@ +varnishtest "Lua: txn:get_priv() scope" +#REQUIRE_OPTIONS=LUA,OPENSSL +#REQUIRE_VERSION=2.4 +#REGTEST_TYPE=bug + +feature ignore_unknown_macro + +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 + + lua-load-per-thread ${testdir}/txn_get_priv.lua + lua-load-per-thread ${testdir}/txn_get_priv-print_r.lua + + frontend fe1 + mode http + bind "fd@${fe1}" + default_backend b1 + + frontend fe2 + mode http + bind ":8443" ssl crt ${testdir}/common.pem + stats enable + stats uri / + + backend b1 + mode http + http-request use-service lua.fakeserv +} -start + +client c0 -repeat 4 -connect ${h1_fe1_sock} { + txreq -url "/0" + rxresp + expect resp.status == 200 + txreq -url "/0" + rxresp + expect resp.status == 200 +} -run + +client c1 -repeat 4 -connect ${h1_fe1_sock} { + txreq -url "/1" + rxresp + expect resp.status == 200 + txreq -url "/1" + rxresp + expect resp.status == 200 +} -run + +client c2 -repeat 4 -connect ${h1_fe1_sock} { + txreq -url "/2" + rxresp + expect resp.status == 200 + txreq -url "/2" + rxresp + expect resp.status == 200 +} -run + +client c3 -repeat 4 -connect ${h1_fe1_sock} { + txreq -url "/3" + rxresp + expect resp.status == 200 + txreq -url "/3" + rxresp + expect resp.status == 200 +} -run + diff --git a/reg-tests/lua/txn_get_priv.lua b/reg-tests/lua/txn_get_priv.lua new file mode 100644 index 0000000..dd5623c --- /dev/null +++ b/reg-tests/lua/txn_get_priv.lua @@ -0,0 +1,180 @@ +Luacurl = {} +Luacurl.__index = Luacurl +setmetatable(Luacurl, { + __call = function (cls, ...) + return cls.new(...) + end, +}) +function Luacurl.new(server, port, ssl) + local self = setmetatable({}, Luacurl) + self.sockconnected = false + self.server = server + self.port = port + self.ssl = ssl + self.cookies = {} + return self +end + +function Luacurl:get(method,url,headers,data) + core.Info("MAKING SOCKET") + if self.sockconnected == false then + self.sock = core.tcp() + if self.ssl then + local r = self.sock:connect_ssl(self.server,self.port) + else + local r = self.sock:connect(self.server,self.port) + end + self.sockconnected = true + end + core.Info("SOCKET MADE") + local request = method.." "..url.." HTTP/1.1" + if data ~= nil then + request = request .. "\r\nContent-Length: "..string.len(data) + end + if headers ~= null then + for h,v in pairs(headers) do + request = request .. "\r\n"..h..": "..v + end + end + cookstring = "" + for cook,cookval in pairs(self.cookies) do + cookstring = cookstring .. cook.."="..cookval.."; " + end + if string.len(cookstring) > 0 then + request = request .. "\r\nCookie: "..cookstring + end + + request = request .. "\r\n\r\n" + if data and string.len(data) > 0 then + request = request .. data + end +--print(request) + core.Info("SENDING REQUEST") + self.sock:send(request) + +-- core.Info("PROCESSING RESPONSE") + return processhttpresponse(self.sock) +end + +function processhttpresponse(socket) + local res = {} +core.Info("1") + res.status = socket:receive("*l") +core.Info("2") + + if res.status == nil then + core.Info(" processhttpresponse RECEIVING status: NIL") + return res + end + core.Info(" processhttpresponse RECEIVING status:"..res.status) + res.headers = {} + res.headerslist = {} + repeat +core.Info("3") + local header = socket:receive("*l") + if header == nil then + return "error" + end + local valuestart = header:find(":") + if valuestart ~= nil then + local head = header:sub(1,valuestart-1) + local value = header:sub(valuestart+2) + table.insert(res.headerslist, {head,value}) + res.headers[head] = value + end + until header == "" + local bodydone = false + if res.headers["Connection"] ~= nil and res.headers["Connection"] == "close" then +-- core.Info("luacurl processresponse with connection:close") + res.body = "" + repeat +core.Info("4") + local d = socket:receive("*a") + if d ~= nil then + res.body = res.body .. d + end + until d == nil or d == 0 + bodydone = true + end + if bodydone == false and res.headers["Content-Length"] ~= nil then + res.contentlength = tonumber(res.headers["Content-Length"]) + if res.contentlength == nil then + core.Warning("res.contentlength ~NIL = "..res.headers["Content-Length"]) + end +-- core.Info("luacur, contentlength="..res.contentlength) + res.body = "" + repeat + local d = socket:receive(res.contentlength) + if d == nil then +-- core.Info("luacurl, ERROR?: received NIL, expecting "..res.contentlength.." bytes only got "..string.len(res.body).." sofar") + return + else + res.body = res.body..d +-- core.Info("luacurl, COMPLETE?: expecting "..res.contentlength.." bytes, got "..string.len(res.body)) + if string.len(res.body) >= res.contentlength then +-- core.Info("luacurl, COMPLETE?: expecting "..res.contentlength.." bytes, got "..string.len(res.body)) + break + end + end +-- core.Info("processhttpresponse, Loopy, get more body data! to receive complete contentlenght") + until false + end + if res.headers["Transfer-Encoding"] ~= nil and res.headers["Transfer-Encoding"] == "chunked" then + local chunksize = 0 + res.contentlength = 0 + res.body = "" + repeat +core.Info("5") + local chunksizestr = socket:receive("*l") + if chunksizestr == nil then + break + end + chunksize = tonumber("0x"..chunksizestr) + if chunksize ~= nil then + res.contentlength = res.contentlength + chunksize + if chunksize ~= 0 then + local chunk = socket:receive(chunksize) + res.body = res.body .. chunk + chunksizestr = socket:receive("*l") + if chunksizestr ~= "" then + return "ERROR Chunk-end expected." + end + end + else + break + end + until false + end +core.Info("6") + return res +end + +function Luacurl:close() + if self.sockconnected == true then + self.sock:close() + self.sockconnected = false + end +end + +function print_r_string(object) + local res = "" + print_r(object,false,function(x) res = res .. x end) + return res +end + +core.register_service("fakeserv", "http", function(applet) + core.Info("APPLET START") + local mc = Luacurl("127.0.0.1",8443, true) + local headers = {} + local body = "" + core.Info("APPLET GET") + local res = mc:get("GET", "/", headers, body) + core.Info("APPLET GET done") + local response = print_r_string(res) + applet:add_header("Server", "haproxy/webstats") + applet:add_header("Content-Length", string.len(response)) + applet:add_header("Content-Type", "text/html") + applet:start_response() + applet:send(response) + core.Info("APPLET DONE") +end) diff --git a/reg-tests/lua/txn_get_priv.vtc b/reg-tests/lua/txn_get_priv.vtc new file mode 100644 index 0000000..71e7bb5 --- /dev/null +++ b/reg-tests/lua/txn_get_priv.vtc @@ -0,0 +1,35 @@ +varnishtest "Lua: txn:get_priv() scope" +#REQUIRE_OPTIONS=LUA,OPENSSL +#REGTEST_TYPE=bug + +feature ignore_unknown_macro + +haproxy h1 -conf { + global + lua-load ${testdir}/txn_get_priv.lua + lua-load ${testdir}/txn_get_priv-print_r.lua + + frontend fe1 + mode http + bind "fd@${fe1}" + default_backend b1 + + frontend fe2 + mode http + bind ":8443" ssl crt ${testdir}/common.pem + stats enable + stats uri / + + backend b1 + mode http + http-request use-service lua.fakeserv +} -start + +client c0 -connect ${h1_fe1_sock} { + txreq -url "/" + rxresp + expect resp.status == 200 + txreq -url "/" + rxresp + expect resp.status == 200 +} -run diff --git a/reg-tests/lua/wrong_types_usage.lua b/reg-tests/lua/wrong_types_usage.lua new file mode 100644 index 0000000..d2401fa --- /dev/null +++ b/reg-tests/lua/wrong_types_usage.lua @@ -0,0 +1,3 @@ +core.register_action("foo", { "http-req" }, function(txn) + txn.sc:ipmask(txn.f:src(), 24, 112) +end) diff --git a/reg-tests/lua/wrong_types_usage.vtc b/reg-tests/lua/wrong_types_usage.vtc new file mode 100644 index 0000000..ed76579 --- /dev/null +++ b/reg-tests/lua/wrong_types_usage.vtc @@ -0,0 +1,77 @@ +# commit f874a83 +# BUG/MINOR: lua: Segfaults with wrong usage of types. +# +# Patrick reported that this simple configuration made haproxy segfaults: +# +# global +# lua-load /tmp/haproxy.lua +# +# frontend f1 +# mode http +# bind :8000 +# default_backend b1 +# +# http-request lua.foo +# +# backend b1 +# mode http +# server s1 127.0.0.1:8080 +# +# with this '/tmp/haproxy.lua' script: +# +# core.register_action("foo", { "http-req" }, function(txn) +# txn.sc:ipmask(txn.f:src(), 24, 112) +# end) +# +# This is due to missing initialization of the array of arguments +# passed to hlua_lua2arg_check() which makes it enter code with +# corrupted arguments. +# +# Thanks a lot to Patrick Hemmer for having reported this issue. + + +varnishtest "Basic LUA test h00000" +#REQUIRE_OPTIONS=LUA +#REGTEST_TYPE=bug + +feature ignore_unknown_macro + +server s1 -repeat 2 { + rxreq + txresp +} -start + +haproxy h1 -conf { + global + lua-load ${testdir}/wrong_types_usage.lua + + frontend fe1 + mode http + bind "fd@${fe1}" + default_backend b1 + + http-request lua.foo + + backend b1 + mode http + server s1 ${s1_addr}:${s1_port} + +} -start + +client c0 -connect ${h1_fe1_sock} { + txreq -url "/foo" + rxresp + expect resp.status == 200 +} + +client c1 -connect ${h1_fe1_sock} { + txreq -url "/foo" + rxresp + expect resp.status == 200 +} + +client c0 -start +client c1 -start + +client c0 -wait +client c1 -wait diff --git a/reg-tests/mailers/healthcheckmail.lua b/reg-tests/mailers/healthcheckmail.lua new file mode 100644 index 0000000..4cb0e9d --- /dev/null +++ b/reg-tests/mailers/healthcheckmail.lua @@ -0,0 +1,70 @@ + +local vtc_port1 = 0 +local mailsreceived = 0 +local mailconnectionsmade = 0 +local healthcheckcounter = 0 + +function RecieveAndCheck(applet, expect) + data = applet:getline() + if data:sub(1,expect:len()) ~= expect then + core.Info("Expected: "..expect.." but got:"..data:sub(1,expect:len())) + applet:send("Expected: "..expect.." but got:"..data.."\r\n") + return false + end + return true +end + +core.register_service("mailservice", "tcp", function(applet) + core.Info("############# Mailservice Called #############") + mailconnectionsmade = mailconnectionsmade + 1 + applet:send("220 Welcome\r\n") + local data + + if RecieveAndCheck(applet, "HELO") == false then + applet:set_var("txn.result", "ERROR (step: HELO)") + return + end + applet:send("250 OK\r\n") + if RecieveAndCheck(applet, "MAIL FROM:") == false then + applet:set_var("txn.result", "ERROR (step: MAIL FROM)") + return + end + applet:send("250 OK\r\n") + if RecieveAndCheck(applet, "RCPT TO:") == false then + applet:set_var("txn.result", "ERROR (step: RCPT TO)") + return + end + applet:send("250 OK\r\n") + if RecieveAndCheck(applet, "DATA") == false then + applet:set_var("txn.result", "ERROR (step: DATA)") + return + end + applet:send("354 OK\r\n") + core.Info("#### Send your mailbody") + local endofmail = false + local subject = "" + while endofmail ~= true do + data = applet:getline() -- BODY CONTENT + --core.Info(data) + if data:sub(1, 9) == "Subject: " then + subject = data + end + if (data == "\r\n") then + data = applet:getline() -- BODY CONTENT + core.Info(data) + if (data == ".\r\n") then + endofmail = true + end + end + end + core.Info("#### Body received OK") + applet:send("250 OK\r\n") + + if RecieveAndCheck(applet, "QUIT") == false then + applet:set_var("txn.result", "ERROR (step: QUIT)") + return + end + applet:send("221 Mail queued for delivery to /dev/null \r\n") + core.Info("Mail queued for delivery to /dev/null subject: "..subject) + applet:set_var("txn.result", "SUCCESS") +end) diff --git a/reg-tests/mailers/healthcheckmail.vtc b/reg-tests/mailers/healthcheckmail.vtc new file mode 100644 index 0000000..821250f --- /dev/null +++ b/reg-tests/mailers/healthcheckmail.vtc @@ -0,0 +1,59 @@ +varnishtest "Check health-check email alerts" +#REQUIRE_OPTIONS=LUA + +feature ignore_unknown_macro + +syslog S1 -level notice { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/srv1 failed.+check duration: [[:digit:]]+ms.+status: 0/1 DOWN." + recv info + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Result=SUCCESS Bytes=[[:digit:]]+" +} -start + +haproxy h1 -conf { + global + lua-load ${testdir}/healthcheckmail.lua + + defaults + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + + listen lisrv + mode tcp + bind "fd@${lisrv}" + tcp-request connection reject + + listen lismtp + mode tcp + bind "fd@${lismtp}" + log ${S1_addr}:${S1_port} daemon + log-format "Result=%[var(txn.result)] Bytes=%B" + tcp-request content use-service lua.mailservice + + frontend fe1 + mode http + bind "fd@${fe1}" + default_backend be1 + + backend be1 + mode http + log ${S1_addr}:${S1_port} daemon + option httpchk + option log-health-checks + + default-server inter 200ms downinter 100ms rise 1 fall 1 + + email-alert mailers mymailers + email-alert level info + email-alert from from@domain.tld + email-alert to to@domain.tld + + server srv1 ${h1_lisrv_addr}:${h1_lisrv_port} check + + mailers mymailers + mailer smtp1 ${h1_lismtp_addr}:${h1_lismtp_port} + +} -start + +syslog S1 -wait diff --git a/reg-tests/mcli/mcli_show_info.vtc b/reg-tests/mcli/mcli_show_info.vtc new file mode 100644 index 0000000..ae533da --- /dev/null +++ b/reg-tests/mcli/mcli_show_info.vtc @@ -0,0 +1,29 @@ +varnishtest "Show info of process 1" + +#REQUIRE_VERSION=1.9 + +feature ignore_unknown_macro + +# Do nothing. Is there only to create s1_* macros +server s1 { +} -start + +haproxy h1 -W -S -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend myfrontend + bind "fd@${my_fe}" + default_backend test + + backend test + server www1 ${s1_addr}:${s1_port} +} -start + +haproxy h1 -mcli { + send "@1 show info" + expect ~ ".*\nProcess_num: 1\n.*" +} -wait diff --git a/reg-tests/mcli/mcli_start_progs.vtc b/reg-tests/mcli/mcli_start_progs.vtc new file mode 100644 index 0000000..a2e0f75 --- /dev/null +++ b/reg-tests/mcli/mcli_start_progs.vtc @@ -0,0 +1,37 @@ +varnishtest "Try to start a master CLI with 2 programs" +#REGTEST_TYPE=bug +#REQUIRE_VERSION=2.0 +feature cmd "command -v sleep" + +feature ignore_unknown_macro + +# Do nothing. Is there only to create s1_* macros +server s1 { +} -start + +haproxy h1 -W -S -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend myfrontend + bind "fd@${my_fe}" + default_backend test + + backend test + server www1 ${s1_addr}:${s1_port} + + program foo + command sleep 10 + + program bar + command sleep 10 + +} -start + +haproxy h1 -mcli { + send "show proc" + expect ~ ".*foo.*\n.*bar.*\n" +} -wait diff --git a/reg-tests/peers/basic_sync.vtc b/reg-tests/peers/basic_sync.vtc new file mode 100644 index 0000000..02449e2 --- /dev/null +++ b/reg-tests/peers/basic_sync.vtc @@ -0,0 +1,121 @@ +vtest "Basic test for peers protocol" +feature ignore_unknown_macro + +#REQUIRE_VERSION=2.0 +#REGTEST_TYPE=slow + +haproxy h1 -arg "-L A" -conf { + defaults + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + backend stkt + stick-table type string size 10m store server_id,gpc0,conn_cur,conn_rate(50000) peers peers + + peers peers + bind "fd@${A}" + server A + server B ${h2_B_addr}:${h2_B_port} + server C ${h3_C_addr}:${h3_C_port} + + frontend fe + bind "fd@${fe}" + tcp-request inspect-delay 100ms + tcp-request content track-sc0 url table stkt + tcp-request content sc-inc-gpc0(0) +} + +haproxy h2 -arg "-L B" -conf { + defaults + mode http + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + backend stkt + stick-table type string size 10m store server_id,gpc0,conn_cur,conn_rate(50000) peers peers + + peers peers + bind "fd@${B}" + server A ${h1_A_addr}:${h1_A_port} + server B + server C ${h3_C_addr}:${h3_C_port} + + frontend fe + bind "fd@${fe}" + http-request track-sc0 url table stkt + http-request sc-inc-gpc0(0) +} + +haproxy h3 -arg "-L C" -conf { + defaults + mode http + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + backend stkt + stick-table type string size 10m store server_id,gpc0,conn_cur,conn_rate(50000) peers peers + + peers peers + bind "fd@${C}" + server A ${h1_A_addr}:${h1_A_port} + server B ${h2_B_addr}:${h2_B_port} + server C + + frontend fe + bind "fd@${fe}" + http-request track-sc0 url table stkt + http-request sc-inc-gpc0(0) +} + +client c1 -connect ${h1_fe_sock} { + txreq -url "/c1_client" + expect_close +} -start + +client c2 -connect ${h1_fe_sock} { + txreq -url "/c2_client" + expect_close +} -start + +client c3 -connect ${h1_fe_sock} { + txreq -url "/c3_client" + expect_close +} -start + +client c4 -connect ${h1_fe_sock} { + txreq -url "/c4_client" + expect_close +} -start + +haproxy h1 -start +delay 0.2 +haproxy h2 -start +delay 0.2 +haproxy h3 -start +delay 0.2 + +client c1 -wait +client c2 -wait +client c3 -wait +client c4 -wait + +delay 2 + +haproxy h1 -cli { + send "show table stkt" + expect ~ "# table: stkt, type: string, size:1048[0-9]{4}, used:4(\n0x[0-9a-f]*: key=/c[1-4]_client use=0 exp=0 server_id=0 gpc0=1 conn_rate\\(50000\\)=1 conn_cur=0){4}" +} + +haproxy h2 -cli { + send "show table stkt" + expect ~ "# table: stkt, type: string, size:1048[0-9]{4}, used:4(\n0x[0-9a-f]*: key=/c[1-4]_client use=0 exp=0 server_id=0 gpc0=1 conn_rate\\(50000\\)=1 conn_cur=0){4}" +} + +haproxy h3 -cli { + send "show table stkt" + expect ~ "# table: stkt, type: string, size:1048[0-9]{4}, used:4(\n0x[0-9a-f]*: key=/c[1-4]_client use=0 exp=0 server_id=0 gpc0=1 conn_rate\\(50000\\)=1 conn_cur=0){4}" +} + diff --git a/reg-tests/peers/basic_sync_wo_stkt_backend.vtc b/reg-tests/peers/basic_sync_wo_stkt_backend.vtc new file mode 100644 index 0000000..e4f59e1 --- /dev/null +++ b/reg-tests/peers/basic_sync_wo_stkt_backend.vtc @@ -0,0 +1,116 @@ +vtest "Basic test for peers protocol stick-table declared in peers sections" +feature ignore_unknown_macro + +#REQUIRE_VERSION=2.0 +#REGTEST_TYPE=slow + +haproxy h1 -arg "-L A" -conf { + defaults + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + + peers peers + bind "fd@${A}" + server A + server B ${h2_B_addr}:${h2_B_port} + server C ${h3_C_addr}:${h3_C_port} + table stkt type string size 10m store server_id,gpc0,conn_cur,conn_rate(50000) + + frontend fe + bind "fd@${fe}" + tcp-request inspect-delay 100ms + tcp-request content track-sc0 url table peers/stkt + tcp-request content sc-inc-gpc0(0) +} + +haproxy h2 -arg "-L B" -conf { + defaults + mode http + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + peers peers + bind "fd@${B}" + server A ${h1_A_addr}:${h1_A_port} + server B + server C ${h3_C_addr}:${h3_C_port} + table stkt type string size 10m store server_id,gpc0,conn_cur,conn_rate(50000) + + frontend fe + bind "fd@${fe}" + http-request track-sc0 url table peers/stkt + http-request sc-inc-gpc0(0) +} + +haproxy h3 -arg "-L C" -conf { + defaults + mode http + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + peers peers + bind "fd@${C}" + server A ${h1_A_addr}:${h1_A_port} + server B ${h2_B_addr}:${h2_B_port} + server C + table stkt type string size 10m store server_id,gpc0,conn_cur,conn_rate(50000) + + frontend fe + bind "fd@${fe}" + http-request track-sc0 url table peers/stkt + http-request sc-inc-gpc0(0) +} + +client c1 -connect ${h1_fe_sock} { + txreq -url "/c1_client" + expect_close +} -start + +client c2 -connect ${h1_fe_sock} { + txreq -url "/c2_client" + expect_close +} -start + +client c3 -connect ${h1_fe_sock} { + txreq -url "/c3_client" + expect_close +} -start + +client c4 -connect ${h1_fe_sock} { + txreq -url "/c4_client" + expect_close +} -start + +haproxy h1 -start +delay 0.2 +haproxy h2 -start +delay 0.2 +haproxy h3 -start +delay 0.2 + +client c1 -wait +client c2 -wait +client c3 -wait +client c4 -wait + +delay 2 + +haproxy h1 -cli { + send "show table peers/stkt" + expect ~ "# table: peers/stkt, type: string, size:1048[0-9]{4}, used:4(\n0x[0-9a-f]*: key=/c[1-4]_client use=0 exp=0 server_id=0 gpc0=1 conn_rate\\(50000\\)=1 conn_cur=0){4}" +} + +haproxy h2 -cli { + send "show table peers/stkt" + expect ~ "# table: peers/stkt, type: string, size:1048[0-9]{4}, used:4(\n0x[0-9a-f]*: key=/c[1-4]_client use=0 exp=0 server_id=0 gpc0=1 conn_rate\\(50000\\)=1 conn_cur=0){4}" +} + +haproxy h3 -cli { + send "show table peers/stkt" + expect ~ "# table: peers/stkt, type: string, size:1048[0-9]{4}, used:4(\n0x[0-9a-f]*: key=/c[1-4]_client use=0 exp=0 server_id=0 gpc0=1 conn_rate\\(50000\\)=1 conn_cur=0){4}" +} + diff --git a/reg-tests/peers/common.pem b/reg-tests/peers/common.pem new file mode 120000 index 0000000..a4433d5 --- /dev/null +++ b/reg-tests/peers/common.pem @@ -0,0 +1 @@ +../ssl/common.pem
\ No newline at end of file diff --git a/reg-tests/peers/tls_basic_sync.vtc b/reg-tests/peers/tls_basic_sync.vtc new file mode 100644 index 0000000..7b6e9b2 --- /dev/null +++ b/reg-tests/peers/tls_basic_sync.vtc @@ -0,0 +1,158 @@ +vtest "Basic test for peers protocol over SSL/TLS" +#REQUIRE_OPTIONS=OPENSSL +#REQUIRE_VERSION=2.0 +feature ignore_unknown_macro + +#REGTEST_TYPE=slow + +haproxy h1 -arg "-L A" -conf { + defaults + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + backend stkt + stick-table type string size 10m store server_id,gpc0,conn_cur,conn_rate(50000) peers peers + + peers peers + default-server ssl crt ${testdir}/common.pem verify none + bind "fd@${A}" ssl crt ${testdir}/common.pem + server A + server B ${h2_B_addr}:${h2_B_port} + server C ${h3_C_addr}:${h3_C_port} + server D ${h4_D_addr}:${h4_D_port} + + frontend fe + bind "fd@${fe}" + tcp-request inspect-delay 100ms + tcp-request content track-sc0 url table stkt + tcp-request content sc-inc-gpc0(0) +} + +haproxy h2 -arg "-L B" -conf { + defaults + mode http + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + backend stkt + stick-table type string size 10m store server_id,gpc0,conn_cur,conn_rate(50000) peers peers + + peers peers + default-server ssl crt ${testdir}/common.pem verify none + bind "fd@${B}" ssl crt ${testdir}/common.pem + server A ${h1_A_addr}:${h1_A_port} + server B + server C ${h3_C_addr}:${h3_C_port} + server D ${h4_D_addr}:${h4_D_port} + + frontend fe + bind "fd@${fe}" + http-request track-sc0 url table stkt + http-request sc-inc-gpc0(0) +} + +haproxy h3 -arg "-L C" -conf { + defaults + mode http + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + backend stkt + stick-table type string size 10m store server_id,gpc0,conn_cur,conn_rate(50000) peers peers + + peers peers + default-server ssl crt ${testdir}/common.pem verify none + bind "fd@${C}" ssl crt ${testdir}/common.pem + server A ${h1_A_addr}:${h1_A_port} + server B ${h2_B_addr}:${h2_B_port} + server C + server D ${h4_D_addr}:${h4_D_port} + + frontend fe + bind "fd@${fe}" + http-request track-sc0 url table stkt + http-request sc-inc-gpc0(0) +} + +haproxy h4 -arg "-L D" -conf { + defaults + mode http + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + backend stkt + stick-table type string size 10m store server_id,gpc0,conn_cur,conn_rate(50000) peers peers + + peers peers + bind "fd@${D}" + server A ${h1_A_addr}:${h1_A_port} + server B ${h2_B_addr}:${h2_B_port} + server C ${h3_C_addr}:${h3_C_port} + server D + + frontend fe + bind "fd@${fe}" + http-request track-sc0 url table stkt + http-request sc-inc-gpc0(0) +} + +client c1 -connect ${h1_fe_sock} { + txreq -url "/c1_client" + expect_close +} -start + +client c2 -connect ${h1_fe_sock} { + txreq -url "/c2_client" + expect_close +} -start + +client c3 -connect ${h1_fe_sock} { + txreq -url "/c3_client" + expect_close +} -start + +client c4 -connect ${h1_fe_sock} { + txreq -url "/c4_client" + expect_close +} -start + +haproxy h1 -start +delay 0.2 +haproxy h2 -start +delay 0.2 +haproxy h3 -start +delay 0.2 +haproxy h4 -start +delay 0.2 + +client c1 -wait +client c2 -wait +client c3 -wait +client c4 -wait + +delay 2 + +haproxy h1 -cli { + send "show table stkt" + expect ~ "# table: stkt, type: string, size:1048[0-9]{4}, used:4(\n0x[0-9a-f]*: key=/c[1-4]_client use=0 exp=0 server_id=0 gpc0=1 conn_rate\\(50000\\)=1 conn_cur=0){4}" +} + +haproxy h2 -cli { + send "show table stkt" + expect ~ "# table: stkt, type: string, size:1048[0-9]{4}, used:4(\n0x[0-9a-f]*: key=/c[1-4]_client use=0 exp=0 server_id=0 gpc0=1 conn_rate\\(50000\\)=1 conn_cur=0){4}" +} + +haproxy h3 -cli { + send "show table stkt" + expect ~ "# table: stkt, type: string, size:1048[0-9]{4}, used:4(\n0x[0-9a-f]*: key=/c[1-4]_client use=0 exp=0 server_id=0 gpc0=1 conn_rate\\(50000\\)=1 conn_cur=0){4}" +} + +haproxy h4 -cli { + send "show table stkt" + expect ~ "# table: stkt, type: string, size:1048[0-9]{4}, used:0\n" +} + diff --git a/reg-tests/peers/tls_basic_sync_wo_stkt_backend.vtc b/reg-tests/peers/tls_basic_sync_wo_stkt_backend.vtc new file mode 100644 index 0000000..7e1bfd3 --- /dev/null +++ b/reg-tests/peers/tls_basic_sync_wo_stkt_backend.vtc @@ -0,0 +1,152 @@ +vtest "Basic test for peers protocol over SSL/TLS with stick-table declared in peers sections" +feature ignore_unknown_macro + +#REQUIRE_VERSION=2.0 +#REQUIRE_OPTIONS=OPENSSL +#REGTEST_TYPE=slow + +haproxy h1 -arg "-L A" -conf { + defaults + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + peers peers + table stkt type string size 10m store server_id,gpc0,conn_cur,conn_rate(50000) + default-server ssl crt ${testdir}/common.pem verify none + bind "fd@${A}" ssl crt ${testdir}/common.pem + server A + server B ${h2_B_addr}:${h2_B_port} + server C ${h3_C_addr}:${h3_C_port} + server D ${h4_D_addr}:${h4_D_port} + + frontend fe + bind "fd@${fe}" + tcp-request inspect-delay 100ms + tcp-request content track-sc0 url table peers/stkt + tcp-request content sc-inc-gpc0(0) +} + +haproxy h2 -arg "-L B" -conf { + defaults + mode http + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + peers peers + table stkt type string size 10m store server_id,gpc0,conn_cur,conn_rate(50000) + default-server ssl crt ${testdir}/common.pem verify none + bind "fd@${B}" ssl crt ${testdir}/common.pem + server A ${h1_A_addr}:${h1_A_port} + server B + server C ${h3_C_addr}:${h3_C_port} + server D ${h4_D_addr}:${h4_D_port} + + frontend fe + bind "fd@${fe}" + http-request track-sc0 url table peers/stkt + http-request sc-inc-gpc0(0) +} + +haproxy h3 -arg "-L C" -conf { + defaults + mode http + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + peers peers + table stkt type string size 10m store server_id,gpc0,conn_cur,conn_rate(50000) + default-server ssl crt ${testdir}/common.pem verify none + bind "fd@${C}" ssl crt ${testdir}/common.pem + server A ${h1_A_addr}:${h1_A_port} + server B ${h2_B_addr}:${h2_B_port} + server C + server D ${h4_D_addr}:${h4_D_port} + + frontend fe + bind "fd@${fe}" + http-request track-sc0 url table peers/stkt + http-request sc-inc-gpc0(0) +} + +haproxy h4 -arg "-L D" -conf { + defaults + mode http + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + backend stkt + + peers peers + table stkt type string size 10m store server_id,gpc0,conn_cur,conn_rate(50000) + bind "fd@${D}" + server A ${h1_A_addr}:${h1_A_port} + server B ${h2_B_addr}:${h2_B_port} + server C ${h3_C_addr}:${h3_C_port} + server D + + frontend fe + bind "fd@${fe}" + http-request track-sc0 url table peers/stkt + http-request sc-inc-gpc0(0) +} + +client c1 -connect ${h1_fe_sock} { + txreq -url "/c1_client" + expect_close +} -start + +client c2 -connect ${h1_fe_sock} { + txreq -url "/c2_client" + expect_close +} -start + +client c3 -connect ${h1_fe_sock} { + txreq -url "/c3_client" + expect_close +} -start + +client c4 -connect ${h1_fe_sock} { + txreq -url "/c4_client" + expect_close +} -start + +haproxy h1 -start +delay 0.02 +haproxy h2 -start +delay 0.02 +haproxy h3 -start +delay 0.02 +haproxy h4 -start +delay 0.02 + +client c1 -wait +client c2 -wait +client c3 -wait +client c4 -wait + +delay 3 + +haproxy h1 -cli { + send "show table peers/stkt" + expect ~ "# table: peers/stkt, type: string, size:1048[0-9]{4}, used:4(\n0x[0-9a-f]*: key=/c[1-4]_client use=0 exp=0 server_id=0 gpc0=1 conn_rate\\(50000\\)=1 conn_cur=0){4}" +} + +haproxy h2 -cli { + send "show table peers/stkt" + expect ~ "# table: peers/stkt, type: string, size:1048[0-9]{4}, used:4(\n0x[0-9a-f]*: key=/c[1-4]_client use=0 exp=0 server_id=0 gpc0=1 conn_rate\\(50000\\)=1 conn_cur=0){4}" +} + +haproxy h3 -cli { + send "show table peers/stkt" + expect ~ "# table: peers/stkt, type: string, size:1048[0-9]{4}, used:4(\n0x[0-9a-f]*: key=/c[1-4]_client use=0 exp=0 server_id=0 gpc0=1 conn_rate\\(50000\\)=1 conn_cur=0){4}" +} + +haproxy h4 -cli { + send "show table peers/stkt" + expect ~ "# table: peers/stkt, type: string, size:1048[0-9]{4}, used:0\n" +} + diff --git a/reg-tests/sample_fetches/cond_set_var.vtc b/reg-tests/sample_fetches/cond_set_var.vtc new file mode 100644 index 0000000..67786ae --- /dev/null +++ b/reg-tests/sample_fetches/cond_set_var.vtc @@ -0,0 +1,362 @@ +#REGTEST_TYPE=devel + +# This regtest checks the multiple conditions that can be specified to a +# set-var call (be it a converter or HTTP or TCP action). It mainly uses the +# actions but since the "var_set" function is used for the converter and for +# the actions, it should be enough to focus on one type of set-var. +# Among the variables that can be defined and the multiple scopes they can +# have, the proc scope is the only one having a specific behaviour. Proc scoped +# variables are created during init when a variable of any other scope is +# created during the first successful set-var. +# Since this test uses variables of different scopes, the validation cannot be +# based on the "show var" command of the CLI because it only displays process +# variables. It then always follows the same logic, for every sub test case : +# an HTTP header is added to the response in which we add a concatenation of +# all the tested variables (which exist in the request/response scope). These +# HTTP headers are then tested upon an expected result (which changes for every +# test case). +# + +varnishtest "Test the conditional set-var converter and action" +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature cmd "command -v socat" +feature ignore_unknown_macro + +server s1 -repeat 10 { + rxreq + txresp +} -start + +haproxy h1 -conf { + global + set-var proc.int12 int(12) + set-var proc.int5 var(proc.str60,60),div(proc.int12) + + defaults + mode http + timeout connect 100ms + timeout client 1s + timeout server 1s + + listen main-fe + bind "fd@${mainfe}" + + use_backend ifexists_be if { path_beg /ifexists } + use_backend ifnotexists_be if { path_beg /ifnotexists } + use_backend ifempty_be if { path_beg /ifempty } + use_backend ifnotempty_be if { path_beg /ifnotempty } + use_backend ifset_be if { path_beg /ifset } + use_backend ifnotset_be if { path_beg /ifnotset } + use_backend ifgt_be if { path_beg /ifgt } + use_backend iflt_be if { path_beg /iflt } + use_backend combined_be if { path_beg /combined } + use_backend converter_be if { path_beg /converter } + + + backend ifexists_be + server s1 ${s1_addr}:${s1_port} + + # proc scope variables are created during configuration parsing so the + # ifexists condition will always be true for those variables + http-response set-var(proc.ifexists_proc,ifexists) var(proc.int12) + http-response set-var(sess.ifexists_sess,ifexists) var(proc.int5) + http-response set-var(res.ifexists_res,ifexists) str(toto) + + http-response set-header x-var "proc.ifexists=%[var(proc.ifexists_proc)] sess.ifexists=%[var(sess.ifexists_sess)] res.ifexists=%[var(res.ifexists_res)]" + + + backend ifnotexists_be + server s1 ${s1_addr}:${s1_port} + + http-response set-header x-var-init "proc.ifnotexists=%[var(proc.ifnotexists_proc)] sess.ifnotexists=%[var(sess.ifnotexists_sess)] res.ifnotexists=%[var(res.ifnotexists_res)]" + + http-response set-var(proc.ifnotexists_proc,ifnotexists) var(proc.int12) + http-response set-var(sess.ifnotexists_sess,ifnotexists) var(proc.int5) + http-response set-var(res.ifnotexists_res,ifnotexists) str(toto) + + http-response set-header x-var "proc.ifnotexists=%[var(proc.ifnotexists_proc)] sess.ifnotexists=%[var(sess.ifnotexists_sess)] res.ifnotexists=%[var(res.ifnotexists_res)]" + + + backend ifempty_be + server s1 ${s1_addr}:${s1_port} + # init + http-response set-var(proc.ifempty_proc) str(ifempty_proc) + http-response set-var(sess.ifempty_sess) bin(6966656d7074795f73657373) #ifempty_sess + http-response set-var(res.ifempty_res) str(ifempty_res) + http-response set-var(res.ifempty_res_int) int(5) + + http-response set-header x-var-init "proc.ifempty=%[var(proc.ifempty_proc)] sess.ifempty=%[var(sess.ifempty_sess)] res.ifempty=%[var(res.ifempty_res)] res.ifempty_res_int=%[var(res.ifempty_res_int)]" + + # None of those set-var calls should actually change their respective variables + # since none of the samples is empty + http-response set-var(proc.ifempty_proc,ifempty) int(12) + http-response set-var(sess.ifempty_sess,ifempty) bool(false) + http-response set-var(res.ifempty_res,ifempty) bin(746F746F) # "toto" + http-response set-var(res.ifempty_res_int,ifempty) str(toto) + + http-response set-header x-var1 "proc.ifempty=%[var(proc.ifempty_proc)] sess.ifempty=%[var(sess.ifempty_sess)] res.ifempty=%[var(res.ifempty_res)] res.ifempty_res_int=%[var(res.ifempty_res_int)]" + + http-response set-var(proc.ifempty_proc,ifempty) str() + http-response set-var(sess.ifempty_sess,ifempty) str() + http-response set-var(res.ifempty_res,ifempty) str() + http-response set-var(res.ifempty_res_int,ifempty) int(7) # should not work, scalar types are never empty + + http-response set-header x-var2 "proc.ifempty=%[var(proc.ifempty_proc)] sess.ifempty=%[var(sess.ifempty_sess)] res.ifempty=%[var(res.ifempty_res)] res.ifempty_res_int=%[var(res.ifempty_res_int)]" + + + backend ifnotempty_be + server s1 ${s1_addr}:${s1_port} + # init + http-response set-var(proc.ifnotempty_proc) str(ifnotempty_proc) + http-response set-var(sess.ifnotempty_sess) bin(69666e6f74656d7074795f73657373) # "ifnotempty_sess" + http-response set-var(res.ifnotempty_res) str(ifnotempty_res) + http-response set-var(res.ifnotempty_res_int) int(5) + + http-response set-header x-var-init "proc.ifnotempty=%[var(proc.ifnotempty_proc)] sess.ifnotempty=%[var(sess.ifnotempty_sess)] res.ifnotempty=%[var(res.ifnotempty_res)] res.ifnotempty_res_int=%[var(res.ifnotempty_res_int)]" + + # None of those set-var calls should actually change their respective variables + # since none of the samples is not empty + http-response set-var(proc.ifnotempty_proc,ifnotempty) str(toto) + http-response set-var(sess.ifnotempty_sess,ifnotempty) bin(746F746F) # "toto" + http-response set-var(res.ifnotempty_res,ifnotempty) str(tata) + http-response set-var(res.ifnotempty_res_int,ifnotempty) int(6) + + http-response set-header x-var1 "proc.ifnotempty=%[var(proc.ifnotempty_proc)] sess.ifnotempty=%[var(sess.ifnotempty_sess)] res.ifnotempty=%[var(res.ifnotempty_res)] res.ifnotempty_res_int=%[var(res.ifnotempty_res_int)]" + + # The first three variables should remain unchanged. + http-response set-var(proc.ifnotempty_proc,ifnotempty) str() + http-response set-var(sess.ifnotempty_sess,ifnotempty) str() + http-response set-var(res.ifnotempty_res,ifnotempty) str() + http-response set-var(res.ifnotempty_res_int,ifnotempty) int(7) # should not work + + http-response set-header x-var2 "proc.ifnotempty=%[var(proc.ifnotempty_proc)] sess.ifnotempty=%[var(sess.ifnotempty_sess)] res.ifnotempty=%[var(res.ifnotempty_res)] res.ifnotempty_res_int=%[var(res.ifnotempty_res_int)]" + + + backend ifset_be + server s1 ${s1_addr}:${s1_port} + # init + http-response set-var(proc.ifset_proc) str(ifset_proc) + http-response set-var(sess.ifset_sess) bin(69667365745f73657373) # "ifset_sess" + http-response set-var(res.ifset_res) str(ifset_res) + http-response set-var(res.ifset_res_int) int(5) + + http-response set-header x-var-init "proc.ifset=%[var(proc.ifset_proc)] sess.ifset=%[var(sess.ifset_sess)] res.ifset=%[var(res.ifset_res)] res.ifset_res_int=%[var(res.ifset_res_int)]" + + # All those set-var calls should succeed + http-response set-var(proc.ifset_proc,ifset) str(toto) + http-response set-var(sess.ifset_sess,ifset) bin(746F746F) # "toto" + http-response set-var(res.ifset_res,ifset) int(123) + http-response set-var(res.ifset_res_int,ifset) str(azerty) + + http-response set-header x-var1 "proc.ifset=%[var(proc.ifset_proc)] sess.ifset=%[var(sess.ifset_sess)] res.ifset=%[var(res.ifset_res)] res.ifset_res_int=%[var(res.ifset_res_int)]" + + http-response unset-var(proc.ifset_proc) + http-response unset-var(sess.ifset_sess) + http-response unset-var(res.ifset_res) + http-response unset-var(res.ifset_res_int) + + http-response set-header x-var2 "proc.ifset=%[var(proc.ifset_proc)] sess.ifset=%[var(sess.ifset_sess)] res.ifset=%[var(res.ifset_res)] res.ifset_res_int=%[var(res.ifset_res_int)]" + + # None of those set-var calls should succeed + http-response set-var(proc.ifset_proc,ifset) str(toto) + http-response set-var(sess.ifset_sess,ifset) bin(746F746F) # "toto" + http-response set-var(res.ifset_res,ifset) int(123) + http-response set-var(res.ifset_res_int,ifset) str(azerty) + + http-response set-header x-var3 "proc.ifset=%[var(proc.ifset_proc)] sess.ifset=%[var(sess.ifset_sess)] res.ifset=%[var(res.ifset_res)] res.ifset_res_int=%[var(res.ifset_res_int)]" + + + backend ifnotset_be + server s1 ${s1_addr}:${s1_port} + # init + http-response set-var(proc.ifnotset_proc) str(ifnotset_proc) + http-response set-var(sess.ifnotset_sess) bin(69666e6f747365745f73657373) # "ifnotset_sess" + http-response set-var(res.ifnotset_res) str(ifnotset_res) + http-response set-var(res.ifnotset_res_int) int(5) + + http-response set-header x-var-init "proc.ifnotset=%[var(proc.ifnotset_proc)] sess.ifnotset=%[var(sess.ifnotset_sess)] res.ifnotset=%[var(res.ifnotset_res)] res.ifnotset_res_int=%[var(res.ifnotset_res_int)]" + + # None of those set-var calls should succeed + http-response set-var(proc.ifnotset_proc,ifnotset) str(toto) + http-response set-var(sess.ifnotset_sess,ifnotset) bin(746F746F) # "toto" + http-response set-var(res.ifnotset_res,ifnotset) int(123) + http-response set-var(res.ifnotset_res_int,ifnotset) str(azerty) + + http-response set-header x-var1 "proc.ifnotset=%[var(proc.ifnotset_proc)] sess.ifnotset=%[var(sess.ifnotset_sess)] res.ifnotset=%[var(res.ifnotset_res)] res.ifnotset_res_int=%[var(res.ifnotset_res_int)]" + + http-response unset-var(proc.ifnotset_proc) + http-response unset-var(sess.ifnotset_sess) + http-response unset-var(res.ifnotset_res) + http-response unset-var(res.ifnotset_res_int) + + http-response set-header x-var2 "proc.ifnotset=%[var(proc.ifnotset_proc)] sess.ifnotset=%[var(sess.ifnotset_sess)] res.ifnotset=%[var(res.ifnotset_res)] res.ifnotset_res_int=%[var(res.ifnotset_res_int)]" + + # All of those set-var calls should succeed + http-response set-var(proc.ifnotset_proc,ifnotset) str(toto) + http-response set-var(sess.ifnotset_sess,ifnotset) bin(746F746F) # "toto" + http-response set-var(res.ifnotset_res,ifnotset) int(123) + http-response set-var(res.ifnotset_res_int,ifnotset) str(azerty) + + http-response set-header x-var3 "proc.ifnotset=%[var(proc.ifnotset_proc)] sess.ifnotset=%[var(sess.ifnotset_sess)] res.ifnotset=%[var(res.ifnotset_res)] res.ifnotset_res_int=%[var(res.ifnotset_res_int)]" + + backend ifgt_be + server s1 ${s1_addr}:${s1_port} + # init + http-response set-var(proc.ifgt_proc) str(ifgt_proc) + http-response set-var(sess.ifgt_sess) bin(696667745f73657373) # "ifgt_sess" + http-response set-var(res.ifgt_res1) str(ifgt_res) + http-response set-var(res.ifgt_res2) int(5) + http-response set-var(res.ifgt_res_int1) int(5) + http-response set-var(res.ifgt_res_int2) int(5) + + http-response set-header x-var-init "proc.ifgt=%[var(proc.ifgt_proc)] sess.ifgt=%[var(sess.ifgt_sess)] res.ifgt1=%[var(res.ifgt_res1)] res.ifgt2=%[var(res.ifgt_res2)] res.ifgt_res_int1=%[var(res.ifgt_res_int1)] res.ifgt_res_int2=%[var(res.ifgt_res_int2)]" + + # ifgt does not apply on non scalar type so the two following set-var will ignore the condition + http-response set-var(proc.ifgt_proc,ifgt) str(toto) + http-response set-var(sess.ifgt_sess,ifgt) bin(746F746F) # "toto" + # ifgt can only apply when the variable and the sample are both scalar. In this case, the variable was a string so the condition is ignored + http-response set-var(res.ifgt_res1,ifgt) int(55) + # ifgt can only apply when the variable and the sample are both scalar. In this case, the sample is a string so the condition is ignored + http-response set-var(res.ifgt_res2,ifgt) str(text) + http-response set-var(res.ifgt_res_int1,ifgt) int(55) # should not work + http-response set-var(res.ifgt_res_int2,ifgt) int(2) # should work + + http-response set-header x-var1 "proc.ifgt=%[var(proc.ifgt_proc)] sess.ifgt=%[var(sess.ifgt_sess)] res.ifgt1=%[var(res.ifgt_res1)] res.ifgt2=%[var(res.ifgt_res2)] res.ifgt_res_int1=%[var(res.ifgt_res_int1)] res.ifgt_res_int2=%[var(res.ifgt_res_int2)]" + + + backend iflt_be + server s1 ${s1_addr}:${s1_port} + # init + http-response set-var(proc.iflt_proc) str(iflt_proc) + http-response set-var(sess.iflt_sess) bin(69666c745f73657373) # "iflt_sess" + http-response set-var(res.iflt_res1) str(iflt_res) + http-response set-var(res.iflt_res2) int(5) + http-response set-var(res.iflt_res_int1) int(5) + http-response set-var(res.iflt_res_int2) int(5) + + http-response set-header x-var-init "proc.iflt=%[var(proc.iflt_proc)] sess.iflt=%[var(sess.iflt_sess)] res.iflt1=%[var(res.iflt_res1)] res.iflt2=%[var(res.iflt_res2)] res.iflt_res_int1=%[var(res.iflt_res_int1)] res.iflt_res_int2=%[var(res.iflt_res_int2)]" + + # iflt does not apply on non scalar type so the two following set-var will ignore the condition + http-response set-var(proc.iflt_proc,iflt) str(toto) + http-response set-var(sess.iflt_sess,iflt) bin(746F746F) # "toto" + # iflt can only apply when the variable and the sample are both scalar. In this case, the variable was a string so the condition is ignored + http-response set-var(res.iflt_res1,iflt) int(55) + # iflt can only apply when the variable and the sample are both scalar. In this case, the sample is a string so the condition is ignored + http-response set-var(res.iflt_res2,iflt) str(text) + http-response set-var(res.iflt_res_int1,iflt) int(55) # should work + http-response set-var(res.iflt_res_int2,iflt) int(2) # should not work + + http-response set-header x-var1 "proc.iflt=%[var(proc.iflt_proc)] sess.iflt=%[var(sess.iflt_sess)] res.iflt1=%[var(res.iflt_res1)] res.iflt2=%[var(res.iflt_res2)] res.iflt_res_int1=%[var(res.iflt_res_int1)] res.iflt_res_int2=%[var(res.iflt_res_int2)]" + + + # Test multiple conditions at once + backend combined_be + server s1 ${s1_addr}:${s1_port} + # init + http-response set-var(proc.combined_proc) str(combined_proc) + http-response set-var(res.combined_res) int(5) + http-response unset-var(proc.combined_proc) + + http-response set-header x-var-init "proc.combined=%[var(proc.combined_proc)] res.combined=%[var(res.combined_res)]" + + http-response set-var(proc.combined_proc,ifnotset,ifnotempty) str(toto) + http-response set-var(res.combined_res,ifset,iflt) int(55) + + http-response set-header x-var1 "proc.combined=%[var(proc.combined_proc)] res.combined=%[var(res.combined_res)]" + + + # Test the set-var converter + backend converter_be + server s1 ${s1_addr}:${s1_port} + + http-request deny if { req.len,set-var(proc.req_len,ifexists) -m int 0 } + http-request deny if { req.hdr("X-Cust"),set-var(sess.x_cust,ifnotempty,ifnotset),length -m int 0 } + + http-response set-header x-var "proc.req_len=%[var(proc.req_len)] sess.x_cust=%[var(sess.x_cust)]" + +} -start + + +client c1 -connect ${h1_mainfe_sock} { + txreq -url "/ifexists" + rxresp + expect resp.status == 200 + expect resp.http.x-var == "proc.ifexists=12 sess.ifexists= res.ifexists=" +} -run + +client c2 -connect ${h1_mainfe_sock} { + txreq -url "/ifnotexists" + rxresp + expect resp.status == 200 + expect resp.http.x-var-init == "proc.ifnotexists= sess.ifnotexists= res.ifnotexists=" + expect resp.http.x-var == "proc.ifnotexists= sess.ifnotexists=5 res.ifnotexists=toto" +} -run + +client c3 -connect ${h1_mainfe_sock} { + txreq -url "/ifempty" + rxresp + expect resp.status == 200 + expect resp.http.x-var-init == "proc.ifempty=ifempty_proc sess.ifempty=ifempty_sess res.ifempty=ifempty_res res.ifempty_res_int=5" + expect resp.http.x-var1 == "proc.ifempty=ifempty_proc sess.ifempty=ifempty_sess res.ifempty=ifempty_res res.ifempty_res_int=5" + expect resp.http.x-var2 == "proc.ifempty= sess.ifempty= res.ifempty= res.ifempty_res_int=5" +} -run + +client c4 -connect ${h1_mainfe_sock} { + txreq -url "/ifnotempty" + rxresp + expect resp.status == 200 + expect resp.http.x-var-init == "proc.ifnotempty=ifnotempty_proc sess.ifnotempty=ifnotempty_sess res.ifnotempty=ifnotempty_res res.ifnotempty_res_int=5" + expect resp.http.x-var1 == "proc.ifnotempty=toto sess.ifnotempty=toto res.ifnotempty=tata res.ifnotempty_res_int=6" + expect resp.http.x-var2 == "proc.ifnotempty=toto sess.ifnotempty=toto res.ifnotempty=tata res.ifnotempty_res_int=7" +} -run + +client c5 -connect ${h1_mainfe_sock} { + txreq -url "/ifset" + rxresp + expect resp.status == 200 + expect resp.http.x-var-init == "proc.ifset=ifset_proc sess.ifset=ifset_sess res.ifset=ifset_res res.ifset_res_int=5" + expect resp.http.x-var1 == "proc.ifset=toto sess.ifset=toto res.ifset=123 res.ifset_res_int=azerty" + expect resp.http.x-var2 == "proc.ifset= sess.ifset= res.ifset= res.ifset_res_int=" + expect resp.http.x-var3 == "proc.ifset= sess.ifset= res.ifset= res.ifset_res_int=" +} -run + +client c6 -connect ${h1_mainfe_sock} { + txreq -url "/ifnotset" + rxresp + expect resp.status == 200 + expect resp.http.x-var-init == "proc.ifnotset=ifnotset_proc sess.ifnotset=ifnotset_sess res.ifnotset=ifnotset_res res.ifnotset_res_int=5" + expect resp.http.x-var1 == "proc.ifnotset=ifnotset_proc sess.ifnotset=ifnotset_sess res.ifnotset=ifnotset_res res.ifnotset_res_int=5" + expect resp.http.x-var2 == "proc.ifnotset= sess.ifnotset= res.ifnotset= res.ifnotset_res_int=" + expect resp.http.x-var3 == "proc.ifnotset=toto sess.ifnotset=toto res.ifnotset=123 res.ifnotset_res_int=azerty" +} -run + +client c7 -connect ${h1_mainfe_sock} { + txreq -url "/ifgt" + rxresp + expect resp.status == 200 + expect resp.http.x-var-init == "proc.ifgt=ifgt_proc sess.ifgt=ifgt_sess res.ifgt1=ifgt_res res.ifgt2=5 res.ifgt_res_int1=5 res.ifgt_res_int2=5" + expect resp.http.x-var1 == "proc.ifgt=toto sess.ifgt=toto res.ifgt1=55 res.ifgt2=text res.ifgt_res_int1=5 res.ifgt_res_int2=2" +} -run + +client c8 -connect ${h1_mainfe_sock} { + txreq -url "/iflt" + rxresp + expect resp.status == 200 + expect resp.http.x-var-init == "proc.iflt=iflt_proc sess.iflt=iflt_sess res.iflt1=iflt_res res.iflt2=5 res.iflt_res_int1=5 res.iflt_res_int2=5" + expect resp.http.x-var1 == "proc.iflt=toto sess.iflt=toto res.iflt1=55 res.iflt2=text res.iflt_res_int1=55 res.iflt_res_int2=5" +} -run + +client c9 -connect ${h1_mainfe_sock} { + txreq -url "/combined" + rxresp + expect resp.status == 200 + expect resp.http.x-var-init == "proc.combined= res.combined=5" + expect resp.http.x-var1 == "proc.combined=toto res.combined=55" +} -run + +client c10 -connect ${h1_mainfe_sock} { + txreq -url "/converter" -hdr "X-Cust: foobar" + rxresp + expect resp.status == 200 + expect resp.http.x-var == "proc.req_len=67 sess.x_cust=foobar" +} -run diff --git a/reg-tests/sample_fetches/cook.vtc b/reg-tests/sample_fetches/cook.vtc new file mode 100644 index 0000000..e2c1284 --- /dev/null +++ b/reg-tests/sample_fetches/cook.vtc @@ -0,0 +1,37 @@ +varnishtest "cook sample fetch Test" + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp +} -start + +haproxy h1 -conf { + defaults + mode http + + frontend fe + bind "fd@${fe}" + http-request set-var(txn.count) req.cook_cnt() + http-request set-var(txn.val) req.cook_val() + http-request set-var(txn.val_cook2) req.cook_val(cook2) + http-response set-header count %[var(txn.count)] + http-response set-header val %[var(txn.val)] + http-response set-header val_cook2 %[var(txn.val_cook2)] + + default_backend be + + backend be + server srv1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe_sock} { + txreq -url "/" \ + -hdr "cookie: cook1=0; cook2=123; cook3=22" + rxresp + expect resp.status == 200 + expect resp.http.count == "3" + expect resp.http.val == "0" + expect resp.http.val_cook2 == "123" +} -run diff --git a/reg-tests/sample_fetches/hashes.vtc b/reg-tests/sample_fetches/hashes.vtc new file mode 100644 index 0000000..2c2f60d --- /dev/null +++ b/reg-tests/sample_fetches/hashes.vtc @@ -0,0 +1,101 @@ +varnishtest "Hash validity test" + +#REQUIRE_VERSION=2.4 + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp +} -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + + # base64 encoding of \x00\x01\x02...\xFF + http-response set-var(res.key) "str(AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==),b64dec" + + # length (start:0, next:255) + http-response set-header x-len0 "%[var(res.key),length]" + http-response set-header x-len1 "%[var(res.key),bytes(1),length]" + + # text-based encoding + http-response set-header x-hex "%[var(res.key),hex]" + http-response set-header x-b64 "%[var(res.key),base64]" + + # SHA family + http-response set-header x-sha1 "%[var(res.key),sha1,hex]" + #http-response set-header x-sha2 "%[var(res.key),sha2,hex]" + #http-response set-header x-sha2-224 "%[var(res.key),sha2(224),hex]" + #http-response set-header x-sha2-256 "%[var(res.key),sha2(256),hex]" + #http-response set-header x-sha2-384 "%[var(res.key),sha2(384),hex]" + #http-response set-header x-sha2-512 "%[var(res.key),sha2(512),hex]" + + # 32-bit hashes, and their avalanche variants + http-response set-header x-crc32 "%[var(res.key),crc32]" + http-response set-header x-crc32-1 "%[var(res.key),crc32(1)]" + + http-response set-header x-crc32c "%[var(res.key),crc32c]" + http-response set-header x-crc32c-1 "%[var(res.key),crc32c(1)]" + + http-response set-header x-djb2 "%[var(res.key),djb2]" + http-response set-header x-djb2-1 "%[var(res.key),djb2(1)]" + + http-response set-header x-sdbm "%[var(res.key),sdbm]" + http-response set-header x-sdbm-1 "%[var(res.key),sdbm(1)]" + + http-response set-header x-wt6 "%[var(res.key),wt6]" + http-response set-header x-wt6-1 "%[var(res.key),wt6(1)]" + + # 32/64-bit hashes, with seed variant + http-response set-header x-xxh3 "%[var(res.key),xxh3]" + http-response set-header x-xxh3-1 "%[var(res.key),xxh3(1)]" + http-response set-header x-xxh32 "%[var(res.key),xxh32]" + http-response set-header x-xxh32-1 "%[var(res.key),xxh32(1)]" + http-response set-header x-xxh64 "%[var(res.key),xxh64]" + http-response set-header x-xxh64-1 "%[var(res.key),xxh64(1)]" + default_backend be + + backend be + server srv1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe_sock} { + txreq -url "/" + rxresp + expect resp.status == 200 + expect resp.http.x-len0 == "0" + expect resp.http.x-len1 == "255" + expect resp.http.x-hex == "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF" + expect resp.http.x-b64 == "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==" + + expect resp.http.x-sha1 == "4916D6BDB7F78E6803698CAB32D1586EA457DFC8" + #expect resp.http.x-sha2 == "40AFF2E9D2D8922E47AFD4648E6967497158785FBD1DA870E7110266BF944880" + #expect resp.http.x-sha2-224 == "88702E63237824C4EB0D0FCFE41469A462493E8BEB2A75BBE5981734" + #expect resp.http.x-sha2-256 == "40AFF2E9D2D8922E47AFD4648E6967497158785FBD1DA870E7110266BF944880" + #expect resp.http.x-sha2-384 == "FFDAEBFF65ED05CF400F0221C4CCFB4B2104FB6A51F87E40BE6C4309386BFDEC2892E9179B34632331A59592737DB5C5" + #expect resp.http.x-sha2-512 == "1E7B80BC8EDC552C8FEEB2780E111477E5BC70465FAC1A77B29B35980C3F0CE4A036A6C9462036824BD56801E62AF7E9FEBA5C22ED8A5AF877BF7DE117DCAC6D" + expect resp.http.x-crc32 == "688229491" + expect resp.http.x-crc32-1 == "4230317029" + expect resp.http.x-crc32c == "2621708363" + expect resp.http.x-crc32c-1 == "2242979626" + expect resp.http.x-djb2 == "2589693061" + expect resp.http.x-djb2-1 == "600622701" + expect resp.http.x-sdbm == "905707648" + expect resp.http.x-sdbm-1 == "3103804144" + expect resp.http.x-wt6 == "4090277559" + expect resp.http.x-wt6-1 == "1192658767" + expect resp.http.x-xxh3 == "-7779787747613135503" + expect resp.http.x-xxh3-1 == "5930632130106562027" + expect resp.http.x-xxh32 == "1497633363" + expect resp.http.x-xxh32-1 == "1070421674" + expect resp.http.x-xxh64 == "2282408585429094475" + expect resp.http.x-xxh64-1 == "-4689339368900765961" +} -run diff --git a/reg-tests/sample_fetches/so_name.vtc b/reg-tests/sample_fetches/so_name.vtc new file mode 100644 index 0000000..c6211fa --- /dev/null +++ b/reg-tests/sample_fetches/so_name.vtc @@ -0,0 +1,22 @@ +varnishtest "so_name sample fetche Test" + +#REQUIRE_VERSION=2.2 + +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + + frontend fe + bind "fd@${fe}" name foo + http-request return status 200 hdr so-name %[so_name] + +} -start + +client c1 -connect ${h1_fe_sock} { + txreq -url "/" + rxresp + expect resp.status == 200 + expect resp.http.so-name == "foo" +} -run diff --git a/reg-tests/sample_fetches/srv_name.vtc b/reg-tests/sample_fetches/srv_name.vtc new file mode 100644 index 0000000..900957e --- /dev/null +++ b/reg-tests/sample_fetches/srv_name.vtc @@ -0,0 +1,46 @@ +varnishtest "srv_name sample fetche Test" + +#REQUIRE_VERSION=2.1 + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp +} -start + +server s2 { + rxreq + txresp +} -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + http-response set-header srv-id "%[srv_id]" + http-response set-header srv-name "%[srv_name]" + default_backend be + + backend be + server srv1 ${s1_addr}:${s1_port} + server srv2 ${s2_addr}:${s2_port} +} -start + +client c1 -connect ${h1_fe_sock} { + txreq -url "/" + rxresp + expect resp.status == 200 + expect resp.http.srv-id == "1" + expect resp.http.srv-name == "srv1" + txreq -url "/" + rxresp + expect resp.status == 200 + expect resp.http.srv-id == "2" + expect resp.http.srv-name == "srv2" +} -run diff --git a/reg-tests/sample_fetches/ubase64.vtc b/reg-tests/sample_fetches/ubase64.vtc new file mode 100644 index 0000000..8e47d86 --- /dev/null +++ b/reg-tests/sample_fetches/ubase64.vtc @@ -0,0 +1,57 @@ +varnishtest "ub64dec sample fetche Test" + +#REQUIRE_VERSION=2.4 + +feature ignore_unknown_macro + +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 + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + acl input hdr(encode) -m found + http-request return content-type text/plain hdr encode %[hdr(encode),ub64enc] hdr decode %[hdr(decode),ub64dec] if input + http-request return content-type text/plain hdr encode %[bin(14fb9c03d97f12d97e),ub64enc] hdr decode %[str(FPucA9l_Etl-),ub64dec,hex,lower] if !input + +} -start + +client c1 -connect ${h1_fe_sock} { + txreq -hdr "encode: f" -hdr "decode: Zg" + rxresp + expect resp.http.encode == "Zg" + expect resp.http.decode == "f" + txreq -hdr "encode: fo" -hdr "decode: Zm8" + rxresp + expect resp.http.encode == "Zm8" + expect resp.http.decode == "fo" + txreq -hdr "encode: foo" -hdr "decode: Zm9v" + rxresp + expect resp.http.encode == "Zm9v" + expect resp.http.decode == "foo" + txreq -hdr "encode: foob" -hdr "decode: Zm9vYg" + rxresp + expect resp.http.encode == "Zm9vYg" + expect resp.http.decode == "foob" + txreq -hdr "encode: fooba" -hdr "decode: Zm9vYmE" + rxresp + expect resp.http.encode == "Zm9vYmE" + expect resp.http.decode == "fooba" + txreq -hdr "encode: foobar" -hdr "decode: Zm9vYmFy" + rxresp + expect resp.http.encode == "Zm9vYmFy" + expect resp.http.decode == "foobar" + txreq + rxresp + expect resp.http.encode == "FPucA9l_Etl-" + expect resp.http.decode == "14fb9c03d97f12d97e" +} -run diff --git a/reg-tests/sample_fetches/vars.vtc b/reg-tests/sample_fetches/vars.vtc new file mode 100644 index 0000000..5144e9f --- /dev/null +++ b/reg-tests/sample_fetches/vars.vtc @@ -0,0 +1,84 @@ +varnishtest "Test a few set-var() in global, tcp and http rule sets, at different scopes" +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev5)'" + +feature ignore_unknown_macro + +haproxy h1 -conf { + global + # note below, str60 is purposely not defined so that the default is used + set-var proc.int12 int(12) + set-var proc.int5 var(proc.str60,60),div(proc.int12) + set-var proc.str1 str("this is") + set-var proc.str2 str("a string") + set-var proc.str var(proc.str1) + set-var-fmt proc.str "%[var(proc.str)] a string" + set-var proc.uuid uuid() + + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe1}" + tcp-request session set-var-fmt(sess.str3) "%[var(proc.str1)] %[var(proc.str2)]" + tcp-request session set-var(sess.int5) var(proc.int5) + tcp-request session set-var(proc.int5) var(proc.int5),add(sess.int5) ## proc. becomes 10 + tcp-request content set-var-fmt(req.str4) "%[var(sess.str3),regsub(is a,is also a)]" + http-request set-var-fmt(txn.str5) "%[var(req.str4)]" + http-request set-var(req.int5) var(sess.int5) + http-request set-var(sess.int5) var(sess.int5),add(req.int5) ## sess. becomes 10 first time, then 15... + http-request return status 200 hdr x-var "proc=%[var(proc.int5)] sess=%[var(sess.int5)] req=%[var(req.int5)] str=%[var(proc.str)] str5=%[var(txn.str5)] uuid=%[var(proc.uuid)]" +} -start + +haproxy h1 -cli { + send "get var proc.int5" + expect ~ "^proc.int5: type=sint value=<5>$" +} + +client c1 -connect ${h1_fe1_sock} { + txreq -req GET -url /req1_1 + rxresp + expect resp.status == 200 + expect resp.http.x-var ~ "proc=10 sess=10 req=5 str=this is a string str5=this is also a string uuid=[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*" + + txreq -req GET -url /req1_2 + rxresp + expect resp.status == 200 + expect resp.http.x-var ~ "proc=10 sess=20 req=10 str=this is a string str5=this is also a string uuid=[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*" +} -run + +haproxy h1 -cli { + send "get var proc.int5" + expect ~ "^proc.int5: type=sint value=<10>$" +} + +client c2 -connect ${h1_fe1_sock} { + txreq -req GET -url /req2_1 + rxresp + expect resp.status == 200 + expect resp.http.x-var ~ "proc=20 sess=20 req=10 str=this is a string str5=this is also a string uuid=[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*" + + txreq -req GET -url /req2_2 + rxresp + expect resp.status == 200 + expect resp.http.x-var ~ "proc=20 sess=40 req=20 str=this is a string str5=this is also a string uuid=[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*" +} -run + +haproxy h1 -cli { + send "get var proc.int5" + expect ~ "^proc.int5: type=sint value=<20>$" +} + +haproxy h1 -cli { + send "experimental-mode on; set var proc.str str(updating); set var proc.str fmt %[var(proc.str),regsub(ing,ed)]" + expect ~ .* +} + +client c3 -connect ${h1_fe1_sock} { + txreq -req GET -url /req3_1 + rxresp + expect resp.status == 200 + expect resp.http.x-var ~ "proc=40 sess=40 req=20 str=updated str5=this is also a string uuid=[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*" +} -run diff --git a/reg-tests/seamless-reload/abns_socket.vtc b/reg-tests/seamless-reload/abns_socket.vtc new file mode 100644 index 0000000..ce1b156 --- /dev/null +++ b/reg-tests/seamless-reload/abns_socket.vtc @@ -0,0 +1,53 @@ +# commit b4dd15b +# BUG/MINOR: unix: Make sure we can transfer abns sockets on seamless reload. +# +# When checking if a socket we got from the parent is suitable for a listener, +# we just checked that the path matched sockname.tmp, however this is +# unsuitable for abns sockets, where we don't have to create a temporary +# file and rename it later. +# To detect that, check that the first character of the sun_path is 0 for +# both, and if so, that &sun_path[1] is the same too. +# +# Note: there are some tricks here. One of them is that we must not bind the +# same abns address to multiple processes that may run in parallel. Since +# vtest cannot provide abns sockets, we're instead concatenating the number +# of the listening port that vtest allocated for another frontend to the abns +# path, which guarantees to make them unique in the system. + +varnishtest "Seamless reload issue with abns sockets" +feature ignore_unknown_macro + +# abns@ sockets are not available on freebsd +#EXCLUDE_TARGETS=freebsd,osx,generic +#REGTEST_TYPE=broken + +haproxy h1 -W -conf { + global + stats socket "${tmpdir}/h1/stats" level admin expose-fd listeners + + defaults + mode http + log global + option httplog + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen testme + bind "fd@${testme}" + server test_abns_server abns@wpproc1_${h1_testme_port} send-proxy-v2 + + frontend test_abns + bind abns@wpproc1_${h1_testme_port} accept-proxy + http-request deny deny_status 200 +} -start + +shell { + kill -USR2 $(cat "${tmpdir}/h1/pid") +} + +client c1 -connect ${h1_testme_sock} { + txreq -url "/" + rxresp +} -repeat 50 -run + diff --git a/reg-tests/server/cli_add_check_server.vtc b/reg-tests/server/cli_add_check_server.vtc new file mode 100644 index 0000000..c63710c --- /dev/null +++ b/reg-tests/server/cli_add_check_server.vtc @@ -0,0 +1,161 @@ +varnishtest "Add/Delete server via cli with check support" + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev3)'" +feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL)'" +feature ignore_unknown_macro + +barrier b1 cond 2 -cyclic +barrier b2 cond 2 -cyclic + +server s1 { + rxreq + txresp +} -start + +server s2 { +} -start + +# used for agent checks +server s3 { + recv 5 + send "ready up\n" + barrier b2 sync +} -start + +syslog S1 -level notice { + recv + expect ~ ".*Server be1/s1 is UP/READY \\(leaving forced maintenance\\)." + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/s1 succeeded.+reason: Layer7 check passed, code: 200, check duration: [[:digit:]]+ms.+status: 1/1 UP" + + barrier b1 sync + + recv + expect ~ ".*Server be1/s2 is UP/READY \\(leaving forced maintenance\\)." + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be1/s2 failed.+reason: Layer7 timeout, check duration: [[:digit:]]+ms.+status: 0/1 DOWN" + + barrier b1 sync + + recv + expect ~ ".*Server be1/s2 was DOWN and now enters maintenance." + + recv + expect ~ ".*Server be1/s3 is UP/READY \\(leaving forced maintenance\\)." + + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Agent check for server be1/s3 succeeded.+reason: Layer7 check passed, code: 0, info: \"via agent : up\", check duration: [[:digit:]]+ms.+status: 1/1 UP" + + barrier b1 sync + barrier b2 sync + + recv + expect ~ ".*Server be1/s4 is UP/READY \\(leaving forced maintenance\\)." + recv + expect ~ "Health check for server be1/s4 failed" + + barrier b1 sync + + recv + expect ~ ".*Server be1/s5 is UP/READY \\(leaving forced maintenance\\)." + recv + expect ~ "Health check for server be1/s5 succeeded." +} -start + +haproxy h1 -conf { + global + stats socket "${tmpdir}/h1/stats" level admin + + backend be1 + option log-health-checks + option httpchk GET / + log ${S1_addr}:${S1_port} daemon + + frontend fe-proxy + mode http + bind "fd@${hapsrv}" accept-proxy + http-request return status 200 +} -start + +# check on a functional server +haproxy h1 -cli { + send "add server be1/s1 ${s1_addr}:${s1_port} check inter 200ms rise 1 fall 1" + expect ~ "New server registered." + + send "enable server be1/s1" + expect ~ ".*" + send "enable health be1/s1" + expect ~ ".*" + + barrier b1 sync + + send "disable server be1/s1" + expect ~ ".*" + + send "del server be1/s1" + expect ~ "Server deleted." +} + +server s2 -break + +# check on a disabled server +haproxy h1 -cli { + send "add server be1/s2 ${s2_addr}:${s2_port} check inter 200ms rise 1 fall 1" + expect ~ "New server registered." + + send "enable server be1/s2" + expect ~ ".*" + send "enable health be1/s2" + expect ~ ".*" + + barrier b1 sync + + send "disable server be1/s2" + expect ~ ".*" + + send "del server be1/s2" + expect ~ "Server deleted." +} + +# agent check +haproxy h1 -cli { + send "add server be1/s3 ${s1_addr}:${s1_port} agent-check agent-addr ${s3_addr} agent-port ${s3_port} agent-send 'hello' agent-inter 200ms rise 1 fall 1" + expect ~ "New server registered." + + send "enable agent be1/s3" + expect ~ ".*" + + barrier b1 sync + + send "disable agent be1/s3; disable server be1/s3" + expect ~ ".*" + + send "del server be1/s3" + expect ~ "Server deleted." +} + +# check PROXY protocol interaction with checks +haproxy h1 -cli { + # no explicit check-send-proxy + # The health check should failed. + send "add server be1/s4 ${h1_hapsrv_addr}:${h1_hapsrv_port} send-proxy check rise 1 fall 1" + expect ~ "New server registered." + + send "enable server be1/s4" + expect ~ ".*" + send "enable health be1/s4" + expect ~ ".*" + + barrier b1 sync + + # explicit check-send-proxy : health check should succeeded + send "add server be1/s5 ${h1_hapsrv_addr}:${h1_hapsrv_port} send-proxy check rise 1 fall 1 check-send-proxy" + expect ~ "New server registered." + + send "enable server be1/s5" + expect ~ ".*" + send "enable health be1/s5" + expect ~ ".*" +} + +syslog S1 -wait diff --git a/reg-tests/server/cli_add_server.vtc b/reg-tests/server/cli_add_server.vtc new file mode 100644 index 0000000..8c29305 --- /dev/null +++ b/reg-tests/server/cli_add_server.vtc @@ -0,0 +1,87 @@ +varnishtest "Add server via cli" + +feature ignore_unknown_macro + +#REQUIRE_VERSION=2.4 + +server s1 { + rxreq + txresp +} -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${feS}" + default_backend test + + backend test + balance random + + backend other + balance static-rr + + backend other2 + balance random + mode tcp +} -start + +client c1 -connect ${h1_feS_sock} { + txreq + rxresp + expect resp.status == 503 +} -run + +haproxy h1 -cli { + # non existent backend + send "add server foo/s1 ${s1_addr}:${s1_port}" + expect ~ "No such backend." + + # missing address + send "add server test/s1" + expect ~ "'server' expects <name> and <addr>\\[:<port>\\] as arguments." + + # invalid load-balancing algo + send "add server other/s1 ${s1_addr}:${s1_port}" + expect ~ "Backend must use a dynamic load balancing to support dynamic servers." + + # invalid mux proto + send "add server other2/s1 ${s1_addr}:${s1_port} proto h2" + expect ~ "MUX protocol is not usable for server." + + # valid command + send "add server test/s1 ${s1_addr}:${s1_port}" + expect ~ "New server registered." + + # duplicate server + send "add server test/s1 ${s1_addr}:${s1_port}" + expect ~ "Already exists a server with the same name in backend." + + # valid command + # specify the proto, it should be accepted for this backend + send "add server test/s2 ${s1_addr}:${s1_port} proto h2" + expect ~ "New server registered." +} + +# dynamic servers are created on MAINT mode and should not be available at first +client c2 -connect ${h1_feS_sock} { + txreq + rxresp + expect resp.status == 503 +} -run + +haproxy h1 -cli { + send "enable server test/s1" + expect ~ ".*" +} + +client c3 -connect ${h1_feS_sock} { + txreq + rxresp + expect resp.status == 200 +} -run diff --git a/reg-tests/server/cli_add_ssl_server.vtc b/reg-tests/server/cli_add_ssl_server.vtc new file mode 100644 index 0000000..95caf3f --- /dev/null +++ b/reg-tests/server/cli_add_ssl_server.vtc @@ -0,0 +1,110 @@ +varnishtest "Add server via cli with SSL activated" + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL)'" +feature cmd "command -v socat" +feature ignore_unknown_macro + +barrier b1 cond 2 -cyclic + +syslog S1 -level notice { + recv + expect ~ ".*Server li-ssl/s1 is UP/READY \\(leaving forced maintenance\\)." + recv + expect ~ ".*Server li-ssl/s2 is UP/READY \\(leaving forced maintenance\\)." + recv + expect ~ "Health check for server li-ssl/s2 failed" + + barrier b1 sync + + recv + expect ~ ".*Server li-ssl/s3 is UP/READY \\(leaving forced maintenance\\)." + recv + expect ~ "Health check for server li-ssl/s3 succeeded." +} -start + +haproxy h1 -conf { + global + stats socket "${tmpdir}/h1/stats" level admin + + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + option log-health-checks + option httpchk GET / + + # proxy to attach a ssl server + listen li-ssl + bind "fd@${feSsl}" + balance random + log ${S1_addr}:${S1_port} daemon + + # frontend used to respond to ssl connection + frontend fe-ssl-term + bind "fd@${feSslTerm}" ssl crt ${testdir}/common.pem + http-request return status 200 +} -start + +### SSL SUPPORT +# 1. first create a ca-file using CLI +# 2. create an SSL server and use it + +client c1 -connect ${h1_feSsl_sock} { + txreq + rxresp + expect resp.status == 503 +} -run + +shell { + echo "new ssl ca-file common.pem" | socat "${tmpdir}/h1/stats" - + printf "set ssl ca-file common.pem <<\n$(cat ${testdir}/common.pem)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl ca-file common.pem" | socat "${tmpdir}/h1/stats" - +} -run + +haproxy h1 -cli { + send "show ssl ca-file common.pem" + expect ~ ".*SHA1 FingerPrint: 9A6418E498C43EDBCF5DD3C4C6FCD1EE0D7A946D" +} + +haproxy h1 -cli { + # non existent backend + send "add server li-ssl/s1 ${h1_feSslTerm_addr}:${h1_feSslTerm_port} ssl ca-file common.pem verify none" + expect ~ "New server registered." + + send "enable server li-ssl/s1" + expect ~ ".*" +} + +client c2 -connect ${h1_feSsl_sock} { + txreq + rxresp + expect resp.status == 200 +} -run + +# test interaction between SSL and checks for dynamic servers +haproxy h1 -cli { + # no explicit check-ssl + # The health check should failed. + send "add server li-ssl/s2 ${h1_feSslTerm_addr}:${h1_feSslTerm_port} ssl verify none check" + expect ~ "New server registered." + + send "enable server li-ssl/s2" + expect ~ ".*" + send "enable health li-ssl/s2" + expect ~ ".*" + + barrier b1 sync + + # explicit check-ssl : health check should succeeded + send "add server li-ssl/s3 ${h1_feSslTerm_addr}:${h1_feSslTerm_port} ssl verify none check check-ssl" + expect ~ "New server registered." + + send "enable server li-ssl/s3" + expect ~ ".*" + send "enable health li-ssl/s3" + expect ~ ".*" +} + +syslog S1 -wait diff --git a/reg-tests/server/cli_add_track_server.vtc b/reg-tests/server/cli_add_track_server.vtc new file mode 100644 index 0000000..318f236 --- /dev/null +++ b/reg-tests/server/cli_add_track_server.vtc @@ -0,0 +1,242 @@ +varnishtest "Add/Delete server via cli with track support" + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL)'" +feature ignore_unknown_macro + + +# just use to provide s1_{addr,port} macros +server s1 { +} + + +# scenario 1 +# -> 3 dynamic servers, delete the first one +syslog S1 { + recv notice + expect ~ "Server be1/s1 is UP/READY" + recv notice + expect ~ "Server be1/s2 is UP/READY" + recv notice + expect ~ "Server be1/s3 is UP/READY" + + recv alert + expect ~ "Server be1/srv is going DOWN for maintenance." + recv alert + expect ~ "Server be1/s3 is going DOWN for maintenance." + recv alert + expect ~ "Server be1/s2 is going DOWN for maintenance." + recv alert + expect ~ "Server be1/s1 is going DOWN for maintenance." + + recv notice + expect ~ "Server be1/srv is UP/READY" + recv notice + expect ~ "Server be1/s3 is UP/READY" + recv notice + expect ~ "Server be1/s2 is UP/READY" +} -start + +# scenario 2 +# -> 3 dynamic servers, delete the middle one +syslog S2 { + recv notice + expect ~ "Server be2/s1 is UP/READY" + recv notice + expect ~ "Server be2/s2 is UP/READY" + recv notice + expect ~ "Server be2/s3 is UP/READY" + + recv alert + expect ~ "Server be2/srv is going DOWN for maintenance." + recv alert + expect ~ "Server be2/s3 is going DOWN for maintenance." + recv alert + expect ~ "Server be2/s2 is going DOWN for maintenance." + recv alert + expect ~ "Server be2/s1 is going DOWN for maintenance." + + recv notice + expect ~ "Server be2/srv is UP/READY" + recv notice + expect ~ "Server be2/s3 is UP/READY" + recv notice + expect ~ "Server be2/s1 is UP/READY" +} -start + +# scenario 3 +# -> 3 dynamic servers, delete all of them +syslog S3 { + recv notice + expect ~ "Server be3/s1 is UP/READY" + recv notice + expect ~ "Server be3/s2 is UP/READY" + recv notice + expect ~ "Server be3/s3 is UP/READY" + + recv alert + expect ~ "Server be3/s1 is going DOWN for maintenance." + recv alert + expect ~ "Server be3/s3 is going DOWN for maintenance." + recv alert + expect ~ "Server be3/s2 is going DOWN for maintenance." + + recv alert + expect ~ "Server be3/srv is going DOWN for maintenance." + + recv notice + expect ~ "Server be3/srv is UP/READY" +} -start + + +haproxy h1 -conf { + global + stats socket "${tmpdir}/h1/stats" level admin + + backend be_check + server srv_check ${s1_addr}:${s1_port} check + server srv_no_check ${s1_addr}:${s1_port} + + backend be1 + log ${S1_addr}:${S1_port} daemon + server srv ${s1_addr}:${s1_port} check + + backend be2 + log ${S2_addr}:${S2_port} daemon + server srv ${s1_addr}:${s1_port} check + + backend be3 + log ${S3_addr}:${S3_port} daemon + server srv ${s1_addr}:${s1_port} check +} -start + + +### +# check the support of the 'track' keyword on 'add server' CLI command. +# rejection must happen if track on a non-checked or a dynamic server +### +haproxy h1 -cli { + # invalid command: track on a non-checked server + send "add server be_check/s1 ${s1_addr}:${s1_port} track be_check/srv_no_check" + expect ~ "unable to use be_check/srv_no_check for tracking as it does not have any check nor agent enabled." + + # valid track usage + send "add server be_check/s1 ${s1_addr}:${s1_port} track be_check/srv_check" + expect ~ "New server registered." + + # invalid command: track on a dynamic server + send "add server be_check/s3 ${s1_addr}:${s1_port} track be_check/s1" + expect ~ "unable to use be_check/s1 for tracking as it is a dynamic server." +} + +### +# scenario 1 +# +# Add 3 dynamic servers with tracking on be1/srv +# Disable be1/srv, S1 should report all servers DOWN +# Delete the first dynamic server, enable be1/srv, S1 should report s1 and s3 UP +#### +haproxy h1 -cli { + send "add server be1/s1 ${s1_addr}:${s1_port} track be1/srv" + expect ~ "New server registered." + send "enable server be1/s1" + expect ~ ".*" + + send "add server be1/s2 ${s1_addr}:${s1_port} track be1/srv" + expect ~ "New server registered." + send "enable server be1/s2" + expect ~ ".*" + + send "add server be1/s3 ${s1_addr}:${s1_port} track be1/srv" + expect ~ "New server registered." + send "enable server be1/s3" + expect ~ ".*" + + send "disable server be1/srv" + expect ~ ".*" + + send "del server be1/s1" + expect ~ "Server deleted." + + send "enable server be1/srv" + expect ~ ".*" +} + +### +# scenario 2 +# +# Add 3 dynamic servers with tracking on be2/srv +# Disable be2/srv, S3 should report all servers DOWN +# Delete the second dynamic server, enable be2/srv, S2 should report s2 and s3 UP +#### +haproxy h1 -cli { + send "add server be2/s1 ${s1_addr}:${s1_port} track be2/srv" + expect ~ "New server registered." + send "enable server be2/s1" + expect ~ ".*" + + send "add server be2/s2 ${s1_addr}:${s1_port} track be2/srv" + expect ~ "New server registered." + send "enable server be2/s2" + expect ~ ".*" + + send "add server be2/s3 ${s1_addr}:${s1_port} track be2/srv" + expect ~ "New server registered." + send "enable server be2/s3" + expect ~ ".*" + + send "disable server be2/srv" + expect ~ ".*" + + send "del server be2/s2" + expect ~ "Server deleted." + + send "enable server be2/srv" + expect ~ ".*" +} + +### +# scenario 3 +# +# Add 3 dynamic servers with tracking on be3/srv +# Delete all of them, disable/enable be3/srv, only be3/srv should be reported +# as DOWN/UP. +#### +haproxy h1 -cli { + # create server 1, track on be3/srv + send "add server be3/s1 ${s1_addr}:${s1_port} track be3/srv" + expect ~ "New server registered." + send "enable server be3/s1" + expect ~ ".*" + + # create server 2, track on be3/srv + send "add server be3/s2 ${s1_addr}:${s1_port} track be3/srv" + expect ~ "New server registered." + send "enable server be3/s2" + expect ~ ".*" + + # create server 3, track on be3/srv + send "add server be3/s3 ${s1_addr}:${s1_port} track be3/srv" + expect ~ "New server registered." + send "enable server be3/s3" + expect ~ ".*" + + # delete all dynamic servers + send "disable server be3/s1; del server be3/s1" + expect ~ "Server deleted." + send "disable server be3/s3; del server be3/s3" + expect ~ "Server deleted." + send "disable server be3/s2; del server be3/s2" + expect ~ "Server deleted." + + # disable / enable the static server + send "disable server be3/srv" + expect ~ ".*" + send "enable server be3/srv" + expect ~ ".*" +} + + +syslog S1 -wait +syslog S2 -wait +syslog S3 -wait diff --git a/reg-tests/server/cli_delete_dynamic_server.vtc b/reg-tests/server/cli_delete_dynamic_server.vtc new file mode 100644 index 0000000..e667641 --- /dev/null +++ b/reg-tests/server/cli_delete_dynamic_server.vtc @@ -0,0 +1,94 @@ +# This script is to test the proper behavior with dynamic servers insertion and +# deletion, in particular with the load-balancing of requests. +# +varnishtest "Delete server via cli" + +feature ignore_unknown_macro + +#REQUIRE_VERSION=2.4 + +# static server +server s1 -repeat 3 { + rxreq + txresp \ + -body "resp from s1" +} -start + +# use as a dynamic server, added then deleted via CLI +server s2 -repeat 3 { + rxreq + txresp \ + -body "resp from s2" +} -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${feS}" + default_backend test + + backend test + server s1 ${s1_addr}:${s1_port} +} -start + +# add a new dynamic server to be able to delete it then +haproxy h1 -cli { + # add a dynamic server and enable it + send "add server test/s2 ${s2_addr}:${s2_port}" + expect ~ "New server registered." + + send "enable server test/s2" + expect ~ ".*" +} + +haproxy h1 -cli { + # non existent backend + send "del server foo/s1" + expect ~ "No such backend." + + # non existent server + send "del server test/other" + expect ~ "No such server." +} + +# first check that both servers are active +client c1 -connect ${h1_feS_sock} { + txreq + rxresp + expect resp.body == "resp from s1" + + txreq + rxresp + expect resp.body == "resp from s2" +} -run + +# delete the dynamic server +haproxy h1 -cli { + # server not in maintenance mode + send "del server test/s2" + expect ~ "Only servers in maintenance mode can be deleted." + + send "disable server test/s2" + expect ~ ".*" + + # valid command + send "del server test/s2" + expect ~ "Server deleted." +} + +# now check that only the first server is used +client c2 -connect ${h1_feS_sock} { + txreq + rxresp + expect resp.body == "resp from s1" + + txreq + rxresp + expect resp.body == "resp from s1" +} -run + diff --git a/reg-tests/server/cli_delete_server.vtc b/reg-tests/server/cli_delete_server.vtc new file mode 100644 index 0000000..61d241c --- /dev/null +++ b/reg-tests/server/cli_delete_server.vtc @@ -0,0 +1,60 @@ +# This script is to test the ability to remove servers, unless they are +# referenced by some elements from the configuration. +# +varnishtest "Delete server via cli" + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${feS}" + acl s1_full srv_sess_rate(test/s1) gt 50 + default_backend test + + backend test + use-server s3 unless { always_false } + server s1 ${s1_addr}:${s1_port} # referenced in ACL + server s2 ${s1_addr}:${s1_port} check # referenced in track + server s3 ${s1_addr}:${s1_port} track s2 # referenced in use-server + server s4 ${s1_addr}:${s1_port} # removable server +} -start + +haproxy h1 -cli { + # non existent backend + send "del server foo/s1" + expect ~ "No such backend." + + # non existent server + send "del server test/other" + expect ~ "No such server." + + # server referenced in ACL + send "del server test/s1" + expect ~ "This server cannot be removed at runtime due to other configuration elements pointing to it." + + # tracked server + send "del server test/s2" + expect ~ "This server cannot be removed at runtime due to other configuration elements pointing to it." + + # tracked server + send "del server test/s3" + expect ~ "This server cannot be removed at runtime due to other configuration elements pointing to it." + + # server in running mode + send "del server test/s4" + expect ~ "Only servers in maintenance mode can be deleted." + + send "disable server test/s4" + expect ~ ".*" + + # valid command + send "del server test/s4" + expect ~ "Server deleted." +} diff --git a/reg-tests/server/cli_delete_server_lua.vtc b/reg-tests/server/cli_delete_server_lua.vtc new file mode 100644 index 0000000..396cd21 --- /dev/null +++ b/reg-tests/server/cli_delete_server_lua.vtc @@ -0,0 +1,43 @@ +# This script is to check that servers that are referenced by a lua script +# cannot be removed at runtime. +varnishtest "Delete lua server via cli" + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature cmd "$HAPROXY_PROGRAM -cc 'feature(LUA)'" +feature ignore_unknown_macro + +server s1 { + rxreq + txresp +} -start + +haproxy h1 -conf { + global + lua-load ${testdir}/get_srv_stats.lua + + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${feS}" + default_backend test + + backend test + http-request add-header s1-stats %[lua.get_srv_stats(s1)] + server s1 ${s1_addr}:${s1_port} # referenced in lua script +} -start + +# make a request to force the execution of the lua script which references a +# server +client c1 -connect ${h1_feS_sock} { + txreq + rxresp +} -run + +haproxy h1 -cli { + send "experimental-mode on; del server test/s1" + expect ~ "This server cannot be removed at runtime due to other configuration elements pointing to it." +} diff --git a/reg-tests/server/cli_set_fdqn.vtc b/reg-tests/server/cli_set_fdqn.vtc new file mode 100644 index 0000000..86f32b6 --- /dev/null +++ b/reg-tests/server/cli_set_fdqn.vtc @@ -0,0 +1,32 @@ +varnishtest "Set server FQDN via CLI crash" + +feature ignore_unknown_macro + +# for "set server <srv> fqdn" +#REGTEST_TYPE=bug + +# Do nothing. Is there only to create s1_* macros +server s1 { +} -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend myfrontend + bind "fd@${my_fe}" + default_backend test + + backend test + server www1 ${s1_addr}:${s1_port} +} -start + +haproxy h1 -cli { + send "set server test/www1 fqdn foo.fqdn" + expect ~ "set server <b>/<s> fqdn failed because no resolution is configured." + send "show servers state test" + expect ~ "test 1 www1 ${s1_addr} .* - ${s1_port}" +} -wait diff --git a/reg-tests/server/cli_set_ssl.vtc b/reg-tests/server/cli_set_ssl.vtc new file mode 100644 index 0000000..fa6fe68 --- /dev/null +++ b/reg-tests/server/cli_set_ssl.vtc @@ -0,0 +1,60 @@ +varnishtest "Set server ssl via CLI" + +feature ignore_unknown_macro + +# for "set server <srv> ssl" +#REQUIRE_VERSION=2.4 +#REGTEST_TYPE=devel +#REQUIRE_OPTIONS=OPENSSL + +# Do nothing. Is there only to create s1_* macros +server s1 { +} -start + +haproxy h1 -conf { + global + ssl-server-verify none + + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend myfrontend + bind "fd@${my_fe}" + default_backend test0 + + backend test0 + server www0 ${s1_addr}:${s1_port} no-ssl + default-server ssl + server www1 ${s1_addr}:${s1_port} no-ssl + + backend test1 + server www0 ${s1_addr}:${s1_port} no-ssl +} -start + +haproxy h1 -cli { + # supported case + send "show servers state test0" + expect ~ "test0 2 www1 ${s1_addr} .* - ${s1_port} - -1" + send "set server test0/www1 ssl on" + expect ~ "server ssl setting updated" + send "show servers state test0" + expect ~ "test0 2 www1 ${s1_addr} .* - ${s1_port} - 1" + send "set server test0/www1 ssl off" + expect ~ "server ssl setting updated" + send "show servers state test0" + expect ~ "test0 2 www1 ${s1_addr} .* - ${s1_port} - 0" + + # unsupported cases + send "show servers state test0" + expect ~ "test0 1 www0 ${s1_addr} .* - ${s1_port} - -1" + send "set server test0/www0 ssl on" + expect ~ "'set server <srv> ssl' cannot be set" + + send "show servers state test1" + expect ~ "test1 1 www0 ${s1_addr} .* - ${s1_port} - -1" + send "set server test1/www0 ssl on" + expect ~ "'set server <srv> ssl' cannot be set" +} -wait diff --git a/reg-tests/server/common.pem b/reg-tests/server/common.pem new file mode 120000 index 0000000..a4433d5 --- /dev/null +++ b/reg-tests/server/common.pem @@ -0,0 +1 @@ +../ssl/common.pem
\ No newline at end of file diff --git a/reg-tests/server/get_srv_stats.lua b/reg-tests/server/get_srv_stats.lua new file mode 100644 index 0000000..105b954 --- /dev/null +++ b/reg-tests/server/get_srv_stats.lua @@ -0,0 +1,11 @@ +local function lua_get_srv_stats(txn, name) + for _, backend in pairs(core.backends) do + for _, server in pairs(backend.servers) do + if server.name == name then + return server:get_stats() + end + end + end +end + +core.register_fetches('get_srv_stats', lua_get_srv_stats) diff --git a/reg-tests/spoe/wrong_init.vtc b/reg-tests/spoe/wrong_init.vtc new file mode 100644 index 0000000..152622c --- /dev/null +++ b/reg-tests/spoe/wrong_init.vtc @@ -0,0 +1,22 @@ +# commit 84c844eb12b250aa86f2aadaff77c42dfc3cb619 +# BUG/MINOR: spoe: Initialize variables used during conf parsing before any check +# +# Some initializations must be done at the beginning of parse_spoe_flt to avoid +# segmentation fault when first errors are caught, when the "filter spoe" line is +# parsed. + +#REGTEST_TYPE=bug + +varnishtest "SPOE bug: missing configuration file" + +feature ignore_unknown_macro + +haproxy h1 -conf-BAD {} { + defaults + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend my-front + filter spoe +} diff --git a/reg-tests/ssl/README b/reg-tests/ssl/README new file mode 100644 index 0000000..f2fc534 --- /dev/null +++ b/reg-tests/ssl/README @@ -0,0 +1,2 @@ +File list: + - common.pem: PEM file which may be used by most of the VTC files. diff --git a/reg-tests/ssl/add_ssl_crt-list.vtc b/reg-tests/ssl/add_ssl_crt-list.vtc new file mode 100644 index 0000000..e62ac48 --- /dev/null +++ b/reg-tests/ssl/add_ssl_crt-list.vtc @@ -0,0 +1,114 @@ +#REGTEST_TYPE=devel + +# This reg-test uses the "add ssl crt-list" command to add a certificate over the CLI. +# It requires socat to upload the certificate + +# this check does 2 requests, the first one will use "www.test1.com" as SNI, and +# the second one will use "localhost". Since vtest can't do SSL, we use haproxy +# as an SSL client with 2 chained listen section. + +# If this test does not work anymore: +# - Check that you have socat + +varnishtest "Test the 'add ssl crt-list' feature of the CLI" +#REQUIRE_VERSION=2.2 +#REQUIRE_OPTIONS=OPENSSL +feature cmd "command -v socat" +feature ignore_unknown_macro + +server s1 -repeat 2 { + rxreq + txresp +} -start + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + tune.ssl.capture-buffer-size 1 + crt-base ${testdir} + stats socket "${tmpdir}/h1/stats" level admin + + defaults + mode http + option httplog + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + + listen clear-lst + bind "fd@${clearlst}" + balance roundrobin + server s1 "${tmpdir}/ssl.sock" ssl verify none sni str(www.test1.com) + server s2 "${tmpdir}/ssl.sock" ssl verify none sni str(localhost) + + + listen ssl-lst + mode http + bind "${tmpdir}/ssl.sock" ssl strict-sni crt-list ${testdir}/localhost.crt-list + + server s1 ${s1_addr}:${s1_port} + server s2 ${s1_addr}:${s1_port} ssl crt "${testdir}/common.pem" weight 0 verify none +} -start + + +haproxy h1 -cli { + send "show ssl cert ${testdir}/common.pem" + expect ~ ".*SHA1 FingerPrint: 2195C9F0FD58470313013FC27C1B9CF9864BD1C6" +} + +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 +} -run + +shell { + echo "new ssl cert ${testdir}/ecdsa.pem" | socat "${tmpdir}/h1/stats" - + printf "set ssl cert ${testdir}/ecdsa.pem <<\n$(cat ${testdir}/ecdsa.pem)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl cert ${testdir}/ecdsa.pem" | socat "${tmpdir}/h1/stats" - + printf "add ssl crt-list ${testdir}/localhost.crt-list/ <<\n${testdir}/common.pem [ssl-min-ver SSLv3 verify none allow-0rtt] !*\n\n" | socat "${tmpdir}/h1/stats" - + printf "add ssl crt-list ${testdir}/localhost.crt-list/ <<\n${testdir}/ecdsa.pem [ssl-min-ver SSLv3 verify none allow-0rtt] localhost !www.test1.com\n\n" | socat "${tmpdir}/h1/stats" - + printf "add ssl crt-list ${testdir}/localhost.crt-list <<\n${testdir}/ecdsa.pem [verify none allow-0rtt]\n\n" | socat "${tmpdir}/h1/stats" - + printf "add ssl crt-list ${testdir}/localhost.crt-list/// <<\n${testdir}/ecdsa.pem localhost !www.test1.com\n\n" | socat "${tmpdir}/h1/stats" - + printf "add ssl crt-list ${testdir}/localhost.crt-list///// <<\n${testdir}/ecdsa.pem\n\n" | socat "${tmpdir}/h1/stats" - + printf "add ssl crt-list ${testdir}/localhost.crt-list// ${testdir}/ecdsa.pem\n" | socat "${tmpdir}/h1/stats" - +} + +haproxy h1 -cli { + send "show ssl cert ${testdir}/ecdsa.pem" + expect ~ ".*SHA1 FingerPrint: A490D069DBAFBEE66DE434BEC34030ADE8BCCBF1" +} + +haproxy h1 -cli { + send "show ssl crt-list ${testdir}/localhost.crt-list//" + # check the options and the filters in any order + expect ~ ".*${testdir}/ecdsa.pem \\[(?=.*verify none)(?=.*allow-0rtt)(?=.*ssl-min-ver SSLv3).*\\](?=.*!www.test1.com)(?=.*localhost).*" +} + +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 +} -run + + +# Try to add a new line that mentions an "unknown" CA file (not loaded yet). +# It should fail since no disk access are allowed during runtime. +shell { + printf "add ssl crt-list ${testdir}/localhost.crt-list/ <<\n${testdir}/ecdsa.pem [ca-file ${testdir}/ca-auth.crt] localhost\n\n" | socat "${tmpdir}/h1/stats" - | grep "unable to load ${testdir}/ca-auth.crt" +} +shell { + printf "add ssl crt-list ${testdir}/localhost.crt-list/ <<\n${testdir}/ecdsa.pem [ca-verify-file ${testdir}/ca-auth.crt] localhost\n\n" | socat "${tmpdir}/h1/stats" - | grep "unable to load ${testdir}/ca-auth.crt" +} +shell { + printf "add ssl crt-list ${testdir}/localhost.crt-list/ <<\n${testdir}/ecdsa.pem [crl-file ${testdir}/ca-auth.crt] localhost\n\n" | socat "${tmpdir}/h1/stats" - | grep "unable to load ${testdir}/ca-auth.crt" +} + +# Check that the new line was not added to the crt-list. +haproxy h1 -cli { + send "show ssl crt-list ${testdir}/localhost.crt-list//" + expect !~ ".*ca-file ${testdir}/ca-auth.crt" +} diff --git a/reg-tests/ssl/ca-auth.crt b/reg-tests/ssl/ca-auth.crt new file mode 100644 index 0000000..1695af5 --- /dev/null +++ b/reg-tests/ssl/ca-auth.crt @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFyzCCA7OgAwIBAgIURpSju/jEN7LJUV4vEibyeuJwd5kwDQYJKoZIhvcNAQEL +BQAwdDELMAkGA1UEBhMCRlIxEzARBgNVBAgMClNvbWUtU3RhdGUxHTAbBgNVBAoM +FEhBUHJveHkgVGVjaG5vbG9naWVzMTEwLwYDVQQDDChIQVByb3h5IFRlY2hub2xv +Z2llcyBDQSBUZXN0IENsaWVudCBBdXRoMCAXDTIwMDQyODE4NTIwMloYDzIwNTAw +NDIxMTg1MjAyWjB0MQswCQYDVQQGEwJGUjETMBEGA1UECAwKU29tZS1TdGF0ZTEd +MBsGA1UECgwUSEFQcm94eSBUZWNobm9sb2dpZXMxMTAvBgNVBAMMKEhBUHJveHkg +VGVjaG5vbG9naWVzIENBIFRlc3QgQ2xpZW50IEF1dGgwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDGlgKEhw5RLOBgaTsPJJYglozt3SVv94084RoA19kw +udemrMaJdXV517MsR9qoHoxFVFdYP//W6vx7c5RadPqMZrWT9QXhJSR0Kr5KdHUs ++t8H8pmlDicxIx0cuRtmKmRuAMoDI1E+5EsRspemyq1ExcBm42zM9Oj9QysKF0wc +FXq56eHgXSmKQGAiGuGB5v6CeVu3DVhZHuGyv3XVeOsf35s2M757hi+N6mqqvtw8 +JiQyw53YxBaB80CRtiIXzLd07S4GZnRCNOWgXLwo6+8K1gId3KRk4DhUIEIMrchy +aqeZmJVToF+8fbjZ97pREJyQo4EXsgPrLE3Ck5Y+TfYJli3NJNhEWhucu4RQ6XXg +lTruatM9uj9ZZEvtJreu5KRvAOfRLBj+C3f+VRoDrE9RSEn/XSGek+/D7+n3U0GO +h2KcrUn7R+Yy6DdwxhGImqDnYaKaZds+vEjtvP4ViOC982eVl5/lFAw3JBHR57iL +/K0zTRwjSasUvlJFQNUNAG9HktCYTdEj0U3C/xBDPayY04BFvn8piZeMpoCN9dre +UxuctmMrz1pIvYAdZSseraf4W0psx6oeU/CcFZnkc5lbUDvn7u6Ozk4gnfyo1fxJ +8a2X7dl3joqUABwaS/FkP/CPoEKBMFf4pcZUhuWbPkhiVNXZIkQYQISY6JOr5qDn +TwIDAQABo1MwUTAdBgNVHQ4EFgQUW4t2W4MUuBG0EyFdHObYYZbtjEowHwYDVR0j +BBgwFoAUW4t2W4MUuBG0EyFdHObYYZbtjEowDwYDVR0TAQH/BAUwAwEB/zANBgkq +hkiG9w0BAQsFAAOCAgEAIqQJu2nX0Rn9EUPuVDhCrirQFDwMFb7Ifoqr6rMoD9OT +pgyQb198TkW550Rhg36LnnmBzifOoPBmHVJQWvMAVnH/BQrkRqXFRk2M3PRoEv44 +twMlUPU/NMLVKnXE+neBlXhBWeyY/bCmVftk/TdLwom0Mer4Nw+rt1JQAXKKNRdj +3b8EnJHGy7Es4fv/traZQ6ZSHoD0GsxydweCjZEO2hLw9/VVrjdM6rNDZlz7cST5 +rhyUeG3mlwWweGY6ahlMx//Z11m/1JLGyDcwMgunRoBiDep7I3ZMcWH1PjM3CyrL +ZrDoUvwtMSEAuT/be5SfU/CzS/DTyBtfSpEUbm1dg9cqm1vG7/GFdzJqafv8ppwh +fZhtxKXcyH4C1BeWlDqA06aNM3ClxWNyrAjdcyI45tosxgDuWyRyUC5IhyK6s81O +6AP7xQH6s+i0k3mzgOxieV/QRo4E67y31XZHJz6uFKSaHOIdpV7li7mAiswFfhMl ++C3ud2rU79X2vTYLzELR05djzAXHJT9sc5NjbODw3RRKRkcB78IoNM7D0Mcctz+3 +1DHcmk6crsxPRDmvKj9zQTjbG1UpjTogdsbh1afuqJ1atxBgav+/YhefAziXazAy +P1CHU/OYq/vjfGobIz6RVUjkg50RwkD58TR3LzQPOpSNoM55U/jGd3x4X3kh8tU= +-----END CERTIFICATE----- diff --git a/reg-tests/ssl/cert1-example.com.pem.ecdsa b/reg-tests/ssl/cert1-example.com.pem.ecdsa new file mode 100644 index 0000000..060d92b --- /dev/null +++ b/reg-tests/ssl/cert1-example.com.pem.ecdsa @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIIBhzCCAQ2gAwIBAgIUWnUgbYQBOPUC1tc9NFqD2gjVBawwCgYIKoZIzj0EAwIw +FjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wIBcNMjEwNDAyMTI0NzAyWhgPMjA1MTAz +MjYxMjQ3MDJaMBYxFDASBgNVBAMMC2V4YW1wbGUuY29tMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAEWuf05jTK9E7VNfDVknHTdp7FHB+LNOMVPB/XBRiLmU/+/EzF0D+5 +t4APkwa4vSw3UckWUMoAxOrJ1dUk8T8Y5AxWGBomcuAQGtfmUlDBXvhUjsJ1s9Zz +iy6WyRkU/fcsoxowGDAWBgNVHREEDzANggtleGFtcGxlLmNvbTAKBggqhkjOPQQD +AgNoADBlAjEAwDVLrc9jL2zx9byM1qGyHKnuk8xsEvZEkUPMor1hrTyqkLGIEu3h +1vyRvboYvGh6AjB45GdtABrNeRHI7QeA1ZX0j34dj7lYP0NvYjSVSyvRhpe/nzl7 +CzU2IkkQ4fmxosI= +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDCSlVR2c8kUsBYDAqrH +M60zwqNVVB0FGafWXBJBn4kgTKRQPCqmwkAJp+yd62Z05iKhZANiAARa5/TmNMr0 +TtU18NWScdN2nsUcH4s04xU8H9cFGIuZT/78TMXQP7m3gA+TBri9LDdRyRZQygDE +6snV1STxPxjkDFYYGiZy4BAa1+ZSUMFe+FSOwnWz1nOLLpbJGRT99yw= +-----END PRIVATE KEY----- diff --git a/reg-tests/ssl/cert1-example.com.pem.rsa b/reg-tests/ssl/cert1-example.com.pem.rsa new file mode 100644 index 0000000..4639b75 --- /dev/null +++ b/reg-tests/ssl/cert1-example.com.pem.rsa @@ -0,0 +1,80 @@ +-----BEGIN CERTIFICATE----- +MIIE1jCCAr6gAwIBAgIUJUqgFv3XQuBU7FxDOYZDO/DZFPowDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wIBcNMjEwNDAyMTI0NzAzWhgPMjA1 +MTAzMjYxMjQ3MDNaMBYxFDASBgNVBAMMC2V4YW1wbGUuY29tMIICIjANBgkqhkiG +9w0BAQEFAAOCAg8AMIICCgKCAgEA1Qyp+JCxptby6yTjlF6GKoSiYXMuTC15GqkQ +9cA5wExRvRj444ZDeltt4qFh50MQGaPL1Uq5pk2LxVhIMApn3aFv0vVXXLOpkcWL +tknYhcL7y1wZCGrYff0jJsi/en2YKbzdJ+avFlkrae7uhTmEwLcDRVhJpJYj0nj7 +7NIRZEzzvYxdNVVDkdNacZtJrtanTagse15OV7w6dniIjzyr7P5backq8EyQTWvg +hf56gx8r/JVoMZdxSd3EXcIXBnyDOU6KTiHu970DJmcz4oEaAlKFCehquNfGyVw5 ++jzUPyMP/IzvJZY68s3TjKYnJhoyu2GRf+SH2DBjYVL/I9ULK5G68Oqrjl3lZMM9 +NCjvLykBVAeQ2wYscCUChmLU9Vor1N5Z0EqZx9Wx/SBSPmlpTR4p1eoEmcrrZjUW +TjDBVk4F3cBrFrMEq0rr+aUSluPzpfYEv/tn1h0WTW/8PbSoQluf85i/BXnzmW1L +JplcembL1cbm0idJjzRvQx8/WGoSSIYHzWFgRhagvQ7xGf88pGGh0+n/K/xPXZ+Z +I1b89rLqs5pdBJtAgj7wd2oTxiKDILkpvwRBq9q2p7+yEnaIhWVQr3UudiSRcB8O +lEk8YHpa8wiKMksezCqs4zfdk3Wh1JEwgy1zYk+penzfvQGaySv5Q20P8V2ZK8i1 +HHnTRLUCAwEAAaMaMBgwFgYDVR0RBA8wDYILZXhhbXBsZS5jb20wDQYJKoZIhvcN +AQELBQADggIBAD6LkOmRDupXUyDmvA1PsZoNAnN6/ikZOzgcLoPbmPto2MAG16VD +VJF+2i4FddUJmuPSYkGoo+eEcIJ6pyifWm0f673dvHSn/Epgkyp+uOQcLnVGE5QK +cYk7ETlw9BQ/uRYi70hXLk8yi/XbBXIZdtICuxzEJrB+uE3tBK33Zy+KoDweifAV +vGNLDdhK2Slq0/ExaifeO2Agkz0Cb5nihsMnNlSiJPh+Qqhcyn0+o5hW80AozD3A +MZYVhiPtCfOoHYO02GpsPkYq1mfez79O+t5d3akLLPXEMO8iK4HUtlkYj84wP220 +fRct1E1apRCCfHORqnlPEYcinoEvlsl+c0olH6L2L3t4sDzWGHQoAzNQMSMAwdPr +NShvuWmKdYoPrTfdp73neP4jkzNMi2FR1SL7M/Mr272njrBrYLayVbb5Aogp9Myp +PrWohhrYaMCeCVLdtX0C8Ijjo+WhQjMJ5I7J2CCsRifhCnloD3nP3Cfd+obmGxTV +spGxTfQxn8BH/rqEkTKZgqz8McpMXJChzSe7JduGnv5E8nZH1UQBqbtgDP+JndI3 +5Ncs7GsU0JLfju4w3IaAjslOmu4TLS0MDSDJo5heo1U/OB/kqocbKcoP39mCiWPy +juW/VTheRaszG8tuPhXYovg9LXZX5HW7eWjgwm9kn9c4fu/3NY7PJbmO +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDVDKn4kLGm1vLr +JOOUXoYqhKJhcy5MLXkaqRD1wDnATFG9GPjjhkN6W23ioWHnQxAZo8vVSrmmTYvF +WEgwCmfdoW/S9Vdcs6mRxYu2SdiFwvvLXBkIath9/SMmyL96fZgpvN0n5q8WWStp +7u6FOYTAtwNFWEmkliPSePvs0hFkTPO9jF01VUOR01pxm0mu1qdNqCx7Xk5XvDp2 +eIiPPKvs/ltpySrwTJBNa+CF/nqDHyv8lWgxl3FJ3cRdwhcGfIM5TopOIe73vQMm +ZzPigRoCUoUJ6Gq418bJXDn6PNQ/Iw/8jO8lljryzdOMpicmGjK7YZF/5IfYMGNh +Uv8j1Qsrkbrw6quOXeVkwz00KO8vKQFUB5DbBixwJQKGYtT1WivU3lnQSpnH1bH9 +IFI+aWlNHinV6gSZyutmNRZOMMFWTgXdwGsWswSrSuv5pRKW4/Ol9gS/+2fWHRZN +b/w9tKhCW5/zmL8FefOZbUsmmVx6ZsvVxubSJ0mPNG9DHz9YahJIhgfNYWBGFqC9 +DvEZ/zykYaHT6f8r/E9dn5kjVvz2suqzml0Em0CCPvB3ahPGIoMguSm/BEGr2ran +v7ISdoiFZVCvdS52JJFwHw6USTxgelrzCIoySx7MKqzjN92TdaHUkTCDLXNiT6l6 +fN+9AZrJK/lDbQ/xXZkryLUcedNEtQIDAQABAoICAAfQoxt/E0UvdVGy1LZIkVtV +6i7w7q3UrTCRKxIYrwWixwzMsbSG5ErEt88sZE77YsfN/lggmZbEGXBvwJYii5TR +qyxt23qHDJ1QRcO2Cb8+W8Yl5rUsViyo8HUnv/5aRQ6i4unnyFxlgPYt0YoJhhkb +nX8ZsfnbmAzMa1FQk1q+h+JYF8MxEX1z50lrjNRhA1oR5S/RUcZeHTbjTP8UFqpm +2iuTOYP/CvwMDPxdTVkp948YW+4VxA4VmHJoADg4sQeVHfWnwQBNaqQp/Pk+Cxoy +tLacU+3b3GreezH2sUJvotJ8yPjz/c2SR0RNg/od0+aTuaabV3BSthKH3NwPoI0z +bfLkwrR5KyJobB399UN3aqg2s4toKNy+6l9x2dh+QimwDOivptvynEd9BIXd0ZCn +ohdE9b9j9eq0l36WX+u30JMyevjjumnZjKCh80Pf7MnTcqzggcWvoPYtjPqBj0ig +WvKwPCmV0TG8wN441mjObUXLa1mFlb8b+NM8k8gy5odkyRGm8ZOOxYlOWmtu/sNM +VBdjG3U6yONDf+TO+v7OVsOVs/IHFOX3RtpCt8wnFZfTxkxjqrk3E8O7RTXcrIny +Tgzmi0h0bSTahsKm/0roQNPK6XNw6S6CW9B2kPz2gBEIpjrEl+C8hmsiYEzNJ9kM +oLWlKEuwcMaXS1oazTqBAoIBAQD3S7icGxwTVypEKq7ZT4859UOtsdrqTKEFIVtf +z4IIwmlo65mfNA7/w2TSV8p/o3NH4yznkEnVzvYYNXKt316oZM2CqCoA3XjeFlO8 +hUoScVn1VV/66E6wTIbRUCMdBfyPVNQ12bTZ/rPpmSlatXfUGarVRlJ15DDS0TpV +s+ohxpT1IUnCx7N0z8cPbTFy2qguSbID6UydajXtM/h8up4866wg8nzT4PBssiqf +NzWgAA+XP7oigfncgqSuQ2zk8Bedbm+tE6bKgK3O6VfTDRIV2Kw89Kvt0OWQYpOD +F/CTarNdlp0kYmos/rC57AVSpdTNQm3944WFi1ts+aL74+b9AoIBAQDcjF0TnKr0 ++uSAFNHDIxf7LHnX+uOZ7cTs284hIHZJ4z/GgwHKimWeG4XZsOGPh9Lk5GGMyDBB +N9daaGYskoQ9qh0e3IyRbbzdcwUMV9xzulYzUg5OKoezpBlp8Ydd8Gp3/9SBQtTi +9jjLZ45Qea7/F/Kk1TebUvqGQa+c7HdeJ60/6121QPw7eFqJIOVqf47Tkaq3Wmpr +csfQulNwN4Gi+v2gp3iMR5q/agKCOtI56daheYyNgPxX+chjiqOqC5WElTxPihde +lKtYtKh3rnboKGUQ4fJOVFoV/wrfo5wfcYkPDB32Ct1B2hsI3oHbnPkBPgvCB0Xa +/HPrEqWP5W4ZAoIBACQgVbnIZBOXOj93FM/+RWgsIlTvlJGB3EwJkXWvtMlezVNc +h7awPjiy7LmlxZlb4W1xDJBPjdnEQENNG5G2/fcPss4RjwFNWWjoThdOSYHkOUYT +0M+wvD4ZD+DoGhkVVM4DkHTFdxwZj2Li0x3DQNwlW8WIXmeGjHNfyWvXuq5wejZN +RJ9F2TuJVwUz6HNk6gjJD05u+JhOec5LN1PRV2iC7URq6D1zsOvQI1XbFORo3d40 +mxaLclr6YuBqTTAsuuZuybW5FzaiEcIWaJQWZrv2SUMmYy98wuyS2gXeq3B9t/JG +HHLCRcyI8HxYtHZcb3gE6liasljOAO8skNjHdGkCggEBANF9dm/Jkc2vf1p17CWJ +8R6BSZ8wzf6JjlNaGjr3JcTbWdnK2Om1ef6rsAFudWKrplQK5uodwVBBpYpXvi26 +YmhcbNrCrbb54LsMpQ/raRh4N6b522K+HTYyun0akfVWBxvC4uyBOcv4C0ySKekh +HGtsKOwPJ4mfUR4zyIarSlsiHvunKtSfTLeEg6Lbn28AiP9HzzvoY0t6tHf8dIMU +Bkx0UnPGf8fnwALvxEBFdSjTiC7LUQmcKpW6SnDa4MkFxdkxFB+NUNNjLjrNJ3S/ +QG0W6aEWrd1fXE6meoKhWwu3AXRMky0Bdtc1QBa1m+2p9hALCoob9Guk/sqcZK0B +RgkCggEAHjEa/4q05VPbMm7TOgF2m5QTdap47LyTBti9TRurGtB/9nWvIHpM9sAy +0xVvGcoZOqVHYvRZGpZ8IX4B+9FGMNUDBMc8shj3oA514tCZVPCEolnHcuwERiZD +c5zh2PccktAmT5EXGch0+eRuxJ1ROKgR0coeo8KMOxtrm0hRFTznsJ0nzNjAoCA4 +zW6DVY7qIb9ksI44rWlgGSwXG1OuUpqH8+tBAvR3uNa/j59psBb7Pu5zmg/qhx1m +Ljd/0JTxE8A00l0bC8S1F15wGn8GQD63pjq8nr/biI0Y39g3TEAffkI33FfCjBxQ +gO96WUZwPEimQAnu4Jw+RlpLtWjOBg== +-----END PRIVATE KEY----- diff --git a/reg-tests/ssl/cert2-example.com.pem.ecdsa b/reg-tests/ssl/cert2-example.com.pem.ecdsa new file mode 100644 index 0000000..9dbf25f --- /dev/null +++ b/reg-tests/ssl/cert2-example.com.pem.ecdsa @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIIBhzCCAQ2gAwIBAgIUJ2zhyUgHjXsPzANqN5ZSHX0RVHYwCgYIKoZIzj0EAwIw +FjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wIBcNMjEwNDAyMTI0ODMxWhgPMjA1MTAz +MjYxMjQ4MzFaMBYxFDASBgNVBAMMC2V4YW1wbGUuY29tMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAEx1lz/PGGGGI9EG5L7qx8JGwt15HNuJI9SsdwzkRV/N8sBFzAEVbS +UWVthQ8tIAdW1y7d9fwkHrzkPulDVwZGGr3qrnZSAgb7NCxBICxgdDI7ku3oPdNd +bsSASmhJrQO4oxowGDAWBgNVHREEDzANggtleGFtcGxlLmNvbTAKBggqhkjOPQQD +AgNoADBlAjEAnHx8jSzldb5z4FR3oZ3twWCzRR98n1IBuBi5fe6hhBlQF5u0iAyb +oDcZ2Tx9UfWhAjB/DKDFrlXAkow4rQxHU602c9SI6hJTCKxIfWWoBYP7zqZXEUjj +2QK7BQb3sHNpsqY= +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDDsiqzn+NewEL5bc3CA +sY4ADwk42yQJCPZalIct5i4e5u660YCUMHqbVAUQe2R6YFyhZANiAATHWXP88YYY +Yj0QbkvurHwkbC3Xkc24kj1Kx3DORFX83ywEXMARVtJRZW2FDy0gB1bXLt31/CQe +vOQ+6UNXBkYavequdlICBvs0LEEgLGB0MjuS7eg9011uxIBKaEmtA7g= +-----END PRIVATE KEY----- diff --git a/reg-tests/ssl/cert2-example.com.pem.rsa b/reg-tests/ssl/cert2-example.com.pem.rsa new file mode 100644 index 0000000..7a6678f --- /dev/null +++ b/reg-tests/ssl/cert2-example.com.pem.rsa @@ -0,0 +1,80 @@ +-----BEGIN CERTIFICATE----- +MIIE1jCCAr6gAwIBAgIUCMeB9uw+PcBIqW8cDI21s7SxWVYwDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wIBcNMjEwNDAyMTI0ODMyWhgPMjA1 +MTAzMjYxMjQ4MzJaMBYxFDASBgNVBAMMC2V4YW1wbGUuY29tMIICIjANBgkqhkiG +9w0BAQEFAAOCAg8AMIICCgKCAgEAzt3oEBc1jWk2PaN/tJA/PTTdwfi6ZXqXCrCA +ZScmo1jvM3CcoOM1BUhiMcoeK4uHRryYUO/eL/ZM5OA11GAIaMevhK65rtBYIh2Q +klRH+IojmRL91U9tXno+oMBS8WwF7K6eCCj4XUTAKuolQ4yiFHTvdwOsqSrVY3m/ +m2Pp4VTqjDSsljmv8GJ0lQpxan5bZt6WWQiCIbdS7ExgJIALDemg+JOIz/bDmCr/ +3tihmHOK94lCcV/CFOs2XctVnkS6W8x/S4U41Y/eciUbLWr5CxAvfZLOQBuriWiU +SMHPJI63VPijGKStnBn/zRMvDJhaadkRqAqXlJUZ7nkcZ5WlPuIMgAOc2uCZioW8 +DvyJmplBjBBQdGqRFaeX2lDvJwDECDxSHglfQgVVz3II3ZMSlDsystu4MCgeFa0e +S0UCvl+5mK1/QVzkzxYj1o9iXhtq5VSLmbaAssDcn20ashJMxmruagsOR4MhaKA0 +RsMosrAiCbcBiY/Q8W6NoOwxNUC8agsqDRNSoJfQgYhTJXqxbnteyy3TXtF4zW+S +7D0ZsRXM+u2z6V7lP8rvS8ZwzI7nDA/hH34IIw4H875IESLA/8ZiMA3luzMNxwWr +xCn58JCJM0lJmgkO+NvKctGAGxgtdKzgHemzczx6GuA3V5mOOD01KUbMpZITN4lP +vAt++qkCAwEAAaMaMBgwFgYDVR0RBA8wDYILZXhhbXBsZS5jb20wDQYJKoZIhvcN +AQELBQADggIBAMc0Z6hDp5VuihQ1LpmfisQtrs0F5SpfxlbCshg9MOrgRGwViRBM +bCw1UhDZPT7sQ47JucUkw4RguJTsNQO6Iacq04EKSfHmbxznlZ9eBpAMdK8vWLQH +jrpmNVE6At3kuyFJrXEc4BOrvzwDqcbG8cFFwT+l9C5BGSZCG/muLPuW3S36IY7i +uVGc4MqrOQLRghyZbjkXrReGzBZVbuCiz9O+zsjorEzt58gdwIhrl8WyHTJ/Nqy7 +ibfFDh+tJxdNkipa0PZEqovMUcMG1N1E+n4nl6QooUsIx8JmeL5OD4J15ZuvrK3A +emggxAMs+rkooocc8SL8i0C7l1m74qRKCP/dhIw8R8XiSKaSU5PQxlmY62qHJNkh +RIkwvv+VcGdUzC74eEPUagKABzYARXBC2410E8vekxVYAZ3U31ypB+/3nWBJOqH0 +P//I1ZKwYLQCuC02O2Uy44kwZsZ1Syh2BYJxjdIeg5oMVnrDhi9kYnMtDmtzLsnC +kP/cMKX7NZ7d/qbF6Aa9vVE/Ta/OrLxETF8CrjSa/nDLdLpm9sDC26/aqZv5L554 +xeSKVxvZyRFtObSKW1qzK40RMkWUarh72urtd9aM1t5PHOnwY77jO/yemjxfhgvp +jUKM0pxIe7EmNqoEay+zdN58x8VPDtLFNehorGUnUGkaS57BFBjpEUvY +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQDO3egQFzWNaTY9 +o3+0kD89NN3B+LplepcKsIBlJyajWO8zcJyg4zUFSGIxyh4ri4dGvJhQ794v9kzk +4DXUYAhox6+Errmu0FgiHZCSVEf4iiOZEv3VT21eej6gwFLxbAXsrp4IKPhdRMAq +6iVDjKIUdO93A6ypKtVjeb+bY+nhVOqMNKyWOa/wYnSVCnFqfltm3pZZCIIht1Ls +TGAkgAsN6aD4k4jP9sOYKv/e2KGYc4r3iUJxX8IU6zZdy1WeRLpbzH9LhTjVj95y +JRstavkLEC99ks5AG6uJaJRIwc8kjrdU+KMYpK2cGf/NEy8MmFpp2RGoCpeUlRnu +eRxnlaU+4gyAA5za4JmKhbwO/ImamUGMEFB0apEVp5faUO8nAMQIPFIeCV9CBVXP +cgjdkxKUOzKy27gwKB4VrR5LRQK+X7mYrX9BXOTPFiPWj2JeG2rlVIuZtoCywNyf +bRqyEkzGau5qCw5HgyFooDRGwyiysCIJtwGJj9Dxbo2g7DE1QLxqCyoNE1Kgl9CB +iFMlerFue17LLdNe0XjNb5LsPRmxFcz67bPpXuU/yu9LxnDMjucMD+EffggjDgfz +vkgRIsD/xmIwDeW7Mw3HBavEKfnwkIkzSUmaCQ7428py0YAbGC10rOAd6bNzPHoa +4DdXmY44PTUpRsylkhM3iU+8C376qQIDAQABAoICAEQ6PiKodPop3EDiHul/tcvL +FuS100xK7WwSIJa8Hes8FtCBcLdDmKYgZHqFbgPwpfI3m4j+Q+rPsja+mCJudfeQ +/JunQQieIKNH2vnYIFChxvHiqKNk6e6CJQvBwtlrRlz0jpykXp3sYfEFfrrTtFVI +5/350UWOIgkIC6EFiArQhfcuHEoDxrpizo6lfhigiibYfP/qZXkXTJsw6XjAXmT9 +TCEQD8x/V61laTSngEyWtxvDQo3ABnP9y9WNjbSAeHJ0dPuEeeU96SD+igMlx/PV +J8Sj2bCdL6tHObjxaw9knqTAyJIFJllY3dxWWmsuCIvmkwM4UxwnPQFBIpQrb+9A +rguNl+t31zljmToDIEF97G/QcbFqMQEKeNCkwIdtD/8tND7RrchcqQPc96rdHbB7 +Hfb/ZXqCSsYNahurEmeAUZJkLO9U6/0GbWHcxkHBTkrmUs2qV4LrhWP71tKpbNY7 +mGXK6Ok6ZfkAD4uau1oQkndqdlKg/rBOjcT+HGPtxWL9gPtG7om+O9mu++BngrGr +oyNgujkVRN0fpJhKLhsT6OiZF+7CVQo4ZIw9dBQ2hzLNw5tKgW36GAVTfFxNRTje +SerlyEog/P3s1tnDn7BngdVOdnDfiOi1O4TEb4btwqP3BSs2p0wJKaJGoClFFuwN +n5dtHMABtSOKPbmWurbtAoIBAQDqPmZjSLfEwSXph33m7Ms2/AbQJltzU0ftRJU9 +TQGVHBajouupVcyrZ+WiWcltLov+JNlseXG/PsIWEmqSiLodIZJyjWSDUiC5iFEM +fn2d9X4NLz0A508pFR5FQnULFEDMDryLn+4ta8Bf5NeL2p/ZavKh9rxX/8LAanse +6Lst59RiiRMkazkjC4DHDmqUAZBt+uQVaHVFpTBJLa1k1nIc82GjsJwWsbADL3+o +PKiggSir/Uf3nOOPhXsegVTZBiq9DNFciCa+kqT4eluUopjWxIuOKnp5mVh2DnTr +NXyZ6jDb2JwjcJpy6HLk9EsqY1YuMpT+OCNnLM3l2Gxp/KovAoIBAQDiFJEh/LHl +++7Z4TE0whMdjkFdSCuPyEnU4WFRKLMTPQRCdS+5GxHDy4lzpArde+51C6UkAjxe +jaAGzQvabKBl4Al6eFpYvv0d8CQMWIrOffzVMRXuHWgm/SBg7um6ok0rM4/BOdUr +CN2nWvBF02ZTSsGzzBmzTo4vMkcAQOiGes0Haefxm0DiVvoElL20Fv/iuEzbf60p +W/0TzeiOBar8WxpTTcnHc6QWQ2t/Zon3/5E1LIOEU2/GQiS6zqNBRGr+kfWtz2wB +d1IFLXITiqAQb+F3EjKqGS8ln0JYLSLRk3ALbb0EtN59lYwrabUYq9WzA1MlprLp +GFqzAHNPc+qnAoIBAFg4DAOUXXGCdK7Q0n/n6ljY7g/ygjqawNoBHFur5s6rd3NF +Zo+tuplLVdahDhVKlHqwkhoiWs516k65vN1XFRDnleoCijpS8fQt/KhB8zlMPZ7l +jYoLk2qbg3z+HGqBxC2V1ziWkPMWQ6tZ2jvXqKAPgTWyYRibQFOLRrdLW0NcrkY1 +7bmnkCs8p9FQAp+fPy/Mb54IazJBlj/ZLhZuFSgGGV22o/KAFRP+DYvk3HUmb5Tm +nPYKZkGlOcsxVi0t/2aXrzm0JTNcszjJjDgcTIeGGjD+moW1VPWRWENFL5of8yq5 +F4TZYbGpDaxgvPZH1ysq7aYYqmyvGRRZP+titw0CggEAaPoB1hU/Cbps0xDEx2mi +dKPcaBMd3xqyZb3tcUEDvdgkRTOi4EHYguDcxyyRuvxT4ldw7AJ5w7Hhb6cAbQDp +jcR0wkBmOzUb1S3vnyfx9CX+I4QyWamf9hKtWTU2pGm+iWPcyW0wNVZdjdslHFcn ++V8KCJGqEV9VmEaxP0XkcqVM1LdxcveTLkYSu9PRLnFLihvn3Dgx0LWdEvgWlvO8 +zIcE9090dT+WHpxZqwOS5uvtohI0U1pm2VlXMsLGfYTmZaSivn1E+n1MQYkzoi1J +W7iHqcFycxdUlBSaOtViiIv8h+IB1dCiSxAI0RO5emY3yXKuxhnck22yl9GKuYbq +mwKCAQA25h2vjVD9x1Yci/qWnKnchjVlTkKWb0D404fhibJpSXHtFOYiE8YXsBBS +zLYDeDXFagl+AorvG45SoodJGl1/uqGbZMPBs0Yh211nBVtR5W+8vHLPEbw/Qvl/ +AXSmwnVT+K3oeJRxUBIlOLQcDtXcFGBhF3CbbjKU7+9gRdj0oq+O4DZXZVnJPeI4 +Rf42bfQYXub1bB+kH4WwkuLYItrzv4vLgS7kO6Z1GXz7mIBZi7zlUI7Wl5pWg1fq +H5X6u6V6N2LKS7Sqwa7ihL1ScUMhfmcPE362FyxqwkSMWOx3F/L812MKCgwVoil6 +yupxw0d9CircRDDG93pWn3WxCHpV +-----END PRIVATE KEY----- diff --git a/reg-tests/ssl/client.ecdsa.pem b/reg-tests/ssl/client.ecdsa.pem new file mode 100644 index 0000000..b9940f6 --- /dev/null +++ b/reg-tests/ssl/client.ecdsa.pem @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIDPzCCAScCAQQwDQYJKoZIhvcNAQELBQAwPjELMAkGA1UEBhMCRlIxHTAbBgNV +BAoMFEhBUHJveHkgVGVjaG5vbG9naWVzMRAwDgYDVQQDDAdSb290IENBMB4XDTIx +MTEzMDExMDIwN1oXDTQ5MDQxNzExMDIwN1owWDELMAkGA1UEBhMCRlIxEzARBgNV +BAgMClNvbWUtU3RhdGUxHTAbBgNVBAoMFEhBUHJveHkgVGVjaG5vbG9naWVzMRUw +EwYDVQQDDAxFQ0RTQSBjbGllbnQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQd +LnaDhFB0RmWq5WQMdPuFXqjBNZutLQRZ5t+AJ1afpujuwr4G79Q0eZKeYyFHldq5 +PMQDBL69D285AsUbMT42MA0GCSqGSIb3DQEBCwUAA4ICAQACnqZefAYCf51Pxhwp +NElVCzLFcrNfMnCcOxHkuaWjdWbKZi+G4PNIT0ghWgX4k5Gzjx6cVjNmWVkLnJxg +r6fL31u+Edl9BLr6KKrh830EOK7jN62zySFVjd9sqqBPiEBnT+3OCI9sXWXWg5nB +B00E6Ll2axwEVrQFIVYnTPC8CJyDvF1t1Jmw/caaiWWVVoUu7Zoq1kVzMCuj7aCO +BmhvDh237+Cjkly829/Q41aKVBSQ6yDsds4uNceOpAcXOQ8A5ZXa2yearIttvvAz +LHvXcJZD3h/23mnLQZWo3YisQb3u7O9iIpIXdxpbVHtJ6JvshmiFHTCNB9KG+q2W +CltrL8lYu2bWzNT8CPJRa5CsFyolIi5fEOfVOWLHKYkOgb9h2hiI9hT9Ujg5H1vM +d7AeqE+frF5dzxslcQ/wLQoUc+v4bfhh3ffeAdNul8bydoSu3Lq1nXWchNkE6rcg +pN2uD0eLC1hAXvxi6kQPlutmFJ8yXHySEA5uCek2Kf7dxudqIRKShT7aDVw6pd6R +ShX4dXTGEO4eBxTcooK4mYQhf+ivyTxfkACnML85C84hXPSoIffMk+Y+PMfNgW/2 +9OH6IwEq7+dSSsAlYweGnqznPCyVfpesMaQCoG3l+5Ciznt5/WA4Mh5HzLE2PE15 +VTEdimSkNohOKYdqQHA3mcH3Dg== +-----END CERTIFICATE----- +-----BEGIN EC PARAMETERS----- +BggqhkjOPQMBBw== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIAe2GvrgpqaNk1wzyawK9CJYQz4lTVLDyf5MtbDDMYrcoAoGCCqGSM49 +AwEHoUQDQgAEHS52g4RQdEZlquVkDHT7hV6owTWbrS0EWebfgCdWn6bo7sK+Bu/U +NHmSnmMhR5XauTzEAwS+vQ9vOQLFGzE+Ng== +-----END EC PRIVATE KEY----- diff --git a/reg-tests/ssl/client1.pem b/reg-tests/ssl/client1.pem new file mode 100644 index 0000000..d830a42 --- /dev/null +++ b/reg-tests/ssl/client1.pem @@ -0,0 +1,187 @@ +-----BEGIN CERTIFICATE----- +MIIFLTCCAxUCAQIwDQYJKoZIhvcNAQELBQAwdDELMAkGA1UEBhMCRlIxEzARBgNV +BAgMClNvbWUtU3RhdGUxHTAbBgNVBAoMFEhBUHJveHkgVGVjaG5vbG9naWVzMTEw +LwYDVQQDDChIQVByb3h5IFRlY2hub2xvZ2llcyBDQSBUZXN0IENsaWVudCBBdXRo +MCAXDTIwMDQyODE4NTk0MloYDzIwNTAwNDIxMTg1OTQyWjBDMQswCQYDVQQGEwJG +UjEiMCAGA1UECgwZSEFQcm94eSBUZWNobm9sb2dpZXMgVGVzdDEQMA4GA1UEAwwH +Y2xpZW50MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMCUnq4y/rYG +n2BPYutNd/dQX3KV1qVKKXBsXXqBzE84qjBg6SeQQVwcVN0UYK+l2Rqnkt9m+sV+ +CxAwDAVHts/QmD/4tbjuP8tMQiZcUsl7hxRzLRK2lXGwoX3B7GJgXxjDckCllert +FgUMylb4ACt8oA1e4c75fY8ppmOcjaNcPBghk09uKVUOKy+UZ/HWkNncF6cO9N82 +Y+bPdL1hg8mr6n7U+jv0bdyBjjN+b/3ggInY8NGyPHpl6ezvmgaI5+stA77YolCY +NoG7ZexMpBbtv/2M7+PHlx5c5lzd4HbuC5fOtfkMvoosIZJaI8/mM5J6aeu6JpPB +XvGRRE1Opmmhk1M3aQvU4q9LPYLkXIivuH+sHZnVZHZ32hhpZ4GhTpgayF22n/hI +fMOzSIMhpao/1YuLVbLgXdWJZx9uOIT//a/3Bd4I/c1/Pt11oNSIhiEAS7beWj0c +QtsSabeQwEIOOlbxWFA1aRogFNNE3iW4gps4p/4oHmT9Warb5AadE6nzh7N1nCiD +oO7JoHUzOj8VunLn2RZ8vWuBJI/2fh1TJVjOBmQBl6YGHD8BaRWlzv/VOiq2z8at +90rXGUb58KYvcfOTOZmYjKK16r/112pEgJuivXXr+N6qJKYxw46m+MAD2eDQ0Bc6 +gFZMlcyBAyJwuxIejUTvWwoddfRnaFajAgMBAAEwDQYJKoZIhvcNAQELBQADggIB +AFk00NuZDresZ9voh2E9J2GvUbG9x+NSjZR6pQ3MiPPXpLYskV2xAvxFSayGcQhG +mIfHshsnEhE35WYU80R5Ag1Mxh+XPbZUiNj/oOEFdBj45c0HGorChaVkZtnLilMo +B0yW+0pnkqKaRkgmVsSrNCgimBtZX1hsZRLDxa2vldJ9lTIg3OuveqBv/uwbMOUC +eT+il/sdl68K6oNHvAFdY1U34oJnvj4yF6ZZM1jRERK38wY0+2C+mlcXNL648k+2 +lOMeBddaDUKhscWdw1+Ui8Sn6lc6H+iPpGo3xdj9awc0568SCH+D5cpuTMNTREuM +p3paOMGpLWuQQisltdmz8Ms8lAcJUDeyDmrgE9CPx9DiydB6Z1uP9y9sozqB2SIN ++QqfQLv+lAaUB6cu5xIWfZIFeTxxziABZ2jDF4vVvK+NN2IdBahbI63HQpfeK4tG +Bkmuny4vlCnHBnzVaAboaQk2xzI9Yp79IN6yhmuO8AjCvd0XlH/nYF6b7WjVy0gU +LpmkYVHWhADLY4q06PUz8gFGsfDHnx9RQIV01SXbcFxhmAjJBequBbTpucW4UAK4 +sTmg59wlYEeNdomLBPW8f0zkY3Nm/IbyJ8kEofUa4kbwdD/osS5fgWgARiVQXEMW +W4oMGWpplJan6qe+hInvd+5syZXtO+K/uSOj63H6BwAu +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIJazCCBVOgAwIBAgIUWHoc5e2FUECgyCvyVf8wCtt8gTYwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCRlIxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDA4MDQxODU4MTZaFw0yMDA5 +MDMxODU4MTZaMEUxCzAJBgNVBAYTAkZSMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggQiMA0GCSqGSIb3DQEB +AQUAA4IEDwAwggQKAoIEAQDARiuHkhrnf38Md1nxGDSneJfwv/QksdNNMNTJBdjg +OVmaRCIAyz43oefTWDQ/TebbSwB+Lg9pud1zadGWhlZRhCgBPP8JDMhIKH4eXIRk +5IIa8WD08EwvSlqJL0r4gsMtVsxy7BZHAkka/2Ket9pyGt4kG5n75RFdc6BI80/8 +RwJt/MDxPrcVBAT7LnCluxQpyya9mZCabj7l+9a2yU2hgWS6QqfZJ133krkP/MMh +AEQkSoA4mmBwWk9yPqXmUqiOi7v6iLkIUEh5SgYVPRk9BtU/kDaUdSwuqRrpCZo4 +SsWZWFLxBmLHkSh+G+BWjCVYMQr2ye7e+VMT/20+5xAfq4fj9n5BsPcx3QcVuTof +RAc/Oygnt4MYnIcUb7zRFvCAvgpUHL7BnEn6nhyXjHJGqGDchsg8m9t3v/Y3ohq+ +qmrSzdeuylE1n3W5aWJlbFmyXegNP45MJ0xicesVrXEWF7YD/ir9mGJ8bQYr4blf +77PrbF02komC6AzVPKOJa0jR+eW1wErzYlkYgez6ylBWCiHJd1dhEHlK3h2rXdYa +Gnb45ILCLpEDjNEUrHifLLNXwqJpgZQsJU6BgMgk7ZgBfAKrCfTeg0rkCqCAPeVb +8eSLf7FBF7YBRJ5P6u8qXc4RtgEu607GaWV0gIMfyVBY52oV+OaNsEdFetrJnp3c +friG8vJ+7jdq6zjUCGgnfUIHoViJPh3JuFfhA3jT0gQDKW5PeI7dxhrNvlqdYfHI +fxX7Y1/J6cTQkqJ1cai2f0bwJIJiTAThNbG+zrtjJ7fZ3wJ4udyU/IKrwShqtmTb +1Ofj0tJDdwOH8i84vIySLUvR9aAb7ClFlnsx6rzwOxG90W7C0LA2M0EHm4FezJm/ +FfujnZwEWr1T9Wki6qE0MHCbdN/TTDws//EKkkE44FC+amL96w0IQl70vpE37j2A +zlDWvFFID95SIxfmpkwWDvXDKv6gr1GMLeysCl2fgpY05Xidw5cEo9/tEkuWn/dG +x/D9hnLBGeroA0251ES12jemqDjI2U0tfaeHakjwSsoWElf94Qmuh2iPZ+1zIxQs +7o6nAWN8X9hfsmrDTTHlww0TEfrjlbzG5Yh+0ZRxmejgiUyOCXck+eh/ZXMXvfWh +y3CorIIuWgkRjm80PYkdaRDJdZuyP6R7tXfTXNVzAiSQf0Qx9ru2KB2Fs/XZPamH +KjItAU5Q6msIVvaRMS0muQgV+b6hqSEBzqXqJfAlpVLHXr5FqK+U7EB9y02B6piB +tAmxqXP8OOCoQql6/vgIcrDFUOo6KtGBW36ef74XE3KCUVaIzVJZSIt6i/Vi0bZj +bAjsJUQ3qDlHdorv9TRVOhnC1GUz7SuYnpEOyiXmyx3LAgMBAAGjUzBRMB0GA1Ud +DgQWBBQ62csZcH/meQcENHhNbqz9LMzwjjAfBgNVHSMEGDAWgBQ62csZcH/meQcE +NHhNbqz9LMzwjjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IEAQBA +wLsGf3R1+/I2zQE+lsj7RasZtA/Cos92iEGDAPvFbx9e+roG8Gg8KBsEJu/HN0JH +lMMiQ8dDRHSBMvRBENL5/57oOOhmqc+1u5sazLuANhzAYPZG17Klib7YpEwWoXar +FDDiJYtCyLW0oNLpCswYopWK9GC0RJNucB0NFvOxehJ2sP2/fxGBQMB09L6mjKjd +4KsOzyd3dNf0VYS6jB+/1pcKSHKQUo9HRHB5FK04PsYHoh4AtmEHvmYQKcWWidgU +v26ftlH00ERzuW2juqBbz9mghlNRqXi0IyZ9b4tSj29dxW+WWFzo7j2zEPaD6z2W +DEHq7zvON+g+q6qLgWeszqMgJzjvWjMj00E/t06PoHPiz/cAnDKEqp+ZzxCIFrxj +/qneChpogDWyLbawhyyzbZvbirx5znOSbWjPZgydqaNEFViqbxwinBx4Xxabo6XN +TU020FuMWmgfbIcvtgjKgyKqc97l7JMNNm7LQV9+9W0U5zdIqQKLZ9MMrd2w3xh4 +MAB8NKnwzHReK0TWwUU9HSgFAGdEX6HnyZ3bQ13ijg+sNBRMEi0gBHaqZKDdyoft +B2u2uasSwioV48dbSIcHl+rTBKxiMh5XQ7ENnaGOJkjsIqTVzizqnPHU8eMBnSbb +dsXlamROYII44+j3Ku6OGt51w86eGk4VxI3tmaECcJKqTkwUFD8AcNDrkjtmLuxK +12yjnoM+u1cclfqQ5NOtRc6MJZ27jCobfBBhVdKVDp4X1WNyqGlbsU5adDAzknuI +GT7MJO7lGjkZX2n54BNPSfrSknYMOVYcZqL0Dbcrhx5IyEmg+iOlOu1HO1tdnZop +ej4vT+1V2w9Sa4Wo3UCo84jcm5v/4z7jCYh4BRQ60CFb7GLxZoqXIslcGSPool3n +jl8JWoaLXrJUPfZGXo1iAlayJ5EiMyZl4eB/TBUf6TMm8vLvsPiUT+CEsjLppOdS +eYppZAZ6H1JrJGs5kKBdOJHGn6Pkp5QsHIswOBd1HqHrBbYbZmDaDLRHduILWLrM +e0/IfDdeXB/bKfmZoEpT8xRiauw15p0AHLumiK7KISAehfgBqUnxx+YmgGoZ7EWX +KnMYAfCuC6oJ1DL0gp4Z9yMK1eu+GV1sLxPq9ZruEHW1R+H+4sGyiA5Gso2tgB6/ +XW//wxKclNp5LZR7hqfs/kGuh5asrJrnEbMwWn2+tr/LqfYtYh1D6nHfIXpT0o1d +rNy/HrsKnRDMWxjm03r4hCViuNVD3Zb9anAF/NSPDVu8ATM5JbJNrCYX4eipz6ZE +aQBkwIBkTPgtgP4r8v2G+uMYDw8nq7xh72FK107aeTTwc6MgU5jfeFNMr2XJisJd +lSem1ngKYQSEzjVsTE4c +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIJazCCBVOgAwIBAgIUJ67hHFw8DWW8omAyqE92SPRxENcwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCRlIxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDA4MDQxODU4NTRaFw0yMDA5 +MDMxODU4NTRaMEUxCzAJBgNVBAYTAkZSMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggQiMA0GCSqGSIb3DQEB +AQUAA4IEDwAwggQKAoIEAQDARiuHkhrnf38Md1nxGDSneJfwv/QksdNNMNTJBdjg +OVmaRCIAyz43oefTWDQ/TebbSwB+Lg9pud1zadGWhlZRhCgBPP8JDMhIKH4eXIRk +5IIa8WD08EwvSlqJL0r4gsMtVsxy7BZHAkka/2Ket9pyGt4kG5n75RFdc6BI80/8 +RwJt/MDxPrcVBAT7LnCluxQpyya9mZCabj7l+9a2yU2hgWS6QqfZJ133krkP/MMh +AEQkSoA4mmBwWk9yPqXmUqiOi7v6iLkIUEh5SgYVPRk9BtU/kDaUdSwuqRrpCZo4 +SsWZWFLxBmLHkSh+G+BWjCVYMQr2ye7e+VMT/20+5xAfq4fj9n5BsPcx3QcVuTof +RAc/Oygnt4MYnIcUb7zRFvCAvgpUHL7BnEn6nhyXjHJGqGDchsg8m9t3v/Y3ohq+ +qmrSzdeuylE1n3W5aWJlbFmyXegNP45MJ0xicesVrXEWF7YD/ir9mGJ8bQYr4blf +77PrbF02komC6AzVPKOJa0jR+eW1wErzYlkYgez6ylBWCiHJd1dhEHlK3h2rXdYa +Gnb45ILCLpEDjNEUrHifLLNXwqJpgZQsJU6BgMgk7ZgBfAKrCfTeg0rkCqCAPeVb +8eSLf7FBF7YBRJ5P6u8qXc4RtgEu607GaWV0gIMfyVBY52oV+OaNsEdFetrJnp3c +friG8vJ+7jdq6zjUCGgnfUIHoViJPh3JuFfhA3jT0gQDKW5PeI7dxhrNvlqdYfHI +fxX7Y1/J6cTQkqJ1cai2f0bwJIJiTAThNbG+zrtjJ7fZ3wJ4udyU/IKrwShqtmTb +1Ofj0tJDdwOH8i84vIySLUvR9aAb7ClFlnsx6rzwOxG90W7C0LA2M0EHm4FezJm/ +FfujnZwEWr1T9Wki6qE0MHCbdN/TTDws//EKkkE44FC+amL96w0IQl70vpE37j2A +zlDWvFFID95SIxfmpkwWDvXDKv6gr1GMLeysCl2fgpY05Xidw5cEo9/tEkuWn/dG +x/D9hnLBGeroA0251ES12jemqDjI2U0tfaeHakjwSsoWElf94Qmuh2iPZ+1zIxQs +7o6nAWN8X9hfsmrDTTHlww0TEfrjlbzG5Yh+0ZRxmejgiUyOCXck+eh/ZXMXvfWh +y3CorIIuWgkRjm80PYkdaRDJdZuyP6R7tXfTXNVzAiSQf0Qx9ru2KB2Fs/XZPamH +KjItAU5Q6msIVvaRMS0muQgV+b6hqSEBzqXqJfAlpVLHXr5FqK+U7EB9y02B6piB +tAmxqXP8OOCoQql6/vgIcrDFUOo6KtGBW36ef74XE3KCUVaIzVJZSIt6i/Vi0bZj +bAjsJUQ3qDlHdorv9TRVOhnC1GUz7SuYnpEOyiXmyx3LAgMBAAGjUzBRMB0GA1Ud +DgQWBBQ62csZcH/meQcENHhNbqz9LMzwjjAfBgNVHSMEGDAWgBQ62csZcH/meQcE +NHhNbqz9LMzwjjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IEAQCa +SXUWwou6JG/0ubilpl4nBPIhK5sp/7jKBSsOEwn4jROz656Qf5M+mSgbQAjp/4I1 +qwCBktTF14bUDrxKpAga4M1KYilal8kiExd3WSGxbeNpdazbjLGdoDKKIBa6++df +lCrxs/2Mg4RvTN4GOaj9A9LanWLj+rhIi27WD039dzHpZwYwgKpLwpvGHz+7bJzE +93BqLqoG2q7/Gj+Y/uVfy9Vn1ikxHGJlS5pggH38F0iGy1QhmVHDp7umNUTHBG3p +Q9a+wcNycrEkHQ/sniXiEaWzn1CFmVt6VcP2AAlioyfv9Q0hF6DRFeQrgNFYixj8 +kpomkqEtFO5Yj+J2FQZFq8UE7Boqv1oSdVnON+7Hy5gb4x5flKvTx5Sok1dg7W9B +bYfICLwKCEi4mr1toQLT7e7PicGJXKh0nyHWHhpn9SeSElQniIlZbVrkDHx7zwOq +fcYbjMha3uyqJbd10Rs0ytlL3uiQcHVs+bc9apSW9QPPFW1r5PC05Wn/9+iwU5Vx +2s9WNgncvvdete/UjGBSbpXROe0fSuJf4+VYNK1SF9DJFaDim1zrOJWiT5bSxJGi +MGKnQjEZZEs304dfunuH/I16l+UzTecd7QHgHgCfRN+pJnGyYbpT2lt9CCBD4YZX +qBSQm1iR/7OjgFuLniOF4GLmatuNgVQdKQd6IcllPVK/E0khUwZ3LNV1RRrkvb0c +9mNsnvhW81rBoD6+KHVgaiA9v9fSqeH8KDNbaqKImt9f9/hZJE1joy2hJIkkc4vz +KNQy4aWmRUU37xlvF2yTWt8MuSf6UcM1IC5pfl+cEXNM3kyUs6dps2D66AfAsz7w +C82xUPJ5blKhEWcskmiGXDL64NnD465WoMHPGVorRlRvdHy2mXQWaePF0OpmGtJh +7LqRuV5ou9M4/fmPHrfLJ81ZDoGoBvKpibr4V/3wxdWYjIaQ97MePssVnBFtBKxI +lcPsvunxL6dyxL16FfQ2WPqWe6Fq3UT39Lz+3y6SjtrIcASKJAE77HIPypITSoRI +7Od5OT7ZxB1hxtvqHz45Wyer/aDMq2YDBDDs45s8qEMSPYozvs7LNprU42SJC/LG +GjVFiIXjeBzwTUIjZOAjQ8lLFN2eBOPljdDLmqNjuVV7CgWrlIQ9PafPRXLsfC11 +71Xx4Kmb+I3v/upagQXKikNQZ3IFuXmCofRoOZEnpIvIj9+Dp3TgvK1Fpe9ldFhN +h4Q09rb/zCMvB/yRMkp/JP6+9qySBCHl9kl5W9/bsgLgvdZKR0nDKSwxu/doyPQg +/lgbeYbaZes520gwORtgSYJzuCt0n1nuYxbxINzo9Dw1hH0xgWEhDNL3gjZonmf5 +gCN9CPQlyEFKI9Q2QVUC +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIIJKQIBAAKCAgEAwJSerjL+tgafYE9i601391BfcpXWpUopcGxdeoHMTziqMGDp +J5BBXBxU3RRgr6XZGqeS32b6xX4LEDAMBUe2z9CYP/i1uO4/y0xCJlxSyXuHFHMt +EraVcbChfcHsYmBfGMNyQKWV6u0WBQzKVvgAK3ygDV7hzvl9jymmY5yNo1w8GCGT +T24pVQ4rL5Rn8daQ2dwXpw703zZj5s90vWGDyavqftT6O/Rt3IGOM35v/eCAidjw +0bI8emXp7O+aBojn6y0DvtiiUJg2gbtl7EykFu2//Yzv48eXHlzmXN3gdu4Ll861 ++Qy+iiwhklojz+Yzknpp67omk8Fe8ZFETU6maaGTUzdpC9Tir0s9guRciK+4f6wd +mdVkdnfaGGlngaFOmBrIXbaf+Eh8w7NIgyGlqj/Vi4tVsuBd1YlnH244hP/9r/cF +3gj9zX8+3XWg1IiGIQBLtt5aPRxC2xJpt5DAQg46VvFYUDVpGiAU00TeJbiCmzin +/igeZP1ZqtvkBp0TqfOHs3WcKIOg7smgdTM6PxW6cufZFny9a4Ekj/Z+HVMlWM4G +ZAGXpgYcPwFpFaXO/9U6KrbPxq33StcZRvnwpi9x85M5mZiMorXqv/XXakSAm6K9 +dev43qokpjHDjqb4wAPZ4NDQFzqAVkyVzIEDInC7Eh6NRO9bCh119GdoVqMCAwEA +AQKCAgEAuDVxE2/z9GmhSZ6mIC2Z8xcONazeBH1L5h3BzM0bgSvSnzQT0aRK4LC4 +/D/hvCIH6VchRlBaz04hhvpuhR5z35TIDWj5akt6+huXqtnk1pUyQH1rP9smV/l8 +f65fTjqgvC83ul6paG4gAfSaF1Zh0zcCYcfAdxpu3+IXJnE5imlPkkWLgw78uj8z +T+/E/a8gH0RH26SS1nBQXxdRs1TzmpS3WVqfgXntHF9QhjELLuzwButcbzjuYKXb +fKgzzMxoCqykSIkvuaffe3ilpcIps0T3wLBvRpJEGucB8xLJAvnwXOV9axylpcVQ +140hdFveON6fMrx86hitmKQ7kTcKNZXEnaduehhQgDn6bqeJoAfHs4EX1JJqPZyw +ibON1LYeUoFw9yWRy35Wr/XMkBoPwAykCWUwmOm2QEbmwhC7ORdjUVVuzrFdn/c8 +beoBfJTJ19GQjqSNcUv0cevfwYMxvimTh6oC0yPn3prRXCzL5Xd6ssSW9ISlIpu1 +etbhkvP1GNDKiAbH5uTZNIYMANbdOybfFHDUDWXHg0ObvXVLOhjH3OzdAORHKugS +PPygnW4eXKt5R/uDRW/B0aUWLDtuB2Uj/+YQoA6Bm2AD75e4BkW9tRTqNBXOCCtk +onvyAVJC4NoBZZQBRaOMBa0FIIxrjPLS9zmlyLehLjg5vjwjbAECggEBAPKmWUhO +0HmwQ4/167CMwn+lIW/v9U1gQ1fvpBClFeJF/Px1AUQP+foajGxuXoMMnwH0fTrE ++ya2PA5ShZCkV+ajlBd1B8ymCRu1lp4ilCzEgjNU5U7nhJESCXBNRFEGFSjmO26a +66sny4FiV7d6DeiJ36vPSn2BV0GezHedhbZBuaE+vVWahCXESsAqhAgejRB0A1uf +sSyxXDaJl365J17jdO3YbS7p8LsovsK/Gfn6tTqxMNDnSJWgfFUPLOBznK64L1bJ +RhW9HVrOeIrgV/l7mWEN/LFmWNMEcvi1E1oF08ZamjcwCmtBdGADaPcx07xQyJnQ +6czKf52RMMcQK1ECggEBAMstD3JinyrNb71kb3fL0qlx3kO2HRsqbFVvuItd5SF8 +3/y6GuKmAikhmiZTx/DtGDGUIHD/ioiWkgswyoNKbuKcuDHklc9v3zk2A2Kac35c +KXg//3keNouPLX/NEsu8haVas6GJhlvA+FxgtuNYQeCRMWzrzyCDBNf9KVnV8uV6 +/DBs7W306Q07im1MGMCc3P9Jl1cA0auyxOPD3mSnoDZfdzJmwNjrELSunM2BfzRn +6h9Yi6adFkIgcEKg1a6/R6CyCTGGYs3QQ7+a+UoiNCXj99td5KWW+WMpSns6I7pw +0bmiCb87lXrit1nn7Zgkk7W46jO6H/KyGgMQDs7b/bMCggEAC4S4AkWzgcNLQb8z +w/q6lOKa1rx2UYj7SWZXzG55vncCDl3jhH6ZqDSwa8lFdUUZGzem5i5JmcnWyftC +2d3jSlCDjCWDDETpc8ZH8xPDIujlIVirVfaJhXVsu0b/sjTutjVPpu11uHc4Itkv +Psdtd5dr5bT+XTzRjoziOd9hZIh0LmJTDIg8M6rAvaSHBfelTJ2lNyk6eNume/RG +G77gTpHPkCbQ8AQs6EWD4Ky/p+0twy58Gb6Q5IFsxYDl6XWzf1vA64a8a/XBOflJ +IZaKto4WdtP6JdWs679vUb0OwRw7tFPCtFH0fKjrxE8FIY7c9TiEfUC8iHsoWat1 +vE1ZMQKCAQBBLl6TQsJvd+LOLsd39kLKK4az0Fv8GBsTOblJtMDKgoZVTNtNNRbi +XS5X927ggx/M4AmcVs75zNxjjK6beiiiuMZ68yuAlhJWB1cErio5MpX3RwjNsXys +Py3In2DVTdDOYI/aVgVtsDW9ZSWnP+w6gDoMCIa1lnLaXBSFBpdbOZ5oZrmxGe4e +WaiqMcyLFofruo870T5yx/JUY8UYI5LJfsz9tWtO6/K7FH2njFDj3iaFEeITfLfk +VQXOykxjOGhhTFyYr9VI0/S4Jp6tQtXaBg3BKZkt6oZtYpTLfbZynLkbxbk8yX/G +Ia/Svw5BThK5LO6t05tmP+8KZn9pq7fzAoIBAQC/JwXRuUelycI7+tIXvcDX1ydu +xASH6fyYcB1378KWNzWddcEb4NscfdRK4ekMO+oPyd40DNFl9ESXSUrxoILUIERV +DywvQPMh+2sEblzDXvKO70BmSBSwq0tgfLSXpnu6nv+EHMRARA/qTk9R+Gl/REF/ +mH4ojpv2jHE50ysWFWvxK6whSG1/bMXBsT7YocR1TLBxZpaB1mVxUJ11ESKDMy+A +lf79rIhGfU41mjzr4fkuYbERQy0yM3+lfG5qShAFAl52Fa2eFVBFso090+1TMhlR +1ZmG9ZnE31uXoKU6OGcAGyFmvwhBIkjczH0z74CIYkD9gZJ1lW4RohgiZUja +-----END RSA PRIVATE KEY----- diff --git a/reg-tests/ssl/client2_expired.pem b/reg-tests/ssl/client2_expired.pem new file mode 100644 index 0000000..9d0d2e5 --- /dev/null +++ b/reg-tests/ssl/client2_expired.pem @@ -0,0 +1,81 @@ +-----BEGIN CERTIFICATE----- +MIIFKzCCAxMCAQMwDQYJKoZIhvcNAQELBQAwdDELMAkGA1UEBhMCRlIxEzARBgNV +BAgMClNvbWUtU3RhdGUxHTAbBgNVBAoMFEhBUHJveHkgVGVjaG5vbG9naWVzMTEw +LwYDVQQDDChIQVByb3h5IFRlY2hub2xvZ2llcyBDQSBUZXN0IENsaWVudCBBdXRo +MB4XDTE4MDQyOTE5MDEwMVoXDTE5MDQyOTE5MDEwMVowQzELMAkGA1UEBhMCRlIx +IjAgBgNVBAoMGUhBUHJveHkgVGVjaG5vbG9naWVzIFRlc3QxEDAOBgNVBAMMB2Ns +aWVudDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQD8JQiW54JVNyFa +lPvw6skL0W5790n5R5kx10H4RUT3sIErV0K6Hvz/KwVG/jYb8yA7YSHZKYaklNis +Zjpxj7tnKop7QwyWViXlbW1hRC+imsyO8PLrrc6YkLujKBmB1/z4523/opgNE0+m +ROEjLIEB/nPHSPy57qdS3RdbCkQoBT/1fG8yyKbhcyHbL1Aj3Hk/553ZSgOo/Xl7 +HJ8wM+MzgkoSvPFGHn4WGckBEtiz9Fvt7v8RQJhMePjOXmDLdoiaRmeyhu0a8drq +fg55s4LFbM58vW/pXAPyb6KzPFC1htFY+yBk2l5s4JpggNuvXEJIiP+9COY4D/oy +79mMxZXWY/6VY5NQu54LN6vt24q9pBtaF6OjsaXUz4ZW5pj8Qpej1uXS8N69jgy1 +3CR4kFDb7pa1roe9zXq14h64kpoLA86Y17B3rRAIkIDGf/LdwL1il92Jdcl+K4g4 +YycbWCzgNb4whgokfYGfwsVV01SG1+19h+Nsme5hYROQmYbCbC94lAWJD/U/7EUN +6KN4A7WgCxTt7Vvz2GSEE+HU/WVO+tfgxOPs40M5R3D2LKC0owEyXqkFxAANstd3 +ky6KZfkVQP0U+iz8m54o5HKvoF6EAzEHR/l2kPNCBj/hhyYGi44SwjXEOdzOcJVM +buA7Hp2U4eOhoAJ/VoWJhY2gntcQJQIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQCl +h7ITBQcBe/Rhc7Q7YE/1Sr9duVrUAUgS5bO1xHzqlBeUxPXqQhBMYBYLnvoVdJUz +Hk/7JgvuTgQWUHHabSmKiQ5ug/8sRJSJpOavWelJW+gKaBbMUDZ2xiVYsVXJSmCk +RpvZV+Gb4Q3JRPxkz7+KddB8FnvPYg16LyfoRKk5aVPD4vjT3ePgFZRRLY2w6BH3 +tQFB/xjCTLyX6Bhu+fC37S2N/+a+i7/vEpcOcjKpqkE/Kvb9W5Usjz9kIy5ceq6h +i0t6FfYVcpwO6ZCSB6DT9OnzbdzPbYILdYhpCua5i64YS4cSaW9ltFvsTMDy1Nvm +VbRh3kEtrkywXa5XmYbQE1Zm56jc7MIiyQRLBS60/SA5IzFQFZQh/NDzysLlvDMf +vdExBQ5HJGKje+GN9deYoN3WXKpK+Qik6YZ3cVKMhBD6hYTM/da/4A6XGJEKvARy +21rreRz/D3YMwac1/b5DPViU/6pXMGKud9/ZtlkEi7NHdzVJHMl/htcVQGlTnZdK +Q6Yeug24JbnBZxIbhcp5aaJ+rzQeswL2SkWpF4td87Ku0gFEBShxG4tQNtfvewML +XFybPNAkKOhR84K2rdMKwjva7vxm3tI22wll6LTVP8YUd1SS3/t9yL4jWxHX4Ds8 +gxdxuGWjJe6zm9R6OX63sv0meKNUsesmKQTpdu/gLw== +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIIJKQIBAAKCAgEA/CUIlueCVTchWpT78OrJC9Fue/dJ+UeZMddB+EVE97CBK1dC +uh78/ysFRv42G/MgO2Eh2SmGpJTYrGY6cY+7ZyqKe0MMllYl5W1tYUQvoprMjvDy +663OmJC7oygZgdf8+Odt/6KYDRNPpkThIyyBAf5zx0j8ue6nUt0XWwpEKAU/9Xxv +Msim4XMh2y9QI9x5P+ed2UoDqP15exyfMDPjM4JKErzxRh5+FhnJARLYs/Rb7e7/ +EUCYTHj4zl5gy3aImkZnsobtGvHa6n4OebOCxWzOfL1v6VwD8m+iszxQtYbRWPsg +ZNpebOCaYIDbr1xCSIj/vQjmOA/6Mu/ZjMWV1mP+lWOTULueCzer7duKvaQbWhej +o7Gl1M+GVuaY/EKXo9bl0vDevY4MtdwkeJBQ2+6Wta6Hvc16teIeuJKaCwPOmNew +d60QCJCAxn/y3cC9YpfdiXXJfiuIOGMnG1gs4DW+MIYKJH2Bn8LFVdNUhtftfYfj +bJnuYWETkJmGwmwveJQFiQ/1P+xFDeijeAO1oAsU7e1b89hkhBPh1P1lTvrX4MTj +7ONDOUdw9iygtKMBMl6pBcQADbLXd5MuimX5FUD9FPos/JueKORyr6BehAMxB0f5 +dpDzQgY/4YcmBouOEsI1xDncznCVTG7gOx6dlOHjoaACf1aFiYWNoJ7XECUCAwEA +AQKCAgEApmQJ9wtvhqyK5ivK1oEZiyL5tfTKbCZDghB7CEst6AYiN2euMQSiEAFj +yiWXr3oRmx3OKHCu2Y0gLySHDMm88aexGwZ0GAFhoLVFqRpGFRfyRaHbrItV+ngI +WvLrYjQWTGrsu/WgQYCs3xw1NfD4cUhpPul7XXeQE66y6vEraP2N54HmH60p8zz2 +6p2eVQv5N6KxF+Mv5yTeNc/9fOHA3QzttM/aqFsW+Z6qdnrpZlerEqjUyZ3G4zAx +gH3ngl0GaEhtxfIkJdPUk0n8Y3OCqKXU3Zxlbam7MRFaXM1AtYnyPLX7+pHgHhlZ +xrVCQ8auNw+xNB3bTsO8aEC/X5ZD+ZdO/NCbhzEXPdx5XF6LDlB9uthC/i5G79DB +5DK3GsrPjFjmeY3gmvKm5ikiLNiAvMqghIrKKdLhMJe/AfUTkwVh0Hh5St1o9zPT +ZZP0sNIw+da5/qW2iB1uBdP8h6sdrZVOsfkY/fynny+wEkkP40FAVRHH42p/evRY +qLu0/4MVUjHEgkC0G2ZLFw3n2Eq5omwH2/4u2xzN8W83+kMdBj8gB3qNFjFXLba0 +Z9izOc8xcFsvnmjWIIZ1RZsby0DqefVSfYuc1ON4qOA4hiZZNywS8Uk52i/+7MDi +Q8eGOdUzFPmM6nTPwMLFspzzLTiflTvGDeEITJO5/DFa2ZWf3AECggEBAP/QNzTx +vxOw3nuEvoa/4yp7TBSwvw1V8KC9298IQ3wIqNs699wNqxADGz3P3Vb37psPyBmk +oOclX7we8hUpP0F7OIQo5oENcRu20fMY9Lvbygr8T9j6rxUj5CCqO/HqiD07J59w +4/DE3kuzG6wLV+Tbuo+kV1ywNT3NnjzjFgaZYVjp1P71uUQfsg9ccX8N6jaF5LTn +UTxMAxxvLJ+7qk+4OmFDLZ5y3LiCyezdsCUQeEcHf3VQKNdafkGSmMlpyIpa7D1b +CLfJcR/UOYMezNzuHlLc18pxATOzbCLLZFmGfhdgI4SnNFpdqGk/tUAyiQrN8tTv +JeSDi/usSQaZXlECggEBAPxUIfMCaSPpG8KM8gHgp7yz+KqY+cErD4Oh/8j9do/x +0JkO2sV8EMSuD/alKzbN9O40KCPPw8unnlvkKE0C4of0ugzRg/e1L8SpOYzKWX5J +zMjO6g7m+QU2kKwrcrjosmaWH32ANPY16fUiUOyl1Md7U0trYFRt9+4eqNdlej9j +xMql9KCii1SrGrrh1sTzluvkIedqKYB7S9nv/z5diTm4F+IiBXU536YfJXJ16LpM +aJE8+yECnV8x5Hr9LEGayjRtxIvLObBrCyeVDCQSXT0fB9sAL+gr5baFO6fq3kS0 +pk2hCkx+r0lqwIOOd8guKSIHIpTFOmd0x2RtoxNOu5UCggEBAKL76yCdYYtPJgD2 +i1lZCof3dHq+PYtmlOAk9uA76Jsu/T5obKDUSIf0IrgYJsKRRoGe5XOJE0cR5dP6 +t2xKElZLBrAVSv8wLD9nFI7Y+Jx0JV8ocEsjNMe4TVGOhJDWR6UTemQ4TdIJ7EO4 +wsmzlHVolY2NPGf+kH1m8wmB+XeM45v9p0omDrrbotvsnxc/K1k/p36m3ngXSegk +4P6IV7NhAjkTzw3jysL3+WUjvWVv/+HpYgjBYLQMoOJwX038StvzoA5bYMuP2bZY +xafHyOh+Ae3zbL07kHN7PktQ4Qe1C8Mi6p5K1a05fOJJx9Y2HGA45R1LnQ3hzh80 +HnbI4nECggEAPGu0+WixXnz6PbrcVGDEKaZ6u/cHjx7NhzqqcilnU46W4Z+x+Sn9 +Jet8PRZN48CrjsKEfhbJDqIjhGN81vwC3IVYa6tby1vihVf0ROdLSLdJRyhs2Yar +SHlJaUC6JtbpqTD3d2jUxcQhMqa19AS9j8rTJjMfDPiMLsO+sF1HSZiNTe0xR6nE +bVDPhMKBWAXwNKobCDveljpv7k7OstNZAa44Ydi9r9Vc3X2FzQO456tWOrj8dWoX +3uymhmDLUSZMlwNV1heix8DKGf9Rue1/0Bv3GJTR4+lnBy6eG1ZdRNxxGhOe0LRh +KtZaJOZfflq3VMOanz8e/hjzifPK4duvhQKCAQB8Mo5dWvs5fCpWAQrNqj+ua8gY +a8ftp7R+idGGgOLSCUArjY7sS1RvZzCB28I3/5QpAuEEhaLFTABNonhbD5MdB5SL +xVxfXqcW/WfXkGF+QqB1AMXpE4zLeGSRERWpWJSaD7B2I8UdS/Leo3lVchvA66qx +SG+Pojcp5DsoZP3hrh54fsPdGorzezoTIwfQtsy3P8DnzPohjzbqDKmloglDbo4Q +rBuJVs/Gc7UwZGvka+roi6VUaVdRa5PAluCE4GS9HSwf31k74jw3TfYVIlQgL5Yi +kIHsC0yXfJ0FPXiw62CMEr51ssX3QNGTIKfos24smCjK09eInNZpIZm+p+SL +-----END RSA PRIVATE KEY----- diff --git a/reg-tests/ssl/client3_revoked.pem b/reg-tests/ssl/client3_revoked.pem new file mode 100644 index 0000000..0aba2ce --- /dev/null +++ b/reg-tests/ssl/client3_revoked.pem @@ -0,0 +1,81 @@ +-----BEGIN CERTIFICATE----- +MIIFLTCCAxUCAQMwDQYJKoZIhvcNAQELBQAwdDELMAkGA1UEBhMCRlIxEzARBgNV +BAgMClNvbWUtU3RhdGUxHTAbBgNVBAoMFEhBUHJveHkgVGVjaG5vbG9naWVzMTEw +LwYDVQQDDChIQVByb3h5IFRlY2hub2xvZ2llcyBDQSBUZXN0IENsaWVudCBBdXRo +MCAXDTIwMDQyODE5MjkxN1oYDzIwNTAwNDIxMTkyOTE3WjBDMQswCQYDVQQGEwJG +UjEiMCAGA1UECgwZSEFQcm94eSBUZWNobm9sb2dpZXMgVGVzdDEQMA4GA1UEAwwH +Y2xpZW50MzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAM+8CxcAKMMh +BILdtSx27Zjlri9ygpI55eW94t9rYb967glYbF+ZGZ2LiqXHzIpabasquXD/oH9l +fQpaeb498ZUblbVb0OPyVkSSBpt4y0wPBYYiUGU7T94drdMwEySIyMEIRNlfXePB +EQJLbdksdFBu4QCQEzzdL3aMBCogFfN85zJ6WJhDHnkbtKdUpKJ5irBB/3Hs+pMq +I3Y4cdeWmFkJ+xQpu9oh0igAhkbSPYXu+asSCzExO4G4ttBnQQh4RYUUe+IqO8z0 +QQ/La+m+OBXWR1ti+/3ImeZWdRlA7xpTNYTOxAg0eO1FuUhwvw6Fpvo5KV7wre4W +Qkmsjc5vpxubWWrdfSK/YB8jZJsdx2zgk8thdhj31Zhv0PUP64fhX03DKFSF+qNG +0POpjPthu+f96umHfIFNNKiLPyWBpl0+ppI1FB8uW9xXRZw00iXl89bXNa1lbQqr +c3cj893HUnEpx3H0Q3piEsKu0mchGXiVVJsoZgbLn6yOXDnkWBQhAFvvRcfrAzki +w3f/gU+BiT05csRCXtmbL28RaK70fBxD6fDhGRHyMt/0MFhYnJRxmIB3GniQAgC0 +lyqyMOplkHVeHO0LhjrLTZwbbD083A/KRzpsrVLHd8sjCEjojae0tPDj65u0xg1R +JrszrjO8ZNLQoXr2rl6hjxeLC2Yn08W1AgMBAAEwDQYJKoZIhvcNAQELBQADggIB +AIzgQBfDxEdowxYsdZ4cb0wySg+xB11XRLeR9k6c1kExDkpTKRyAy+6CNS0X2mAz +3v/jVoh3G4crlBkL7UJn6ycunuJ2SdiUexsJAOveVgPPml7YnRRfPW9ddM+gn0y/ +TtTB0D52XaXczeIqQKFD67OtjbVvObbrO1cITkh9q+mMtTO8T/V1gBRd1VH1YFdi +nPqTYYA9QqJ2zAaufhZVCkpJJn5onpT5t+GBpe9O0lKlkQrduLzjr2rrfJCg2Uuw +xBXwpvFdOK4BY5tDqVLb7BOLkEUUltWKTYd4IFjonRE6OSxtY+1L/RnEYMfSSVIf +GsTkKugTuVSmmyFmh5H10YjwMMD3j36hjxJcGJDzZIuOQMY+2UKI61eF7StqZTXE +wRj+JMHHRHIEw0181lHxGSCArWyLEoSn57NSAqJEzdhq7wb6eZwqZzRo8EJUSYIK +3fLnfjSLHS/XaH9mCbx7VpYfC310UGzQ1QXSOIp1LtKtxUbT1YL7RTwa7GVfvQ0e +9nsY9/qd9Oo2VJtxKQRsfro6Z/MdP97lUpTaigQEUpB7KICl1ks56oQrunRLXkO7 +EoDNlnDGkp8DghO+tPqx44OogbXBFCRTO7ncYxSE83WcG0UMUvVfGoMJKqF8V0n3 +LmKLNCvzLQ2Gt21Cp/zNiwHSjMNIIqybjAe+nVT4+sSI +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIIJKgIBAAKCAgEAz7wLFwAowyEEgt21LHbtmOWuL3KCkjnl5b3i32thv3ruCVhs +X5kZnYuKpcfMilptqyq5cP+gf2V9Clp5vj3xlRuVtVvQ4/JWRJIGm3jLTA8FhiJQ +ZTtP3h2t0zATJIjIwQhE2V9d48ERAktt2Sx0UG7hAJATPN0vdowEKiAV83znMnpY +mEMeeRu0p1SkonmKsEH/cez6kyojdjhx15aYWQn7FCm72iHSKACGRtI9he75qxIL +MTE7gbi20GdBCHhFhRR74io7zPRBD8tr6b44FdZHW2L7/ciZ5lZ1GUDvGlM1hM7E +CDR47UW5SHC/DoWm+jkpXvCt7hZCSayNzm+nG5tZat19Ir9gHyNkmx3HbOCTy2F2 +GPfVmG/Q9Q/rh+FfTcMoVIX6o0bQ86mM+2G75/3q6Yd8gU00qIs/JYGmXT6mkjUU +Hy5b3FdFnDTSJeXz1tc1rWVtCqtzdyPz3cdScSnHcfRDemISwq7SZyEZeJVUmyhm +BsufrI5cOeRYFCEAW+9Fx+sDOSLDd/+BT4GJPTlyxEJe2ZsvbxForvR8HEPp8OEZ +EfIy3/QwWFiclHGYgHcaeJACALSXKrIw6mWQdV4c7QuGOstNnBtsPTzcD8pHOmyt +Usd3yyMISOiNp7S08OPrm7TGDVEmuzOuM7xk0tChevauXqGPF4sLZifTxbUCAwEA +AQKCAgEAr48B6ExQJqhOwbJRHOTdY6woCx1BUAbyTbiudZawozxm0ysRW7FtvoFh +iT1TlVFbAZ833VGL+F5y0D8qSCbddeA8I2sXHK1/TrACOX5agUropjV1sDfyBYsb +jjFA3E1lLA2q8fHwzTwq/b91dGZnXlp2eR1JxNRA+nTWSCuZoY9bbIONQBDpPfy2 +LfwQrub82HzOPx/BnIGuOoj1XPd+hTE0KhQjF/QhQYE/+bZQHFKcWYEESGyNF9Jd +Xb8FbP0H87IeCEMdCtcZ7RlDd+U0TPAsmgULZa0Us1850z/XUm4j+rsrXKvLzupv +7dKrBMDbHvkUB5Jry5ywJMdZiK8/j0QW5bw9Hw8tEyXxT2gzXFze4DrEHC1cPLod +3bcMOnp8axtdfm23tlFQuq4fGsERABFWByylF2Pu9KQ1AgH8/53IcVnNjd7Z4ZlA +eBrZynEDg67sggFNRa6EnjAYFS0Zqgmfo/160awcGSLPLSkE5FhtByQOEzyAumXn +UmDO4zlP3dc54WzCnxdS8GpbbmjniXGSDe9D16D0uWQeo+LCoDDTExT3wDjY3tDt +R4VjIBVs1vWXH2oG/oC/ulgXwcSKSSvtqftcGnPj9EE6exNzanTQwCFHosYWl5Tn +MkRsxNRFITKksNH5sXAkzwogWlyG4PK4ink0IixpYh2N0WgncDkCggEBAPqZ7z45 +F/YusR+eJdMrloECYhP1BId7zUzZglAUof/KJH86TVnQ/wGBcl6x9SXGzy5Mix8S +q0qUILJ3nXkyRqFjlch9c8NlMR5P/IPyQWupSGNFPTIBvNefCfqosEFD9635P4ND +sN19gwrx9IqMYgyPzw05G2CJPafemjF5NLIHKyhUnjGUij+D/WZYCKvHIrq085ac +0dLncRvlnzloa8PCGXDXcTuFacVGcj6QZJvn7ZrprMOwpwh7RT02U9cqlLYKfjEg +9xnTSmxbb8esRtWDlJPoj3+P732Cj7BynSpvLFSsvHAAFS4j/g3XIjdY/yocd0xG +UfYDEcilgPiaEnMCggEBANQ1st6aaf/7oH4hJ/mgOc2RhGYxpjHgXs+ux77llHks +o4VlAILV9CLQyQ9/3PU/4vidw/rseZwPmONDlBeU4319MQzjZeihaqfaTQXnQRBj +xX2sJ/7EeBoq6Xlkvc+lVbiWcA7i97dYEumV/q7ozYRyAhP/D/VAdmT9ZWK3qJ+l +/L7h43ch9PWGDOjiUIfWx/xAodyDUEM1iforv/S7D4+3j9BriRnhpZRLZT5bG24h +vVN344ETxaoVWwjw9yzmJHF/4ooqJgdTsjJ8ujPPLvJKXAD7ZVerhcUpZWmyMACL +Dj8IuNZeB7IN9LOCr1xPenR0jdltz7+LU6WTK0F4NTcCggEBALvxvOL+sMDaTc63 +rgiM1ShWIDZ1ePsfV15+dmQWxVRwRyUAFcj5nHaFnb/1WTUGwJUppOEeAEdDhq4y +VXDyytP5OvmNVMfDWa4xMOHIS1YyNG73G6kocneH+FT8NIwOLHBW0VJh7wB+RExu +IAfUtyhSpmd1X9nrs8j1gtD95Q5rn+t0YtwuWey+0cny1jX2eE5srY9Ud2zkVQkm +El9cuA2twaTGf06zhRsF9WKEql/e9m1LOV3eW7dZtBjvaLujXLqWbgPshEXjGBri +DJhE1S8GquSu8wgpa+TGiXs8yjBsBmRO1FhvR3M+XSgGI8w8u8naZYJX7tpBfRHt +RiesbY8CggEBAKMcm14rBmryOIx6Y8Wl+Igf38rFQt93fKjZyULcKGFzhEUWO2xV +lA/mt4SoXWhNMOK0MV1/woHII1YcLYpqsOlV/wvPBhfnapmWXDm7ZPF6HuTYHO3g +ighjD451dshSZy84wu1OW+WbVv4gguBipQW2tA42sUdrwxUhCHr2fDAqX7lA25xI +h4bpAKdIvWmMF6+25jMe4+SlFGcslaFA31cyWuJypbE1FhaEVU+2q8DdQi8UKdSf +JAH15EFdJkBmrYBoMfLNLunW1VOlN2J3T7iAm3NNyLm4Z1wC06aIhgkE2XBt/dUX +9YZQ39PTEYM8u/0jUZzcoSCzsRnFoyvxf8UCggEAblaNsi8/Nx8FId/aW3klrIxY +UfSVXL3InIkrr2hJs7GYMpdWRwQZpo+Nv45cBnGoRwWWIsYkcWEbrs1vxvkNg0Ro +pTa0Pt5gb1u7BfvpSqC/VyFBd66BcTQeJqTUHzWPKhMyCrP/eRYfFFQtpy5EZ+/O +cjEVO1Tv5VhqM1PtANHdsS6o0jKMWFQ/Ofu4sOp6hQl4E1oOAzjLdtyBgJzSk1Jg +M1lKPzSpYgRWcMB9CFTE2JO/4b+iMhxQjvGtD5nkeA6ZD7DSDItH6lhAQsho1pMi +uoFlxDSFYHt0KcFp9zMrB2810mmNvjiEaqVXkA7QRH3XCA0BTkIXxzQe5QgTNg== +-----END RSA PRIVATE KEY----- diff --git a/reg-tests/ssl/common.4096.dh b/reg-tests/ssl/common.4096.dh new file mode 100644 index 0000000..8db27ac --- /dev/null +++ b/reg-tests/ssl/common.4096.dh @@ -0,0 +1,13 @@ +-----BEGIN DH PARAMETERS----- +MIICCAKCAgEAvpZPDLMGhdop4RgoSzRJfr681WeWplvSvBsIqyKB8D3uNPZchSg7 +Aci6+yupRDtVeaLMmJgqjiTb9wYXhJNxyuVMPfnFrYwGSm32OUcMhECD6N2elOj5 +WS8fvoYIMvnENyDsutmBObXISKLxeaY+PJEbwyEeJmdzEV6oM0qM/2bEJcgQ00p2 +V1Nge6OZpjahlRCpKHsQAIgtUpchZVTKZCrO9WbYUPVYcUIAmyNLmTlPmM08EcsN +dJqkhse0xZN2isnGJybe1ABIW8D31aWqfWhjmuNqe9JTqz8BS00WOeKGYiEENIIF +lHmU1uKYm+9ii1stT7WyrtAMRjbQSVsye9CEkne5jsQuhF2gzLMFhsEwE5svDBn9 +CeJC7V0WHef0kHNUSm9yzRQWFp4Y9sJI7Uq3Po1xOBBCDUQnDJTFsNiJSF84gYGo +fvjMsvf3mLNkDE12g3trHUMjrns4MLpla21bA3FKEqyfUuR/yYQRtLOkR7sxF4+J +lporo7jHhgPK57euhG8YLOgSEa0LIYXsNSHI7yDpkXFmwtPBQRE5ZOaN4mw1fsHp +/+adsUAh30KDeoXXyZg9dpZFnq/GZlAHdiO48oVsYnloNNYwrPH9bU53u5oj73bo +CTCZOb7V2BvfvnfwNmzwuofXMFXBvNqDSKcM3rkMSi3OomuHBZ/QQwsCAQI= +-----END DH PARAMETERS----- diff --git a/reg-tests/ssl/common.crt b/reg-tests/ssl/common.crt new file mode 100644 index 0000000..1f0c275 --- /dev/null +++ b/reg-tests/ssl/common.crt @@ -0,0 +1,90 @@ +-----BEGIN CERTIFICATE----- +MIIGeTCCBGGgAwIBAgIBAjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJGUjEW +MBQGA1UECBMNSWxlLWRlLUZyYW5jZTEOMAwGA1UEBxMFUGFyaXMxEDAOBgNVBAoT +B296b24uaW8xFTATBgNVBAMTDE96b24gVGVzdCBDQTEeMBwGCSqGSIb3DQEJARYP +c3VwcG9ydEBvem9uLmlvMB4XDTE2MDExNzIzMDIzOFoXDTE4MDExNjIzMDIzOFow +gb4xCzAJBgNVBAYTAkZSMRYwFAYDVQQIEw1JbGUtZGUtRnJhbmNlMRowGAYDVQQH +ExFOZXVpbGx5LXN1ci1TZWluZTEYMBYGA1UEChMPVE9BRCBDb25zdWx0aW5nMRcw +FQYDVQQLEw5lUGFyYXBoZXIgVGVhbTEWMBQGA1UEAxMNd3d3LnRlc3QxLmNvbTEw +MC4GCSqGSIb3DQEJARYhYXJuYXVsdC5taWNoZWxAdG9hZC1jb25zdWx0aW5nLmZy +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnb0BDF7FsqzslakNg7u/ +n/JQkq6nheuKwvyTqECfpc9y7uSBe/vrEFqBaDSLQagJxuZdL5geFeVtRbdAoB97 +N1/LZa6vecjjgGSP0Aag/gS/ocnMRIyvlVWWT9MrD46OG3qZY1ORU1ltrVL0NKtt +JP8xME7j3bTwIDElx/hNI0n7L+ySkAe2xb/7CbZRfoOhjTVAcGv4aSLVc/Hi8k6V +kIzdOEtH6TcghXmuGcuqvLNH9BuosyngKTcQ8zg6J+e64aVvC+e7vi94uil9Qu+J +Hm0pkDzAZ2WluNsuXlrJToPirWyj6/YdN6xgSI1hbZkBmUPAebgYuxBt6huvfyQd +3wIDAQABo4IBvzCCAbswCwYDVR0PBAQDAgOoMBMGA1UdJQQMMAoGCCsGAQUFBwMB +MB0GA1UdDgQWBBTIihFNVNgOseQnsWEcAQxAbIKE4TCBsgYDVR0jBIGqMIGngBRv +G9At9gzk2MW5Z7JVey1LtPIZ8KGBg6SBgDB+MQswCQYDVQQGEwJGUjEWMBQGA1UE +CBMNSWxlLWRlLUZyYW5jZTEOMAwGA1UEBxMFUGFyaXMxEDAOBgNVBAoTB296b24u +aW8xFTATBgNVBAMTDE96b24gVGVzdCBDQTEeMBwGCSqGSIb3DQEJARYPc3VwcG9y +dEBvem9uLmlvggkA15FtIaGcrk8wDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg9j +b21tb25OYW1lOmNvcHkwCQYDVR0SBAIwADBIBgNVHR8EQTA/MD2gO6A5hjdodHRw +Oi8vb3BlbnNzbGNhLnRvYWQtY29uc3VsdGluZy5jb20vb3BlbnZwbi9MYXRlc3Qu +Y3JsMBEGCWCGSAGG+EIBAQQEAwIGQDAxBglghkgBhvhCAQ0EJBYiVE9BRC1Db25z +dWx0aW5nIHNlcnZlciBjZXJ0aWZpY2F0ZTANBgkqhkiG9w0BAQsFAAOCAgEAewDa +9BukGNJMex8gsXmmdaczTr8yh9Uvw4NJcZS38I+26o//2g+d6i7wxcQg8hIm62Hj +0TblGU3+RsJo4uzcWxxA5YUYlVszbHNBRpQengEE5pjwHvoXVMNES6Bt8xP04+Vj +0qVnA8gUaDMk9lN5anK7tF/mbHOIJwHJZYCa2t3y95dIOVEXFwOIzzbSbaprjkLN +w0BgR5paJz7NZWNqo4sZHUUz94uH2bPEd01SqHO0dJwEVxadgxuPnD05I9gqGpGX +Zf3Rn7EQylvUtX9mpPaulQPXc3emefewLUSSAdnZrVikZK2J/B4lSi9FpUwl4iQH +pZoE0QLQHtB1SBKacnOAddGSTLSdFvpzjErjjWSpMukF0vutmrP86GG3xtshWVhI +u+yLfDJVm/pXfaeDtWMXpxIT/U1i0avpk5MZtFMRC0MTaxEWBTnnJm+/yiaAXQYg +E1ZIP0mkZkiUojIawTR7JTjHGhIraP9UVPNceVy0DLfETHEou3vhwBn7PFOz7piJ +wjp3A47DStJD4fapaX6B1fqM+n34CMD9ZAiJFgQEIQfObAWC9hyr4m+pqkp1Qfuw +vsAP/ZoS1CBirJfm3i+Gshh+VeH+TAmO/NBBYCfzBdgkNz4tJCkOc7CUT/NQTR/L +N2OskR/Fkge149RJi7hHvE3gk/mtGtNmHJPuQ+s= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIJazCCBVOgAwIBAgIUWHoc5e2FUECgyCvyVf8wCtt8gTYwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCRlIxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDA4MDQxODU4MTZaFw0yMDA5 +MDMxODU4MTZaMEUxCzAJBgNVBAYTAkZSMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggQiMA0GCSqGSIb3DQEB +AQUAA4IEDwAwggQKAoIEAQDARiuHkhrnf38Md1nxGDSneJfwv/QksdNNMNTJBdjg +OVmaRCIAyz43oefTWDQ/TebbSwB+Lg9pud1zadGWhlZRhCgBPP8JDMhIKH4eXIRk +5IIa8WD08EwvSlqJL0r4gsMtVsxy7BZHAkka/2Ket9pyGt4kG5n75RFdc6BI80/8 +RwJt/MDxPrcVBAT7LnCluxQpyya9mZCabj7l+9a2yU2hgWS6QqfZJ133krkP/MMh +AEQkSoA4mmBwWk9yPqXmUqiOi7v6iLkIUEh5SgYVPRk9BtU/kDaUdSwuqRrpCZo4 +SsWZWFLxBmLHkSh+G+BWjCVYMQr2ye7e+VMT/20+5xAfq4fj9n5BsPcx3QcVuTof +RAc/Oygnt4MYnIcUb7zRFvCAvgpUHL7BnEn6nhyXjHJGqGDchsg8m9t3v/Y3ohq+ +qmrSzdeuylE1n3W5aWJlbFmyXegNP45MJ0xicesVrXEWF7YD/ir9mGJ8bQYr4blf +77PrbF02komC6AzVPKOJa0jR+eW1wErzYlkYgez6ylBWCiHJd1dhEHlK3h2rXdYa +Gnb45ILCLpEDjNEUrHifLLNXwqJpgZQsJU6BgMgk7ZgBfAKrCfTeg0rkCqCAPeVb +8eSLf7FBF7YBRJ5P6u8qXc4RtgEu607GaWV0gIMfyVBY52oV+OaNsEdFetrJnp3c +friG8vJ+7jdq6zjUCGgnfUIHoViJPh3JuFfhA3jT0gQDKW5PeI7dxhrNvlqdYfHI +fxX7Y1/J6cTQkqJ1cai2f0bwJIJiTAThNbG+zrtjJ7fZ3wJ4udyU/IKrwShqtmTb +1Ofj0tJDdwOH8i84vIySLUvR9aAb7ClFlnsx6rzwOxG90W7C0LA2M0EHm4FezJm/ +FfujnZwEWr1T9Wki6qE0MHCbdN/TTDws//EKkkE44FC+amL96w0IQl70vpE37j2A +zlDWvFFID95SIxfmpkwWDvXDKv6gr1GMLeysCl2fgpY05Xidw5cEo9/tEkuWn/dG +x/D9hnLBGeroA0251ES12jemqDjI2U0tfaeHakjwSsoWElf94Qmuh2iPZ+1zIxQs +7o6nAWN8X9hfsmrDTTHlww0TEfrjlbzG5Yh+0ZRxmejgiUyOCXck+eh/ZXMXvfWh +y3CorIIuWgkRjm80PYkdaRDJdZuyP6R7tXfTXNVzAiSQf0Qx9ru2KB2Fs/XZPamH +KjItAU5Q6msIVvaRMS0muQgV+b6hqSEBzqXqJfAlpVLHXr5FqK+U7EB9y02B6piB +tAmxqXP8OOCoQql6/vgIcrDFUOo6KtGBW36ef74XE3KCUVaIzVJZSIt6i/Vi0bZj +bAjsJUQ3qDlHdorv9TRVOhnC1GUz7SuYnpEOyiXmyx3LAgMBAAGjUzBRMB0GA1Ud +DgQWBBQ62csZcH/meQcENHhNbqz9LMzwjjAfBgNVHSMEGDAWgBQ62csZcH/meQcE +NHhNbqz9LMzwjjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IEAQBA +wLsGf3R1+/I2zQE+lsj7RasZtA/Cos92iEGDAPvFbx9e+roG8Gg8KBsEJu/HN0JH +lMMiQ8dDRHSBMvRBENL5/57oOOhmqc+1u5sazLuANhzAYPZG17Klib7YpEwWoXar +FDDiJYtCyLW0oNLpCswYopWK9GC0RJNucB0NFvOxehJ2sP2/fxGBQMB09L6mjKjd +4KsOzyd3dNf0VYS6jB+/1pcKSHKQUo9HRHB5FK04PsYHoh4AtmEHvmYQKcWWidgU +v26ftlH00ERzuW2juqBbz9mghlNRqXi0IyZ9b4tSj29dxW+WWFzo7j2zEPaD6z2W +DEHq7zvON+g+q6qLgWeszqMgJzjvWjMj00E/t06PoHPiz/cAnDKEqp+ZzxCIFrxj +/qneChpogDWyLbawhyyzbZvbirx5znOSbWjPZgydqaNEFViqbxwinBx4Xxabo6XN +TU020FuMWmgfbIcvtgjKgyKqc97l7JMNNm7LQV9+9W0U5zdIqQKLZ9MMrd2w3xh4 +MAB8NKnwzHReK0TWwUU9HSgFAGdEX6HnyZ3bQ13ijg+sNBRMEi0gBHaqZKDdyoft +B2u2uasSwioV48dbSIcHl+rTBKxiMh5XQ7ENnaGOJkjsIqTVzizqnPHU8eMBnSbb +dsXlamROYII44+j3Ku6OGt51w86eGk4VxI3tmaECcJKqTkwUFD8AcNDrkjtmLuxK +12yjnoM+u1cclfqQ5NOtRc6MJZ27jCobfBBhVdKVDp4X1WNyqGlbsU5adDAzknuI +GT7MJO7lGjkZX2n54BNPSfrSknYMOVYcZqL0Dbcrhx5IyEmg+iOlOu1HO1tdnZop +ej4vT+1V2w9Sa4Wo3UCo84jcm5v/4z7jCYh4BRQ60CFb7GLxZoqXIslcGSPool3n +jl8JWoaLXrJUPfZGXo1iAlayJ5EiMyZl4eB/TBUf6TMm8vLvsPiUT+CEsjLppOdS +eYppZAZ6H1JrJGs5kKBdOJHGn6Pkp5QsHIswOBd1HqHrBbYbZmDaDLRHduILWLrM +e0/IfDdeXB/bKfmZoEpT8xRiauw15p0AHLumiK7KISAehfgBqUnxx+YmgGoZ7EWX +KnMYAfCuC6oJ1DL0gp4Z9yMK1eu+GV1sLxPq9ZruEHW1R+H+4sGyiA5Gso2tgB6/ +XW//wxKclNp5LZR7hqfs/kGuh5asrJrnEbMwWn2+tr/LqfYtYh1D6nHfIXpT0o1d +rNy/HrsKnRDMWxjm03r4hCViuNVD3Zb9anAF/NSPDVu8ATM5JbJNrCYX4eipz6ZE +aQBkwIBkTPgtgP4r8v2G+uMYDw8nq7xh72FK107aeTTwc6MgU5jfeFNMr2XJisJd +lSem1ngKYQSEzjVsTE4c +-----END CERTIFICATE----- diff --git a/reg-tests/ssl/common.key b/reg-tests/ssl/common.key new file mode 100644 index 0000000..4b06553 --- /dev/null +++ b/reg-tests/ssl/common.key @@ -0,0 +1,28 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAnb0BDF7FsqzslakNg7u/n/JQkq6nheuKwvyTqECfpc9y7uSB +e/vrEFqBaDSLQagJxuZdL5geFeVtRbdAoB97N1/LZa6vecjjgGSP0Aag/gS/ocnM +RIyvlVWWT9MrD46OG3qZY1ORU1ltrVL0NKttJP8xME7j3bTwIDElx/hNI0n7L+yS +kAe2xb/7CbZRfoOhjTVAcGv4aSLVc/Hi8k6VkIzdOEtH6TcghXmuGcuqvLNH9Buo +syngKTcQ8zg6J+e64aVvC+e7vi94uil9Qu+JHm0pkDzAZ2WluNsuXlrJToPirWyj +6/YdN6xgSI1hbZkBmUPAebgYuxBt6huvfyQd3wIDAQABAoIBABojc8UE/2W4WgwC +04Z82ig7Ezb7Ui9S9M+S4zUCYHItijIkE4DkIfO3y7Hk4x6iJdyb191HK9UdC5p9 +32upS9XFPgM/izx3GZvxDhO+xXbSep7ovbyuQ3pPkHTx3TTavpm3GyvmcTKKoy4R +jP4dWhzDXPdQW1ol3ZS4EDau4rlyClY6oi1mq9aBEX3MqVjB/nO7s2AbdgclAgP2 +OZMhTzWYR1k5tYySHCXh3ggGMCikyvHU0+SsGyrstYzP1VYi/n3f0VgqW/5ZjG8x +6SHpe04unErPF3HuSun2ZMCFdBxaTFZ8FENb8evrSXe3nQOc9W21RQdRRrNNUbjl +JYI4veECgYEA0ATYKMS1VCUYRZoQ49b5GTg7avUYqfW4bEo4fSfBue8NrnKR3Wu8 +PPBiCTuIYq1vSF+60B7Vu+hW0A8OuQ2UuMxLpYcQ7lKfNad/+yAfoWWafIqCqNU9 +at0QMdbW6A69d6jZt7OrXtleBsphCnN58jTz4ch4PIa2Oyq46NUXCvUCgYEAwh8t +G6BOHOs3yRNI2s9Y9EEfwoil2uIKrZhqiL3AwdIpu5uNIMuPnbaEpXvRX6jv/qtL +321i8vZLc31aM7zfxQ6B4ReQFJfYC80FJsWvcLwT9hB9mTJpLS4sIu5tzQc87O6w +RtjFMom+5ns5hfPB4Eccy0EtbQWVY4nCzUeO6QMCgYBSvqqRRPXwG7VU8lznlHqP +upuABzChYrnScY+Y0TixUlL54l79Wb6N6vzEOWceAWkzu8iewrU4QspNhr/PgoR3 +IeSxWlG0yy7Dc/ZnmTabx8O06I/iwrfkizzG5nOj6UEamRLJjPGNEB/jyZriQl7u +pnugg1K4mMliLbNSAnlhBQKBgQCmYepbv260Qrex1KGhSg9Ia3k5V74weYYFfJnz +UhChD+1NK+ourcsOtp3C6PlwMHBjq5aAjlU9QfUxq8NgjQaO8/xGXdfUjsFSfAtq +TA4vZkUFpuTAJgEYBHc4CXx7OzTxLzRPxQRgaMgC7KNFOMR34vu/CsJQq3R7uFwL +bsYC2QKBgQCtEmg1uDZVdByX9zyUMuRxz5Tq/vDcp+A5lJj2mha1+bUMaKX2+lxQ +vPxY55Vaw/ukWkJirRrpGv6IytBn0dLAFSlKZworZGBaxsm8OGTFJ5Oe9+kZTjI9 +hvjpClOA1otbmj2F2uZAbuIjxQGDNUkLoifN5yDYCC8JPujHuHmULw== +-----END RSA PRIVATE KEY----- + diff --git a/reg-tests/ssl/common.pem b/reg-tests/ssl/common.pem new file mode 100644 index 0000000..206e417 --- /dev/null +++ b/reg-tests/ssl/common.pem @@ -0,0 +1,117 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAnb0BDF7FsqzslakNg7u/n/JQkq6nheuKwvyTqECfpc9y7uSB +e/vrEFqBaDSLQagJxuZdL5geFeVtRbdAoB97N1/LZa6vecjjgGSP0Aag/gS/ocnM +RIyvlVWWT9MrD46OG3qZY1ORU1ltrVL0NKttJP8xME7j3bTwIDElx/hNI0n7L+yS +kAe2xb/7CbZRfoOhjTVAcGv4aSLVc/Hi8k6VkIzdOEtH6TcghXmuGcuqvLNH9Buo +syngKTcQ8zg6J+e64aVvC+e7vi94uil9Qu+JHm0pkDzAZ2WluNsuXlrJToPirWyj +6/YdN6xgSI1hbZkBmUPAebgYuxBt6huvfyQd3wIDAQABAoIBABojc8UE/2W4WgwC +04Z82ig7Ezb7Ui9S9M+S4zUCYHItijIkE4DkIfO3y7Hk4x6iJdyb191HK9UdC5p9 +32upS9XFPgM/izx3GZvxDhO+xXbSep7ovbyuQ3pPkHTx3TTavpm3GyvmcTKKoy4R +jP4dWhzDXPdQW1ol3ZS4EDau4rlyClY6oi1mq9aBEX3MqVjB/nO7s2AbdgclAgP2 +OZMhTzWYR1k5tYySHCXh3ggGMCikyvHU0+SsGyrstYzP1VYi/n3f0VgqW/5ZjG8x +6SHpe04unErPF3HuSun2ZMCFdBxaTFZ8FENb8evrSXe3nQOc9W21RQdRRrNNUbjl +JYI4veECgYEA0ATYKMS1VCUYRZoQ49b5GTg7avUYqfW4bEo4fSfBue8NrnKR3Wu8 +PPBiCTuIYq1vSF+60B7Vu+hW0A8OuQ2UuMxLpYcQ7lKfNad/+yAfoWWafIqCqNU9 +at0QMdbW6A69d6jZt7OrXtleBsphCnN58jTz4ch4PIa2Oyq46NUXCvUCgYEAwh8t +G6BOHOs3yRNI2s9Y9EEfwoil2uIKrZhqiL3AwdIpu5uNIMuPnbaEpXvRX6jv/qtL +321i8vZLc31aM7zfxQ6B4ReQFJfYC80FJsWvcLwT9hB9mTJpLS4sIu5tzQc87O6w +RtjFMom+5ns5hfPB4Eccy0EtbQWVY4nCzUeO6QMCgYBSvqqRRPXwG7VU8lznlHqP +upuABzChYrnScY+Y0TixUlL54l79Wb6N6vzEOWceAWkzu8iewrU4QspNhr/PgoR3 +IeSxWlG0yy7Dc/ZnmTabx8O06I/iwrfkizzG5nOj6UEamRLJjPGNEB/jyZriQl7u +pnugg1K4mMliLbNSAnlhBQKBgQCmYepbv260Qrex1KGhSg9Ia3k5V74weYYFfJnz +UhChD+1NK+ourcsOtp3C6PlwMHBjq5aAjlU9QfUxq8NgjQaO8/xGXdfUjsFSfAtq +TA4vZkUFpuTAJgEYBHc4CXx7OzTxLzRPxQRgaMgC7KNFOMR34vu/CsJQq3R7uFwL +bsYC2QKBgQCtEmg1uDZVdByX9zyUMuRxz5Tq/vDcp+A5lJj2mha1+bUMaKX2+lxQ +vPxY55Vaw/ukWkJirRrpGv6IytBn0dLAFSlKZworZGBaxsm8OGTFJ5Oe9+kZTjI9 +hvjpClOA1otbmj2F2uZAbuIjxQGDNUkLoifN5yDYCC8JPujHuHmULw== +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIGeTCCBGGgAwIBAgIBAjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJGUjEW +MBQGA1UECBMNSWxlLWRlLUZyYW5jZTEOMAwGA1UEBxMFUGFyaXMxEDAOBgNVBAoT +B296b24uaW8xFTATBgNVBAMTDE96b24gVGVzdCBDQTEeMBwGCSqGSIb3DQEJARYP +c3VwcG9ydEBvem9uLmlvMB4XDTE2MDExNzIzMDIzOFoXDTE4MDExNjIzMDIzOFow +gb4xCzAJBgNVBAYTAkZSMRYwFAYDVQQIEw1JbGUtZGUtRnJhbmNlMRowGAYDVQQH +ExFOZXVpbGx5LXN1ci1TZWluZTEYMBYGA1UEChMPVE9BRCBDb25zdWx0aW5nMRcw +FQYDVQQLEw5lUGFyYXBoZXIgVGVhbTEWMBQGA1UEAxMNd3d3LnRlc3QxLmNvbTEw +MC4GCSqGSIb3DQEJARYhYXJuYXVsdC5taWNoZWxAdG9hZC1jb25zdWx0aW5nLmZy +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnb0BDF7FsqzslakNg7u/ +n/JQkq6nheuKwvyTqECfpc9y7uSBe/vrEFqBaDSLQagJxuZdL5geFeVtRbdAoB97 +N1/LZa6vecjjgGSP0Aag/gS/ocnMRIyvlVWWT9MrD46OG3qZY1ORU1ltrVL0NKtt +JP8xME7j3bTwIDElx/hNI0n7L+ySkAe2xb/7CbZRfoOhjTVAcGv4aSLVc/Hi8k6V +kIzdOEtH6TcghXmuGcuqvLNH9BuosyngKTcQ8zg6J+e64aVvC+e7vi94uil9Qu+J +Hm0pkDzAZ2WluNsuXlrJToPirWyj6/YdN6xgSI1hbZkBmUPAebgYuxBt6huvfyQd +3wIDAQABo4IBvzCCAbswCwYDVR0PBAQDAgOoMBMGA1UdJQQMMAoGCCsGAQUFBwMB +MB0GA1UdDgQWBBTIihFNVNgOseQnsWEcAQxAbIKE4TCBsgYDVR0jBIGqMIGngBRv +G9At9gzk2MW5Z7JVey1LtPIZ8KGBg6SBgDB+MQswCQYDVQQGEwJGUjEWMBQGA1UE +CBMNSWxlLWRlLUZyYW5jZTEOMAwGA1UEBxMFUGFyaXMxEDAOBgNVBAoTB296b24u +aW8xFTATBgNVBAMTDE96b24gVGVzdCBDQTEeMBwGCSqGSIb3DQEJARYPc3VwcG9y +dEBvem9uLmlvggkA15FtIaGcrk8wDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg9j +b21tb25OYW1lOmNvcHkwCQYDVR0SBAIwADBIBgNVHR8EQTA/MD2gO6A5hjdodHRw +Oi8vb3BlbnNzbGNhLnRvYWQtY29uc3VsdGluZy5jb20vb3BlbnZwbi9MYXRlc3Qu +Y3JsMBEGCWCGSAGG+EIBAQQEAwIGQDAxBglghkgBhvhCAQ0EJBYiVE9BRC1Db25z +dWx0aW5nIHNlcnZlciBjZXJ0aWZpY2F0ZTANBgkqhkiG9w0BAQsFAAOCAgEAewDa +9BukGNJMex8gsXmmdaczTr8yh9Uvw4NJcZS38I+26o//2g+d6i7wxcQg8hIm62Hj +0TblGU3+RsJo4uzcWxxA5YUYlVszbHNBRpQengEE5pjwHvoXVMNES6Bt8xP04+Vj +0qVnA8gUaDMk9lN5anK7tF/mbHOIJwHJZYCa2t3y95dIOVEXFwOIzzbSbaprjkLN +w0BgR5paJz7NZWNqo4sZHUUz94uH2bPEd01SqHO0dJwEVxadgxuPnD05I9gqGpGX +Zf3Rn7EQylvUtX9mpPaulQPXc3emefewLUSSAdnZrVikZK2J/B4lSi9FpUwl4iQH +pZoE0QLQHtB1SBKacnOAddGSTLSdFvpzjErjjWSpMukF0vutmrP86GG3xtshWVhI +u+yLfDJVm/pXfaeDtWMXpxIT/U1i0avpk5MZtFMRC0MTaxEWBTnnJm+/yiaAXQYg +E1ZIP0mkZkiUojIawTR7JTjHGhIraP9UVPNceVy0DLfETHEou3vhwBn7PFOz7piJ +wjp3A47DStJD4fapaX6B1fqM+n34CMD9ZAiJFgQEIQfObAWC9hyr4m+pqkp1Qfuw +vsAP/ZoS1CBirJfm3i+Gshh+VeH+TAmO/NBBYCfzBdgkNz4tJCkOc7CUT/NQTR/L +N2OskR/Fkge149RJi7hHvE3gk/mtGtNmHJPuQ+s= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIJazCCBVOgAwIBAgIUWHoc5e2FUECgyCvyVf8wCtt8gTYwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCRlIxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDA4MDQxODU4MTZaFw0yMDA5 +MDMxODU4MTZaMEUxCzAJBgNVBAYTAkZSMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggQiMA0GCSqGSIb3DQEB +AQUAA4IEDwAwggQKAoIEAQDARiuHkhrnf38Md1nxGDSneJfwv/QksdNNMNTJBdjg +OVmaRCIAyz43oefTWDQ/TebbSwB+Lg9pud1zadGWhlZRhCgBPP8JDMhIKH4eXIRk +5IIa8WD08EwvSlqJL0r4gsMtVsxy7BZHAkka/2Ket9pyGt4kG5n75RFdc6BI80/8 +RwJt/MDxPrcVBAT7LnCluxQpyya9mZCabj7l+9a2yU2hgWS6QqfZJ133krkP/MMh +AEQkSoA4mmBwWk9yPqXmUqiOi7v6iLkIUEh5SgYVPRk9BtU/kDaUdSwuqRrpCZo4 +SsWZWFLxBmLHkSh+G+BWjCVYMQr2ye7e+VMT/20+5xAfq4fj9n5BsPcx3QcVuTof +RAc/Oygnt4MYnIcUb7zRFvCAvgpUHL7BnEn6nhyXjHJGqGDchsg8m9t3v/Y3ohq+ +qmrSzdeuylE1n3W5aWJlbFmyXegNP45MJ0xicesVrXEWF7YD/ir9mGJ8bQYr4blf +77PrbF02komC6AzVPKOJa0jR+eW1wErzYlkYgez6ylBWCiHJd1dhEHlK3h2rXdYa +Gnb45ILCLpEDjNEUrHifLLNXwqJpgZQsJU6BgMgk7ZgBfAKrCfTeg0rkCqCAPeVb +8eSLf7FBF7YBRJ5P6u8qXc4RtgEu607GaWV0gIMfyVBY52oV+OaNsEdFetrJnp3c +friG8vJ+7jdq6zjUCGgnfUIHoViJPh3JuFfhA3jT0gQDKW5PeI7dxhrNvlqdYfHI +fxX7Y1/J6cTQkqJ1cai2f0bwJIJiTAThNbG+zrtjJ7fZ3wJ4udyU/IKrwShqtmTb +1Ofj0tJDdwOH8i84vIySLUvR9aAb7ClFlnsx6rzwOxG90W7C0LA2M0EHm4FezJm/ +FfujnZwEWr1T9Wki6qE0MHCbdN/TTDws//EKkkE44FC+amL96w0IQl70vpE37j2A +zlDWvFFID95SIxfmpkwWDvXDKv6gr1GMLeysCl2fgpY05Xidw5cEo9/tEkuWn/dG +x/D9hnLBGeroA0251ES12jemqDjI2U0tfaeHakjwSsoWElf94Qmuh2iPZ+1zIxQs +7o6nAWN8X9hfsmrDTTHlww0TEfrjlbzG5Yh+0ZRxmejgiUyOCXck+eh/ZXMXvfWh +y3CorIIuWgkRjm80PYkdaRDJdZuyP6R7tXfTXNVzAiSQf0Qx9ru2KB2Fs/XZPamH +KjItAU5Q6msIVvaRMS0muQgV+b6hqSEBzqXqJfAlpVLHXr5FqK+U7EB9y02B6piB +tAmxqXP8OOCoQql6/vgIcrDFUOo6KtGBW36ef74XE3KCUVaIzVJZSIt6i/Vi0bZj +bAjsJUQ3qDlHdorv9TRVOhnC1GUz7SuYnpEOyiXmyx3LAgMBAAGjUzBRMB0GA1Ud +DgQWBBQ62csZcH/meQcENHhNbqz9LMzwjjAfBgNVHSMEGDAWgBQ62csZcH/meQcE +NHhNbqz9LMzwjjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IEAQBA +wLsGf3R1+/I2zQE+lsj7RasZtA/Cos92iEGDAPvFbx9e+roG8Gg8KBsEJu/HN0JH +lMMiQ8dDRHSBMvRBENL5/57oOOhmqc+1u5sazLuANhzAYPZG17Klib7YpEwWoXar +FDDiJYtCyLW0oNLpCswYopWK9GC0RJNucB0NFvOxehJ2sP2/fxGBQMB09L6mjKjd +4KsOzyd3dNf0VYS6jB+/1pcKSHKQUo9HRHB5FK04PsYHoh4AtmEHvmYQKcWWidgU +v26ftlH00ERzuW2juqBbz9mghlNRqXi0IyZ9b4tSj29dxW+WWFzo7j2zEPaD6z2W +DEHq7zvON+g+q6qLgWeszqMgJzjvWjMj00E/t06PoHPiz/cAnDKEqp+ZzxCIFrxj +/qneChpogDWyLbawhyyzbZvbirx5znOSbWjPZgydqaNEFViqbxwinBx4Xxabo6XN +TU020FuMWmgfbIcvtgjKgyKqc97l7JMNNm7LQV9+9W0U5zdIqQKLZ9MMrd2w3xh4 +MAB8NKnwzHReK0TWwUU9HSgFAGdEX6HnyZ3bQ13ijg+sNBRMEi0gBHaqZKDdyoft +B2u2uasSwioV48dbSIcHl+rTBKxiMh5XQ7ENnaGOJkjsIqTVzizqnPHU8eMBnSbb +dsXlamROYII44+j3Ku6OGt51w86eGk4VxI3tmaECcJKqTkwUFD8AcNDrkjtmLuxK +12yjnoM+u1cclfqQ5NOtRc6MJZ27jCobfBBhVdKVDp4X1WNyqGlbsU5adDAzknuI +GT7MJO7lGjkZX2n54BNPSfrSknYMOVYcZqL0Dbcrhx5IyEmg+iOlOu1HO1tdnZop +ej4vT+1V2w9Sa4Wo3UCo84jcm5v/4z7jCYh4BRQ60CFb7GLxZoqXIslcGSPool3n +jl8JWoaLXrJUPfZGXo1iAlayJ5EiMyZl4eB/TBUf6TMm8vLvsPiUT+CEsjLppOdS +eYppZAZ6H1JrJGs5kKBdOJHGn6Pkp5QsHIswOBd1HqHrBbYbZmDaDLRHduILWLrM +e0/IfDdeXB/bKfmZoEpT8xRiauw15p0AHLumiK7KISAehfgBqUnxx+YmgGoZ7EWX +KnMYAfCuC6oJ1DL0gp4Z9yMK1eu+GV1sLxPq9ZruEHW1R+H+4sGyiA5Gso2tgB6/ +XW//wxKclNp5LZR7hqfs/kGuh5asrJrnEbMwWn2+tr/LqfYtYh1D6nHfIXpT0o1d +rNy/HrsKnRDMWxjm03r4hCViuNVD3Zb9anAF/NSPDVu8ATM5JbJNrCYX4eipz6ZE +aQBkwIBkTPgtgP4r8v2G+uMYDw8nq7xh72FK107aeTTwc6MgU5jfeFNMr2XJisJd +lSem1ngKYQSEzjVsTE4c +-----END CERTIFICATE----- diff --git a/reg-tests/ssl/crl-auth.pem b/reg-tests/ssl/crl-auth.pem new file mode 100644 index 0000000..af59d1d --- /dev/null +++ b/reg-tests/ssl/crl-auth.pem @@ -0,0 +1,18 @@ +-----BEGIN X509 CRL----- +MIIC0jCBuzANBgkqhkiG9w0BAQUFADB0MQswCQYDVQQGEwJGUjETMBEGA1UECAwK +U29tZS1TdGF0ZTEdMBsGA1UECgwUSEFQcm94eSBUZWNobm9sb2dpZXMxMTAvBgNV +BAMMKEhBUHJveHkgVGVjaG5vbG9naWVzIENBIFRlc3QgQ2xpZW50IEF1dGgXDTIw +MDQyODE5MjkyNloYDzIwNTAwNDIxMTkyOTI2WjAUMBICAQMXDTIwMDQyODE5MDE1 +MVowDQYJKoZIhvcNAQEFBQADggIBAMPJgdU6bsFMFKBop0dngtAG1DXSrHo1XlYY +J1uWEuVcNnimH1EHQXMmL5C26ALrHlQILLzq3RVcNZIT0tVF6jvcf8tzcaGeybS1 +tpDloE2A2jPz3Pf/uS4MB7eTPiMvY7cUl7fk4Oif/PjGPxdu+E5SP6HWVdjCvBHb +2yye/KjN/vj3g5uI6z2l1Hxh2yzYmMVS8cTRG5SfUXgH+IXJOS8zE7CsMB/IRctQ +TXD0q0iZLn7Q0liA/wxxJHYg2m3RdFa82THdWaqsIM4ao2KLz324ycQpWT0eRWpv +6gyVXbEU/sX8HdZdNpfgQADiU8eK4XlnEmXehSE3TwyM1ysnoFRtOqDvaQrHbAMh +Av0/9JLOPGDqCjof4lLfAW6JDtU55J4SxCYlaRj152939eXwDkb70WefZMssfqcw +ZPDK6afY358kb7Yb0U2pE73+Z3VDcczBF085nc6q/2m5lvA+XwZYr4xBkVzHbdP3 +USEFd06FHlh2i2rpaiihR7sQx9KJ75ko3TjDbeg/QryMBKsS2CeJoHPDcFjjzFZF +RW1HYReV1MZT8UEuskMvl+w57OYbfqf/pwhQcJTL8XE9PRtzntmLMofmiN/X5PQV +YS6JvGVAIC7HFDiZ8Wn8B+WT93ecCNQL1FpIpo1JxuRfx6jTtGqGg65R3CzwbqUH +dBkieO8E +-----END X509 CRL----- diff --git a/reg-tests/ssl/del_ssl_crt-list.vtc b/reg-tests/ssl/del_ssl_crt-list.vtc new file mode 100644 index 0000000..70dbbb5 --- /dev/null +++ b/reg-tests/ssl/del_ssl_crt-list.vtc @@ -0,0 +1,102 @@ +#REGTEST_TYPE=devel + +# This reg-test uses the "del ssl crt-list" command to remove a line from a crt-list. + +# It performs three requests towards a frontend that uses simple.crt-list. +# Between the second and third requests, a line is deleted from the crt-list, +# which makes the third request fail since it would have used the deleted line +# and the strict-sni option is enabled on the frontend. +# Another test is performed as well. A line corresponding to the default instance +# of a frontend that does not have the strict-sni option enabled cannot be deleted. + +varnishtest "Test the 'del ssl crt-list' feature of the CLI" +#REQUIRE_VERSION=2.2 +#REQUIRE_OPTIONS=OPENSSL +feature ignore_unknown_macro + +server s1 -repeat 2 { + rxreq + txresp +} -start + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + tune.ssl.capture-buffer-size 1 + crt-base ${testdir} + stats socket "${tmpdir}/h1/stats" level admin + + defaults + mode http + option httplog + retries 0 + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + + listen clear-lst + bind "fd@${clearlst}" + balance roundrobin + http-response set-header X-SSL-Server-SHA1 %[ssl_s_sha1,hex] + server s1 "${tmpdir}/first-ssl.sock" ssl verify none sni str(record2.bug940.domain.tld) + server s2 "${tmpdir}/first-ssl.sock" ssl verify none sni str(record3.bug940.domain.tld) + server s3 "${tmpdir}/first-ssl.sock" ssl verify none sni str(record2.bug940.domain.tld) + + listen first-ssl-fe + mode http + bind "${tmpdir}/first-ssl.sock" ssl strict-sni crt-list ${testdir}/simple.crt-list + server s1 ${s1_addr}:${s1_port} + + listen second-ssl-fe + mode http + bind "${tmpdir}/second-ssl.sock" ssl crt-list ${testdir}/localhost.crt-list + server s1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.http.X-SSL-Server-SHA1 == "2195C9F0FD58470313013FC27C1B9CF9864BD1C6" + expect resp.status == 200 +} -run + +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.http.X-SSL-Server-SHA1 == "A490D069DBAFBEE66DE434BEC34030ADE8BCCBF1" + expect resp.status == 200 +} -run + +haproxy h1 -cli { + send "del ssl crt-list ${testdir}/simple.crt-list ${testdir}/common.pem:2" + expect ~ "Entry '${testdir}/common.pem' deleted in crtlist '${testdir}/simple.crt-list'!" +} + +haproxy h1 -cli { + send "show ssl crt-list -n ${testdir}/simple.crt-list" + expect !~ "common.pem:2" +} + +# This connection should fail since the corresponding line was deleted from the crt-list +# and the strict-sni option is enabled. +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 503 +} -run + +# We should not be able to delete the crt-list's first line since it is the +# default certificate of this bind line and the strict-sni option is not enabled. +haproxy h1 -cli { + send "del ssl crt-list ${testdir}/localhost.crt-list ${testdir}/common.pem:1" + expect ~ "Can't delete the entry: certificate '${testdir}/common.pem' cannot be deleted, it is used as default certificate by the following frontends:" +} + +# We should be able to delete any line of the crt-list since the strict-sni option is enabled. +haproxy h1 -cli { + send "del ssl crt-list ${testdir}/simple.crt-list ${testdir}/common.pem:1" + expect ~ "Entry '${testdir}/common.pem' deleted in crtlist '${testdir}/simple.crt-list'!" +} diff --git a/reg-tests/ssl/dynamic_server_ssl.vtc b/reg-tests/ssl/dynamic_server_ssl.vtc new file mode 100644 index 0000000..b7730f5 --- /dev/null +++ b/reg-tests/ssl/dynamic_server_ssl.vtc @@ -0,0 +1,113 @@ +#REGTEST_TYPE=bug +# Test if a certificate can be dynamically updated once a server which used it +# was removed. +# +varnishtest "Delete server via cli and update certificates" + +feature ignore_unknown_macro + +#REQUIRE_VERSION=2.4 +#REQUIRE_OPTIONS=OPENSSL +feature cmd "command -v socat" + +# static server +server s1 -repeat 3 { + rxreq + txresp \ + -body "resp from s1" +} -start + +haproxy h1 -conf { + global + stats socket "${tmpdir}/h1/stats" level admin + + defaults + mode http + option httpclose + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${feS}" + default_backend test + + backend test + server s1 "${tmpdir}/ssl.sock" ssl verify none crt "${testdir}/client1.pem" + server s2 "${tmpdir}/ssl.sock" ssl verify none crt "${testdir}/client1.pem" + server s3 "${tmpdir}/ssl.sock" ssl verify none crt "${testdir}/client1.pem" + + + listen ssl-lst + bind "${tmpdir}/ssl.sock" ssl crt "${testdir}/common.pem" + server s1 ${s1_addr}:${s1_port} + +} -start + + +haproxy h1 -cli { + send "show ssl cert ${testdir}/client1.pem" + expect ~ ".*SHA1 FingerPrint: D9C3BAE37EA5A7EDB7B3C9BDD4DCB2FE58A412E4" +} +client c1 -connect ${h1_feS_sock} { + txreq + rxresp + expect resp.body == "resp from s1" +} -run + +haproxy h1 -cli { + send "show ssl cert ${testdir}/client1.pem" + expect ~ ".*SHA1 FingerPrint: D9C3BAE37EA5A7EDB7B3C9BDD4DCB2FE58A412E4" +} + +## delete the servers +haproxy h1 -cli { + send "disable server test/s1" + expect ~ ".*" + send "disable server test/s2" + expect ~ ".*" + send "disable server test/s3" + expect ~ ".*" + + # valid command + send "del server test/s1" + expect ~ "Server deleted." + send "del server test/s2" + expect ~ "Server deleted." + send "del server test/s3" + expect ~ "Server deleted." +} + +# Replace certificate with an expired one +shell { + printf "set ssl cert ${testdir}/client1.pem <<\n$(cat ${testdir}/client2_expired.pem)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl cert ${testdir}/client1.pem" | socat "${tmpdir}/h1/stats" - +} + +haproxy h1 -cli { + send "show ssl cert ${testdir}/client1.pem" + expect ~ ".*SHA1 FingerPrint: C625EB01A0A660294B9D7F44C5CEEE5AFC495BE4" +} + +haproxy h1 -cli { + send "show ssl cert ${testdir}/client1.pem" + expect ~ ".*Status: Unused" +} + +haproxy h1 -cli { + send "add server test/s1 ${tmpdir}/ssl.sock ssl verify none crt ${testdir}/client1.pem" + expect ~ "New server registered." + send "enable server test/s1" + expect ~ ".*" + send "show ssl cert ${testdir}/client1.pem" + expect ~ ".*Status: Used" +} + + +# check that servers are active +client c1 -connect ${h1_feS_sock} { + txreq + rxresp + expect resp.body == "resp from s1" +} -run + diff --git a/reg-tests/ssl/ecdsa.crt b/reg-tests/ssl/ecdsa.crt new file mode 100644 index 0000000..27b5f5d --- /dev/null +++ b/reg-tests/ssl/ecdsa.crt @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBfzCCAQWgAwIBAgIUYDgleyiLJSKbSWzlU3PTCB/PPYIwCgYIKoZIzj0EAwIw +FDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTE5MTIxOTA5MzExMloXDTIwMDExODA5 +MzExMlowFDESMBAGA1UEAwwJbG9jYWxob3N0MHYwEAYHKoZIzj0CAQYFK4EEACID +YgAEHNNG/ZSuS7CXvL03ye/Y+LpWnX818mnYkxqUQdFO2N1CO0p6kSIMHrzMQIRe +v3+j2g6drKehMGjBmeZJwsbD6nYyUO1z+0MatW5UiTMWFmPq4v08TDDtd8sNcWgs +SWrToxgwFjAUBgNVHREEDTALgglsb2NhbGhvc3QwCgYIKoZIzj0EAwIDaAAwZQIw +N2BdTJOH3BZlJ7HRIJNRC7jjByI9+QYAHiBoXmJVi9aoKd7OIz1Nb2DPe3QS1sDw +AjEA9KzI8BVIZJEmsVA6rs+vRjX0tUfBhD7BCHKas0roOny9Smj/TkBFxVTNnjzM +8iLn +-----END CERTIFICATE----- + diff --git a/reg-tests/ssl/ecdsa.key b/reg-tests/ssl/ecdsa.key new file mode 100644 index 0000000..6eec0ec --- /dev/null +++ b/reg-tests/ssl/ecdsa.key @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDDZMkuztqaUgCAC9/7P +CsmlC2ac7rWerq5+NKbP0Cz1+mao6+F5Hc8DKNXHgi5GPr2hZANiAAQc00b9lK5L +sJe8vTfJ79j4uladfzXyadiTGpRB0U7Y3UI7SnqRIgwevMxAhF6/f6PaDp2sp6Ew +aMGZ5knCxsPqdjJQ7XP7Qxq1blSJMxYWY+ri/TxMMO13yw1xaCxJatM= +-----END PRIVATE KEY----- diff --git a/reg-tests/ssl/ecdsa.pem b/reg-tests/ssl/ecdsa.pem new file mode 100644 index 0000000..e737689 --- /dev/null +++ b/reg-tests/ssl/ecdsa.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIIBfzCCAQWgAwIBAgIUYDgleyiLJSKbSWzlU3PTCB/PPYIwCgYIKoZIzj0EAwIw +FDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTE5MTIxOTA5MzExMloXDTIwMDExODA5 +MzExMlowFDESMBAGA1UEAwwJbG9jYWxob3N0MHYwEAYHKoZIzj0CAQYFK4EEACID +YgAEHNNG/ZSuS7CXvL03ye/Y+LpWnX818mnYkxqUQdFO2N1CO0p6kSIMHrzMQIRe +v3+j2g6drKehMGjBmeZJwsbD6nYyUO1z+0MatW5UiTMWFmPq4v08TDDtd8sNcWgs +SWrToxgwFjAUBgNVHREEDTALgglsb2NhbGhvc3QwCgYIKoZIzj0EAwIDaAAwZQIw +N2BdTJOH3BZlJ7HRIJNRC7jjByI9+QYAHiBoXmJVi9aoKd7OIz1Nb2DPe3QS1sDw +AjEA9KzI8BVIZJEmsVA6rs+vRjX0tUfBhD7BCHKas0roOny9Smj/TkBFxVTNnjzM +8iLn +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDDZMkuztqaUgCAC9/7P +CsmlC2ac7rWerq5+NKbP0Cz1+mao6+F5Hc8DKNXHgi5GPr2hZANiAAQc00b9lK5L +sJe8vTfJ79j4uladfzXyadiTGpRB0U7Y3UI7SnqRIgwevMxAhF6/f6PaDp2sp6Ew +aMGZ5knCxsPqdjJQ7XP7Qxq1blSJMxYWY+ri/TxMMO13yw1xaCxJatM= +-----END PRIVATE KEY----- diff --git a/reg-tests/ssl/filters.crt-list b/reg-tests/ssl/filters.crt-list new file mode 100644 index 0000000..e72ee0b --- /dev/null +++ b/reg-tests/ssl/filters.crt-list @@ -0,0 +1,2 @@ +common.pem *.bug810.domain.tld record.bug810.domain.tld *.bug818.domain.tld !another-record.bug818.domain.tld +ecdsa.pem record.bug810.domain.tld another-record.bug810.domain.tld *.bug818.domain.tld diff --git a/reg-tests/ssl/generate_certificates/gen_cert_ca.pem b/reg-tests/ssl/generate_certificates/gen_cert_ca.pem new file mode 100644 index 0000000..1aae9a7 --- /dev/null +++ b/reg-tests/ssl/generate_certificates/gen_cert_ca.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIICOjCCAcCgAwIBAgIUf+VQOeilN1b1jiOroaMItFRozf8wCgYIKoZIzj0EAwIw +VDELMAkGA1UEBhMCRlIxEzARBgNVBAgMClNvbWUtU3RhdGUxHTAbBgNVBAoMFEhB +UHJveHkgVGVjaG5vbG9naWVzMREwDwYDVQQDDAhFQ0RTQSBDQTAeFw0yMjAxMTIx +NDAzNTlaFw00OTA1MzAxNDAzNTlaMFQxCzAJBgNVBAYTAkZSMRMwEQYDVQQIDApT +b21lLVN0YXRlMR0wGwYDVQQKDBRIQVByb3h5IFRlY2hub2xvZ2llczERMA8GA1UE +AwwIRUNEU0EgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARyx1wAgb1/fuAflF73 +j3Z1intP7+11kGtVZ1EAKd//xqtxFuJ+98/gc5cpiOBMWcn6FyEZ+GShTpQeqsFs +2C4k0LTtKadXwuQaIs05QMpahTN2vmc6LPgzOrEJxFafjdejUzBRMB0GA1UdDgQW +BBTX2Q6ojJB88kEKjdnoufDv8TGphzAfBgNVHSMEGDAWgBTX2Q6ojJB88kEKjdno +ufDv8TGphzAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA2gAMGUCMQCLVP3+ +dvfS2k6GYplmmkyC7YVlmNre5gZwIE9zYDDvKDxsS95oqXLT5dTVm9W0MhACMAgB +D9uOlqoGaHbRGBE8wlV33bVdpzD6JEqVyGCdEtdCW4T5Vsg3pAsUiG2tPWQ2LA== +-----END CERTIFICATE----- +-----BEGIN EC PARAMETERS----- +BgUrgQQAIg== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MIGkAgEBBDDosJpJuqxVdp/wuJYM1k2OTK8Pri+ChDRVlDySnHYP92aFT0GXX8A5 +X5rLNDtbaCGgBwYFK4EEACKhZANiAARyx1wAgb1/fuAflF73j3Z1intP7+11kGtV +Z1EAKd//xqtxFuJ+98/gc5cpiOBMWcn6FyEZ+GShTpQeqsFs2C4k0LTtKadXwuQa +Is05QMpahTN2vmc6LPgzOrEJxFafjdc= +-----END EC PRIVATE KEY----- diff --git a/reg-tests/ssl/generate_certificates/gen_cert_server.pem b/reg-tests/ssl/generate_certificates/gen_cert_server.pem new file mode 100644 index 0000000..ce2f621 --- /dev/null +++ b/reg-tests/ssl/generate_certificates/gen_cert_server.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIBujCCAV8CAQEwCgYIKoZIzj0EAwIwWDELMAkGA1UEBhMCRlIxEzARBgNVBAgM +ClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDER +MA8GA1UEAwwIRUNEU0EgQ0EwHhcNMjIwMjA4MTU0MjMxWhcNNDkwNjI2MTU0MjMx +WjBcMQswCQYDVQQGEwJGUjETMBEGA1UECAwKU29tZS1TdGF0ZTEdMBsGA1UECgwU +SEFQcm94eSBUZWNobm9sb2dpZXMxGTAXBgNVBAMMEHNlcnZlci5lY2RzYS5jb20w +djAQBgcqhkjOPQIBBgUrgQQAIgNiAARXlODrnr208aoToRb8MqTp4GYgnk9V4LJ5 +XE8HyM7EWbqx46PdUpLUseFOtF/Yr9nyzMcdd6GNZrHkgM2NaQ/13tTbLJ84wXRQ +jS9FSqFmDmmgbEARiyEf0K8D9lxI0bgwCgYIKoZIzj0EAwIDSQAwRgIhAJlwV5oJ +Uz4nYUEWIrgFd7de5GZseFBIbW+UWr17Ip6gAiEAhrVEpmd4Tl5JPTwQznPa6ZlJ +Zc8S6ipcwXPCJzsSOnQ= +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDD6ONh7kiRD6TxwQGIa +bY5kUclHcPXiWO1QNscmeVtObmTKYiVcRR+Mj4tNRXWH6lyhZANiAARXlODrnr20 +8aoToRb8MqTp4GYgnk9V4LJ5XE8HyM7EWbqx46PdUpLUseFOtF/Yr9nyzMcdd6GN +ZrHkgM2NaQ/13tTbLJ84wXRQjS9FSqFmDmmgbEARiyEf0K8D9lxI0bg= +-----END PRIVATE KEY----- diff --git a/reg-tests/ssl/interCA1_crl.pem b/reg-tests/ssl/interCA1_crl.pem new file mode 100644 index 0000000..b4b8b03 --- /dev/null +++ b/reg-tests/ssl/interCA1_crl.pem @@ -0,0 +1,27 @@ +-----BEGIN X509 CRL----- +MIIBpDCBjTANBgkqhkiG9w0BAQsFADBHMQswCQYDVQQGEwJGUjEdMBsGA1UECgwU +SEFQcm94eSBUZWNobm9sb2dpZXMxGTAXBgNVBAMMEEludGVybWVkaWF0ZSBDQTEX +DTIxMDQyMzE0MzYyNloXDTQ4MDkwODE0MzYyNlowFTATAgIQBxcNMjEwNDIzMTQz +NjE1WjANBgkqhkiG9w0BAQsFAAOCAQEAi9NKPoPVgYo68ZvTJP2STnFLk71bLoB/ +PbQsM7gpJvgStmLs2lVpSxL2y5CUEG8Ok73yNkQIcOZq9DAXVL/49QHXQOZ0pPMD +XbUn5py3mEQfuuM46n3wPP8lDgbfbDMPxs2yDf7FZKQQpxBVBq9H3m+nc3RIPP9B +3kDvYuo3PeRlqkzIdP9ceEfBGY8+cOfvPHFzLl+BEeUI2dhhdRxtWUrfPXfLXSks +TWp0hgu9vFHguuV3mZGcxzxvdRTsq/vu0rxg2aqGOVJyNhshRn14Tt7z9uQty4Qr +vrkvpoKVzq93bI6ITRzXlgKKzXK70wGm8tAfbioNostRJ6/gcjaWAg== +-----END X509 CRL----- +-----BEGIN X509 CRL----- +MIICgzBtMA0GCSqGSIb3DQEBCwUAMD4xCzAJBgNVBAYTAkZSMR0wGwYDVQQKDBRI +QVByb3h5IFRlY2hub2xvZ2llczEQMA4GA1UEAwwHUm9vdCBDQRcNMjEwNDIzMTQz +MDQ0WhcNNDgwOTA4MTQzMDQ0WjANBgkqhkiG9w0BAQsFAAOCAgEAa39JkwPzmyPc +1SY8HfJjrkvvaIO4qV/lMUzYjg6yxuTw6g7hoH0fyxK+2+RCoplXwFS7NTDG+jS1 +H3sZWvTg/aY3g4SRudJGSxeqT2a43+U4QjmTm8uClXAA7tuOcz+wSXP7sDGQ0kyg +PCQGGmiOL5Q2lpziVRuWTHVmUkH48Na7Lyeq5cCry2AwAPjUQtcUiivuASjhUGXh +Gya8gPV5MXNVq5T2WcZWJnkMGbWLvSFAm5POX1i8c3o2rlIjoYws/VAwOi6wqe9K +NGNNUUXbOhyqocbzhZvWreyNUx63Pk4TxAAHwSn7H7fJe0yzfqjbZRF3KHCBPRbB +NBOCYr5YKH6i1xQbrEGzj8+jrXWVvpYF0FXkjzO78I5c366HXPwBCPEsoIYlgjBN ++AqgiyB7xGWiRa2SZVPn+j6wHWdohar6zw4UIBLS7EIjvb/RAM6SduScIbc9l+0I +VrciCgPScQXbkxLoh0sVBPdfR0cU08JNG+eZ8gUNce8PKdWO2mnFSNiaEz6ESgRn +0j7q+s4V15LX/vkKyA6u2JTYZCJi23DDBzZp57sgXsQwzp50lkoFmNNASXdURJL3 +60PvFGxzBDgOUhq4yTRbz945SF3jwF9CEl9kFOffOHigwrcbKS0Cib2ac+IpXYrE +BCm2lSjFCK0p/mAgK8yiNQFKnCAgsXU= +-----END X509 CRL----- diff --git a/reg-tests/ssl/interCA1_crl_empty.pem b/reg-tests/ssl/interCA1_crl_empty.pem new file mode 100644 index 0000000..ce9e0f4 --- /dev/null +++ b/reg-tests/ssl/interCA1_crl_empty.pem @@ -0,0 +1,27 @@ +-----BEGIN X509 CRL----- +MIIBjDB2MA0GCSqGSIb3DQEBCwUAMEcxCzAJBgNVBAYTAkZSMR0wGwYDVQQKDBRI +QVByb3h5IFRlY2hub2xvZ2llczEZMBcGA1UEAwwQSW50ZXJtZWRpYXRlIENBMRcN +MjEwNDIzMTQzNDI3WhcNNDgwOTA4MTQzNDI3WjANBgkqhkiG9w0BAQsFAAOCAQEA +As2A6ys84+wpG7vpjDnxD1Pri45M3sxn9Wb0v7kLBV1AsRADE6bquKYH73pUwsQB +FmfpgE6KfagM5d/1Pap9rV0PuMc3n8Uc0Q1c30AhHELlzObEzVVeT2WTHBm5XPWn ++jY5eijsWp9NCivDwzCXP/dEXxjXPtO0l4Mctq1vv5c1Ipq9FczpfDiJJMFh7Pxy +uVDhsnfx6uel851NxA5h2US0tQLbL/50t6vtdAgWaQdUprQwFc9oLStePbLEzT43 +zOQh7DIx0hZltd0p+OqQnfZFR0P/TlLLMGE/HZSzNi0L7WOwuG3MtrFzJwV/wqT+ +AH08jXjU5Pc3XThatlTvGA== +-----END X509 CRL----- +-----BEGIN X509 CRL----- +MIICgzBtMA0GCSqGSIb3DQEBCwUAMD4xCzAJBgNVBAYTAkZSMR0wGwYDVQQKDBRI +QVByb3h5IFRlY2hub2xvZ2llczEQMA4GA1UEAwwHUm9vdCBDQRcNMjEwNDIzMTQz +MDQ0WhcNNDgwOTA4MTQzMDQ0WjANBgkqhkiG9w0BAQsFAAOCAgEAa39JkwPzmyPc +1SY8HfJjrkvvaIO4qV/lMUzYjg6yxuTw6g7hoH0fyxK+2+RCoplXwFS7NTDG+jS1 +H3sZWvTg/aY3g4SRudJGSxeqT2a43+U4QjmTm8uClXAA7tuOcz+wSXP7sDGQ0kyg +PCQGGmiOL5Q2lpziVRuWTHVmUkH48Na7Lyeq5cCry2AwAPjUQtcUiivuASjhUGXh +Gya8gPV5MXNVq5T2WcZWJnkMGbWLvSFAm5POX1i8c3o2rlIjoYws/VAwOi6wqe9K +NGNNUUXbOhyqocbzhZvWreyNUx63Pk4TxAAHwSn7H7fJe0yzfqjbZRF3KHCBPRbB +NBOCYr5YKH6i1xQbrEGzj8+jrXWVvpYF0FXkjzO78I5c366HXPwBCPEsoIYlgjBN ++AqgiyB7xGWiRa2SZVPn+j6wHWdohar6zw4UIBLS7EIjvb/RAM6SduScIbc9l+0I +VrciCgPScQXbkxLoh0sVBPdfR0cU08JNG+eZ8gUNce8PKdWO2mnFSNiaEz6ESgRn +0j7q+s4V15LX/vkKyA6u2JTYZCJi23DDBzZp57sgXsQwzp50lkoFmNNASXdURJL3 +60PvFGxzBDgOUhq4yTRbz945SF3jwF9CEl9kFOffOHigwrcbKS0Cib2ac+IpXYrE +BCm2lSjFCK0p/mAgK8yiNQFKnCAgsXU= +-----END X509 CRL----- diff --git a/reg-tests/ssl/interCA2_crl.pem b/reg-tests/ssl/interCA2_crl.pem new file mode 100644 index 0000000..798096c --- /dev/null +++ b/reg-tests/ssl/interCA2_crl.pem @@ -0,0 +1,27 @@ +-----BEGIN X509 CRL----- +MIIBpDCBjTANBgkqhkiG9w0BAQsFADBHMQswCQYDVQQGEwJGUjEdMBsGA1UECgwU +SEFQcm94eSBUZWNobm9sb2dpZXMxGTAXBgNVBAMMEEludGVybWVkaWF0ZSBDQTIX +DTIxMDQyMzE0NDUzOVoXDTQ4MDkwODE0NDUzOVowFTATAgIQCBcNMjEwNDIzMTQ0 +NTM2WjANBgkqhkiG9w0BAQsFAAOCAQEAdD35Sf47YUxG6GXiMsT4jFY0hXWgc8QS +vR6gx6MQkWFV973ALVe1bfIXBGLZ2bTU/IppFUEJxVtyXyMCJIIpdYHirF1Y7kTi +DLVuWE4I0ZnDSF4LI5g73dYciKeVCq+ZvKx2dZ7Y37pKqNYvhVwp+HwtB4536XvQ +m7WjFYJFFR71gAscGky621XiRflQoGvpCOVRiJxFQFYRWRA+eR+vjQ4NTYvotDKe +O9ejZNEpfTeil+wxi5h38GVIBa2aocMVLIu5o0EQGg8d0SEU46rJKowaUz7kESuf +Al4jnmsb1W8LSD9Agp4GQE8pV2d42kXwpWk/JrUovHRPV2vy5PQuGA== +-----END X509 CRL----- +-----BEGIN X509 CRL----- +MIICgzBtMA0GCSqGSIb3DQEBCwUAMD4xCzAJBgNVBAYTAkZSMR0wGwYDVQQKDBRI +QVByb3h5IFRlY2hub2xvZ2llczEQMA4GA1UEAwwHUm9vdCBDQRcNMjEwNDIzMTQz +MDQ0WhcNNDgwOTA4MTQzMDQ0WjANBgkqhkiG9w0BAQsFAAOCAgEAa39JkwPzmyPc +1SY8HfJjrkvvaIO4qV/lMUzYjg6yxuTw6g7hoH0fyxK+2+RCoplXwFS7NTDG+jS1 +H3sZWvTg/aY3g4SRudJGSxeqT2a43+U4QjmTm8uClXAA7tuOcz+wSXP7sDGQ0kyg +PCQGGmiOL5Q2lpziVRuWTHVmUkH48Na7Lyeq5cCry2AwAPjUQtcUiivuASjhUGXh +Gya8gPV5MXNVq5T2WcZWJnkMGbWLvSFAm5POX1i8c3o2rlIjoYws/VAwOi6wqe9K +NGNNUUXbOhyqocbzhZvWreyNUx63Pk4TxAAHwSn7H7fJe0yzfqjbZRF3KHCBPRbB +NBOCYr5YKH6i1xQbrEGzj8+jrXWVvpYF0FXkjzO78I5c366HXPwBCPEsoIYlgjBN ++AqgiyB7xGWiRa2SZVPn+j6wHWdohar6zw4UIBLS7EIjvb/RAM6SduScIbc9l+0I +VrciCgPScQXbkxLoh0sVBPdfR0cU08JNG+eZ8gUNce8PKdWO2mnFSNiaEz6ESgRn +0j7q+s4V15LX/vkKyA6u2JTYZCJi23DDBzZp57sgXsQwzp50lkoFmNNASXdURJL3 +60PvFGxzBDgOUhq4yTRbz945SF3jwF9CEl9kFOffOHigwrcbKS0Cib2ac+IpXYrE +BCm2lSjFCK0p/mAgK8yiNQFKnCAgsXU= +-----END X509 CRL----- diff --git a/reg-tests/ssl/interCA2_crl_empty.pem b/reg-tests/ssl/interCA2_crl_empty.pem new file mode 100644 index 0000000..175528b --- /dev/null +++ b/reg-tests/ssl/interCA2_crl_empty.pem @@ -0,0 +1,27 @@ +-----BEGIN X509 CRL----- +MIIBjDB2MA0GCSqGSIb3DQEBCwUAMEcxCzAJBgNVBAYTAkZSMR0wGwYDVQQKDBRI +QVByb3h5IFRlY2hub2xvZ2llczEZMBcGA1UEAwwQSW50ZXJtZWRpYXRlIENBMhcN +MjEwNDIzMTQ0NTE2WhcNNDgwOTA4MTQ0NTE2WjANBgkqhkiG9w0BAQsFAAOCAQEA +IriCgDMzPowZl99/LoDW42xKFL5Db9mdPPNMY1Xk/6BowIhugz2vP5z38Ryfxy8B +f1IFaGSf6Twl+F1RHv8twHMi4Vf8hbzPG4PRoEhy0gvzbD8YBtaV/GPyJY8iQt2o +nuecskDhRp/D2YU5GXy90BMwBfH89yGPW4fUpFn3/83fZ1hhvkewTQedcLihxWGC +KPuuWyrIN8qw/VKLARlXoFPIqyEdqttJliR1/GHej5iY1msMCftUQpC5sowse3B7 +F2oNySIPxm4jZ+QBrtMNbY7E1EHDBjcLInAfY17fKs6P0HytInBOhpeqz3Jcft2i +b3qzM/7Ac5k6KPXs/UplMg== +-----END X509 CRL----- +-----BEGIN X509 CRL----- +MIICgzBtMA0GCSqGSIb3DQEBCwUAMD4xCzAJBgNVBAYTAkZSMR0wGwYDVQQKDBRI +QVByb3h5IFRlY2hub2xvZ2llczEQMA4GA1UEAwwHUm9vdCBDQRcNMjEwNDIzMTQz +MDQ0WhcNNDgwOTA4MTQzMDQ0WjANBgkqhkiG9w0BAQsFAAOCAgEAa39JkwPzmyPc +1SY8HfJjrkvvaIO4qV/lMUzYjg6yxuTw6g7hoH0fyxK+2+RCoplXwFS7NTDG+jS1 +H3sZWvTg/aY3g4SRudJGSxeqT2a43+U4QjmTm8uClXAA7tuOcz+wSXP7sDGQ0kyg +PCQGGmiOL5Q2lpziVRuWTHVmUkH48Na7Lyeq5cCry2AwAPjUQtcUiivuASjhUGXh +Gya8gPV5MXNVq5T2WcZWJnkMGbWLvSFAm5POX1i8c3o2rlIjoYws/VAwOi6wqe9K +NGNNUUXbOhyqocbzhZvWreyNUx63Pk4TxAAHwSn7H7fJe0yzfqjbZRF3KHCBPRbB +NBOCYr5YKH6i1xQbrEGzj8+jrXWVvpYF0FXkjzO78I5c366HXPwBCPEsoIYlgjBN ++AqgiyB7xGWiRa2SZVPn+j6wHWdohar6zw4UIBLS7EIjvb/RAM6SduScIbc9l+0I +VrciCgPScQXbkxLoh0sVBPdfR0cU08JNG+eZ8gUNce8PKdWO2mnFSNiaEz6ESgRn +0j7q+s4V15LX/vkKyA6u2JTYZCJi23DDBzZp57sgXsQwzp50lkoFmNNASXdURJL3 +60PvFGxzBDgOUhq4yTRbz945SF3jwF9CEl9kFOffOHigwrcbKS0Cib2ac+IpXYrE +BCm2lSjFCK0p/mAgK8yiNQFKnCAgsXU= +-----END X509 CRL----- diff --git a/reg-tests/ssl/localhost.crt-list b/reg-tests/ssl/localhost.crt-list new file mode 100644 index 0000000..a0d9756 --- /dev/null +++ b/reg-tests/ssl/localhost.crt-list @@ -0,0 +1,5 @@ +common.pem !not.test1.com *.test1.com !localhost # comment + + + common.pem !not.test1.com *.test1.com !localhost +# comment diff --git a/reg-tests/ssl/log_forward_ssl.vtc b/reg-tests/ssl/log_forward_ssl.vtc new file mode 100644 index 0000000..6b7515b --- /dev/null +++ b/reg-tests/ssl/log_forward_ssl.vtc @@ -0,0 +1,60 @@ +varnishtest "Test the TCP+SSL load-forward" +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.3-dev1)'" +feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL)'" +feature ignore_unknown_macro + +server s1 { + rxreq + txresp +} -repeat 500 -start + +syslog Slg1 -level info { + recv + expect ~ "[^:\\[ ]\\[${h1_pid}\\]: .* \"GET /client_c1 HTTP/1.1\"" +} -repeat 50 -start + +haproxy h1 -conf { + global + insecure-fork-wanted + defaults + mode http + option httplog + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe_1}" + log 127.0.0.1:1514 local0 +# log ${Slg1_addr}:${Slg1_port} local0 + default_backend be + + backend be + server app1 ${s1_addr}:${s1_port} + + ring myring + description "My local buffer" + format rfc5424 + maxlen 1200 + size 32764 + timeout connect 5s + timeout server 10s + # syslog tcp server + server mysyslogsrv 127.0.0.1:2514 ssl verify none + + log-forward syslog2tcp + dgram-bind 127.0.0.1:1514 + log ring@myring local0 # To TCP log + + log-forward syslog2local + bind 127.0.0.1:2514 ssl crt ${testdir}/common.pem + log ${Slg1_addr}:${Slg1_port} local0 # To VTest syslog +} -start + +client c1 -connect ${h1_fe_1_sock} { + txreq -url "/client_c1" + rxresp + expect resp.status == 200 +} -repeat 50 -start + +syslog Slg1 -wait diff --git a/reg-tests/ssl/new_del_ssl_cafile.vtc b/reg-tests/ssl/new_del_ssl_cafile.vtc new file mode 100644 index 0000000..4b04571 --- /dev/null +++ b/reg-tests/ssl/new_del_ssl_cafile.vtc @@ -0,0 +1,137 @@ +#REGTEST_TYPE=devel + +# This test uses the "new ssl ca-file" and "del ssl ca-file" commands to create +# a new CA file or delete an unused CA file. +# +# It requires socat to upload the CA file. +# +# If this test does not work anymore: +# - Check that you have socat + +varnishtest "Test the 'new ssl ca-file' and 'del ssl ca-file' commands of the CLI" +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL)'" +feature cmd "command -v socat" +feature ignore_unknown_macro + +server s1 -repeat 2 { + rxreq + txresp +} -start + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + tune.ssl.capture-buffer-size 1 + stats socket "${tmpdir}/h1/stats" level admin + crt-base ${testdir} + + defaults + mode http + option httplog + retries 0 + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen clear-lst + bind "fd@${clearlst}" + balance roundrobin + use_backend with_ca_be if { path /with-ca } + default_backend default_be + + backend default_be + server s1 "${tmpdir}/ssl.sock" ssl verify none crt ${testdir}/set_cafile_client.pem sni str(www.test1.com) + + backend with_ca_be + server s1 "${tmpdir}/ssl.sock" ssl verify none crt ${testdir}/set_cafile_client.pem sni str(with-ca.com) + + listen ssl-lst + bind "${tmpdir}/ssl.sock" ssl strict-sni crt-list ${testdir}/localhost.crt-list ca-verify-file ${testdir}/set_cafile_rootCA.crt ca-file ${testdir}/set_cafile_interCA2.crt verify required crt-ignore-err all + http-response add-header X-SSL-Client-Verify %[ssl_c_verify] + server s1 ${s1_addr}:${s1_port} +} -start + +# Request using the default backend and the www.test1.com sni +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 + # The CA file known by the frontend does not allow to verify the client's certificate + expect resp.http.X-SSL-Client-Verify ~ "20|21" +} -run + +# This connection should fail because the with-ca.com sni is not mentioned in the crt-list yet. +client c1 -connect ${h1_clearlst_sock} { + txreq -url "/with-ca" + rxresp + expect resp.status == 503 +} -run + +# Create a new unlinked CA file +haproxy h1 -cli { + send "new ssl ca-file new_cafile.crt" + expect ~ "New CA file created 'new_cafile.crt'!" +} + +shell { + printf "set ssl ca-file new_cafile.crt <<\n$(cat ${testdir}/set_cafile_interCA1.crt)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl ca-file new_cafile.crt" | socat "${tmpdir}/h1/stats" - +} + +haproxy h1 -cli { + send "show ssl ca-file" + expect ~ ".*new_cafile.crt - 1 certificate.*" + + send "show ssl ca-file new_cafile.crt" + expect ~ ".*SHA1 FingerPrint: 4FFF535278883264693CEA72C4FAD13F995D0098" +} + +# The new CA file is still not linked anywhere so the request should fail. +client c1 -connect ${h1_clearlst_sock} { + txreq -url "/with-ca" + rxresp + expect resp.status == 503 +} -run + +# Add a new certificate that will use the new CA file +shell { + echo "new ssl cert ${testdir}/set_cafile_server.pem" | socat "${tmpdir}/h1/stats" - + printf "set ssl cert ${testdir}/set_cafile_server.pem <<\n$(cat ${testdir}/set_cafile_server.pem)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl cert ${testdir}/set_cafile_server.pem" | socat "${tmpdir}/h1/stats" - +} + +# Create a new crt-list line that will use the new CA file +shell { + printf "add ssl crt-list ${testdir}/localhost.crt-list <<\n${testdir}/set_cafile_server.pem [ca-file new_cafile.crt] with-ca.com\n\n" | socat "${tmpdir}/h1/stats" - +} + +client c1 -connect ${h1_clearlst_sock} { + txreq -url "/with-ca" + rxresp + expect resp.status == 200 + # Thanks to the newly added CA file, the client's certificate can be verified + expect resp.http.X-SSL-Client-Verify == 0 +} -run + +# Delete the newly added crt-list line and CA file +haproxy h1 -cli { + send "del ssl crt-list ${testdir}/localhost.crt-list ${testdir}/set_cafile_server.pem" + expect ~ "Entry '${testdir}/set_cafile_server.pem' deleted in crtlist '${testdir}/localhost.crt-list'!" + + send "del ssl ca-file new_cafile.crt" + expect ~ "CA file 'new_cafile.crt' deleted!" + + send "show ssl ca-file" + expect !~ "new_cafile.crt" +} + +# The connection should now fail since the crt-list line was deleted +client c1 -connect ${h1_clearlst_sock} { + txreq -url "/with-ca" + rxresp + expect resp.status == 503 +} -run + diff --git a/reg-tests/ssl/new_del_ssl_crlfile.vtc b/reg-tests/ssl/new_del_ssl_crlfile.vtc new file mode 100644 index 0000000..8658a1a --- /dev/null +++ b/reg-tests/ssl/new_del_ssl_crlfile.vtc @@ -0,0 +1,139 @@ +#REGTEST_TYPE=devel + +# This test uses the "new ssl crl-file" and "del ssl crl-file" commands to create +# a new CRL file or delete an unused CRL file. +# +# It requires socat to upload the CRL file. +# +# If this test does not work anymore: +# - Check that you have socat + +varnishtest "Test the 'new ssl crl-file' and 'del ssl crl-file' commands of the CLI" +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL)'" +feature cmd "command -v socat" +feature ignore_unknown_macro + +server s1 -repeat 3 { + rxreq + txresp +} -start + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + tune.ssl.capture-buffer-size 1 + stats socket "${tmpdir}/h1/stats" level admin + crt-base ${testdir} + + defaults + mode http + option httplog + retries 0 + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen clear-lst + bind "fd@${clearlst}" + balance roundrobin + use_backend with_crl_be if { path /with-crl } + default_backend default_be + + backend default_be + server s1 "${tmpdir}/ssl.sock" ssl verify none crt ${testdir}/client3_revoked.pem sni str(www.test1.com) + + backend with_crl_be + server s1 "${tmpdir}/ssl.sock" ssl verify none crt ${testdir}/client3_revoked.pem sni str(with-crl.com) + + listen ssl-lst + bind "${tmpdir}/ssl.sock" ssl strict-sni crt-list ${testdir}/localhost.crt-list ca-file ${testdir}/ca-auth.crt verify required crt-ignore-err all + http-response add-header X-SSL-Client-Verify %[ssl_c_verify] + server s1 ${s1_addr}:${s1_port} +} -start + +# Request using the default backend and the www.test1.com sni +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 + # The backend has no CRL so the connection should succeed + expect resp.http.X-SSL-Client-Verify == 0 +} -run + +# This connection should fail because the with-crl.com sni is not mentioned in the crt-list yet. +client c1 -connect ${h1_clearlst_sock} { + txreq -url "/with-crl" + rxresp + expect resp.status == 503 +} -run + +# Create a new unlinked CRL file +haproxy h1 -cli { + send "new ssl crl-file new_crlfile.crt" + expect ~ "New CRL file created 'new_crlfile.crt'!" +} + +shell { + printf "set ssl crl-file new_crlfile.crt <<\n$(cat ${testdir}/crl-auth.pem)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl crl-file new_crlfile.crt" | socat "${tmpdir}/h1/stats" - +} + +haproxy h1 -cli { + send "show ssl crl-file" + expect ~ ".*new_crlfile.crt" + + send "show ssl crl-file new_crlfile.crt" + expect ~ ".*Issuer:.*/CN=HAProxy Technologies CA Test Client Auth" +} + +# Add a new certificate that will use the new CA file +shell { + echo "new ssl cert ${testdir}/set_cafile_server.pem" | socat "${tmpdir}/h1/stats" - + printf "set ssl cert ${testdir}/set_cafile_server.pem <<\n$(cat ${testdir}/set_cafile_server.pem)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl cert ${testdir}/set_cafile_server.pem" | socat "${tmpdir}/h1/stats" - +} + +# Create a new crt-list line that will use the new CA file +shell { + printf "add ssl crt-list ${testdir}/localhost.crt-list <<\n${testdir}/set_cafile_server.pem [crl-file new_crlfile.crt] with-crl.com\n\n" | socat "${tmpdir}/h1/stats" - +} + +client c1 -connect ${h1_clearlst_sock} { + txreq -url "/with-crl" + rxresp + expect resp.status == 200 + # The frontend's certificate is revoked in the newly added CRL, connection should fail + expect resp.http.X-SSL-Client-Verify == 23 +} -run + +# Request using the default backend and the www.test1.com sni +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 + # The backend has no CRL for this SNI so the connection should still succeed + expect resp.http.X-SSL-Client-Verify == 0 +} -run + +# Delete the newly added crt-list line and CRL file +haproxy h1 -cli { + send "del ssl crt-list ${testdir}/localhost.crt-list ${testdir}/set_cafile_server.pem" + expect ~ "Entry '${testdir}/set_cafile_server.pem' deleted in crtlist '${testdir}/localhost.crt-list'!" + + send "del ssl crl-file new_crlfile.crt" + expect ~ "CRL file 'new_crlfile.crt' deleted!" + + send "show ssl crl-file" + expect !~ "new_crlfile.crt" +} + +# The connection should now fail since the crt-list line was deleted +client c1 -connect ${h1_clearlst_sock} { + txreq -url "/with-crl" + rxresp + expect resp.status == 503 +} -run + diff --git a/reg-tests/ssl/rootCA_crl.pem b/reg-tests/ssl/rootCA_crl.pem new file mode 100644 index 0000000..cee411e --- /dev/null +++ b/reg-tests/ssl/rootCA_crl.pem @@ -0,0 +1,16 @@ +-----BEGIN X509 CRL----- +MIICmzCBhDANBgkqhkiG9w0BAQsFADA+MQswCQYDVQQGEwJGUjEdMBsGA1UECgwU +SEFQcm94eSBUZWNobm9sb2dpZXMxEDAOBgNVBAMMB1Jvb3QgQ0EXDTIxMDQyMzA4 +MjM0NVoXDTQ4MDkwODA4MjM0NVowFTATAgIQBxcNMjEwNDIzMDgyMDM5WjANBgkq +hkiG9w0BAQsFAAOCAgEAgECfAAcCu1yojdIa3BxpfXgnUoi/Kgp796w67fAOZ9ZS +0r68n754rWNC6QXsolrMVB4xIHe9PWWY5aCFcdmrZOts3JWaP8/UD/CeUSK30+jR +jPhDaZJHarHfocPAOvhR2faFmFMrT2NWC9swX1UMPXKAeWg8YubxT7ACx/Yrja3F +3p/UAAHpGmfPpRPGC6G2zN2zmpycpsH7vDQ7vS/pImyjuOYjMY9qKJeyHhwBIZXK +C0fuK/40HkFpcWBq6rFoiWRX8gfuKwo0i6BUDyHoFXrptvkXW/ufk+H3uM82/g4I +ZxLaCSoST+S2aoJOzF8JtjOEjCokP0I4Qs/4uVhbd5PNofgAZhdZY/CREErlVgIa +OT4hGgyjom7T8+QWApSWRdAkkSDpITSFnXJYXScmxfeT1nRjG9HBX3NHCgQWL8a/ +VwCrzBkCsLfXxFoCuMIKQ2JwhHMTl+gm1YaO6p9BrGMVfxgXvCPWKH0D52pM0z4L +6F1pKV3OA/LhQMW2tfZpvoWYtlSEy9RnaThS8OdEDI2pxlnI2F4Z6BAMVHUtlBHA +raklj6ZnD8NkzpVlU7+0OK1rSasP/UEFBXhAOHxDEGXWA8nJCVQiOUjMbitEvQRS ++L+aSMfdpXQcIA3mTJQGXMgsnR75YXllWeHv9EYMHRkoBBUuDi4QX3MvTwa97DM= +-----END X509 CRL----- diff --git a/reg-tests/ssl/set_cafile_client.pem b/reg-tests/ssl/set_cafile_client.pem new file mode 100644 index 0000000..f2fe6f3 --- /dev/null +++ b/reg-tests/ssl/set_cafile_client.pem @@ -0,0 +1,95 @@ +Certificate: + Data: + Version: 1 (0x0) + Serial Number: 4103 (0x1007) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=FR, O=HAProxy Technologies, CN=Intermediate CA1 + Validity + Not Before: Apr 22 15:16:27 2021 GMT + Not After : Sep 7 15:16:27 2048 GMT + Subject: C=FR, O=HAProxy Technologies, CN=Client + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:bb:d6:23:03:04:ae:d2:41:19:3c:6a:91:f1:41: + 07:2f:db:87:fa:ac:d5:c3:ad:db:cd:b3:fd:fa:55: + 78:3d:eb:b1:50:98:ce:de:f7:1d:44:42:56:15:e6: + cf:f3:75:d5:54:90:39:07:54:70:d1:d2:71:f9:26: + 96:79:14:8b:20:e0:7c:dd:8f:d0:13:f1:16:a5:85: + 52:5f:ff:16:bf:3d:f3:5b:78:e8:00:6e:0b:79:6a: + b7:c3:17:49:df:96:1a:7f:c7:e0:cf:c6:01:03:55: + af:36:03:95:aa:95:93:08:75:e4:46:86:9f:af:23: + 69:ac:fa:65:f0:5d:5a:97:f6:36:78:b2:a7:11:a7: + 93:8b:6b:4b:c4:54:67:b1:82:23:91:72:0f:d9:8b: + d8:1a:b4:d4:99:9e:cd:3f:3c:34:73:48:ba:cd:f4: + 7d:c8:9f:b2:17:a8:90:9c:e6:c2:f3:46:39:8b:06: + af:d0:df:e7:7d:05:92:33:4d:08:80:17:e7:a7:39: + 49:eb:f1:35:06:ac:07:d6:0b:1a:4d:55:ae:26:1a: + 49:4a:a1:b2:5f:c5:8b:39:98:2c:0c:63:41:2e:be: + 0e:3f:5c:c3:3a:39:25:2a:23:a3:a2:d3:51:03:cb: + 81:5e:76:04:76:a8:fb:80:a8:5b:19:9f:6c:e3:d7: + 31:ff + Exponent: 65537 (0x10001) + Signature Algorithm: sha256WithRSAEncryption + 71:76:f0:82:f0:06:c8:ed:5a:dd:92:37:16:82:c5:9c:dd:7d: + 65:b7:47:ee:d5:3c:cc:cd:69:d2:57:83:6a:c1:20:ef:28:a8: + b9:c2:db:1b:2b:e1:36:95:e5:e7:03:84:67:64:20:ff:ed:a4: + 3c:8b:d5:35:32:fe:7e:c8:c5:fc:04:15:ef:be:de:56:dc:f6: + d8:cc:1c:fb:03:02:01:66:fa:e4:2b:3f:2c:3e:9b:46:ec:29: + f3:02:1b:d4:c2:be:fe:fa:4d:0c:48:e0:d7:af:30:ca:6c:b3: + ea:0b:60:5b:a5:17:17:6f:f6:2f:0b:25:db:7c:ce:65:a5:94: + 94:09:84:10:39:1e:69:16:e5:0e:bc:1e:96:68:88:54:39:83: + b6:0f:74:61:6a:1c:d3:b6:65:36:bc:4f:75:30:9a:84:8f:98: + 68:ab:61:ab:57:88:8b:7c:64:7b:7f:39:a7:56:8a:e0:88:e3: + 66:7d:2c:0a:eb:f3:aa:9c:a6:f4:88:e1:0b:58:66:69:06:6b: + 93:e8:78:52:56:fc:7f:96:69:1d:76:40:30:fa:d6:4a:c7:2a: + 47:24:e0:cd:14:32:74:70:ba:b7:b4:0f:33:ca:3a:3c:75:49: + ff:65:2e:4f:65:e3:79:14:1f:76:5e:3f:44:39:60:42:df:97: + 0e:f3:a2:2e +-----BEGIN CERTIFICATE----- +MIIC+TCCAeECAhAHMA0GCSqGSIb3DQEBCwUAMEcxCzAJBgNVBAYTAkZSMR0wGwYD +VQQKDBRIQVByb3h5IFRlY2hub2xvZ2llczEZMBcGA1UEAwwQSW50ZXJtZWRpYXRl +IENBMTAeFw0yMTA0MjIxNTE2MjdaFw00ODA5MDcxNTE2MjdaMD0xCzAJBgNVBAYT +AkZSMR0wGwYDVQQKDBRIQVByb3h5IFRlY2hub2xvZ2llczEPMA0GA1UEAwwGQ2xp +ZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu9YjAwSu0kEZPGqR +8UEHL9uH+qzVw63bzbP9+lV4PeuxUJjO3vcdREJWFebP83XVVJA5B1Rw0dJx+SaW +eRSLIOB83Y/QE/EWpYVSX/8Wvz3zW3joAG4LeWq3wxdJ35Yaf8fgz8YBA1WvNgOV +qpWTCHXkRoafryNprPpl8F1al/Y2eLKnEaeTi2tLxFRnsYIjkXIP2YvYGrTUmZ7N +Pzw0c0i6zfR9yJ+yF6iQnObC80Y5iwav0N/nfQWSM00IgBfnpzlJ6/E1BqwH1gsa +TVWuJhpJSqGyX8WLOZgsDGNBLr4OP1zDOjklKiOjotNRA8uBXnYEdqj7gKhbGZ9s +49cx/wIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBxdvCC8AbI7VrdkjcWgsWc3X1l +t0fu1TzMzWnSV4NqwSDvKKi5wtsbK+E2leXnA4RnZCD/7aQ8i9U1Mv5+yMX8BBXv +vt5W3PbYzBz7AwIBZvrkKz8sPptG7CnzAhvUwr7++k0MSODXrzDKbLPqC2BbpRcX +b/YvCyXbfM5lpZSUCYQQOR5pFuUOvB6WaIhUOYO2D3RhahzTtmU2vE91MJqEj5ho +q2GrV4iLfGR7fzmnVorgiONmfSwK6/OqnKb0iOELWGZpBmuT6HhSVvx/lmkddkAw ++tZKxypHJODNFDJ0cLq3tA8zyjo8dUn/ZS5PZeN5FB92Xj9EOWBC35cO86Iu +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC71iMDBK7SQRk8 +apHxQQcv24f6rNXDrdvNs/36VXg967FQmM7e9x1EQlYV5s/zddVUkDkHVHDR0nH5 +JpZ5FIsg4Hzdj9AT8RalhVJf/xa/PfNbeOgAbgt5arfDF0nflhp/x+DPxgEDVa82 +A5WqlZMIdeRGhp+vI2ms+mXwXVqX9jZ4sqcRp5OLa0vEVGexgiORcg/Zi9gatNSZ +ns0/PDRzSLrN9H3In7IXqJCc5sLzRjmLBq/Q3+d9BZIzTQiAF+enOUnr8TUGrAfW +CxpNVa4mGklKobJfxYs5mCwMY0Euvg4/XMM6OSUqI6Oi01EDy4FedgR2qPuAqFsZ +n2zj1zH/AgMBAAECggEAE60Fs948tdeN3i9HpF7scs3rO435Qmsm2DBfjWaAlvPm +egvXt7FpBmpwfBDWfak9NIN7BdKJkuEZgUDSiFJnlIUPb2IOKNibR7FkhJvC9Tt3 +D4DlxI3Cc/CC2VPKMDqYAgSc/wa9umyyUtUjS2Apq7w1slGNzpnGCxGbtgcBY2OA +ILjPffpVYJv87LijTIozScjx/Xdub5fWgcLtByWEDk8SxAb47qAAIAjbilpARWmf +CHOeF+BG7ku2PT9+tLeMDabwRctNs88pef4+Dbe9+2Ess+2bdsG8As1/fw49QCnm +ODNV1wPXdpS5wHEEdLxnQNXOQEVSRrVOhz5KWG3F0QKBgQDo/LXfjzcrNoVRG29/ +4l9aInk0+5tE4MCsM828LBmGxbYsQqt2g3ZGQCNW2IfnwQOYlujIm+F7ZYivT5Dq +j3QvuuHjo/EGz4JuJef1oSkWeYVLm+gSzlmt5EzYximtfnEBBeJJh1Zl0R8nQfWh +RjRMTboVC22dcBSVJdCM+lg8uQKBgQDOY8A2HxDuK3RyVgz9/YtIEqtMg2tzh0jE +NnqPcy0AGMc1V1lmhn9ZHuUwspc3ZCi7gHRSjFoW+SWIIDFcPqRcZ5ZPxIejhwtF +vbi20OAx+mbSdXjyYH0Z/CaVOIMHKaOWv6EbYLWIjVRGfLsMHl1xzYjE8SiNdcMf +naLjF564dwKBgQDStSmuw5D7TdWIIq3WFF5z39WKazpjMnhNxJP96Ew1rL0yjiEP +j5j5s6vCMRXILLEZ4PEp7IAh3xOcqPLAj3heaj88ZtnmdOjawQFlDZlhMAmy9Y8O +4vwL3fr52U18EGwWpsGeCf3DGzt3f5mrfxhxIaJ2wd0ik2ip8ocH2KjQUQKBgQCS +D23730hwBTjHobZYGZL0UqH/6BGnFNqeYZ+i3XO/WcnBKiwOrqh5PbAdIoZ5oNxi +tamcsc8f6vpwt7e2/G39JyHtGbyUMgH8PSP33SKMvBUAZDpP7ZEbTqNPf0rbStCG +4t71LR/Ln5lAuQz2qpae70IXfkOguPJ58WlRJWoiSQKBgHwgYsjep0Ms/ZJkkhAp +59vwahpyWmnq/Wm6I9eyM84H+VQNqJf9/pQ3q3afPl4hRQydpenPBQF3GJ1m/9Nb +BenesNrmJabCBYsaZEnwOnb7xlai5xjBEQxAJ5ROxdmTYmA0xWzuGwuu9fHwdCvW +2ZXtTzEEzU7mLUhbiQWAF+H4 +-----END PRIVATE KEY----- diff --git a/reg-tests/ssl/set_cafile_interCA1.crt b/reg-tests/ssl/set_cafile_interCA1.crt new file mode 100644 index 0000000..840af61 --- /dev/null +++ b/reg-tests/ssl/set_cafile_interCA1.crt @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEETCCAfmgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPjELMAkGA1UEBhMCRlIx +HTAbBgNVBAoMFEhBUHJveHkgVGVjaG5vbG9naWVzMRAwDgYDVQQDDAdSb290IENB +MB4XDTIxMDQyMjE0MDEyMFoXDTQ4MDkwNzE0MDEyMFowRzELMAkGA1UEBhMCRlIx +HTAbBgNVBAoMFEhBUHJveHkgVGVjaG5vbG9naWVzMRkwFwYDVQQDDBBJbnRlcm1l +ZGlhdGUgQ0ExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAteNSI+ds +/DWtxa69I3qQ2dn6nKTCHx3IxS5/UprcO/4t0z/gOgsAn+jDVnMRh57SNQGm5/7o +DkiYnhV04qfdR8amKVKqAhFHUdpKXRZhP6XpqmpKLwvJH/kQmz1oIg27LPlvrAyV +UqV1Y0vKkMCVEPuap5sJYQasYfYaavpATOAEAC10dlnpYjQQYt4fHetVi10Jmtzr +Yea5BDsdeajbq8jWgSWGxA3BrbCubCwhCZfih5ct1KTjotj1hsfVyjPwtp8xVpMs ++amWSL/OI6pxdkVBH/dQa4M67rkQdCezLq3UAryQbdbJJLeJKqgGyIpYpKcS0GQA +JF3UeWxWgur1IQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUA +A4ICAQCiVX9SJFgXpoHHRw42A6AZDyhdv+gagQRhcjtRzdhJM+syot5WL+jxGU7U +26v3MGDRpn0zDRJ8Hdy+IYefB3NO/D5OPxTiziQcx15qf2fj8VtCygbC77u8QHHR +08b2uvEDgj9K3b5skfwwez4HabD0Ol1QRZOyykG/wl2g1Bz2lgS6Jfz1wYpmT3Ju +omufTFfB1a07DkkokGe7qAAsnfUidBScIJbLoD7xMr/zY9iMTVo+MI+Pb/4fivxq ++T75ybJwxlCpv74Zk2ATI/VEfHgPpidYtTkScRe8fsnFrE9z5TNKgNwXRhiDZe8U +F2oggdnA0fBux5H4AmjbXHgAB8x4NjRZ9yrurjdP7AIOdOn5vvXfDehFKN+OP0Pk ++5ZoUEtd876UrupaeEPd7XZIRrGItmytuntA1pW3RCU2yGsA9ep9Ur84ogzBxXpp +5/8eGnV/TLfaB56f9cYqL9rcTCI+VLhaTFpBpEjCae5EtS50gsAoaideb45F0wCt +P266qAc69MU7hPqc6z2rzumcQiAKM6krELhTOVSfRo+Gzuei6bFbTK0RqwGYn+Oc +shQN++eqrT6YAVudGUJWrKp6JEj3Y24fVhW1x631NRW5JinV2jWVWPgObDrReyya +4KlIwKMR8vPGOa3qlIRP/QPozktkoonRYg+DsLqAD6sQhJllww== +-----END CERTIFICATE----- diff --git a/reg-tests/ssl/set_cafile_interCA2.crt b/reg-tests/ssl/set_cafile_interCA2.crt new file mode 100644 index 0000000..dab7bc0 --- /dev/null +++ b/reg-tests/ssl/set_cafile_interCA2.crt @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEETCCAfmgAwIBAgICEAQwDQYJKoZIhvcNAQELBQAwPjELMAkGA1UEBhMCRlIx +HTAbBgNVBAoMFEhBUHJveHkgVGVjaG5vbG9naWVzMRAwDgYDVQQDDAdSb290IENB +MB4XDTIxMDQyMjE0MDEyMVoXDTQ4MDkwNzE0MDEyMVowRzELMAkGA1UEBhMCRlIx +HTAbBgNVBAoMFEhBUHJveHkgVGVjaG5vbG9naWVzMRkwFwYDVQQDDBBJbnRlcm1l +ZGlhdGUgQ0EyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0jJiCfXy +yzBDFTW3kaznyYZOZ6+IK1xnN6HhrB0nHwpNtC5nNtFKqbN2uNhOs9qvsX6Lx+oI +4+811OEdn269EGdlsdni/fLo+nofoD/bkcnvUGTnnmJNp4SGL6npHbHhJaAB0ETe +3F+blo9N6i+g41c+/8gD2VTgjoSiB6/Cm1sJw5jMxlmZ6dkk+HiHqg2B2o4pkOQm +0DmRuT3c6mN8I1sMWvZeMq7WaAzwbGmERK88p79QhPKr2kl5gfOOOphhPYqyN8dk +c1xooWoeUo8ZI+uI8LFVljR7+VMKmkG59wtYW6vVoUrGMH8tKPZVEmKVG57wjoqP +72n7IodhBFWnBwIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUA +A4ICAQBHTi+Wzg6g5N5/R88Zt9MFiNfQQJwLm5arVjmw+y8uSIsi5e8l2ZrqSi8i +AtbduX5PID0kzaDAAzH37YpbJScdXBymh2kX6qJOs+bRFl/GkCD7nD9VjV23h72R +F67bNpNsT3crcxZTD4QytahdKY43XQwicyrmLl9NahxOOfWR6RD2RriBe1Wj5v/R +SEu5pVcON5qIgo5mgO0GM7X/IW7hZaUyCdboqd29zgYWsiqIGB23V6RTwAZ2WN/0 +xz3IPgwBwzif9L0RNZaGbg+jlmgMJTv+m+/VYoZsFwxgWIaHkR6dYxEZ2ak/djeb +DOc764Obg+5XlxIgK+hZQbvK2zRkysUTMdzuPZtIgQU4+V4NzeEdsU2Y3IcsUzvG +29n9CCZxyeG2hTQ1eJrvLqolPUZAn/u+EbH59h01nrycd3k7AJtr05UCrTKk+6EJ +YwSNvnNEkmw0MX+aYNE0JYtHp8IrFgnO1vbAT6YCxR69LKWAWMy9eDVxK0bTEnrW +7lRTTgbUCaM31g2peNoiQdSS5xVwO5bcWmi3CHJtrLavMOV7OVi9f+ggTju4CZqK +v5U6stVyrLSUkdLZP3uMLvDVSPzPt6kGbeyHxqHfE2ywOwFtF3uxKskTNwdxYwuJ +T8kCxcSLTyefVwkCn7P6r+LdRpJhcbDRdt9cmyfiePElj2uq2w== +-----END CERTIFICATE----- diff --git a/reg-tests/ssl/set_cafile_rootCA.crt b/reg-tests/ssl/set_cafile_rootCA.crt new file mode 100644 index 0000000..bed2061 --- /dev/null +++ b/reg-tests/ssl/set_cafile_rootCA.crt @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFGjCCAwKgAwIBAgIUHgviUJMgCZlOPOhVc09pZ4NhfxcwDQYJKoZIhvcNAQEL +BQAwPjELMAkGA1UEBhMCRlIxHTAbBgNVBAoMFEhBUHJveHkgVGVjaG5vbG9naWVz +MRAwDgYDVQQDDAdSb290IENBMB4XDTIxMDQyMjE0MDEyMFoXDTQ4MDkwNzE0MDEy +MFowPjELMAkGA1UEBhMCRlIxHTAbBgNVBAoMFEhBUHJveHkgVGVjaG5vbG9naWVz +MRAwDgYDVQQDDAdSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC +AgEAti+5onUeFJNyF5s6xlnBxDnFhw7Q5VbBestHeQttjBWN31zq5yaf/+CYXdu+ +lY6gNZj6JBiFJ5P7VXX3DqUIJBX6byXWfIUWM+auBAMKlTz0+hWrF/UxI/3uG67N ++Z6NVffEPYbA4Emqozr0DIicWorRyHnrhEQQP87xBCUboUr3QEkNngfiJ0fPm3fj +7HfQemGL2OnTA8qdy0q1l4aUhVr9bgedP2Klvs0XhbszCGLI0Gq5lyNadlH1MEiw +SXa9rklE6NCNcyamO7Wt8LVrg6pxopa7oGnkLbnjzSuE+xsN0isOLaHH5LfYg6gT +aAHpnBHiWuDZQIyzKc+Z37gNksd46/y9B+oBZoCTcYMOsn7PK+gPzTbu3ic4L9hO +WCsTV0tn+qUGj6/J98gRgvuvZGA7NPDKNZU5p34oyApBPBUOgpn6pCuT5NlkPYAe +Rp/ypiy5NCHp0JW3JWkJ4+wEasZM34TZUYrOsicA0GV4ZVkoQ3WYyAjmLvRXmo/w +Z3sSlmHvCg9MrQ9pk24+OtvCbii0bb/Zmlx0Y4lU5TogcuJffJDVbj7oxTc2gRmI +SIZsnYLv2qVoeBoMY5otj+ef0Y8v98mKCbiWe2MzBkC2h5wmwyWedez8RysTaFHS +Z4yOYoCsEAtCxnib9d5fXf0+6aOuFtKMknkuWbYj6En647ECAwEAAaMQMA4wDAYD +VR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAjVzxHzq/87uj24It5hYj4mq4 +ero0zix4fA4tJNuTpZ/5r7GUYaf/uT4xfDilBX2fGMsxVTxJC25KzhdFeTzg1Tde +/N0LAeLWHfe6jR/P5XDATD0ZA73DQALOxRM5uRMeWJDVaUeco/aXsdQaCz2STDI3 +h7VVFoaOlmxQW3BBEvg2VUp9DS2UjqqdwsUDtzwKfrmj/FqyBvGrvNeIMv28HCu7 +r1WE1Z0UEJhpc1BPbu7F/vl60gRF3bQjh2tL8pWThxTJe6Qy+pLoSShyi85AM9XK +scCmUtQWjy7KQDL8XVFvuCWvMzknZQjJcncbKddPaaSIDkKUpz9FDv+wSJj/LKf7 +bGSFPM6sblioLbLNJByRYI8G7VHvKDbUnYHbHp75NTGA2eDeNqx5bC2G/EJUTwLM +bfcZr9hv+z1QpvSLEpar30kJjc1QMQcf60ToGYIC93rsVAKou2GPGry4h/nzwro0 +jjFWNgORTXllfcQDbDNOPkV1kFFibPbAU4faZMgC+xwIwDBsndvcvXjLaRUa4fmw +1xNkOO5Lj9AuvTXdCc9yUXRzmPZhU6Q4YB2daWvs3vbMTtvkAXGyQL4b2HD+NYZs +cMUtbteGgQzwM1gpMBn4GX53vhlCXq28r3cH1/1tLDweglSrxyvZbB7pZU7BAmLk +TEj2fXcvdcX+TtYhC10= +-----END CERTIFICATE----- diff --git a/reg-tests/ssl/set_cafile_server.pem b/reg-tests/ssl/set_cafile_server.pem new file mode 100644 index 0000000..04e2c22 --- /dev/null +++ b/reg-tests/ssl/set_cafile_server.pem @@ -0,0 +1,95 @@ +Certificate: + Data: + Version: 1 (0x0) + Serial Number: 4104 (0x1008) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=FR, O=HAProxy Technologies, CN=Intermediate CA2 + Validity + Not Before: Apr 22 15:18:37 2021 GMT + Not After : Sep 7 15:18:37 2048 GMT + Subject: C=FR, O=HAProxy Technologies, CN=Server + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:a3:9f:14:1d:de:57:84:a9:8e:17:2a:75:92:be: + 70:0e:6d:95:82:36:7a:2d:b2:57:e3:82:fd:20:be: + 83:e5:71:0a:ae:3e:58:cc:31:bc:42:12:e7:42:50: + 9d:47:c6:f4:02:01:1f:6e:a1:74:38:12:27:df:45: + 23:56:9a:b7:74:cb:f1:5a:1a:35:60:0d:6d:59:5e: + 71:87:19:9e:84:16:3a:69:ff:8d:ea:b2:77:dd:40: + d1:8f:c8:5d:35:c1:53:a4:0b:3f:73:c4:c2:03:52: + 2a:f1:bf:dc:2f:32:75:d3:2b:d2:e7:3a:de:ac:ac: + 43:59:f1:be:52:a7:30:51:54:ff:3d:a4:5f:97:e7: + f8:aa:65:86:b4:7d:a6:9d:c4:2d:94:68:2d:71:dc: + 5c:d2:2f:bf:d4:9c:ca:7e:2e:97:a7:10:ad:d9:ad: + 8b:74:c9:dd:91:54:71:83:1c:51:17:7e:1b:10:fc: + 00:c3:f7:5b:43:76:2d:a3:1e:93:a5:c4:cb:c1:eb: + 8e:df:a3:6c:6e:31:1e:27:fc:40:54:ac:8e:a2:ba: + 6d:d3:26:0d:ef:8b:e6:20:18:55:fd:11:37:61:90: + 40:48:d9:86:fc:34:0b:9c:65:1b:d5:02:02:28:16: + 08:1f:df:d8:91:8b:be:89:63:1a:09:27:00:4c:a4: + f4:59 + Exponent: 65537 (0x10001) + Signature Algorithm: sha256WithRSAEncryption + 01:be:4e:27:fe:cd:03:c9:df:30:5f:a8:e5:b7:33:21:a1:9e: + d3:1f:cb:4c:00:64:a0:47:c6:73:c8:f8:f5:a5:f3:ee:8d:b4: + 2c:b9:7a:47:71:fb:4a:bd:a4:df:c9:b2:2b:06:f5:77:69:ec: + c6:90:8d:16:d0:3d:fa:c0:fb:30:50:39:56:0f:2b:78:15:0a: + c2:62:6a:98:59:70:aa:6b:61:55:58:ee:50:b7:cf:d3:7c:0a: + 24:04:3d:db:ab:bc:c4:ba:82:52:0c:62:4b:aa:48:47:f4:4f: + 05:d8:4f:b2:88:f1:d6:1a:10:e1:bc:98:0b:b9:7f:f9:47:21: + 89:7a:37:61:f0:1a:e3:1d:c1:23:ba:71:8d:c8:de:cc:b0:da: + 6a:21:5c:41:02:a1:8a:6a:d4:02:32:de:a9:84:97:38:27:de: + 2d:8c:bc:c4:fa:a9:fc:3a:7c:58:92:62:20:4b:be:60:25:f6: + f4:4e:49:a1:b2:f3:e3:97:7c:84:cd:6c:f5:42:e6:3f:ca:34: + a3:26:c7:91:e4:0c:8c:df:36:5e:6b:68:e6:45:2d:c0:af:56: + 3c:1e:85:46:79:db:85:6e:98:49:69:ea:4f:fc:00:fc:23:8c: + dc:b8:fe:b9:fd:f9:fb:ec:28:f0:1a:f7:3c:b4:74:38:5e:71: + bc:1e:39:90 +-----BEGIN CERTIFICATE----- +MIIC+TCCAeECAhAIMA0GCSqGSIb3DQEBCwUAMEcxCzAJBgNVBAYTAkZSMR0wGwYD +VQQKDBRIQVByb3h5IFRlY2hub2xvZ2llczEZMBcGA1UEAwwQSW50ZXJtZWRpYXRl +IENBMjAeFw0yMTA0MjIxNTE4MzdaFw00ODA5MDcxNTE4MzdaMD0xCzAJBgNVBAYT +AkZSMR0wGwYDVQQKDBRIQVByb3h5IFRlY2hub2xvZ2llczEPMA0GA1UEAwwGU2Vy +dmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo58UHd5XhKmOFyp1 +kr5wDm2VgjZ6LbJX44L9IL6D5XEKrj5YzDG8QhLnQlCdR8b0AgEfbqF0OBIn30Uj +Vpq3dMvxWho1YA1tWV5xhxmehBY6af+N6rJ33UDRj8hdNcFTpAs/c8TCA1Iq8b/c +LzJ10yvS5zrerKxDWfG+UqcwUVT/PaRfl+f4qmWGtH2mncQtlGgtcdxc0i+/1JzK +fi6XpxCt2a2LdMndkVRxgxxRF34bEPwAw/dbQ3Ytox6TpcTLweuO36NsbjEeJ/xA +VKyOorpt0yYN74vmIBhV/RE3YZBASNmG/DQLnGUb1QICKBYIH9/YkYu+iWMaCScA +TKT0WQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQABvk4n/s0Dyd8wX6jltzMhoZ7T +H8tMAGSgR8ZzyPj1pfPujbQsuXpHcftKvaTfybIrBvV3aezGkI0W0D36wPswUDlW +Dyt4FQrCYmqYWXCqa2FVWO5Qt8/TfAokBD3bq7zEuoJSDGJLqkhH9E8F2E+yiPHW +GhDhvJgLuX/5RyGJejdh8BrjHcEjunGNyN7MsNpqIVxBAqGKatQCMt6phJc4J94t +jLzE+qn8OnxYkmIgS75gJfb0TkmhsvPjl3yEzWz1QuY/yjSjJseR5AyM3zZea2jm +RS3Ar1Y8HoVGeduFbphJaepP/AD8I4zcuP65/fn77CjwGvc8tHQ4XnG8HjmQ +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCjnxQd3leEqY4X +KnWSvnAObZWCNnotslfjgv0gvoPlcQquPljMMbxCEudCUJ1HxvQCAR9uoXQ4Eiff +RSNWmrd0y/FaGjVgDW1ZXnGHGZ6EFjpp/43qsnfdQNGPyF01wVOkCz9zxMIDUirx +v9wvMnXTK9LnOt6srENZ8b5SpzBRVP89pF+X5/iqZYa0faadxC2UaC1x3FzSL7/U +nMp+LpenEK3ZrYt0yd2RVHGDHFEXfhsQ/ADD91tDdi2jHpOlxMvB647fo2xuMR4n +/EBUrI6ium3TJg3vi+YgGFX9ETdhkEBI2Yb8NAucZRvVAgIoFggf39iRi76JYxoJ +JwBMpPRZAgMBAAECggEAAj1OKC5/4ifz8us42r5SiFAFqNeYCoITY+DKGCWjZoOK +kuH1ky3nFrxtf+HclTvq4RAk3v3EunO9KfgnSKsrcaTM89/B9UOZyIxbX28BVWt8 +dzDxP1IcA+I8PAyRAghYXbltr+b0hNkeD1sB5394T2CdLV8H5zMgZN3DLhxts99B +V6fp77eSxKvjCByKzTvlECYwxt6GnkAfZulmYGtThBoTyIz9clzl2lcpoPwp9VpF +IwYn6qig4Gfkrwj/2iMg3b6KOQIGcbH493cGmU+ujK1l4ZbkG6VIYHqLnbD+myui +LpUjUeZPigvgvhkdakGyrwqBxqNFDMOFTdunKuZ65QKBgQDVKKuAf5NeBWAPUiaN +AI82+4RTIecw5svrgk/9qSNCVnUwm9qJHyDpJZLvYUXcfB1CW6iYUQ9oo/+RvK5O +YhouwQotKMI7moIyUiRhvOSFC/7QFYLSf8uMOPlYOxofq1OAqzAsGTHItrydu709 +sdox1alxroScpRfZm8I2fm9l4wKBgQDEgaKDTY3UgpY/KWH4SWMc0+UD9ordf96m +E9rYTLW7pleZB/L5YvmpAiewUvwk1YipiLh0fQZVEx1BKirzmiWeLm2FO4SX7z9t +kMeVb3XiGgeoTdPV98YNfB6tx3+2WEYQ5FkvyABsdoUp6e8AkwbFPZnFmM/a0ZSU +Ob/Sfq8xkwKBgCfzTmlv/7PAeCeG8xi8QRtB+qQGF6mPqCqEqu9U0vns8Fvi6guH +HQj1dNuOtKRFUsqMGUYq8yNekVjELzsboeKfZYPfPsAjDkHWKWF0ILRa8jAXyAQh +1Yl7aChEM3o6BxV3gDjTpAQFU8aQWECG4+kxLWfUGKCvRJARZE4IVmKXAoGAU2Hy +tKaW9ULIQFruAG4biWL8fbcC68RTlMM+DKRYRRzrdLsjxeDSsX2Bm9dKuNKHH/Es +2/klU7o9oqYi/aU+KyXmQS+lLtdNYc+acPWP3vZOo4MKzXNK7fPqDLFnptdEO+y5 +T4Ydb+jGzqc+TE8XA2EFPAyAvohJ9K+gjtBExNMCgYEAhQSFwr8FRE4TVJT9zTxG +PUsKzCMin5ewrYSVReBBKSEymrEC2MhsDgikfJHbDF4N3o8gbhXJKf3LcLJH0761 +y6Wt+0tyfUWk4Zv8oliiZi9vcFeNmArLW5+NHQLBh5SX2UXGRmtguZUAs1gkAe5E +S3GzLHPhcWNEOE/PxejIRKI= +-----END PRIVATE KEY----- diff --git a/reg-tests/ssl/set_default_cert.crt-list b/reg-tests/ssl/set_default_cert.crt-list new file mode 100644 index 0000000..a0d2caa --- /dev/null +++ b/reg-tests/ssl/set_default_cert.crt-list @@ -0,0 +1,2 @@ +set_default_cert.pem !* +set_default_cert.pem www.test1.com diff --git a/reg-tests/ssl/set_default_cert.pem b/reg-tests/ssl/set_default_cert.pem new file mode 100644 index 0000000..550208a --- /dev/null +++ b/reg-tests/ssl/set_default_cert.pem @@ -0,0 +1,52 @@ +-----BEGIN CERTIFICATE----- +MIIENjCCAh4CAQEwDQYJKoZIhvcNAQELBQAwWzELMAkGA1UEBhMCRlIxDjAMBgNV +BAgMBVBhcmlzMQ4wDAYDVQQHDAVQYXJpczEVMBMGA1UECgwMSEFQcm94eSBUZWNo +MRUwEwYDVQQDDAxIQVByb3h5IFRlY2gwHhcNMjEwMzAyMTcxODUwWhcNMjIwMzAy +MTcxODUwWjBnMQswCQYDVQQGEwJGUjETMBEGA1UECAwKU29tZS1TdGF0ZTEOMAwG +A1UEBwwFUGFyaXMxHTAbBgNVBAoMFEhBUHJveHkgVGVjaG5vbG9naWVzMRQwEgYD +VQQDDAsqLnRlc3QxLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +APjmyWLJ1olKg/EOarln7oQB7pdUrF6kS1YG+Nz0sgFzxnU0PHn/IeARCprHyEZ4 +eBOrQ0CHhM5hdEFDX8iq32rektcQqwfH83iwD9zXxFBJ7ItoWG6YAN6WLXjEDYEI +hxLJMlW3kfYODKhNMvoqXyZi2wTyAJI+aLJI7pbeD+YNb0AwOnSH5ag5ohZIr3QU +99UD/VUhndv4OP8JZwBiV6Qy79jVDVbPFGaOc70VkMQSCHytyudQicUZrYQdIw1E +981JF/UpbnECLWyB3V+4t1KtWOW90vkUoBEj8Nxe6kYnMaNSjQhfKSF6zGmUOXYp +oHPCgms8v4JaovQygo02Qi8CAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAAz8IntYc +zrbIqweHfD9CZTNIQiobhQmgykT0KQ23Gm2y/e3o63XOqxDv0bEctg4zE83w3g7d +mJlEyCB0N0qC8UGGsbRm5Cny7H//g3u06NqSMBYbdU+BgZBBj16I5Kcw/kSBb9dA +wslLlrUjBj6dK83EB1cpyqpyZHIXkR/E424ggfc45rmD60AtU0SvzVNZfIK0PmB0 +3YKiUlO7cl5CzTeTg2BooRvqwblya62SRkhfFL7NCRX1/S9tO/XiaYzgP7J6J09x +yYs2XhQqJFgtS+1vDp8rHKhcANFVXBJ6rDSbp1qBv7qZkQhlFf8hQtd5iBXvCb0a +KtN9L4o6t1wvyo0BbERroGU7rkPPUNiMc3gWEf/mgwGLsNNOYqY5eYoeAF7arX5f +c4LCHiAYMWa/bEY29zmm51GH5ddxFSu1j95Hfd+HlNcX8Oyfed2oCoSamochmbzA +Kktk0QfCYIv4LlaG5pUliLa6DCLK7yMfT5RC5GGb350p3uDobVj/taY2cVwXOBQb +MjXK32K9CFrnqKQptPV1ohlWgNiqhvxiGp3Yx17Cn54WL9ksO+8TlwWAttazKVlT +40tHqGOu6ld90xGZitxL2oA9kBg9Nkxas/f9+9p6sJe5wj09dj/cqRjyiKv7nek1 +TIPtsNbJghDRDQ3uPEYHdX0h490qGMyGARw= +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIIEpgIBAAKCAQEA+ObJYsnWiUqD8Q5quWfuhAHul1SsXqRLVgb43PSyAXPGdTQ8 +ef8h4BEKmsfIRnh4E6tDQIeEzmF0QUNfyKrfat6S1xCrB8fzeLAP3NfEUEnsi2hY +bpgA3pYteMQNgQiHEskyVbeR9g4MqE0y+ipfJmLbBPIAkj5oskjult4P5g1vQDA6 +dIflqDmiFkivdBT31QP9VSGd2/g4/wlnAGJXpDLv2NUNVs8UZo5zvRWQxBIIfK3K +51CJxRmthB0jDUT3zUkX9SlucQItbIHdX7i3Uq1Y5b3S+RSgESPw3F7qRicxo1KN +CF8pIXrMaZQ5dimgc8KCazy/glqi9DKCjTZCLwIDAQABAoIBAQC/arWb7L+56/2W +iFDZb62GBfpYlXzOeCmb6la/jsvKxB/vCRItfGGv8Usnh9dlIsat0bsxyEcBdP80 +Jb1nFMonZS6miSIPJN4Ahd5dJ+7JFGD/QWso+mtIw1QLGTONdWJztxmnxDpTcbCY +Sm6W57kvSz1HC1oXHjnkSqR6kCLH9y6/i7ox6IPYyDA1t/TKJMnKFOPkxKJ8A96v +1avPrCWfXWYdn6Og5ERd8FJF2L5BYImmmkPpoUeWPyMBfAYqdK5FRijO6JMn/h5k +XkJm+2bru+cRwcNYUNPuDIa+ZBWhjFfZfSOhOoECeKLe+lhfcFPC7cCSeDJAjGtR +dakm15ohAoGBAP4+rVBeSCBhPH27T3HWp74qMWkYJzkdqTV0wUUJ1wtuWZFDg/RP +OYKC+6cM0nW3K+j/9pTWMS1eM61x/VNyFQGUq/rMJGEWFH08NXnV8AxCtwKUV/rP +Uq3MB4QWfSYGMo9QL+9lu23fMWYpBLo+KIcqPjLb+8FEJGmaC9JCIYQfAoGBAPqe +qp7NzMmX2b1VR2XXm1CZzwTEFXb4NeDIxSfNbsqXCmws3jgBX3Lx7dQ9k8ymvaA5 +ucYLU3ppozeB//8Ir9lSA1A4w3VN9a+l1ZdQpKQ4SuHtqDwkmKAT85vmGHCPhwlq +Er9ests3wQ4T/8HPG92QWs+Gg34F+x9U6h2FMv/xAoGBAOM6h1HWAeaWoSbKWvWm +YKNQOHryMFQW011IbVfTtJOt23U9/1hB2mdvw5SInCzDOgZzhiF90dP3Zn5063FB ++84+3vo2q6jtwAAx6KVsdK+wjLpMdNlfpEhamrkOFGoAjf2SMFVo+fv3x8HDlUsT +NMuhEJgKDlasHVMYb8pKeoQHAoGBAMAF7ij6+lvD03tz6d6oUkJxduLp8qBTEcUH +T7hteOQU0lGMFz/GHYIOx/EEtUfqwgQP9r09VFrIsdwH6UNZPpM+eXdv5qLsdsB8 +SalEisGguA9fbrWWPLL6Vn8uz67+6bJW6cJjJps8ntjQjffLXkhnII09PWbD4mNh +RngT5L2hAoGBANqa+yYSvEGNAxvdfxE0u3U/4OtjCl168nNwHXmyaCKZ1e4XYflz +wGI4J1ngcCKN37RkCgfu/XRKrc82XhAhV+YYjAUqQYrTyh26b4v9Dp9tBUWiv7bk +6L+ZlCms+HpsuYmsCAu/od41OWSSpdg+R3VOE0t3rp0r1QdAGYd1nwQC +-----END RSA PRIVATE KEY----- diff --git a/reg-tests/ssl/set_ssl_cafile.vtc b/reg-tests/ssl/set_ssl_cafile.vtc new file mode 100644 index 0000000..bda620f --- /dev/null +++ b/reg-tests/ssl/set_ssl_cafile.vtc @@ -0,0 +1,165 @@ +#REGTEST_TYPE=devel + +# This reg-test uses the "set ssl ca-file" command to update a CA file over the CLI. +# It also tests the "abort ssl ca-file" and "show ssl ca-file" commands. +# +# It is based on two CA certificates, set_cafile_interCA1.crt and set_cafile_interCA2.crt, +# and a client certificate that was signed with set_cafile_interCA1.crt (set_cafile_client.pem) +# and a server certificate that was signed with set_cafile_interCA2.crt (set_cafile_server.pem). +# The CA files used by the client and the server will be updated through the CLI until a +# proper connection can be established between them. +# +# It requires socat to upload the certificate +# +# If this test does not work anymore: +# - Check that you have socat + +varnishtest "Test the 'set ssl ca-file' feature of the CLI" +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL)'" +feature cmd "command -v socat" +feature ignore_unknown_macro + +server s1 -repeat 4 { + rxreq + txresp +} -start + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + tune.ssl.capture-buffer-size 1 + stats socket "${tmpdir}/h1/stats" level admin + + defaults + mode http + option httplog + retries 0 + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen clear-lst + bind "fd@${clearlst}" + # dummy bind used to test a change when the same crt is used as server and bind + bind "fd@${foobarlst}" ssl crt ${testdir}/set_cafile_client.pem ca-file ${testdir}/set_cafile_interCA1.crt verify none + server s1 "${tmpdir}/ssl.sock" ssl crt ${testdir}/set_cafile_client.pem ca-file ${testdir}/set_cafile_interCA1.crt verify none + + listen clear-verified-lst + bind "fd@${clearverifiedlst}" + server s1 "${tmpdir}/ssl.sock" ssl crt ${testdir}/set_cafile_client.pem ca-file ${testdir}/set_cafile_interCA1.crt verify required + + listen ssl-lst + # crt: certificate of the server + # ca-file: CA used for client authentication request + bind "${tmpdir}/ssl.sock" ssl crt ${testdir}/set_cafile_server.pem ca-verify-file ${testdir}/set_cafile_rootCA.crt ca-file ${testdir}/set_cafile_interCA2.crt verify required crt-ignore-err all + http-response add-header X-SSL-Client-Verify %[ssl_c_verify] + server s1 ${s1_addr}:${s1_port} +} -start + + +# Test the "show ssl ca-file" command +haproxy h1 -cli { + send "show ssl ca-file" + expect ~ ".*${testdir}/set_cafile_interCA1.crt - 1 certificate.*" + send "show ssl ca-file" + expect ~ ".*${testdir}/set_cafile_interCA2.crt - 1 certificate.*" + + send "show ssl ca-file ${testdir}/set_cafile_interCA2.crt" + expect ~ ".*SHA1 FingerPrint: 3D3D1D10AD74A8135F05A818E10E5FA91433954D" +} + + +# This first connection should fail because the client's certificate was signed with the +# set_cafile_interCA1.crt certificate which is not known by the backend. +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 + # unable to verify the client certificate + expect resp.http.X-SSL-Client-Verify ~ "20|21" +} -run + +# Set a new ca-file without committing it and check that the new ca-file is not taken into account +shell { + printf "set ssl ca-file ${testdir}/set_cafile_interCA2.crt <<\n$(cat ${testdir}/set_cafile_interCA1.crt)\n\n" | socat "${tmpdir}/h1/stats" - +} + +# Test the "show ssl ca-file" command +# The transaction should be mentioned in the list +haproxy h1 -cli { + send "show ssl ca-file" + expect ~ "\\*${testdir}/set_cafile_interCA2.crt - 1 certificate.*" + +# The original CA file did not change + send "show ssl ca-file ${testdir}/set_cafile_interCA2.crt" + expect ~ ".*SHA1 FingerPrint: 3D3D1D10AD74A8135F05A818E10E5FA91433954D" + +# Only the current transaction displays a new certificate + send "show ssl ca-file *${testdir}/set_cafile_interCA2.crt" + expect ~ ".*SHA1 FingerPrint: 4FFF535278883264693CEA72C4FAD13F995D0098" +} + +# This connection should still fail for the same reasons as previously +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 + # unable to verify the client certificate + expect resp.http.X-SSL-Client-Verify ~ "20|21" +} -run + +haproxy h1 -cli { + send "abort ssl ca-file ${testdir}/set_cafile_interCA2.crt" + expect ~ "Transaction aborted for certificate '${testdir}/set_cafile_interCA2.crt'!" + send "commit ssl ca-file ${testdir}/set_cafile_interCA2.crt" + expect ~ "No ongoing transaction!" +} + + +# Update the bind line's ca-file in order to accept the client certificate +shell { + printf "set ssl ca-file ${testdir}/set_cafile_interCA2.crt <<\n$(cat ${testdir}/set_cafile_interCA1.crt)\n$(cat ${testdir}/set_cafile_rootCA.crt)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl ca-file ${testdir}/set_cafile_interCA2.crt" | socat "${tmpdir}/h1/stats" - +} + + +# The backend's certificate can't be verified by the frontend because it was signed with +# the set_cafile_interCA2.crt certificate. +client c1 -connect ${h1_clearverifiedlst_sock} { + txreq + rxresp + expect resp.status == 503 +} -run + + +# Update the server line's ca-file. The server certificate should now be accepted by +# the frontend. We replace the single CA by a list of CAs that includes the correct one. +shell { + printf "set ssl ca-file ${testdir}/set_cafile_interCA1.crt <<\n$(cat ${testdir}/set_cafile_interCA1.crt)\n$(cat ${testdir}/set_cafile_interCA2.crt)\n$(cat ${testdir}/set_cafile_rootCA.crt)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl ca-file ${testdir}/set_cafile_interCA1.crt" | socat "${tmpdir}/h1/stats" - +} + +# Test the "show ssl ca-file" with a certificate index +haproxy h1 -cli { + send "show ssl ca-file" + expect ~ ".*${testdir}/set_cafile_interCA1.crt - 3 certificate.*" + + send "show ssl ca-file ${testdir}/set_cafile_interCA1.crt:1" + expect ~ ".*SHA1 FingerPrint: 4FFF535278883264693CEA72C4FAD13F995D0098" + + send "show ssl ca-file ${testdir}/set_cafile_interCA1.crt:2" + expect !~ ".*SHA1 FingerPrint: 4FFF535278883264693CEA72C4FAD13F995D0098" + send "show ssl ca-file ${testdir}/set_cafile_interCA1.crt:2" + expect ~ ".*SHA1 FingerPrint: 3D3D1D10AD74A8135F05A818E10E5FA91433954D" +} + +client c1 -connect ${h1_clearverifiedlst_sock} { + txreq + rxresp + expect resp.status == 200 + # there should be no error on the backend side but one on the frontend side + expect resp.http.X-SSL-Client-Verify == 0 +} -run diff --git a/reg-tests/ssl/set_ssl_cert.vtc b/reg-tests/ssl/set_ssl_cert.vtc new file mode 100644 index 0000000..a0fe5e7 --- /dev/null +++ b/reg-tests/ssl/set_ssl_cert.vtc @@ -0,0 +1,206 @@ +#REGTEST_TYPE=devel + +# This reg-test uses the "set ssl cert" command to update a certificate over the CLI. +# It requires socat to upload the certificate +# +# This check has two separate parts. +# In the first part, there are 3 requests, the first one will use "www.test1.com" as SNI, +# the second one with the same but that must fail and the third one will use +# "localhost". Since vtest can't do SSL, we use haproxy as an SSL client with 2 +# chained listen section. +# +# In the second part, we check the update of a default certificate in a crt-list. +# This corresponds to a bug raised in https://github.com/haproxy/haproxy/issues/1143. +# A certificate is used as default certificate as well as regular one, and during the update +# the default certificate would not be properly updated if the default instance did not have +# any SNI. The test consists in checking that the used certificate is the right one after +# updating it via a "set ssl cert" call. +# +# If this test does not work anymore: +# - Check that you have socat + +varnishtest "Test the 'set ssl cert' feature of the CLI" +#REQUIRE_VERSION=2.2 +#REQUIRE_OPTIONS=OPENSSL +feature cmd "command -v socat" +feature ignore_unknown_macro + +server s1 -repeat 9 { + rxreq + txresp +} -start + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + tune.ssl.capture-buffer-size 1 + stats socket "${tmpdir}/h1/stats" level admin + crt-base ${testdir} + + defaults + mode http + option httplog + retries 0 + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen clear-lst + bind "fd@${clearlst}" + balance roundrobin + + http-response set-header X-SSL-Server-SHA1 %[ssl_s_sha1,hex] + + retries 0 # 2nd SSL connection must fail so skip the retry + server s1 "${tmpdir}/ssl.sock" ssl verify none sni str(www.test1.com) + server s2 "${tmpdir}/ssl.sock" ssl verify none sni str(www.test1.com) + server s3 "${tmpdir}/ssl.sock" ssl verify none sni str(localhost) + + server s4 "${tmpdir}/other-ssl.sock" ssl verify none sni str(www.test1.com) + server s5 "${tmpdir}/other-ssl.sock" ssl verify none sni str(other.test1.com) # uses the default certificate + server s6 "${tmpdir}/other-ssl.sock" ssl verify none sni str(www.test1.com) + server s7 "${tmpdir}/other-ssl.sock" ssl verify none sni str(other.test1.com) # uses the default certificate + + server s8 "${tmpdir}/other-ssl.sock" ssl verify none sni str(www.test1.com) + server s9 "${tmpdir}/other-ssl.sock" ssl verify none sni str(other.test1.com) # uses the default certificate + + listen ssl-lst + bind "${tmpdir}/ssl.sock" ssl crt ${testdir}/common.pem strict-sni + server s1 ${s1_addr}:${s1_port} + # dummy server used to test a change when the same crt is used as server and bind + server s2 ${s1_addr}:${s1_port} ssl crt ${testdir}/common.pem verify none weight 0 + + listen other-ssl-lst + bind "${tmpdir}/other-ssl.sock" ssl crt-list ${testdir}/set_default_cert.crt-list + server s1 ${s1_addr}:${s1_port} + +} -start + + +haproxy h1 -cli { + send "show ssl cert ${testdir}/common.pem" + expect ~ ".*SHA1 FingerPrint: 2195C9F0FD58470313013FC27C1B9CF9864BD1C6" +} + +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 +} -run + +shell { + printf "set ssl cert ${testdir}/common.pem <<\n$(cat ${testdir}/ecdsa.pem)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl cert ${testdir}/common.pem" | socat "${tmpdir}/h1/stats" - +} + +haproxy h1 -cli { + send "show ssl cert ${testdir}/common.pem" + expect ~ ".*SHA1 FingerPrint: A490D069DBAFBEE66DE434BEC34030ADE8BCCBF1" +} + +# check that the "www.test1.com" SNI was removed +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 503 +} -run + +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 +} -run + +shell { + printf "set ssl cert ${testdir}/common.pem <<\n$(cat ${testdir}/common.pem)\n\n" | socat "${tmpdir}/h1/stats" - + echo "abort ssl cert ${testdir}/common.pem" | socat "${tmpdir}/h1/stats" - +} + +haproxy h1 -cli { + send "show ssl cert ${testdir}/common.pem" + expect ~ ".*SHA1 FingerPrint: A490D069DBAFBEE66DE434BEC34030ADE8BCCBF1" +} + + + +# The following requests are aimed at a backend that uses the set_default_cert.crt-list file + +# Uses the www.test1.com sni +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.http.X-SSL-Server-SHA1 == "9DC18799428875976DDE706E9956035EE88A4CB3" + expect resp.status == 200 +} -run + +# Uses the other.test1.com sni and the default line of the crt-list +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.http.X-SSL-Server-SHA1 == "9DC18799428875976DDE706E9956035EE88A4CB3" + expect resp.status == 200 +} -run + +shell { + printf "set ssl cert ${testdir}/set_default_cert.pem <<\n$(cat ${testdir}/common.pem)\n\n" | socat "${tmpdir}/h1/stats" - +} + +# Certificate should not have changed yet +haproxy h1 -cli { + send "show ssl cert ${testdir}/set_default_cert.pem" + expect ~ ".*SHA1 FingerPrint: 9DC18799428875976DDE706E9956035EE88A4CB3" +} + +shell { + echo "commit ssl cert ${testdir}/set_default_cert.pem" | socat "${tmpdir}/h1/stats" - +} + +haproxy h1 -cli { + send "show ssl cert ${testdir}/set_default_cert.pem" + expect ~ ".*SHA1 FingerPrint: 2195C9F0FD58470313013FC27C1B9CF9864BD1C6" +} + +# Uses the www.test1.com sni +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.http.X-SSL-Server-SHA1 == "2195C9F0FD58470313013FC27C1B9CF9864BD1C6" + expect resp.status == 200 +} -run + +# Uses the other.test1.com sni and the default line of the crt-list +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.http.X-SSL-Server-SHA1 == "2195C9F0FD58470313013FC27C1B9CF9864BD1C6" + expect resp.status == 200 +} -run + +# Restore original certificate +shell { + printf "set ssl cert ${testdir}/set_default_cert.pem <<\n$(cat ${testdir}/set_default_cert.pem)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl cert ${testdir}/set_default_cert.pem" | socat "${tmpdir}/h1/stats" - +} + +haproxy h1 -cli { + send "show ssl cert ${testdir}/set_default_cert.pem" + expect ~ ".*SHA1 FingerPrint: 9DC18799428875976DDE706E9956035EE88A4CB" +} + +# Uses the www.test1.com sni +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.http.X-SSL-Server-SHA1 == "9DC18799428875976DDE706E9956035EE88A4CB3" + expect resp.status == 200 +} -run + +# Uses the other.test1.com sni and the default line of the crt-list +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.http.X-SSL-Server-SHA1 == "9DC18799428875976DDE706E9956035EE88A4CB3" + expect resp.status == 200 +} -run diff --git a/reg-tests/ssl/set_ssl_cert_bundle.vtc b/reg-tests/ssl/set_ssl_cert_bundle.vtc new file mode 100644 index 0000000..270cba6 --- /dev/null +++ b/reg-tests/ssl/set_ssl_cert_bundle.vtc @@ -0,0 +1,111 @@ +#REGTEST_TYPE=devel + +# This reg-test uses the "set ssl cert" command to update a multi-certificate +# bundle over the CLI. +# It requires socat to upload the certificate +# +# This regtests loads a multi-certificates bundle "cert1-example.com.pem" +# composed of a .rsa and a .ecdsa +# +# After verifying that the RSA and ECDSA algorithms were avalailble with the +# right certificate, the test changes the certificates and try new requests. +# +# If this test does not work anymore: +# - Check that you have socat +# - Check that you have at least OpenSSL 1.1.1 + +varnishtest "Test the 'set ssl cert' feature of the CLI with bundles" +# could work with haproxy 2.3 but the -cc is not available +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev9)'" +feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL) && ssllib_name_startswith(OpenSSL) && openssl_version_atleast(1.1.1)'" +feature cmd "command -v socat" +feature ignore_unknown_macro + +server s1 -repeat 9 { + rxreq + txresp +} -start + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + tune.ssl.capture-buffer-size 1 + stats socket "${tmpdir}/h1/stats" level admin + crt-base ${testdir} + + defaults + mode http + option httplog + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen clear-lst + bind "fd@${clearlst}" + balance roundrobin + + http-response set-header X-SSL-Server-SHA1 %[ssl_s_sha1,hex] + + retries 0 # 2nd SSL connection must fail so skip the retry + server s1 "${tmpdir}/ssl.sock" ssl verify none sni str(example.com) force-tlsv12 ciphers ECDHE-RSA-AES128-GCM-SHA256 + server s2 "${tmpdir}/ssl.sock" ssl verify none sni str(example.com) force-tlsv12 ciphers ECDHE-ECDSA-AES256-GCM-SHA384 + + server s3 "${tmpdir}/ssl.sock" ssl verify none sni str(example.com) force-tlsv12 ciphers ECDHE-RSA-AES128-GCM-SHA256 + server s4 "${tmpdir}/ssl.sock" ssl verify none sni str(example.com) force-tlsv12 ciphers ECDHE-ECDSA-AES256-GCM-SHA384 + + listen ssl-lst + bind "${tmpdir}/ssl.sock" ssl crt ${testdir}/cert1-example.com.pem + server s1 ${s1_addr}:${s1_port} + +} -start + + +haproxy h1 -cli { + send "show ssl cert ${testdir}/cert1-example.com.pem.rsa" + expect ~ ".*SHA1 FingerPrint: 94F720DACA71B8B1A0AC9BD48C65BA688FF047DE" + send "show ssl cert ${testdir}/cert1-example.com.pem.ecdsa" + expect ~ ".*SHA1 FingerPrint: C1BA055D452F92EB02D449F0498C289F50698300" +} + +client c1 -connect ${h1_clearlst_sock} { +# RSA + txreq + rxresp + expect resp.http.X-SSL-Server-SHA1 == "94F720DACA71B8B1A0AC9BD48C65BA688FF047DE" + expect resp.status == 200 +# ECDSA + txreq + rxresp + expect resp.http.X-SSL-Server-SHA1 == "C1BA055D452F92EB02D449F0498C289F50698300" + expect resp.status == 200 +} -run + +shell { + printf "set ssl cert ${testdir}/cert1-example.com.pem.rsa <<\n$(cat ${testdir}/cert2-example.com.pem.rsa)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl cert ${testdir}/cert1-example.com.pem.rsa" | socat "${tmpdir}/h1/stats" - + printf "set ssl cert ${testdir}/cert1-example.com.pem.ecdsa <<\n$(cat ${testdir}/cert2-example.com.pem.ecdsa)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl cert ${testdir}/cert1-example.com.pem.ecdsa" | socat "${tmpdir}/h1/stats" - +} + +haproxy h1 -cli { + send "show ssl cert ${testdir}/cert1-example.com.pem.rsa" + expect ~ ".*SHA1 FingerPrint: ADC863817FC40C2A9CA913CE45C9A92232558F90" + send "show ssl cert ${testdir}/cert1-example.com.pem.ecdsa" + expect ~ ".*SHA1 FingerPrint: F49FFA446D072262445C197B85D2F400B3F58808" +} + +client c1 -connect ${h1_clearlst_sock} { +# RSA + txreq + rxresp + expect resp.http.X-SSL-Server-SHA1 == "ADC863817FC40C2A9CA913CE45C9A92232558F90" + expect resp.status == 200 +# ECDSA + txreq + rxresp + expect resp.http.X-SSL-Server-SHA1 == "F49FFA446D072262445C197B85D2F400B3F58808" + expect resp.status == 200 +} -run + diff --git a/reg-tests/ssl/set_ssl_cert_noext.vtc b/reg-tests/ssl/set_ssl_cert_noext.vtc new file mode 100644 index 0000000..4326711 --- /dev/null +++ b/reg-tests/ssl/set_ssl_cert_noext.vtc @@ -0,0 +1,90 @@ +#REGTEST_TYPE=devel + +# This reg-test uses the "set ssl cert" command to update a certificate over the CLI. +# It requires socat to upload the certificate +# +# this check does 3 requests, the first one will use "www.test1.com" as SNI, +# the second one with the same but that must fail and the third one will use +# "localhost". Since vtest can't do SSL, we use haproxy as an SSL client with 2 +# chained listen section. +# +# If this test does not work anymore: +# - Check that you have socat + +varnishtest "Test the 'set ssl cert' feature of the CLI with separate key and crt" +#REQUIRE_VERSION=2.2 +#REQUIRE_OPTIONS=OPENSSL +feature cmd "command -v socat" +feature ignore_unknown_macro + +server s1 -repeat 3 { + rxreq + txresp +} -start + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + tune.ssl.capture-buffer-size 1 + ssl-load-extra-del-ext + stats socket "${tmpdir}/h1/stats" level admin + + defaults + mode http + option httplog + retries 0 + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen clear-lst + bind "fd@${clearlst}" + balance roundrobin + retries 0 # 2nd SSL connection must fail so skip the retry + server s1 "${tmpdir}/ssl.sock" ssl verify none sni str(www.test1.com) + server s2 "${tmpdir}/ssl.sock" ssl verify none sni str(www.test1.com) + server s3 "${tmpdir}/ssl.sock" ssl verify none sni str(localhost) + + listen ssl-lst + bind "${tmpdir}/ssl.sock" ssl crt ${testdir}/common.crt strict-sni + + server s1 ${s1_addr}:${s1_port} +} -start + + +haproxy h1 -cli { + send "show ssl cert ${testdir}/common.crt" + expect ~ ".*SHA1 FingerPrint: 2195C9F0FD58470313013FC27C1B9CF9864BD1C6" +} + +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 +} -run + +shell { + printf "set ssl cert ${testdir}/common.crt <<\n$(cat ${testdir}/ecdsa.crt)\n\n" | socat "${tmpdir}/h1/stats" - + printf "set ssl cert ${testdir}/common.key <<\n$(cat ${testdir}/ecdsa.key)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl cert ${testdir}/common.crt" | socat "${tmpdir}/h1/stats" - +} + +haproxy h1 -cli { + send "show ssl cert ${testdir}/common.crt" + expect ~ ".*SHA1 FingerPrint: A490D069DBAFBEE66DE434BEC34030ADE8BCCBF1" +} + +# check that the "www.test1.com" SNI was removed +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 503 +} -run + +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 +} -run diff --git a/reg-tests/ssl/set_ssl_crlfile.vtc b/reg-tests/ssl/set_ssl_crlfile.vtc new file mode 100644 index 0000000..c9ac904 --- /dev/null +++ b/reg-tests/ssl/set_ssl_crlfile.vtc @@ -0,0 +1,146 @@ +#REGTEST_TYPE=devel + +# This reg-test uses the "set ssl crl-file" command to update a CRL file over the CLI. +# It also tests the "abort ssl crl-file" and "show ssl crl-file" commands. +# +# The frontend's certificate is signed by set_cafile_interCA1.crt and is revoked in interCA1_crl.pem +# but not in interCA1_crl_empty.pem. +# The backend's certificate is signed by set_cafile_interCA2.crt and is revoked in interCA2_crl.pem +# but not in interCA2_crl_empty.pem. +# +# The test consists in replacing the two empty CRLs by their not empty equivalent thanks to CLI +# calls and to check that the certificates (frontend and backend) are indeed revoked after the +# update. +# +# It requires socat to upload the certificate +# +# If this test does not work anymore: +# - Check that you have socat + +varnishtest "Test the 'set ssl crl-file' feature of the CLI" +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL)'" +feature cmd "command -v socat" +feature ignore_unknown_macro + +server s1 -repeat 4 { + rxreq + txresp +} -start + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + tune.ssl.capture-buffer-size 1 + stats socket "${tmpdir}/h1/stats" level admin + + defaults + mode http + option httplog + retries 0 + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen clear-lst + bind "fd@${clearlst}" + server s1 "${tmpdir}/ssl.sock" ssl crt ${testdir}/set_cafile_client.pem ca-file ${testdir}/set_cafile_interCA2.crt crl-file ${testdir}/interCA2_crl_empty.pem verify required + + listen ssl-lst + # crt: certificate of the server + # ca-file: CA used for client authentication request + # crl-file: revocation list for client auth + bind "${tmpdir}/ssl.sock" ssl crt ${testdir}/set_cafile_server.pem ca-file ${testdir}/set_cafile_interCA1.crt ca-verify-file ${testdir}/set_cafile_rootCA.crt crl-file ${testdir}/interCA1_crl_empty.pem verify required crt-ignore-err all + http-response add-header X-SSL-Client-Verify %[ssl_c_verify] + server s1 ${s1_addr}:${s1_port} +} -start + +# Test the "show ssl ca-file" command +haproxy h1 -cli { + send "show ssl ca-file" + expect ~ ".*${testdir}/set_cafile_interCA1.crt - 1 certificate.*" + send "show ssl ca-file" + expect ~ ".*${testdir}/set_cafile_interCA2.crt - 1 certificate.*" +} + +# Add the rootCA certificate to set_cafile_interCA2.crt in order for the frontend to +# be able to validate the server's certificate +shell { + printf "set ssl ca-file ${testdir}/set_cafile_interCA2.crt <<\n$(cat ${testdir}/set_cafile_interCA2.crt)\n$(cat ${testdir}/set_cafile_rootCA.crt)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl ca-file ${testdir}/set_cafile_interCA2.crt" | socat "${tmpdir}/h1/stats" - +} + +haproxy h1 -cli { + send "show ssl ca-file" + expect ~ ".*${testdir}/set_cafile_interCA2.crt - 2 certificate.*" + + send "show ssl ca-file ${testdir}/set_cafile_interCA2.crt" + expect ~ ".*Subject.*/CN=Root CA" +} + +# This first connection should succeed +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.X-SSL-Client-Verify == 0 +} -run + +# Change the frontend's crl-file to one in which the server certificate is revoked +shell { + printf "set ssl crl-file ${testdir}/interCA2_crl_empty.pem <<\n$(cat ${testdir}/interCA2_crl.pem)\n\n" | socat "${tmpdir}/h1/stats" - +} + +# Check that the transaction is displayed in the output of "show ssl crl-list" +haproxy h1 -cli { + send "show ssl crl-file" + expect ~ "\\*${testdir}/interCA2_crl_empty.pem" + + send "show ssl crl-file \\*${testdir}/interCA2_crl_empty.pem" + expect ~ "Revoked Certificates:" + send "show ssl crl-file \\*${testdir}/interCA2_crl_empty.pem:1" + expect ~ "Serial Number: 1008" +} + +# This connection should still succeed since the transaction was not committed +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.X-SSL-Client-Verify == 0 +} -run + +haproxy h1 -cli { + send "commit ssl crl-file ${testdir}/interCA2_crl_empty.pem" + expect ~ "Committing ${testdir}/interCA2_crl_empty.pem" +} + +# This connection should fail, the server's certificate is revoked in the newly updated CRL file +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 503 +} -run + +# Restore the frontend's CRL +shell { + printf "set ssl crl-file ${testdir}/interCA2_crl_empty.pem <<\n$(cat ${testdir}/interCA2_crl_empty.pem)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl crl-file ${testdir}/interCA2_crl_empty.pem" | socat "${tmpdir}/h1/stats" - +} + +# Change the backend's CRL file to one in which the frontend's certificate is revoked +shell { + printf "set ssl crl-file ${testdir}/interCA1_crl_empty.pem <<\n$(cat ${testdir}/interCA1_crl.pem)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl crl-file ${testdir}/interCA1_crl_empty.pem" | socat "${tmpdir}/h1/stats" - +} + +# This connection should fail, the client's certificate is revoked in the newly updated CRL file +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 + # Revoked certificate + expect resp.http.X-SSL-Client-Verify == 23 +} -run diff --git a/reg-tests/ssl/set_ssl_server_cert.vtc b/reg-tests/ssl/set_ssl_server_cert.vtc new file mode 100644 index 0000000..2699b37 --- /dev/null +++ b/reg-tests/ssl/set_ssl_server_cert.vtc @@ -0,0 +1,129 @@ +#REGTEST_TYPE=devel + +# This reg-test uses the "set ssl cert" command to update a backend certificate over the CLI. +# It requires socat to upload the certificate + +varnishtest "Test the 'set ssl cert' feature of the CLI" +#REQUIRE_VERSION=2.4 +#REQUIRE_OPTIONS=OPENSSL +feature cmd "command -v socat" +feature ignore_unknown_macro + +server s1 -repeat 4 { + rxreq + txresp +} -start + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + tune.ssl.capture-buffer-size 1 + stats socket "${tmpdir}/h1/stats" level admin + nbthread 1 + + defaults + mode http + option httplog + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen clear-lst + bind "fd@${clearlst}" + retries 0 # 2nd SSL connection must fail so skip the retry + server s1 "${tmpdir}/ssl.sock" ssl verify none crt ${testdir}/client1.pem + + listen ssl-lst + # crt: certificate of the server + # ca-file: CA used for client authentication request + # crl-file: revocation list for client auth: the client1 certificate is revoked + bind "${tmpdir}/ssl.sock" ssl crt ${testdir}/common.pem ca-file ${testdir}/ca-auth.crt verify optional crt-ignore-err all crl-file ${testdir}/crl-auth.pem + + acl cert_expired ssl_c_verify 10 + acl cert_revoked ssl_c_verify 23 + acl cert_ok ssl_c_verify 0 + + http-response add-header X-SSL Ok if cert_ok + http-response add-header X-SSL Expired if cert_expired + http-response add-header X-SSL Revoked if cert_revoked + http-response add-header x-ssl-sha1 %[ssl_c_sha1,hex] + + server s1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-sha1 == "D9C3BAE37EA5A7EDB7B3C9BDD4DCB2FE58A412E4" + expect resp.http.x-ssl == "Ok" +} -run + +haproxy h1 -cli { + send "show ssl cert ${testdir}/client1.pem" + expect ~ ".*SHA1 FingerPrint: D9C3BAE37EA5A7EDB7B3C9BDD4DCB2FE58A412E4" +} + +# Replace certificate with an expired one +shell { + printf "set ssl cert ${testdir}/client1.pem <<\n$(cat ${testdir}/client2_expired.pem)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl cert ${testdir}/client1.pem" | socat "${tmpdir}/h1/stats" - +} + +haproxy h1 -cli { + send "show ssl cert ${testdir}/client1.pem" + expect ~ ".*SHA1 FingerPrint: C625EB01A0A660294B9D7F44C5CEEE5AFC495BE4" +} + + +# The updated client certificate is an expired one so this request should fail +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-sha1 == "C625EB01A0A660294B9D7F44C5CEEE5AFC495BE4" + expect resp.http.x-ssl == "Expired" +} -run + +# Replace certificate with a revoked one +shell { + printf "set ssl cert ${testdir}/client1.pem <<\n$(cat ${testdir}/client3_revoked.pem)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl cert ${testdir}/client1.pem" | socat "${tmpdir}/h1/stats" - +} + +haproxy h1 -cli { + send "show ssl cert ${testdir}/client1.pem" + expect ~ ".*SHA1 FingerPrint: 992386628A40C9D49C89BAC0058B5D45D8575151" +} + +# The updated client certificate is a revoked one so this request should fail +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-sha1 == "992386628A40C9D49C89BAC0058B5D45D8575151" + expect resp.http.x-ssl == "Revoked" +} -run + +# Abort a transaction +shell { + printf "set ssl cert ${testdir}/client1.pem <<\n$(cat ${testdir}/client3_revoked.pem)\n\n" | socat "${tmpdir}/h1/stats" - + echo "abort ssl cert ${testdir}/client1.pem" | socat "${tmpdir}/h1/stats" - +} + +haproxy h1 -cli { + send "show ssl cert ${testdir}/client1.pem" + expect ~ ".*SHA1 FingerPrint: 992386628A40C9D49C89BAC0058B5D45D8575151" +} + +# The certificate was not updated so it should still be revoked +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl == "Revoked" +} -run + + diff --git a/reg-tests/ssl/show_ocsp_server.pem b/reg-tests/ssl/show_ocsp_server.pem new file mode 100644 index 0000000..a652359 --- /dev/null +++ b/reg-tests/ssl/show_ocsp_server.pem @@ -0,0 +1,119 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 4111 (0x100f) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=FR, O=HAProxy Technologies, CN=Root CA + Validity + Not Before: Jun 10 08:54:19 2021 GMT + Not After : Oct 26 08:54:19 2048 GMT + Subject: C=FR, O=HAProxy Technologies, CN=Server Certificate + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:e9:88:7e:5e:ec:81:d0:f7:2b:9b:c9:5d:81:ea: + 9c:ff:61:2f:4b:a2:ad:08:4d:44:7c:65:fa:ab:3a: + f2:be:63:ac:34:5c:c4:05:35:be:d4:79:af:a5:fc: + 9e:92:10:75:b1:4d:70:d6:82:a3:7e:7e:b0:e6:2c: + ba:ec:1b:e9:7f:55:f3:98:6e:d5:b2:00:37:05:76: + df:28:be:3e:89:52:ec:47:58:45:7a:dd:7d:89:ae: + 7f:43:d6:a5:ce:f6:8d:8d:32:fe:33:dc:16:15:01: + 82:23:d1:77:12:75:a2:e2:2a:08:eb:cd:32:1e:5b: + 54:12:68:83:21:3a:6e:07:f5:99:f4:e7:79:eb:f7: + d0:d9:71:f2:1d:79:08:a2:63:df:ab:59:f3:ac:33: + 18:d6:0a:9c:48:0b:9a:b0:ae:79:7b:8e:5a:1d:d2: + fc:5c:6c:a5:d5:61:88:e8:50:c2:0f:f2:5b:0d:0c: + 82:18:c8:a1:98:19:8a:fc:28:c6:27:e7:94:de:3d: + 13:44:16:12:9e:e1:a8:b0:17:a1:4d:14:84:3e:44: + bc:76:5d:cd:4e:67:9c:e6:69:0b:5a:fe:cf:08:bb: + 6d:0b:be:d6:8e:5d:c6:fc:53:e2:ab:34:28:2f:ef: + 03:5a:c4:ad:b7:e8:4e:1c:89:67:78:f5:a4:41:fd: + 80:f3 + Exponent: 65537 (0x10001) + X509v3 extensions: + Authority Information Access: + OCSP - URI:http://ocsp.haproxy.com + + Signature Algorithm: sha256WithRSAEncryption + 14:c3:1a:2c:37:d4:91:74:10:be:eb:f3:1e:f3:da:cf:ed:0d: + b1:37:8e:e8:0c:44:cb:28:ce:4b:5c:ed:02:35:13:55:e1:34: + 93:aa:7d:91:fa:4c:a7:31:09:6a:23:b7:0a:d3:37:70:dd:48: + 9c:b6:af:31:d7:28:c1:cf:7d:44:f0:d5:ac:58:56:74:40:48: + a6:21:85:ea:bf:38:52:fc:8e:16:7c:4d:79:d3:b4:18:11:90: + 95:a7:f4:b6:5f:91:dc:3e:bd:e7:58:96:ff:c2:d2:59:20:ed: + 4e:de:e5:92:c9:a6:5a:37:a1:fd:00:cb:13:51:ef:ce:98:c8: + 01:b5:a1:9a:74:63:a0:da:dc:39:1e:08:8b:60:04:7f:96:c8: + 02:cd:cc:dc:04:a4:4c:84:8f:a1:30:49:99:e1:6c:0c:39:65: + 2c:03:f8:60:46:cb:28:42:6a:c4:b0:bb:7f:be:67:de:1e:55: + 10:2a:55:1f:58:d4:fc:b0:74:9e:11:95:0b:c0:cc:f6:fc:6d: + ce:25:17:48:dc:30:5e:b3:29:44:10:11:2d:47:2d:06:81:21: + 51:55:4a:4d:72:79:49:ad:29:77:64:92:e7:4e:c9:4f:4c:25: + 4d:24:3c:49:07:af:53:74:b5:14:05:e2:f2:fc:ba:d7:a0:db: + e4:e4:38:74:fe:f0:34:98:78:f4:2c:68:2d:a6:1e:2d:16:d6: + 2b:1d:95:3c:ac:9d:16:6a:7e:d4:cd:0c:94:2b:f4:94:1c:ef: + 3b:23:13:78:14:ea:ea:2f:08:f4:ed:21:3d:50:77:4b:50:fe: + db:47:19:d1:36:92:7d:7e:e3:18:40:1d:65:0e:fe:95:4f:54: + 60:15:16:57:72:06:93:03:ee:8c:89:4e:7b:0b:13:a5:ef:52: + c9:53:8d:77:b4:7f:11:f8:03:f1:ce:a0:f8:33:06:89:44:7b: + f7:14:4a:51:ba:0e:35:88:ea:69:44:bd:3f:76:78:23:86:79: + 13:00:40:1a:d0:69:42:41:72:e6:81:a7:b2:11:25:37:73:15: + 89:a7:36:5d:75:3c:e9:1b:dc:ea:8c:98:6e:24:f9:98:e1:62: + d6:12:34:a4:c1:bc:08:fd:4d:86:8e:43:a9:9a:36:26:ba:f5: + ab:13:9c:08:09:8d:bf:13:84:a0:5f:52:78:fc:1d:11:0c:d6: + e1:a3:0c:ce:4d:21:79:90:2a:bb:04:03:d9:76:71:81:36:2a: + 1c:56:79:e7:32:03:d8:41:cc:73:e5:6e:45:4e:2d:c9:b0:cc: + 70:6b:47:93:6b:00:d0:6d:94:5f:db:e1:d5:dd:73:11:9f:b7: + c1:75:50:43:17:b5:e6:51 +-----BEGIN CERTIFICATE----- +MIIEOjCCAiKgAwIBAgICEA8wDQYJKoZIhvcNAQELBQAwPjELMAkGA1UEBhMCRlIx +HTAbBgNVBAoMFEhBUHJveHkgVGVjaG5vbG9naWVzMRAwDgYDVQQDDAdSb290IENB +MB4XDTIxMDYxMDA4NTQxOVoXDTQ4MTAyNjA4NTQxOVowSTELMAkGA1UEBhMCRlIx +HTAbBgNVBAoMFEhBUHJveHkgVGVjaG5vbG9naWVzMRswGQYDVQQDDBJTZXJ2ZXIg +Q2VydGlmaWNhdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDpiH5e +7IHQ9yubyV2B6pz/YS9Loq0ITUR8ZfqrOvK+Y6w0XMQFNb7Uea+l/J6SEHWxTXDW +gqN+frDmLLrsG+l/VfOYbtWyADcFdt8ovj6JUuxHWEV63X2Jrn9D1qXO9o2NMv4z +3BYVAYIj0XcSdaLiKgjrzTIeW1QSaIMhOm4H9Zn053nr99DZcfIdeQiiY9+rWfOs +MxjWCpxIC5qwrnl7jlod0vxcbKXVYYjoUMIP8lsNDIIYyKGYGYr8KMYn55TePRNE +FhKe4aiwF6FNFIQ+RLx2Xc1OZ5zmaQta/s8Iu20LvtaOXcb8U+KrNCgv7wNaxK23 +6E4ciWd49aRB/YDzAgMBAAGjNzA1MDMGCCsGAQUFBwEBBCcwJTAjBggrBgEFBQcw +AYYXaHR0cDovL29jc3AuaGFwcm94eS5jb20wDQYJKoZIhvcNAQELBQADggIBABTD +Giw31JF0EL7r8x7z2s/tDbE3jugMRMsozktc7QI1E1XhNJOqfZH6TKcxCWojtwrT +N3DdSJy2rzHXKMHPfUTw1axYVnRASKYhheq/OFL8jhZ8TXnTtBgRkJWn9LZfkdw+ +vedYlv/C0lkg7U7e5ZLJplo3of0AyxNR786YyAG1oZp0Y6Da3DkeCItgBH+WyALN +zNwEpEyEj6EwSZnhbAw5ZSwD+GBGyyhCasSwu3++Z94eVRAqVR9Y1PywdJ4RlQvA +zPb8bc4lF0jcMF6zKUQQES1HLQaBIVFVSk1yeUmtKXdkkudOyU9MJU0kPEkHr1N0 +tRQF4vL8uteg2+TkOHT+8DSYePQsaC2mHi0W1isdlTysnRZqftTNDJQr9JQc7zsj +E3gU6uovCPTtIT1Qd0tQ/ttHGdE2kn1+4xhAHWUO/pVPVGAVFldyBpMD7oyJTnsL +E6XvUslTjXe0fxH4A/HOoPgzBolEe/cUSlG6DjWI6mlEvT92eCOGeRMAQBrQaUJB +cuaBp7IRJTdzFYmnNl11POkb3OqMmG4k+ZjhYtYSNKTBvAj9TYaOQ6maNia69asT +nAgJjb8ThKBfUnj8HREM1uGjDM5NIXmQKrsEA9l2cYE2KhxWeecyA9hBzHPlbkVO +LcmwzHBrR5NrANBtlF/b4dXdcxGft8F1UEMXteZR +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEA6Yh+XuyB0Pcrm8ldgeqc/2EvS6KtCE1EfGX6qzryvmOsNFzE +BTW+1HmvpfyekhB1sU1w1oKjfn6w5iy67Bvpf1XzmG7VsgA3BXbfKL4+iVLsR1hF +et19ia5/Q9alzvaNjTL+M9wWFQGCI9F3EnWi4ioI680yHltUEmiDITpuB/WZ9Od5 +6/fQ2XHyHXkIomPfq1nzrDMY1gqcSAuasK55e45aHdL8XGyl1WGI6FDCD/JbDQyC +GMihmBmK/CjGJ+eU3j0TRBYSnuGosBehTRSEPkS8dl3NTmec5mkLWv7PCLttC77W +jl3G/FPiqzQoL+8DWsStt+hOHIlnePWkQf2A8wIDAQABAoIBAQDktypU2zrUpo6O +F6u9xkIWl17Tq7HddJdDYjkbJDODJWkNK2FLXPTVcYwGe5/tm7M4f4iofe+Tvo6Q +D3TOMxP/AvX872fY2f8JGf+7Dn9+zLjdsuTxTSVbB4xaq0lepffCNxPhRIZX8k87 +tzTv3kg1SkfMcP3J31Y6ZSMwEuKaZR9bkIT2MlLw89Qrg/o1Z1Yuu4CoJhgJ9x4Q +smJmu6uu152i0tqQDK76nHfTgK6GTyHQpP/njXZ3gD/4vTOKsZPoXEtM9gq1Ihqm +c7Pcy71q9nOBWfG3KUVhIlOahyVPewAFG7vNsPWVE0mN3FhCIEUPPLNnvAydSPaV +vbwohs4BAoGBAPqXF6cTKWIfHTn4TrcOcKslKEzVSgJabZeYw1kTRsSLCsvV3ojx +txW4A8FM+EVwX+K6FmpAxN9aKERVv1Ez3xvjmZf6czgREd8F2X2j6SwkcSwVZaxz +FCl81jz6r/9CGP6Wbq0uVKGhEdNYddhc3RvR8oWwnMEgwIkOvfnpCevzAoGBAO6T +IljTIzsZmLLFdhvS49C4bQ71vQbEnybqHENZcPdjrgbwRDLjQ4ZEGLm/O1zmKVZh +C5rRqd/fWVtzMPmZJr0aNeVN3dYob/1SS6ixu/D55jRII6RtkTrm8bmOlUXIx3BB +sgDOhG61U4LJ8n4Utcgv4go1feRNQkIo5qXkLFcBAoGALB0HE+liopxZl8fni4Am +Q2qiIox1n95tZn+E/BxRm+3iM6ntp+vtUAx51MCJAChdKNubcI8AWVVUu1rg+BmK +kC1L754uRFN08u7jr6N4O8YaiikmIeqMRRVt3YRAEU6AeejfiOscCOwC6FKtRC5s +2iXmbLR/k9wBKN+IgAMPNRMCgYEA44MIxDBFbrzQM9u+8HXCr27RAe0y4Fttcszb +Oxb2ddVnRlKmlujHoikaczh8wfD0Bt3xFSlQmKAENQO69qwolzmBoDULkolpkuiC +IlOsaPfHoqAQ7WNXlhZa+puQmsYH+3OK7t4CyRi+lQFE8RuK52dSZm3wqmFLCJC8 +tALOjgECgYEAjREmEh/o/moOfIp8x18GYkYkJCv3+/UwMD8kJUu3KtXhER6Kgi2t +GgqGV7nHm+sZjck+tcWdT7s+SJWQ2t8QkOf9xavy6mhG6ptJT7xoXSCxAUzNjLQZ +WpoLVecRfaiAwj9DbbVWhjy8RDkyAHcHveVSIH40I7K0oTbNPqyJk6U= +-----END RSA PRIVATE KEY----- diff --git a/reg-tests/ssl/show_ocsp_server.pem.issuer b/reg-tests/ssl/show_ocsp_server.pem.issuer new file mode 100644 index 0000000..bed2061 --- /dev/null +++ b/reg-tests/ssl/show_ocsp_server.pem.issuer @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFGjCCAwKgAwIBAgIUHgviUJMgCZlOPOhVc09pZ4NhfxcwDQYJKoZIhvcNAQEL +BQAwPjELMAkGA1UEBhMCRlIxHTAbBgNVBAoMFEhBUHJveHkgVGVjaG5vbG9naWVz +MRAwDgYDVQQDDAdSb290IENBMB4XDTIxMDQyMjE0MDEyMFoXDTQ4MDkwNzE0MDEy +MFowPjELMAkGA1UEBhMCRlIxHTAbBgNVBAoMFEhBUHJveHkgVGVjaG5vbG9naWVz +MRAwDgYDVQQDDAdSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC +AgEAti+5onUeFJNyF5s6xlnBxDnFhw7Q5VbBestHeQttjBWN31zq5yaf/+CYXdu+ +lY6gNZj6JBiFJ5P7VXX3DqUIJBX6byXWfIUWM+auBAMKlTz0+hWrF/UxI/3uG67N ++Z6NVffEPYbA4Emqozr0DIicWorRyHnrhEQQP87xBCUboUr3QEkNngfiJ0fPm3fj +7HfQemGL2OnTA8qdy0q1l4aUhVr9bgedP2Klvs0XhbszCGLI0Gq5lyNadlH1MEiw +SXa9rklE6NCNcyamO7Wt8LVrg6pxopa7oGnkLbnjzSuE+xsN0isOLaHH5LfYg6gT +aAHpnBHiWuDZQIyzKc+Z37gNksd46/y9B+oBZoCTcYMOsn7PK+gPzTbu3ic4L9hO +WCsTV0tn+qUGj6/J98gRgvuvZGA7NPDKNZU5p34oyApBPBUOgpn6pCuT5NlkPYAe +Rp/ypiy5NCHp0JW3JWkJ4+wEasZM34TZUYrOsicA0GV4ZVkoQ3WYyAjmLvRXmo/w +Z3sSlmHvCg9MrQ9pk24+OtvCbii0bb/Zmlx0Y4lU5TogcuJffJDVbj7oxTc2gRmI +SIZsnYLv2qVoeBoMY5otj+ef0Y8v98mKCbiWe2MzBkC2h5wmwyWedez8RysTaFHS +Z4yOYoCsEAtCxnib9d5fXf0+6aOuFtKMknkuWbYj6En647ECAwEAAaMQMA4wDAYD +VR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAjVzxHzq/87uj24It5hYj4mq4 +ero0zix4fA4tJNuTpZ/5r7GUYaf/uT4xfDilBX2fGMsxVTxJC25KzhdFeTzg1Tde +/N0LAeLWHfe6jR/P5XDATD0ZA73DQALOxRM5uRMeWJDVaUeco/aXsdQaCz2STDI3 +h7VVFoaOlmxQW3BBEvg2VUp9DS2UjqqdwsUDtzwKfrmj/FqyBvGrvNeIMv28HCu7 +r1WE1Z0UEJhpc1BPbu7F/vl60gRF3bQjh2tL8pWThxTJe6Qy+pLoSShyi85AM9XK +scCmUtQWjy7KQDL8XVFvuCWvMzknZQjJcncbKddPaaSIDkKUpz9FDv+wSJj/LKf7 +bGSFPM6sblioLbLNJByRYI8G7VHvKDbUnYHbHp75NTGA2eDeNqx5bC2G/EJUTwLM +bfcZr9hv+z1QpvSLEpar30kJjc1QMQcf60ToGYIC93rsVAKou2GPGry4h/nzwro0 +jjFWNgORTXllfcQDbDNOPkV1kFFibPbAU4faZMgC+xwIwDBsndvcvXjLaRUa4fmw +1xNkOO5Lj9AuvTXdCc9yUXRzmPZhU6Q4YB2daWvs3vbMTtvkAXGyQL4b2HD+NYZs +cMUtbteGgQzwM1gpMBn4GX53vhlCXq28r3cH1/1tLDweglSrxyvZbB7pZU7BAmLk +TEj2fXcvdcX+TtYhC10= +-----END CERTIFICATE----- diff --git a/reg-tests/ssl/show_ocsp_server.pem.ocsp b/reg-tests/ssl/show_ocsp_server.pem.ocsp Binary files differnew file mode 100644 index 0000000..5ac1457 --- /dev/null +++ b/reg-tests/ssl/show_ocsp_server.pem.ocsp diff --git a/reg-tests/ssl/show_ocsp_server.pem.ocsp.revoked b/reg-tests/ssl/show_ocsp_server.pem.ocsp.revoked Binary files differnew file mode 100644 index 0000000..bf69b3d --- /dev/null +++ b/reg-tests/ssl/show_ocsp_server.pem.ocsp.revoked diff --git a/reg-tests/ssl/show_ssl_ocspresponse.vtc b/reg-tests/ssl/show_ssl_ocspresponse.vtc new file mode 100644 index 0000000..3d67fe5 --- /dev/null +++ b/reg-tests/ssl/show_ssl_ocspresponse.vtc @@ -0,0 +1,135 @@ +#REGTEST_TYPE=devel + +# broken with BoringSSL. + +# This reg-test uses the "show ssl ocsp-response" command to display the details +# of the OCSP responses used by HAProxy. +# It also uses the new special cases of the "show ssl cert" command, where an OCSP +# extension is provided to the certificate name (with or without preceding * for an +# ongoing transaction). +# +# It uses the show_ocsp_server.pem server certificate, signed off by set_cafile_rootCA.crt, +# which has two OCSP responses, show_ocsp_server.pem.ocsp which is loaded by default and in +# which it is valid, and show_ocsp_server.pem.ocsp.revoked in which it is revoked. +# The OSCP response is updated through the two means available in the CLI, the +# "set ssl ocsp-response" command and the update through a "set ssl cert foo.ocsp". +# +# It requires socat to upload the new OCSP responses. +# +# If this test does not work anymore: +# - Check that you have socat + +varnishtest "Test the 'show ssl ocsp-response' and 'show ssl cert foo.pem.ocsp' features of the CLI" +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL) && !ssllib_name_startswith(BoringSSL)'" +feature cmd "command -v socat && command -v openssl" +feature ignore_unknown_macro + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + tune.ssl.capture-buffer-size 1 + stats socket "${tmpdir}/h1/stats" level admin + + defaults + mode http + option httplog + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen clear-lst + bind "fd@${clearlst}" + server s1 "${tmpdir}/ssl.sock" ssl ca-file ${testdir}/set_cafile_rootCA.crt verify none + + listen ssl-lst + # crt: certificate of the server + # ca-file: CA used for client authentication request + bind "${tmpdir}/ssl.sock" ssl crt ${testdir}/show_ocsp_server.pem ca-file ${testdir}/set_cafile_rootCA.crt verify none crt-ignore-err all + http-response add-header X-SSL-Client-Verify %[ssl_c_verify] + server s1 ${s1_addr}:${s1_port} +} -start + + +# Test the "show ssl ocsp-response" command +haproxy h1 -cli { + send "show ssl ocsp-response" + expect ~ "Certificate ID key : 303b300906052b0e03021a050004148a83e0060faff709ca7e9b95522a2e81635fda0a0414f652b0e435d5ea923851508f0adbe92d85de007a0202100f" + + send "show ssl ocsp-response 303b300906052b0e03021a050004148a83e0060faff709ca7e9b95522a2e81635fda0a0414f652b0e435d5ea923851508f0adbe92d85de007a0202100f" + expect ~ "Responder Id: C = FR, O = HAProxy Technologies, CN = ocsp.haproxy.com" + send "show ssl ocsp-response 303b300906052b0e03021a050004148a83e0060faff709ca7e9b95522a2e81635fda0a0414f652b0e435d5ea923851508f0adbe92d85de007a0202100f" + expect ~ "Cert Status: good" +} + +# Test the "show ssl cert foo.pem.ocsp" command +haproxy h1 -cli { + send "show ssl cert" + expect ~ ".*show_ocsp_server.pem" + + send "show ssl cert ${testdir}/show_ocsp_server.pem" + expect ~ "Serial: 100F" + send "show ssl cert ${testdir}/show_ocsp_server.pem" + expect ~ "OCSP Response Key: 303b300906052b0e03021a050004148a83e0060faff709ca7e9b95522a2e81635fda0a0414f652b0e435d5ea923851508f0adbe92d85de007a0202100f" + + send "show ssl cert ${testdir}/show_ocsp_server.pem.ocsp" + expect ~ "Responder Id: C = FR, O = HAProxy Technologies, CN = ocsp.haproxy.com" + send "show ssl cert ${testdir}/show_ocsp_server.pem.ocsp" + expect ~ "Cert Status: good" +} + + +# Change the server certificate's OCSP response through "set ssl ocsp-response" +shell { + printf "set ssl ocsp-response <<\n$(cat ${testdir}/show_ocsp_server.pem.ocsp.revoked|openssl base64)\n\n" | socat "${tmpdir}/h1/stats" - +} + +# Check that the change was taken into account +haproxy h1 -cli { + send "show ssl ocsp-response" + expect ~ "Certificate ID key : 303b300906052b0e03021a050004148a83e0060faff709ca7e9b95522a2e81635fda0a0414f652b0e435d5ea923851508f0adbe92d85de007a0202100f" + + send "show ssl ocsp-response 303b300906052b0e03021a050004148a83e0060faff709ca7e9b95522a2e81635fda0a0414f652b0e435d5ea923851508f0adbe92d85de007a0202100f" + expect ~ "Responder Id: C = FR, O = HAProxy Technologies, CN = ocsp.haproxy.com" + send "show ssl ocsp-response 303b300906052b0e03021a050004148a83e0060faff709ca7e9b95522a2e81635fda0a0414f652b0e435d5ea923851508f0adbe92d85de007a0202100f" + expect ~ "Cert Status: revoked" + + send "show ssl cert ${testdir}/show_ocsp_server.pem.ocsp" + expect ~ "Cert Status: revoked" +} + + +# Change the server certificate's OCSP response through a transaction +shell { + printf "set ssl cert ${testdir}/show_ocsp_server.pem <<\n$(cat ${testdir}/show_ocsp_server.pem)\n\n" | socat "${tmpdir}/h1/stats" - + printf "set ssl cert ${testdir}/show_ocsp_server.pem.ocsp <<\n$(cat ${testdir}/show_ocsp_server.pem.ocsp|openssl base64)\n\n" | socat "${tmpdir}/h1/stats" - +} + + +# Check that the actual tree entry was not changed and that the uncommitted +# transaction's OCSP response is the new one +haproxy h1 -cli { + send "show ssl ocsp-response 303b300906052b0e03021a050004148a83e0060faff709ca7e9b95522a2e81635fda0a0414f652b0e435d5ea923851508f0adbe92d85de007a0202100f" + expect ~ "Cert Status: revoked" + send "show ssl ocsp-response 303b300906052b0e03021a050004148a83e0060faff709ca7e9b95522a2e81635fda0a0414f652b0e435d5ea923851508f0adbe92d85de007a0202100f" + expect ~ "This Update: Jun 10 08:57:45 2021 GMT" + + send "show ssl cert *${testdir}/show_ocsp_server.pem.ocsp" + expect ~ "Cert Status: good" + send "show ssl cert *${testdir}/show_ocsp_server.pem.ocsp" + expect ~ "This Update: Jun 10 08:55:04 2021 GMT" +} + + +# Commit the transaction and check that it was taken into account +haproxy h1 -cli { + send "commit ssl cert ${testdir}/show_ocsp_server.pem" + expect ~ "Success!" + + send "show ssl ocsp-response 303b300906052b0e03021a050004148a83e0060faff709ca7e9b95522a2e81635fda0a0414f652b0e435d5ea923851508f0adbe92d85de007a0202100f" + expect ~ "Cert Status: good" + send "show ssl ocsp-response 303b300906052b0e03021a050004148a83e0060faff709ca7e9b95522a2e81635fda0a0414f652b0e435d5ea923851508f0adbe92d85de007a0202100f" + expect ~ "This Update: Jun 10 08:55:04 2021 GMT" +} diff --git a/reg-tests/ssl/simple.crt-list b/reg-tests/ssl/simple.crt-list new file mode 100644 index 0000000..9ffacb4 --- /dev/null +++ b/reg-tests/ssl/simple.crt-list @@ -0,0 +1,5 @@ +common.pem record1.bug940.domain.tld +common.pem record2.bug940.domain.tld +ecdsa.pem record3.bug940.domain.tld +ecdsa.pem record4.bug940.domain.tld + diff --git a/reg-tests/ssl/ssl_client_auth.vtc b/reg-tests/ssl/ssl_client_auth.vtc new file mode 100644 index 0000000..0278ec0 --- /dev/null +++ b/reg-tests/ssl/ssl_client_auth.vtc @@ -0,0 +1,83 @@ +#REGTEST_TYPE=devel + +# This reg-test tests the client auth feature of HAProxy for both the backend +# and frontend section with a CRL list +# +# This reg-test uses 2 chained listeners because vtest does not handle the SSL. +# Test the frontend client auth and the backend side at the same time. +# +# The sends 3 requests one with a correct certificate, one with an expired one and one which was revoked. +# The client then check if we received the right one with the right error. +# +# Certificates, CA and CRL are expiring in 2050 so it should be fine for the CI. +# +# Detail about configuration is explained there: +# https://www.haproxy.com/blog/ssl-client-certificate-management-at-application-level/ + +varnishtest "Test the client auth" +#REQUIRE_OPTIONS=OPENSSL +feature ignore_unknown_macro + +server s1 -repeat 3 { + rxreq + txresp +} -start + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + + defaults + mode http + option httplog + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen clear-lst + bind "fd@${clearlst}" + balance roundrobin + # crt: certificate sent for a client certificate request + server s1 "${tmpdir}/ssl.sock" ssl verify none crt ${testdir}/client1.pem + server s2 "${tmpdir}/ssl.sock" ssl verify none crt ${testdir}/client2_expired.pem # expired + server s3 "${tmpdir}/ssl.sock" ssl verify none crt ${testdir}/client3_revoked.pem # revoked + + listen ssl-lst + # crt: certificate of the server + # ca-file: CA used for client authentication request + # crl-file: revocation list for client auth: the client1 certificate is revoked + bind "${tmpdir}/ssl.sock" ssl crt ${testdir}/common.pem ca-file ${testdir}/ca-auth.crt verify optional crt-ignore-err all crl-file ${testdir}/crl-auth.pem + + acl cert_expired ssl_c_verify 10 + acl cert_revoked ssl_c_verify 23 + acl cert_ok ssl_c_verify 0 + + http-response add-header X-SSL Ok if cert_ok + http-response add-header X-SSL Expired if cert_expired + http-response add-header X-SSL Revoked if cert_revoked + + server s1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl == "Ok" +} -run + +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl == "Expired" +} -run + +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl == "Revoked" +} -run diff --git a/reg-tests/ssl/ssl_client_samples.vtc b/reg-tests/ssl/ssl_client_samples.vtc new file mode 100644 index 0000000..81a52ab --- /dev/null +++ b/reg-tests/ssl/ssl_client_samples.vtc @@ -0,0 +1,72 @@ +#REGTEST_TYPE=devel + +varnishtest "Test the ssl_c_* sample fetches" +#REQUIRE_VERSION=2.2 +#REQUIRE_OPTIONS=OPENSSL +feature ignore_unknown_macro + +server s1 -repeat 3 { + rxreq + txresp +} -start + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + tune.ssl.capture-buffer-size 1 + crt-base ${testdir} + + defaults + mode http + option httplog + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + + listen clear-lst + bind "fd@${clearlst}" + balance roundrobin + server s1 "${tmpdir}/ssl.sock" ssl verify none crt ${testdir}/client1.pem + + listen ssl-lst + mode http + + http-response add-header x-ssl-der %[ssl_c_der,hex] + http-response add-header x-ssl-chain-der %[ssl_c_chain_der,hex] + http-response add-header x-ssl-sha1 %[ssl_c_sha1,hex] + http-response add-header x-ssl-notafter %[ssl_c_notafter] + http-response add-header x-ssl-notbefore %[ssl_c_notbefore] + http-response add-header x-ssl-sig_alg %[ssl_c_sig_alg] + http-response add-header x-ssl-i_dn %[ssl_c_i_dn] + http-response add-header x-ssl-s_dn %[ssl_c_s_dn] + http-response add-header x-ssl-s_serial %[ssl_c_serial,hex] + http-response add-header x-ssl-key_alg %[ssl_c_key_alg] + http-response add-header x-ssl-version %[ssl_c_version] + + bind "${tmpdir}/ssl.sock" ssl crt ${testdir}/common.pem ca-file ${testdir}/ca-auth.crt verify optional crt-ignore-err all crl-file ${testdir}/crl-auth.pem + + server s1 ${s1_addr}:${s1_port} +} -start + + +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-der ~ 3082052D30820315020102300D0.*995ED3BE2BFB923A3EB71FA07002E + expect resp.http.x-ssl-chain-der ~ 3082096B30820553A0030201020.*0237D08F425C8414A23D436415502 + expect resp.http.x-ssl-sha1 == "D9C3BAE37EA5A7EDB7B3C9BDD4DCB2FE58A412E4" + expect resp.http.x-ssl-notafter == "500421185942Z" + expect resp.http.x-ssl-notbefore == "200428185942Z" + expect resp.http.x-ssl-sig_alg == "RSA-SHA256" + expect resp.http.x-ssl-i_dn == "/C=FR/ST=Some-State/O=HAProxy Technologies/CN=HAProxy Technologies CA Test Client Auth" + expect resp.http.x-ssl-s_dn == "/C=FR/O=HAProxy Technologies Test/CN=client1" + expect resp.http.x-ssl-s_serial == "02" + expect resp.http.x-ssl-key_alg == "rsaEncryption" + expect resp.http.x-ssl-version == "1" +} -run + + diff --git a/reg-tests/ssl/ssl_crt-list_filters.vtc b/reg-tests/ssl/ssl_crt-list_filters.vtc new file mode 100644 index 0000000..099a400 --- /dev/null +++ b/reg-tests/ssl/ssl_crt-list_filters.vtc @@ -0,0 +1,64 @@ +#REGTEST_TYPE=bug +varnishtest "Test for the bug #810 and #818" +feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL) && ssllib_name_startswith(OpenSSL) && openssl_version_atleast(1.1.1)'" +# This test checks if the multiple certificate types works correctly with the +# SNI, and that the negative filters are correctly excluded + +#REQUIRE_VERSION=2.2 +#REQUIRE_OPTIONS=OPENSSL +feature ignore_unknown_macro + +server s1 -repeat 3 { + rxreq + txresp +} -start + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + crt-base ${testdir} + stats socket "${tmpdir}/h1/stats" level admin + + defaults + mode http + option httplog + retries 0 + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + + listen clear-lst + bind "fd@${clearlst}" + balance roundrobin + server s1 "${tmpdir}/ssl.sock" ssl verify none sni str(another-record.bug810.domain.tld) ssl-min-ver TLSv1.2 ssl-max-ver TLSv1.2 ciphers "kRSA" + server s2 "${tmpdir}/ssl.sock" ssl verify none sni str(another-record.bug810.domain.tld) ssl-min-ver TLSv1.2 ssl-max-ver TLSv1.2 ciphers "aECDSA" + server s3 "${tmpdir}/ssl.sock" ssl verify none sni str(another-record.bug818.domain.tld) ssl-min-ver TLSv1.2 ssl-max-ver TLSv1.2 ciphers "kRSA" + + listen ssl-lst + mode http + bind "${tmpdir}/ssl.sock" ssl strict-sni ssl-min-ver TLSv1.2 ssl-max-ver TLSv1.2 ciphers "kRSA:aECDSA" crt-list ${testdir}/filters.crt-list + + server s1 ${s1_addr}:${s1_port} +} -start + + +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 +} -run + +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 +} -run + +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 503 +} -run diff --git a/reg-tests/ssl/ssl_curves.vtc b/reg-tests/ssl/ssl_curves.vtc new file mode 100644 index 0000000..5cc70df --- /dev/null +++ b/reg-tests/ssl/ssl_curves.vtc @@ -0,0 +1,134 @@ +#REGTEST_TYPE=devel + +# This reg-test checks the behaviour of the 'curves' and 'ecdhe' options on a +# bind line. Its main point is to ensure that the default curve used in +# HAProxy is indeed prime256v1 (or P-256 depending on the curve's +# representation). In order to check this, is uses two ssl frontends that have +# different lists of accepted curves, one of them accepting this default curve +# while the other one does not. A backend tries to connect to those two +# frontends by using the default curve, and it should succeed in one case and +# fail in the other. +# For some strange reason, OpenSSL 1.0.2 does not behave the same way as later +# versions when it comes to ECDH and curves related matters. Instead of trying +# to make it work the same way as the other (more used) versions, we will +# ignore it and disable this test on OpenSSL 1.0.2. +# For the same reason, this test is disabled for other SSL libraries as well. +# + +varnishtest "Test the 'curves' and 'ecdhe' options and default curve value" +feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL) && ssllib_name_startswith(OpenSSL) && openssl_version_atleast(1.1.1)'" +feature ignore_unknown_macro + +server s1 -repeat 2 { + rxreq + txresp +} -start + +barrier b1 cond 2 -cyclic + +syslog Slg_cust_fmt -level info { + recv + expect ~ "ERROR.*conn_status:\"34:SSL handshake failure\" hsk_err:\".*wrong curve\".*" + + barrier b1 sync + + recv + expect ~ "ERROR ECDHE.*conn_status:\"34:SSL handshake failure\" hsk_err:\".*wrong curve\".*" +} -start + + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + + defaults + mode http + option httpslog + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + retries 0 + + listen clear-lst + bind "fd@${clearlst}" + + use_backend ssl-curves-be if { path /curves } + use_backend ssl-ecdhe-521-be if { path /ecdhe-521 } + use_backend ssl-ecdhe-256-be if { path /ecdhe-256 } + default_backend ssl-be + + backend ssl-be + server s1 "${tmpdir}/ssl1.sock" ssl verify none crt ${testdir}/client.ecdsa.pem force-tlsv12 + + backend ssl-curves-be + server s1 "${tmpdir}/ssl2.sock" ssl verify none crt ${testdir}/client.ecdsa.pem force-tlsv12 + + backend ssl-ecdhe-256-be + server s1 "${tmpdir}/ssl-ecdhe-256.sock" ssl verify none crt ${testdir}/client.ecdsa.pem force-tlsv12 + + backend ssl-ecdhe-521-be + server s1 "${tmpdir}/ssl-ecdhe-521.sock" ssl verify none crt ${testdir}/client.ecdsa.pem force-tlsv12 + + + listen ssl1-lst + bind "${tmpdir}/ssl1.sock" ssl crt ${testdir}/common.pem ca-file ${testdir}/set_cafile_rootCA.crt verify optional curves P-256:P-384 + server s1 ${s1_addr}:${s1_port} + + # The prime256v1 curve, which is used by default by a backend when no + # 'curves' or 'ecdhe' option is specified, is not allowed on this listener + listen ssl2-lst + log ${Slg_cust_fmt_addr}:${Slg_cust_fmt_port} local0 + error-log-format "ERROR conn_status:\"%[fc_err]:%[fc_err_str]\" hsk_err:%{+Q}[ssl_fc_err_str]" + + bind "${tmpdir}/ssl2.sock" ssl crt ${testdir}/common.pem ca-file ${testdir}/set_cafile_rootCA.crt verify optional curves P-384 + server s1 ${s1_addr}:${s1_port} + + listen ssl-ecdhe-521-lst + log ${Slg_cust_fmt_addr}:${Slg_cust_fmt_port} local0 + error-log-format "ERROR ECDHE-521 conn_status:\"%[fc_err]:%[fc_err_str]\" hsk_err:%{+Q}[ssl_fc_err_str]" + + bind "${tmpdir}/ssl-ecdhe-521.sock" ssl crt ${testdir}/common.pem ca-file ${testdir}/set_cafile_rootCA.crt verify optional ecdhe secp521r1 + server s1 ${s1_addr}:${s1_port} + + listen ssl-ecdhe-256-lst + log ${Slg_cust_fmt_addr}:${Slg_cust_fmt_port} local0 + error-log-format "ERROR ECDHE-256 conn_status:\"%[fc_err]:%[fc_err_str]\" hsk_err:%{+Q}[ssl_fc_err_str]" + + bind "${tmpdir}/ssl-ecdhe-256.sock" ssl crt ${testdir}/common.pem ca-file ${testdir}/set_cafile_rootCA.crt verify optional ecdhe prime256v1 + server s1 ${s1_addr}:${s1_port} + +} -start + +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 +} -run + +# The backend tries to use the prime256v1 curve that is not accepted by the +# frontend so the handshake should fail. +client c2 -connect ${h1_clearlst_sock} { + txreq -url "/curves" + rxresp + expect resp.status == 503 +} -run + +barrier b1 sync + +# The backend tries to use the prime256v1 curve that is not accepted by the +# frontend so the handshake should fail. +client c3 -connect ${h1_clearlst_sock} { + txreq -url "/ecdhe-521" + rxresp + expect resp.status == 503 +} -run + +client c4 -connect ${h1_clearlst_sock} { + txreq -url "/ecdhe-256" + rxresp + expect resp.status == 200 +} -run + +syslog Slg_cust_fmt -wait diff --git a/reg-tests/ssl/ssl_default_server.vtc b/reg-tests/ssl/ssl_default_server.vtc new file mode 100644 index 0000000..485a9ba --- /dev/null +++ b/reg-tests/ssl/ssl_default_server.vtc @@ -0,0 +1,142 @@ +#REGTEST_TYPE=devel + +# This reg-test ensures that SSL related configuration specified in a +# default-server option are properly taken into account by the servers +# (frontend). It mainly focuses on the client certificate used by the frontend, +# that can either be defined in the server line itself, in the default-server +# line or in both. +# +# It was created following a bug raised in redmine (issue #3906) in which a +# server used an "empty" SSL context instead of the proper one. +# + +varnishtest "Test the 'set ssl cert' feature of the CLI" +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL)'" +feature ignore_unknown_macro + +server s1 -repeat 7 { + rxreq + txresp +} -start + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + tune.ssl.capture-buffer-size 1 + stats socket "${tmpdir}/h1/stats" level admin + crt-base ${testdir} + ca-base ${testdir} + + defaults + mode http + option httplog + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen clear-lst + bind "fd@${clearlst}" + use_backend first_be if { path /first } + use_backend second_be if { path /second } + use_backend third_be if { path /third } + use_backend fourth_be if { path /fourth } + use_backend fifth_be if { path /fifth } + + + backend first_be + default-server ssl crt client1.pem ca-file ca-auth.crt verify none + server s1 "${tmpdir}/ssl.sock" + + backend second_be + default-server ssl ca-file ca-auth.crt verify none + server s1 "${tmpdir}/ssl.sock" crt client1.pem + + backend third_be + default-server ssl crt client1.pem ca-file ca-auth.crt verify none + server s1 "${tmpdir}/ssl.sock" crt client2_expired.pem + + backend fourth_be + default-server ssl crt client1.pem verify none + server s1 "${tmpdir}/ssl.sock" ca-file ca-auth.crt + + backend fifth_be + balance roundrobin + default-server ssl crt client1.pem verify none + server s1 "${tmpdir}/ssl.sock" + server s2 "${tmpdir}/ssl.sock" crt client2_expired.pem + server s3 "${tmpdir}/ssl.sock" + + + listen ssl-lst + bind "${tmpdir}/ssl.sock" ssl crt ${testdir}/common.pem ca-file ca-auth.crt verify required crt-ignore-err all + + acl cert_expired ssl_c_verify 10 + acl cert_revoked ssl_c_verify 23 + acl cert_ok ssl_c_verify 0 + + http-response add-header X-SSL Ok if cert_ok + http-response add-header X-SSL Expired if cert_expired + http-response add-header X-SSL Revoked if cert_revoked + + server s1 ${s1_addr}:${s1_port} +} -start + + + +client c1 -connect ${h1_clearlst_sock} { + txreq -url "/first" + rxresp + expect resp.status == 200 + expect resp.http.x-ssl == "Ok" +} -run + +client c1 -connect ${h1_clearlst_sock} { + txreq -url "/second" + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl == "Ok" +} -run + +client c1 -connect ${h1_clearlst_sock} { + txreq -url "/third" + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl == "Expired" +} -run + +client c1 -connect ${h1_clearlst_sock} { + txreq -url "/fourth" + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl == "Ok" +} -run + +client c1 -connect ${h1_clearlst_sock} { + txreq -url "/fifth" + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl == "Ok" +} -run + +client c1 -connect ${h1_clearlst_sock} { + txreq -url "/fifth" + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl == "Expired" +} -run + +client c1 -connect ${h1_clearlst_sock} { + txreq -url "/fifth" + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl == "Ok" +} -run diff --git a/reg-tests/ssl/ssl_dh.vtc b/reg-tests/ssl/ssl_dh.vtc new file mode 100644 index 0000000..9553f37 --- /dev/null +++ b/reg-tests/ssl/ssl_dh.vtc @@ -0,0 +1,233 @@ +#REGTEST_TYPE=devel + +# This reg-tests checks that the DH-related mechanisms works properly. +# When no DH is specified, either directly in the server's PEM or through a +# ssl-dh-param-file global option, and no tune.ssl.default-dh-param is defined, +# DHE ciphers are disabled. +# If a default-dh-param is defined, we will use DH parameters of the same size +# as the server's RSA or DSA key, or default-dh-param if it is smaller. +# This test has three distinct HAProxy instances, one with no DH-related option +# used, one with the tune.ssl.default-dh-param global parameter set, and one +# with an ssl-dh-param-file global option. +# We use "openssl s_client" calls in order to check the size of the "Server +# Temp Key" (which will be the same as the DH parameters in case a DHE cipher +# is used). +# +# The main goal of this test was to check that the newly added OpenSSLv3 +# specific DH code worked as before, since it needed to be created in order to +# stop using deprecated APIs. + +varnishtest "Test the DH related SSL options" +feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL)'" +feature cmd "command -v openssl && command -v grep && command -v socat" +feature ignore_unknown_macro + +server s1 -repeat 8 { + rxreq + txresp +} -start + + +haproxy h1 -conf { + global + stats socket "${tmpdir}/h1/stats" level admin + + defaults + mode http + option httpslog + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + retries 0 + + frontend clear-fe + bind "fd@${clearlst}" + use_backend gen_cert_be if { path /gencert } + default_backend dflt_be + + backend dflt_be + server s1 "${tmpdir}/ssl_dflt.sock" ssl verify none ssl-max-ver TLSv1.2 + + backend gen_cert_be + server s1 "${tmpdir}/ssl_dflt_gencert.sock" ssl verify none ssl-max-ver TLSv1.2 + + listen ssl-dflt-lst + bind "${tmpdir}/ssl_dflt.sock" ssl crt ${testdir}/common.pem ca-file ${testdir}/set_cafile_rootCA.crt verify optional ciphers "DHE-RSA-AES256-GCM-SHA384" ssl-max-ver TLSv1.2 + http-response set-header x-ssl-cipher %[ssl_fc_cipher] + server s1 ${s1_addr}:${s1_port} + + listen ssl-dflt-gencert-lst + bind "${tmpdir}/ssl_dflt_gencert.sock" ssl generate-certificates crt ${testdir}/common.pem ca-file ${testdir}/set_cafile_rootCA.crt ca-sign-file ${testdir}/generate_certificates/gen_cert_ca.pem verify optional ciphers "DHE-RSA-AES256-GCM-SHA384" ssl-max-ver TLSv1.2 + http-response set-header x-ssl-cipher %[ssl_fc_cipher] + server s1 ${s1_addr}:${s1_port} +} -start + +haproxy h2 -conf { + global + stats socket "${tmpdir}/h2/stats" level admin + + global + tune.ssl.default-dh-param 4096 + + defaults + mode http + option httpslog + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + retries 0 + + listen clear-lst + bind "fd@${clearlst_dfltdh}" + server s1 "${tmpdir}/ssl_dfltdh.sock" ssl verify none ssl-max-ver TLSv1.2 + + listen ssl-4096dh-dflt-lst + bind "${tmpdir}/ssl_dfltdh.sock" ssl crt ${testdir}/common.pem ca-file ${testdir}/set_cafile_rootCA.crt verify optional ciphers "DHE-RSA-AES256-GCM-SHA384" ssl-max-ver TLSv1.2 + http-response set-header x-ssl-cipher %[ssl_fc_cipher] + server s1 ${s1_addr}:${s1_port} +} -start + +haproxy h3 -conf { + global + stats socket "${tmpdir}/h3/stats" level admin + + global + ssl-dh-param-file ${testdir}/common.4096.dh + + defaults + mode http + option httpslog + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + retries 0 + + listen clear-lst + bind "fd@${clearlst_dhfile}" + server s1 "${tmpdir}/ssl_dhfile.sock" ssl verify none ssl-max-ver TLSv1.2 + + listen ssl-dhfile-lst + bind "${tmpdir}/ssl_dhfile.sock" ssl crt ${testdir}/common.pem ca-file ${testdir}/set_cafile_rootCA.crt verify optional ciphers "DHE-RSA-AES256-GCM-SHA384" ssl-max-ver TLSv1.2 + http-response set-header x-ssl-cipher %[ssl_fc_cipher] + server s1 ${s1_addr}:${s1_port} +} -start + +# +# Check that all the SSL backend <-> SSL frontend connections work +# +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + # No DH parameters are defined, DHE ciphers are unavailable + expect resp.status == 503 +} -run + +client c2 -connect ${h2_clearlst_dfltdh_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-cipher == "DHE-RSA-AES256-GCM-SHA384" +} -run + +client c3 -connect ${h3_clearlst_dhfile_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-cipher == "DHE-RSA-AES256-GCM-SHA384" +} -run + +client c4 -connect ${h1_clearlst_sock} { + txreq -url "/gencert" + rxresp + # No DH parameters are defined, DHE ciphers are unavailable + expect resp.status == 503 +} -run + + +# On the second HAProxy instance, even if default-dh-param is set to 4096, this +# value is only considered as a maximum DH key length and we will always try to +# match the server's certificate key length in our DHE key exchange (2048 bits +# in the case of common.pem). +shell { + echo "Q" | openssl s_client -unix "${tmpdir}/ssl_dfltdh.sock" -tls1_2 2>/dev/null | grep -E "Server Temp Key: DH, 2048 bits" +} + +shell { + echo "Q" | openssl s_client -unix "${tmpdir}/ssl_dhfile.sock" -tls1_2 2>/dev/null | grep -E "Server Temp Key: DH, 4096 bits" +} + + +# +# Add a custom DH to the server's PEM certificate +# +shell { + printf "set ssl cert ${testdir}/common.pem <<\n$(cat ${testdir}/common.pem)\n$(cat ${testdir}/common.4096.dh)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl cert ${testdir}/common.pem" | socat "${tmpdir}/h1/stats" - + + printf "set ssl cert ${testdir}/common.pem <<\n$(cat ${testdir}/common.pem)\n$(cat ${testdir}/common.4096.dh)\n\n" | socat "${tmpdir}/h2/stats" - + echo "commit ssl cert ${testdir}/common.pem" | socat "${tmpdir}/h2/stats" - + + printf "set ssl cert ${testdir}/common.pem <<\n$(cat ${testdir}/common.pem)\n$(cat ${testdir}/common.4096.dh)\n\n" | socat "${tmpdir}/h3/stats" - + echo "commit ssl cert ${testdir}/common.pem" | socat "${tmpdir}/h3/stats" - +} + + +# +# Check that all the SSL backend <-> SSL frontend connections still work +# Common.pem now contains DH parameters so the first instance's frontends +# can now use DHE ciphers. +# +client c5 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-cipher == "DHE-RSA-AES256-GCM-SHA384" +} -run + +client c6 -connect ${h2_clearlst_dfltdh_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-cipher == "DHE-RSA-AES256-GCM-SHA384" +} -run + +client c7 -connect ${h3_clearlst_dhfile_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-cipher == "DHE-RSA-AES256-GCM-SHA384" +} -run + +client c8 -connect ${h1_clearlst_sock} { + txreq -url "/gencert" + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-cipher == "DHE-RSA-AES256-GCM-SHA384" +} -run + + + +# +# Check the new size of the DH key +# +shell { + echo "Q" | openssl s_client -unix "${tmpdir}/ssl_dflt.sock" -tls1_2 2>/dev/null | grep -E "Server Temp Key: DH, 4096 bits" +} + +shell { + echo "Q" | openssl s_client -unix "${tmpdir}/ssl_dfltdh.sock" -tls1_2 2>/dev/null | grep -E "Server Temp Key: DH, 4096 bits" +} + +shell { + echo "Q" | openssl s_client -unix "${tmpdir}/ssl_dhfile.sock" -tls1_2 2>/dev/null | grep -E "Server Temp Key: DH, 4096 bits" +} + +shell { + echo "Q" | openssl s_client -unix "${tmpdir}/ssl_dflt_gencert.sock" -tls1_2 2>/dev/null | grep -E "Server Temp Key: DH, 4096 bits" +} diff --git a/reg-tests/ssl/ssl_errors.vtc b/reg-tests/ssl/ssl_errors.vtc new file mode 100644 index 0000000..8fb9c5a --- /dev/null +++ b/reg-tests/ssl/ssl_errors.vtc @@ -0,0 +1,439 @@ +#REGTEST_TYPE=devel + +# This reg-test checks that the connection and SSL sample fetches related to +# errors are functioning properly. It also tests the proper behaviour of the +# default HTTPS log format and of the error-log-format option which allows to +# define a specific log format used only in case of connection error (otherwise +# a line following the configured log-format is output). +# +# It works by sending request through three different paths, one using a custom +# log-format line that contains the connection error and SSL handshake error +# sample fetches, one using the default HTTPS log-format and one using the +# legacy error log format. +# +# The output log lines are caught by syslog blocks (one for each path) and +# compared to an expected format. +# Since the syslog is not by design synchronized with the Varnish clients and +# servers, synchronization is achieved through barriers, which ensure that +# syslog messages arrive in the right order. +# +# In order to ensure that the log line raised in case of connection error if an +# error-log-format is defined still follows the log-separate-error option, the +# log lines raised by the https_fmt_lst listener will be sent to two separate +# syslog servers. +# + +varnishtest "Test the connection and SSL error fetches." +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev2)'" +feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL) && ssllib_name_startswith(OpenSSL)'" +feature cmd "command -v socat" +feature ignore_unknown_macro + +server s1 -repeat 4 { + rxreq + txresp +} -start + +barrier b1 cond 4 -cyclic +barrier b2 cond 2 -cyclic + + +syslog Slg_cust_fmt -level info { + recv + expect ~ ".*conn_status:\"0:Success\" hsk_err:\"0:-\" CN=\"/C=FR/O=HAProxy Technologies/CN=Client\",serial=1007,hash=063DCC2E6A9159E66994B325D6D2EF3D17A75B6F" + + barrier b1 sync + + recv + expect ~ "ERROR.*conn_status:\"30:SSL client CA chain cannot be verified\" hsk_err:\"134:.*:certificate verify failed\" CN=\"/C=FR/O=HAProxy Technologies/CN=Client\",serial=1007,hash=063DCC2E6A9159E66994B325D6D2EF3D17A75B6F" + + barrier b1 sync + + recv + expect ~ "ERROR.*conn_status:\"31:SSL client certificate not trusted\" hsk_err:\"134:.*:certificate verify failed\" CN=\"/C=FR/O=HAProxy Technologies/CN=Client\",serial=1007,hash=063DCC2E6A9159E66994B325D6D2EF3D17A75B6F" + + barrier b1 sync + + # In case of an error occurring before the certificate verification process, + # the client certificate chain is never parsed and verified so we can't + # have information about the client's certificate. + recv + expect ~ "ERROR.*conn_status:\"34:SSL handshake failure\" hsk_err:\"193:.*:no shared cipher\" CN=\"\",serial=-,hash=-" +} -start + +syslog Slg_https_fmt -level info { + recv + expect ~ ".*https_logfmt_ssl_lst~ https_logfmt_ssl_lst/s1.*0/0000000000000000/0/0/.? foo.com/TLSv1.2/AES256-GCM-SHA384" + + barrier b1 sync +} -start + +syslog Slg_https_fmt_err -level info { + recv + expect ~ "ERROR.*https_logfmt_ssl_lst~ https_logfmt_ssl_lst/<NOSRV>.*30/0000000000000086/0/2/.? foo.com/TLSv1.2/\\(NONE\\)" + + barrier b1 sync + + recv + expect ~ "ERROR.*https_logfmt_ssl_lst~ https_logfmt_ssl_lst/<NOSRV>.*31/0000000000000086/20/0/.? foo.com/TLSv1.2/\\(NONE\\)" + + barrier b1 sync + + recv + expect ~ "ERROR.*https_logfmt_ssl_lst~ https_logfmt_ssl_lst/<NOSRV>.*34/00000000000000C1/0/0/.? foo.com/TLSv1.2/\\(NONE\\)" +} -start + +syslog Slg_logconnerror -level info { + recv + expect ~ ".*logconnerror_ssl_lst~ logconnerror_ssl_lst/s1" + + barrier b1 sync + + recv + expect ~ ".*logconnerror_ssl_lst/1: SSL client CA chain cannot be verified" + + barrier b1 sync + + recv + expect ~ ".*logconnerror_ssl_lst/1: SSL client certificate not trusted" + + barrier b1 sync + + recv + expect ~ ".*logconnerror_ssl_lst/1: SSL handshake failure" +} -start + +syslog Slg_bcknd -level info { + recv + expect ~ ".*bc_err:0:\"Success\" ssl_bc_err:0:" + + barrier b2 sync + + recv + expect ~ ".*bc_err:34:\"SSL handshake failure\" ssl_bc_err:134:.*:certificate verify failed" + + barrier b2 sync + + recv + expect ~ ".*bc_err:33:\"Server presented an SSL certificate different from the expected one\" ssl_bc_err:134:.*:certificate verify failed" + + barrier b2 sync + + # Verify errors on the server side cannot be caught when using TLSv1.3 but it works for TLSv1.2 + recv + expect ~ ".*bc_err:34:\"SSL handshake failure\" ssl_bc_err:1048:.*:tlsv1 alert unknown ca" + + barrier b2 sync + + recv + expect ~ ".*bc_err:34:\"SSL handshake failure\" ssl_bc_err:1040:.* alert handshake failure" + + barrier b2 sync + + recv + expect ~ ".*bc_err:34:\"SSL handshake failure\" ssl_bc_err:1040:.* alert handshake failure" +} -start + +syslog Slg_bcknd_fe -level info { + # Client c13 - No error + # Depending on the version of OpenSSL, the TLS version and ciphersuite will change + recv + expect ~ ".* Server/(TLSv1.3/TLS_AES_256_GCM_SHA384|TLSv1.2/ECDHE-RSA-AES256-GCM-SHA384)" + + # Client c14 - Server certificate rejected + # Depending on the version of OpenSSL, the TLS version and ciphersuite will change + recv + expect ~ ".* foo.com/(TLSv1.3/TLS_AES_256_GCM_SHA384|TLSv1.2/\\(NONE\\))" + + # Client c15 - Server certificate mismatch (verifyhost option on backend) + # Depending on the version of OpenSSL, the TLS version and ciphersuite will change + recv + expect ~ ".* foo.com/(TLSv1.3/TLS_AES_256_GCM_SHA384|TLSv1.2/\\(NONE\\))" + + # Client c16 - Client certificate rejected + recv + expect ~ ".* foo.com/TLSv1.2/\\(NONE\\)" + + # Client c17 - Wrong ciphers TLSv1.2 + recv + expect ~ ".* foo.com/TLSv1.2/\\(NONE\\)" + + # Client c18 + # With OpenSSL1.0.2 -Wrong ciphers TLSv1.2 (same as c17) + # With newer versions - Wrong ciphers TLSv1.3 - the client does not get to send its certificate because the error happens before + recv + expect ~ ".* (foo.com/TLSv1.2|-/TLSv1.3)/\\(NONE\\)" +} -start + + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + tune.ssl.capture-buffer-size 1 + stats socket "${tmpdir}/h1/stats" level admin + .if openssl_version_atleast(3.0.0) + set-var proc.ssl_error_mask str(7FFFFF),hex2i + .else + set-var proc.ssl_error_mask str(FFF),hex2i + .endif + + defaults + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + retries 0 + + listen clear_lst + bind "fd@${clearlst}" + default-server ssl crt ${testdir}/set_cafile_client.pem ca-file ${testdir}/set_cafile_interCA2.crt verify none no-ssl-reuse force-tlsv12 sni str(foo.com) + + balance roundrobin + server cust_fmt "${tmpdir}/cust_logfmt_ssl.sock" + server https_fmt "${tmpdir}/https_logfmt_ssl.sock" + server logconnerror "${tmpdir}/logconnerror_ssl.sock" + + + listen clear_wrong_ciphers_lst + bind "fd@${wrongcipherslst}" + default-server ssl crt ${testdir}/set_cafile_client.pem ca-file ${testdir}/set_cafile_interCA2.crt verify none no-ssl-reuse force-tlsv12 ciphers "aECDSA" sni str(foo.com) + + balance roundrobin + server cust_fmt "${tmpdir}/cust_logfmt_ssl.sock" + server https_fmt "${tmpdir}/https_logfmt_ssl.sock" + server logconnerror "${tmpdir}/logconnerror_ssl.sock" + + + # This listener will be used to test backend fetches (bc_err and ssl_bc_err) + listen clear_backend_errors_lst + bind "fd@${backenderrorslst}" + log ${Slg_bcknd_addr}:${Slg_bcknd_port} local0 + log-format "bc_err:%[bc_err]:%{+Q}[bc_err_str]\ ssl_bc_err:%[ssl_bc_err,and(proc.ssl_error_mask)]:%{+Q}[ssl_bc_err_str]" + error-log-format "ERROR bc_err:%[bc_err]:%{+Q}[bc_err_str]\ ssl_bc_err:%[ssl_bc_err,and(proc.ssl_error_mask)]:%[ssl_bc_err_str]" + + balance roundrobin + server no_err "${tmpdir}/no_err_ssl.sock" ssl crt ${testdir}/set_cafile_client.pem ca-file ${testdir}/set_cafile_interCA2.crt verify required sni str(Server) + server srv_cert_rejected "${tmpdir}/srv_rejected_ssl.sock" ssl crt ${testdir}/set_cafile_client.pem ca-file ${testdir}/set_cafile_interCA1.crt verify required sni str(foo.com) + server mismatch_frontend "${tmpdir}/mismatch_fe_ssl.sock" ssl crt ${testdir}/set_cafile_client.pem ca-file ${testdir}/set_cafile_interCA2.crt verify required sni str(foo.com) verifyhost str(toto) # We force TLSv1.2 for this specific case because server-side + # verification errors cannot be caught by the backend fetches when + # using TLSv1.3 + server clt_cert_rejected "${tmpdir}/rejected_ssl.sock" ssl crt ${testdir}/set_cafile_client.pem ca-file ${testdir}/set_cafile_interCA2.crt verify none force-tlsv12 sni str(foo.com) + server wrong_ciphers "${tmpdir}/wrong_ciphers_ssl.sock" ssl verify none crt ${testdir}/client1.pem ca-file ${testdir}/ca-auth.crt force-tlsv12 ciphers "aECDSA" sni str(foo.com) + + # No TLSv1.3 support with OpenSSL 1.0.2 so we duplicate the previous + # wrong cipher test in this case so that the error log remains the same +.if openssl_version_before(1.1.1) + server wrong_ciphers2 "${tmpdir}/wrong_ciphers_ssl.sock" ssl verify none crt ${testdir}/client1.pem ca-file ${testdir}/ca-auth.crt force-tlsv12 ciphers "aECDSA" sni str(foo.com) +.else + server wrong_ciphers_tls13 "${tmpdir}/wrong_ciphers_tls13_ssl.sock" ssl verify none crt ${testdir}/client1.pem ca-file ${testdir}/ca-auth.crt ciphersuites "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256" force-tlsv13 sni str(foo.com) +.endif + + + + + listen cust_logfmt_ssl_lst + log ${Slg_cust_fmt_addr}:${Slg_cust_fmt_port} local0 + mode http + log-format "conn_status:\"%[fc_err]:%[fc_err_str]\" hsk_err:\"%[ssl_fc_err]:%[ssl_fc_err_str]\" CN=%{+Q}[ssl_c_s_dn],serial=%[ssl_c_serial,hex],hash=%[ssl_c_sha1,hex]" + error-log-format "ERROR conn_status:\"%[fc_err]:%[fc_err_str]\" hsk_err:\"%[ssl_fc_err,and(proc.ssl_error_mask)]:%[ssl_fc_err_str]\" CN=%{+Q}[ssl_c_s_dn],serial=%[ssl_c_serial,hex],hash=%[ssl_c_sha1,hex]" + bind "${tmpdir}/cust_logfmt_ssl.sock" ssl crt ${testdir}/set_cafile_server.pem ca-verify-file ${testdir}/set_cafile_rootCA.crt ca-file ${testdir}/set_cafile_interCA1.crt verify required ciphers "kRSA" + server s1 ${s1_addr}:${s1_port} + + listen https_logfmt_ssl_lst + log ${Slg_https_fmt_addr}:${Slg_https_fmt_port} local0 info + log ${Slg_https_fmt_err_addr}:${Slg_https_fmt_err_port} local0 err info + option log-separate-errors + mode http + option httpslog + error-log-format "ERROR %ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r %[fc_err]/%[ssl_fc_err,and(proc.ssl_error_mask),hex]/%[ssl_c_err]/%[ssl_c_ca_err]/%[ssl_fc_is_resumed] %[ssl_fc_sni]/%sslv/%sslc" + bind "${tmpdir}/https_logfmt_ssl.sock" ssl crt ${testdir}/set_cafile_server.pem ca-verify-file ${testdir}/set_cafile_rootCA.crt ca-file ${testdir}/set_cafile_interCA1.crt verify required ciphers "kRSA" + server s1 ${s1_addr}:${s1_port} + + listen logconnerror_ssl_lst + log ${Slg_logconnerror_addr}:${Slg_logconnerror_port} local0 info + mode http + option httplog + bind "${tmpdir}/logconnerror_ssl.sock" ssl crt ${testdir}/set_cafile_server.pem ca-verify-file ${testdir}/set_cafile_rootCA.crt ca-file ${testdir}/set_cafile_interCA1.crt verify required ciphers "kRSA" + server s1 ${s1_addr}:${s1_port} + + + + defaults bknd_err_dflt + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + retries 0 + log ${Slg_bcknd_fe_addr}:${Slg_bcknd_fe_port} local0 + log-format "%ci:%cp %[ssl_fc_sni]/%sslv/%sslc" + error-log-format "ERROR %ci:%cp %[ssl_fc_sni]/%sslv/%sslc" + + # The following listeners allow to test backend error fetches + listen no_backend_err_ssl_lst from bknd_err_dflt + bind "${tmpdir}/no_err_ssl.sock" ssl crt ${testdir}/set_cafile_server.pem ca-file ${testdir}/set_cafile_interCA2.crt verify none + server s1 ${s1_addr}:${s1_port} + + listen srv_rejected_ssl_lst from bknd_err_dflt + bind "${tmpdir}/srv_rejected_ssl.sock" ssl crt ${testdir}/set_cafile_server.pem ca-file ${testdir}/set_cafile_interCA2.crt verify none + server s1 ${s1_addr}:${s1_port} + + listen mismatch_fe_ssl_lst from bknd_err_dflt + bind "${tmpdir}/mismatch_fe_ssl.sock" ssl crt ${testdir}/set_cafile_server.pem ca-file ${testdir}/set_cafile_interCA2.crt verify none + server s1 ${s1_addr}:${s1_port} + + listen rejected_clt_ssl_lst from bknd_err_dflt + bind "${tmpdir}/rejected_ssl.sock" ssl crt ${testdir}/set_cafile_server.pem ca-file ${testdir}/set_cafile_interCA2.crt verify required + server s1 ${s1_addr}:${s1_port} + + listen wrong_ciphers_ssl_lst from bknd_err_dflt + bind "${tmpdir}/wrong_ciphers_ssl.sock" ssl crt ${testdir}/common.pem ca-file ${testdir}/ca-auth.crt verify none force-tlsv12 ciphers "kRSA" + server s1 ${s1_addr}:${s1_port} + +.if openssl_version_atleast(1.1.1) + listen wrong_ciphers_tls13_ssl_lst from bknd_err_dflt + bind "${tmpdir}/wrong_ciphers_tls13_ssl.sock" ssl crt ${testdir}/common.pem ca-file ${testdir}/ca-auth.crt verify none force-tlsv13 ciphersuites "TLS_AES_128_GCM_SHA256" + server s1 ${s1_addr}:${s1_port} +.endif + +} -start + + +# The three following requests should all succeed +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 +} -run + +client c2 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 +} -run + +client c3 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 +} -run + + +barrier b1 sync + + +# Change the root CA in the frontends +shell { + printf "set ssl ca-file ${testdir}/set_cafile_rootCA.crt <<\n$(cat ${testdir}/set_cafile_interCA1.crt)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl ca-file ${testdir}/set_cafile_rootCA.crt" | socat "${tmpdir}/h1/stats" - +} + +client c4 -connect ${h1_clearlst_sock} { + txreq + expect_close +} -run + +client c5 -connect ${h1_clearlst_sock} { + txreq + expect_close +} -run + +client c6 -connect ${h1_clearlst_sock} { + txreq + expect_close +} -run + +barrier b1 sync + + + +# Restore the root CA +shell { + printf "set ssl ca-file ${testdir}/set_cafile_rootCA.crt <<\n$(cat ${testdir}/set_cafile_rootCA.crt)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl ca-file ${testdir}/set_cafile_rootCA.crt" | socat "${tmpdir}/h1/stats" - +} + +# Change the intermediate CA in the frontends +shell { + printf "set ssl ca-file ${testdir}/set_cafile_interCA1.crt <<\n$(cat ${testdir}/set_cafile_interCA2.crt)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl ca-file ${testdir}/set_cafile_interCA1.crt" | socat "${tmpdir}/h1/stats" - +} + +client c7 -connect ${h1_clearlst_sock} { + txreq + expect_close +} -run + +client c8 -connect ${h1_clearlst_sock} { + txreq + expect_close +} -run + +client c9 -connect ${h1_clearlst_sock} { + txreq + expect_close +} -run + +barrier b1 sync + + +# Restore the intermediate CA in the frontends +shell { + printf "set ssl ca-file ${testdir}/set_cafile_interCA1.crt <<\n$(cat ${testdir}/set_cafile_interCA1.crt)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl ca-file ${testdir}/set_cafile_interCA1.crt" | socat "${tmpdir}/h1/stats" - +} + +# "No shared cipher" errors +client c10 -connect ${h1_wrongcipherslst_sock} { + txreq + expect_close +} -run +client c11 -connect ${h1_wrongcipherslst_sock} { + txreq + expect_close +} -run +client c12 -connect ${h1_wrongcipherslst_sock} { + txreq + expect_close +} -run + + +shell { + printf "set ssl ca-file ${testdir}/set_cafile_interCA2.crt <<\n$(cat ${testdir}/set_cafile_interCA2.crt)\n$(cat ${testdir}/set_cafile_rootCA.crt)\n\n" | socat "${tmpdir}/h1/stats" - + echo "commit ssl ca-file ${testdir}/set_cafile_interCA2.crt" | socat "${tmpdir}/h1/stats" - +} + +client c13 -connect ${h1_backenderrorslst_sock} { + txreq + rxresp + expect resp.status == 200 +} -run +barrier b2 sync +client c14 -connect ${h1_backenderrorslst_sock} { + txreq + expect_close +} -run +barrier b2 sync +client c15 -connect ${h1_backenderrorslst_sock} { + txreq + expect_close +} -run +barrier b2 sync +client c16 -connect ${h1_backenderrorslst_sock} { + txreq + expect_close +} -run +barrier b2 sync +client c17 -connect ${h1_backenderrorslst_sock} { + txreq + expect_close +} -run +barrier b2 sync +client c18 -connect ${h1_backenderrorslst_sock} { + txreq + expect_close +} -run + +syslog Slg_cust_fmt -wait +syslog Slg_https_fmt -wait +syslog Slg_https_fmt_err -wait +syslog Slg_logconnerror -wait +syslog Slg_bcknd -wait +syslog Slg_bcknd_fe -wait diff --git a/reg-tests/ssl/ssl_frontend_samples.vtc b/reg-tests/ssl/ssl_frontend_samples.vtc new file mode 100644 index 0000000..e94a37a --- /dev/null +++ b/reg-tests/ssl/ssl_frontend_samples.vtc @@ -0,0 +1,69 @@ +#REGTEST_TYPE=devel + +varnishtest "Test the ssl_f_* sample fetches" +#REQUIRE_OPTIONS=OPENSSL +feature ignore_unknown_macro + +server s1 -repeat 3 { + rxreq + txresp +} -start + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + tune.ssl.capture-buffer-size 1 + crt-base ${testdir} + + defaults + mode http + option httplog + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + + listen clear-lst + bind "fd@${clearlst}" + balance roundrobin + server s1 "${tmpdir}/ssl.sock" ssl verify none + + listen ssl-lst + mode http + + http-response add-header x-ssl-der %[ssl_f_der,hex] + http-response add-header x-ssl-sha1 %[ssl_f_sha1,hex] + http-response add-header x-ssl-notafter %[ssl_f_notafter] + http-response add-header x-ssl-notbefore %[ssl_f_notbefore] + http-response add-header x-ssl-sig_alg %[ssl_f_sig_alg] + http-response add-header x-ssl-i_dn %[ssl_f_i_dn] + http-response add-header x-ssl-s_dn %[ssl_f_s_dn] + http-response add-header x-ssl-s_serial %[ssl_f_serial,hex] + http-response add-header x-ssl-key_alg %[ssl_f_key_alg] + http-response add-header x-ssl-version %[ssl_f_version] + + bind "${tmpdir}/ssl.sock" ssl crt ${testdir}/common.pem + + server s1 ${s1_addr}:${s1_port} +} -start + + +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-der ~ 3082067930820461A0030201020201.*207B5E3D4498BB847BC4DE093F9AD1AD3661C93EE43EB + expect resp.http.x-ssl-sha1 == "2195C9F0FD58470313013FC27C1B9CF9864BD1C6" + expect resp.http.x-ssl-notafter == "180116230238Z" + expect resp.http.x-ssl-notbefore == "160117230238Z" + expect resp.http.x-ssl-sig_alg == "RSA-SHA256" + expect resp.http.x-ssl-i_dn == "/C=FR/ST=Ile-de-France/L=Paris/O=ozon.io/CN=Ozon Test CA/emailAddress=support@ozon.io" + expect resp.http.x-ssl-s_dn == "/C=FR/ST=Ile-de-France/L=Neuilly-sur-Seine/O=TOAD Consulting/OU=eParapher Team/CN=www.test1.com/emailAddress=arnault.michel@toad-consulting.fr" + expect resp.http.x-ssl-s_serial == "02" + expect resp.http.x-ssl-key_alg == "rsaEncryption" + expect resp.http.x-ssl-version == "3" +} -run + + diff --git a/reg-tests/ssl/ssl_generate_certificate.vtc b/reg-tests/ssl/ssl_generate_certificate.vtc new file mode 100644 index 0000000..96549df --- /dev/null +++ b/reg-tests/ssl/ssl_generate_certificate.vtc @@ -0,0 +1,168 @@ +#REGTEST_TYPE=devel + +# This reg-test checks that the 'generate-certificates' SSL option works +# properly. This option allows to generate server-side certificates on the fly +# for clients that use an SNI for which no certificate was specified in the +# configuration file. +# This test also aims at checking that the 'generate-certificates' and the +# 'ecdhe' bind options work correctly together. +# Any bind line having a 'generate-certificates' needs to have a ca-sign-file +# option as well that specifies the path to a CA pem file (containing a +# certificate as well as its private key). For this reason, a new +# ssl_gen_ca.pem CA certificate was created, along with the ssl_gen_server.pem +# server certificate signed by the CA. This server certificate will be used as +# a default certificate and will serve as a base for any newly created +# certificate. + +varnishtest "Test the 'generate-certificates' SSL option" +feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL)'" +feature cmd "command -v openssl && command -v grep" +feature ignore_unknown_macro + +server s1 -repeat 6 { + rxreq + txresp +} -start + + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + tune.ssl.capture-buffer-size 2048 + + defaults + mode http + option httpslog + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + option httpslog + + listen clear-lst + bind "fd@${clearlst}" + http-request set-var(sess.sni) hdr(x-sni) + + use_backend P-384_backend if { path /P-384 } + default_backend default_backend + + backend default_backend + server s1 "${tmpdir}/ssl.sock" ssl verify none ssl-max-ver TLSv1.2 sni var(sess.sni) + + backend P-384_backend + server s1 "${tmpdir}/ssl_P-384.sock" ssl verify none ssl-max-ver TLSv1.2 sni var(sess.sni) + + listen ssl-lst + bind "${tmpdir}/ssl.sock" ssl generate-certificates crt ${testdir}/generate_certificates/gen_cert_server.pem ca-sign-file ${testdir}/generate_certificates/gen_cert_ca.pem ca-file ${testdir}/generate_certificates/gen_cert_ca.pem verify optional + http-response add-header x-ssl-s_dn %[ssl_f_s_dn(CN)] + http-response add-header x-ssl-i_dn %[ssl_f_i_dn(CN)] + http-response add-header x-ssl-sig_alg %[ssl_f_sig_alg] + http-response add-header x-ssl-key_alg %[ssl_f_key_alg] + http-response add-header x-ssl-sha1 %[ssl_f_sha1,hex] + + server s1 ${s1_addr}:${s1_port} + + listen ssl-lst-P-384 + bind "${tmpdir}/ssl_P-384.sock" ssl generate-certificates crt ${testdir}/generate_certificates/gen_cert_server.pem ca-sign-file ${testdir}/generate_certificates/gen_cert_ca.pem ca-file ${testdir}/generate_certificates/gen_cert_ca.pem verify optional ecdhe secp384r1 + http-response add-header x-ssl-s_dn %[ssl_f_s_dn(CN)] + http-response add-header x-ssl-i_dn %[ssl_f_i_dn(CN)] + http-response add-header x-ssl-sig_alg %[ssl_f_sig_alg] + http-response add-header x-ssl-key_alg %[ssl_f_key_alg] + http-response add-header x-ssl-sha1 %[ssl_f_sha1,hex] + + server s1 ${s1_addr}:${s1_port} + +} -start + +# Use default certificate +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-sig_alg == "ecdsa-with-SHA256" + expect resp.http.x-ssl-i_dn == "ECDSA CA" + expect resp.http.x-ssl-s_dn == "server.ecdsa.com" + expect resp.http.x-ssl-key_alg == "id-ecPublicKey" + expect resp.http.x-ssl-sha1 == "66AC64728CEA0C1F614A89C278FA2F94EDE9AB11" +} -run + + +# Use default certificate's sni +client c2 -connect ${h1_clearlst_sock} { + txreq -hdr "x-sni: server.ecdsa.com" + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-sig_alg == "ecdsa-with-SHA256" + expect resp.http.x-ssl-i_dn == "ECDSA CA" + expect resp.http.x-ssl-s_dn == "server.ecdsa.com" + expect resp.http.x-ssl-key_alg == "id-ecPublicKey" + expect resp.http.x-ssl-sha1 == "66AC64728CEA0C1F614A89C278FA2F94EDE9AB11" +} -run + + + +# Use another SNI - the server certificate should be generated and different +# than the default one +client c3 -connect ${h1_clearlst_sock} { + txreq -hdr "x-sni: unknown-sni.com" + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-sig_alg == "ecdsa-with-SHA256" + expect resp.http.x-ssl-i_dn == "ECDSA CA" + expect resp.http.x-ssl-s_dn == "ECDSA CA" + expect resp.http.x-ssl-key_alg == "id-ecPublicKey" + expect resp.http.x-ssl-sha1 != "66AC64728CEA0C1F614A89C278FA2F94EDE9AB11" +} -run + + +# Use default certificate +client c4 -connect ${h1_clearlst_sock} { + txreq -url "/P-384" + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-sig_alg == "ecdsa-with-SHA256" + expect resp.http.x-ssl-i_dn == "ECDSA CA" + expect resp.http.x-ssl-s_dn == "server.ecdsa.com" + expect resp.http.x-ssl-key_alg == "id-ecPublicKey" + expect resp.http.x-ssl-sha1 == "66AC64728CEA0C1F614A89C278FA2F94EDE9AB11" +} -run + + +# Use default certificate's sni +client c5 -connect ${h1_clearlst_sock} { + txreq -url "/P-384" -hdr "x-sni: server.ecdsa.com" + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-sig_alg == "ecdsa-with-SHA256" + expect resp.http.x-ssl-i_dn == "ECDSA CA" + expect resp.http.x-ssl-s_dn == "server.ecdsa.com" + expect resp.http.x-ssl-key_alg == "id-ecPublicKey" + expect resp.http.x-ssl-sha1 == "66AC64728CEA0C1F614A89C278FA2F94EDE9AB11" +} -run + + +# Use another SNI - the server certificate should be generated and different +# than the default one +client c6 -connect ${h1_clearlst_sock} { + txreq -url "/P-384" -hdr "x-sni: unknown-sni.com" + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-sig_alg == "ecdsa-with-SHA256" + expect resp.http.x-ssl-i_dn == "ECDSA CA" + expect resp.http.x-ssl-s_dn == "ECDSA CA" + expect resp.http.x-ssl-key_alg == "id-ecPublicKey" + expect resp.http.x-ssl-sha1 != "66AC64728CEA0C1F614A89C278FA2F94EDE9AB11" +} -run + +# Check that the curves that the server accepts to use correspond to what we +# expect it to be (according to ecdhe option). +# The curve with the highest priority is X25519 for OpenSSL 1.1.1 and later, +# and P-256 for OpenSSL 1.0.2. +shell { + echo "Q" | openssl s_client -unix "${tmpdir}/ssl.sock" -servername server.ecdsa.com -tls1_2 2>/dev/null | grep -E "Server Temp Key: (ECDH, P-256, 256 bits|ECDH, prime256v1, 256 bits|X25519, 253 bits)" +} + +shell { + echo "Q" | openssl s_client -unix "${tmpdir}/ssl_P-384.sock" -servername server.ecdsa.com 2>/dev/null| grep -E "Temp Key: ECDH,.+, 384 bits" +} diff --git a/reg-tests/ssl/ssl_reuse.vtc b/reg-tests/ssl/ssl_reuse.vtc new file mode 100644 index 0000000..4ebd34e --- /dev/null +++ b/reg-tests/ssl/ssl_reuse.vtc @@ -0,0 +1,141 @@ +#REGTEST_TYPE=devel + +# This reg-test tests 4 scenarios with and without resumption tickets, with TLSv1.3 and TLSv1.2 +# Each client will try to established a connection, then try to reconnect 20 times resuming. + + +varnishtest "Test if the SSL session/ticket reuse work correctly" +feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL) && ssllib_name_startswith(OpenSSL) && openssl_version_atleast(1.1.1)'" +feature ignore_unknown_macro + +server s1 -repeat 84 { + rxreq + txresp +} -start + +haproxy h1 -conf { + global + # forced to 1 here, because there is a cached session per thread + nbthread 1 + + + defaults + mode http + option httplog + option logasap + log stderr local0 debug err + option httpclose + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen clst1 + bind "fd@${clst1}" + server s1 "${h1_fe1_addr}:${h1_fe1_port}" ssl verify none sni str(www.test1.com) + http-response add-header x-ssl-bc-resumed %[ssl_bc_is_resumed] + + listen clst2 + bind "fd@${clst2}" + server s1 "${h1_fe2_addr}:${h1_fe2_port}" ssl verify none sni str(www.test1.com) + http-response add-header x-ssl-bc-resumed %[ssl_bc_is_resumed] + + listen clst3 + bind "fd@${clst3}" + server s1 "${h1_fe3_addr}:${h1_fe3_port}" ssl verify none sni str(www.test1.com) + http-response add-header x-ssl-bc-resumed %[ssl_bc_is_resumed] + + listen clst4 + bind "fd@${clst4}" + server s1 "${h1_fe4_addr}:${h1_fe4_port}" ssl verify none sni str(www.test1.com) + http-response add-header x-ssl-bc-resumed %[ssl_bc_is_resumed] + + listen ssl + bind "fd@${fe1}" ssl crt ${testdir}/common.pem ssl-max-ver TLSv1.2 + bind "fd@${fe2}" ssl crt ${testdir}/common.pem ssl-max-ver TLSv1.2 no-tls-tickets + bind "fd@${fe3}" ssl crt ${testdir}/common.pem ssl-min-ver TLSv1.3 + bind "fd@${fe4}" ssl crt ${testdir}/common.pem ssl-min-ver TLSv1.3 no-tls-tickets + + http-response add-header x-ssl-resumed %[ssl_fc_is_resumed] + server s1 ${s1_addr}:${s1_port} +} -start + + +# first bind +# the first connection is not resumed +client c1 -connect ${h1_clst1_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-resumed == 0 +} -run +# the next 20 connections are resumed +client c1 -connect ${h1_clst1_sock} -repeat 20 { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-resumed == 1 +} -run + +# second bind +client c2 -connect ${h1_clst2_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-resumed == 0 +} -run + +client c2 -connect ${h1_clst2_sock} -repeat 20 { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-resumed == 1 +} -run + +# third bind +client c3 -connect ${h1_clst3_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-resumed == 0 +} -run + +client c3 -connect ${h1_clst3_sock} -repeat 20 { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-resumed == 1 +} -run + +# fourth bind +client c4 -connect ${h1_clst4_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-resumed == 0 +} -run + +client c4 -connect ${h1_clst4_sock} -repeat 20 { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-resumed == 1 +} -run + + +# Could be useful to debug the result, the ssl_fc_is_resumed field in the log must be 1 after the 2nd command +#shell { +# +# HOST=${h1_fe4_addr} +# if [ "${h1_fe4_addr}" = "::1" ] ; then +# HOST="\[::1\]" +# fi +# +# rm sess.pem; (echo -e -n "GET / HTTP/1.1\r\n\r\n"; sleep 1) | openssl s_client -connect $HOST:${h1_fe4_port} -tls1_3 -sess_out sess.pem -keylogfile keys1.txt -servername www.test1.com > /tmp/ssl_debug1; echo | openssl s_client -connect ${HOST}:${h1_fe4_port} -tls1_3 -sess_in sess.pem -keylogfile keys2.txt -servername www.test1.com >> /tmp/ssl_debug1 +# echo "GET / HTTP/1.1" | openssl s_client -connect $HOST:${h1_fe4_port} -tls1_3 -servername www.test1.com +#} + +haproxy h1 -cli { + send "show info" + expect ~ ".*SslFrontendSessionReuse_pct: 95.*" +} + diff --git a/reg-tests/ssl/ssl_server_samples.vtc b/reg-tests/ssl/ssl_server_samples.vtc new file mode 100644 index 0000000..ebfaad0 --- /dev/null +++ b/reg-tests/ssl/ssl_server_samples.vtc @@ -0,0 +1,73 @@ +#REGTEST_TYPE=devel + +varnishtest "Test the ssl_s_* sample fetches" +#REQUIRE_VERSION=2.2 +#REQUIRE_OPTIONS=OPENSSL +feature ignore_unknown_macro + +server s1 -repeat 3 { + rxreq + txresp +} -start + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + tune.ssl.capture-buffer-size 1 + crt-base ${testdir} + stats socket "${tmpdir}/h1/stats" level admin + + defaults + mode http + option httplog + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + + listen clear-lst + bind "fd@${clearlst}" + balance roundrobin + http-response add-header x-ssl-sha1 %[ssl_s_sha1,hex] + http-response add-header x-ssl-notafter %[ssl_s_notafter] + http-response add-header x-ssl-notbefore %[ssl_s_notbefore] + http-response add-header x-ssl-sig_alg %[ssl_s_sig_alg] + http-response add-header x-ssl-i_dn %[ssl_s_i_dn] + http-response add-header x-ssl-s_dn %[ssl_s_s_dn] + http-response add-header x-ssl-s_serial %[ssl_s_serial,hex] + http-response add-header x-ssl-key_alg %[ssl_s_key_alg] + http-response add-header x-ssl-der %[ssl_s_der,hex] + http-response add-header x-ssl-chain-der %[ssl_s_chain_der,hex] + http-response add-header x-ssl-version %[ssl_s_version] + + server s1 "${tmpdir}/ssl.sock" ssl verify none sni str(www.test1.com) + + listen ssl-lst + mode http + + bind "${tmpdir}/ssl.sock" ssl strict-sni crt-list ${testdir}/localhost.crt-list + + server s1 ${s1_addr}:${s1_port} +} -start + + +client c1 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 + expect resp.http.x-ssl-sha1 == "2195C9F0FD58470313013FC27C1B9CF9864BD1C6" + expect resp.http.x-ssl-notafter == "180116230238Z" + expect resp.http.x-ssl-notbefore == "160117230238Z" + expect resp.http.x-ssl-sig_alg == "RSA-SHA256" + expect resp.http.x-ssl-i_dn == "/C=FR/ST=Ile-de-France/L=Paris/O=ozon.io/CN=Ozon Test CA/emailAddress=support@ozon.io" + expect resp.http.x-ssl-s_dn == "/C=FR/ST=Ile-de-France/L=Neuilly-sur-Seine/O=TOAD Consulting/OU=eParapher Team/CN=www.test1.com/emailAddress=arnault.michel@toad-consulting.fr" + expect resp.http.x-ssl-s_serial == "02" + expect resp.http.x-ssl-key_alg == "rsaEncryption" + expect resp.http.x-ssl-version == "3" + expect resp.http.x-ssl-der ~ 3082067930820461A0030201020201.*5E3D4498BB847BC4DE093F9AD1AD3 + expect resp.http.x-ssl-chain-der ~ 3082067930820461A0030201020201.*527A6D6780A610484CE356C4C4E1C +} -run + + diff --git a/reg-tests/ssl/ssl_simple_crt-list.vtc b/reg-tests/ssl/ssl_simple_crt-list.vtc new file mode 100644 index 0000000..7f15056 --- /dev/null +++ b/reg-tests/ssl/ssl_simple_crt-list.vtc @@ -0,0 +1,50 @@ +#REGTEST_TYPE=bug +varnishtest "Test for the bug #940" +# Test that the SNI are correctly inserted with the same file multiple times. + +#REQUIRE_VERSION=2.2 +#REQUIRE_OPTIONS=OPENSSL +feature ignore_unknown_macro + +server s1 -repeat 4 { + rxreq + txresp +} -start + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + crt-base ${testdir} + stats socket "${tmpdir}/h1/stats" level admin + + defaults + mode http + option httplog + log stderr local0 debug err + option logasap + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + + listen clear-lst + bind "fd@${clearlst}" + balance roundrobin + server s1 "${tmpdir}/ssl.sock" ssl verify none sni str(record1.bug940.domain.tld) + server s2 "${tmpdir}/ssl.sock" ssl verify none sni str(record2.bug940.domain.tld) + server s3 "${tmpdir}/ssl.sock" ssl verify none sni str(record3.bug940.domain.tld) + server s4 "${tmpdir}/ssl.sock" ssl verify none sni str(record4.bug940.domain.tld) + + listen ssl-lst + mode http + bind "${tmpdir}/ssl.sock" ssl strict-sni crt-list ${testdir}/simple.crt-list + + server s1 ${s1_addr}:${s1_port} +} -start + + +client c1 -repeat 4 -connect ${h1_clearlst_sock} { + txreq + rxresp + expect resp.status == 200 +} -run diff --git a/reg-tests/ssl/wrong_ctx_storage.vtc b/reg-tests/ssl/wrong_ctx_storage.vtc new file mode 100644 index 0000000..c6cb19a --- /dev/null +++ b/reg-tests/ssl/wrong_ctx_storage.vtc @@ -0,0 +1,45 @@ +# commit 28962c9 +# BUG/MAJOR: ssl: OpenSSL context is stored in non-reserved memory slot +# +# We never saw unexplicated crash with SSL, so I suppose that we are +# luck, or the slot 0 is always reserved. Anyway the usage of the macro +# SSL_get_app_data() and SSL_set_app_data() seem wrong. This patch change +# the deprecated functions SSL_get_app_data() and SSL_set_app_data() +# by the new functions SSL_get_ex_data() and SSL_set_ex_data(), and +# it reserves the slot in the SSL memory space. +# +# For information, this is the two declaration which seems wrong or +# incomplete in the OpenSSL ssl.h file. We can see the usage of the +# slot 0 whoch is hardcoded, but never reserved. +# +# #define SSL_set_app_data(s,arg) (SSL_set_ex_data(s,0,(char *)arg)) +# #define SSL_get_app_data(s) (SSL_get_ex_data(s,0)) + +#REGTEST_TYPE=bug + +varnishtest "OpenSSL bug: Random crashes" +#REQUIRE_OPTIONS=OPENSSL +feature ignore_unknown_macro + + +haproxy h1 -conf { + global + tune.ssl.default-dh-param 2048 + tune.ssl.capture-buffer-size 1 + + listen frt + mode http + bind "fd@${frt}" ssl crt ${testdir}/common.pem + http-request redirect location / +} -start + +shell { + HOST=${h1_frt_addr} + if [ "${h1_frt_addr}" = "::1" ] ; then + HOST="\[::1\]" + fi + for i in 1 2 3 4 5; do + curl -i -k https://$HOST:${h1_frt_port} & pids="$pids $!" + done + wait $pids +} diff --git a/reg-tests/startup/automatic_maxconn.vtc b/reg-tests/startup/automatic_maxconn.vtc new file mode 100644 index 0000000..0173916 --- /dev/null +++ b/reg-tests/startup/automatic_maxconn.vtc @@ -0,0 +1,104 @@ +varnishtest "Automatic maxconn computation" +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature cmd "$HAPROXY_PROGRAM -cc '!feature(OBSOLETE_LINKER)'" +feature cmd "$HAPROXY_PROGRAM -cc 'feature(OPENSSL)'" +feature ignore_unknown_macro +#REGTEST_TYPE=broken + + +# Check the maxconn computation with the -m parameter +# Broken because it can't work with ASAN. + + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp +} -start + + +haproxy h1 -arg "-m 1024" -conf { +} -start + +haproxy h1 -cli { + send "show info" + expect ~ ".*Maxconn: (29000|28000)\n.*" +} + +haproxy h2 -arg "-m 384" -conf { +} -start + +haproxy h2 -cli { + send "show info" + expect ~ ".*Maxconn: (11000|10000)\n.*" +} + +haproxy h3 -arg "-m 256" -conf { +} -start + +haproxy h3 -cli { + send "show info" + expect ~ ".*Maxconn: (7300|7000)\n.*" +} + +# 1 SSL front but no back + +haproxy h4 -arg "-m 256" -conf { + defaults + mode http + timeout connect 1s + timeout client 1s + timeout server 1s + + frontend fe1 + bind "fd@${fe1}" ssl crt ${testdir}/common.pem + +} -start + +haproxy h4 -cli { + send "show info" + expect ~ ".*Maxconn: 1900\n.*" +} + +# 1 SSL back but not front + +haproxy h5 -arg "-m 256" -conf { + defaults + mode http + timeout connect 1s + timeout client 1s + timeout server 1s + + listen li2 + bind "fd@${li2}" + server ssl "${s1_addr}:${s1_port}" ssl verify none + +} -start + +haproxy h5 -cli { + send "show info" + expect ~ ".*Maxconn: 1900\n.*" +} + + +# 1 SSL front and 1 back + +haproxy h6 -arg "-m 256" -conf { + defaults + mode http + timeout connect 1s + timeout client 1s + timeout server 1s + + listen li3 + bind "fd@${li3}" ssl crt ${testdir}/common.pem + server ssl "${s1_addr}:${s1_port}" ssl verify none + +} -start + +haproxy h6 -cli { + send "show info" + expect ~ ".*Maxconn: 1700\n.*" +} + diff --git a/reg-tests/startup/check_condition.vtc b/reg-tests/startup/check_condition.vtc new file mode 100644 index 0000000..3ab6ae4 --- /dev/null +++ b/reg-tests/startup/check_condition.vtc @@ -0,0 +1,32 @@ +varnishtest "Tests the -cc argument" + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" + +shell { + set -e + $HAPROXY_PROGRAM -cc "version_atleast(2.4)" + ! $HAPROXY_PROGRAM -cc "version_atleast(1024)" + + $HAPROXY_PROGRAM -cc "streq(foo,'foo')" + $HAPROXY_PROGRAM -cc "streq(\"foo bar\",'foo bar')" + ! $HAPROXY_PROGRAM -cc "streq(foo,bar)" + + if $HAPROXY_PROGRAM -cc "version_atleast(2.5-dev2)"; then + export TESTVAR=1 + $HAPROXY_PROGRAM -cc 'defined(TESTVAR) && streq("$TESTVAR","1")' + $HAPROXY_PROGRAM -cc 'feature(OPENSSL) || !feature(OPENSSL)' + $HAPROXY_PROGRAM -cc '1&&!0&&!((streq(a,b)||!streq(a,a)&&1)||strneq(a,a))' + $HAPROXY_PROGRAM -cc '1 &&! 0&& !((streq(a,b)||!streq(a,a)&&1)||strneq(a,a))' + $HAPROXY_PROGRAM -cc '1 && !0 && !((streq(a,b) || !streq(a,a) && 1) || strneq(a,a))' + ! $HAPROXY_PROGRAM -cc '1 && !0 && !((streq(a,b) || !streq(a,a) && 1) || strneq(a,b))' + ! $HAPROXY_PROGRAM -cc '1 && !0 && !((streq(a,a) || !streq(a,a) && 1) || strneq(a,a))' + # empty string is always false + ! $HAPROXY_PROGRAM -cc '' + # non-zero is true + $HAPROXY_PROGRAM -cc '-1000 && 200' + # check for various parsing errors (extra/missing chars) + ! $HAPROXY_PROGRAM -cc '200rrr' + ! $HAPROXY_PROGRAM -cc '!(0))' + ! $HAPROXY_PROGRAM -cc 'streq(a,"a)' + fi +} -run diff --git a/reg-tests/startup/common.pem b/reg-tests/startup/common.pem new file mode 100644 index 0000000..206e417 --- /dev/null +++ b/reg-tests/startup/common.pem @@ -0,0 +1,117 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAnb0BDF7FsqzslakNg7u/n/JQkq6nheuKwvyTqECfpc9y7uSB +e/vrEFqBaDSLQagJxuZdL5geFeVtRbdAoB97N1/LZa6vecjjgGSP0Aag/gS/ocnM +RIyvlVWWT9MrD46OG3qZY1ORU1ltrVL0NKttJP8xME7j3bTwIDElx/hNI0n7L+yS +kAe2xb/7CbZRfoOhjTVAcGv4aSLVc/Hi8k6VkIzdOEtH6TcghXmuGcuqvLNH9Buo +syngKTcQ8zg6J+e64aVvC+e7vi94uil9Qu+JHm0pkDzAZ2WluNsuXlrJToPirWyj +6/YdN6xgSI1hbZkBmUPAebgYuxBt6huvfyQd3wIDAQABAoIBABojc8UE/2W4WgwC +04Z82ig7Ezb7Ui9S9M+S4zUCYHItijIkE4DkIfO3y7Hk4x6iJdyb191HK9UdC5p9 +32upS9XFPgM/izx3GZvxDhO+xXbSep7ovbyuQ3pPkHTx3TTavpm3GyvmcTKKoy4R +jP4dWhzDXPdQW1ol3ZS4EDau4rlyClY6oi1mq9aBEX3MqVjB/nO7s2AbdgclAgP2 +OZMhTzWYR1k5tYySHCXh3ggGMCikyvHU0+SsGyrstYzP1VYi/n3f0VgqW/5ZjG8x +6SHpe04unErPF3HuSun2ZMCFdBxaTFZ8FENb8evrSXe3nQOc9W21RQdRRrNNUbjl +JYI4veECgYEA0ATYKMS1VCUYRZoQ49b5GTg7avUYqfW4bEo4fSfBue8NrnKR3Wu8 +PPBiCTuIYq1vSF+60B7Vu+hW0A8OuQ2UuMxLpYcQ7lKfNad/+yAfoWWafIqCqNU9 +at0QMdbW6A69d6jZt7OrXtleBsphCnN58jTz4ch4PIa2Oyq46NUXCvUCgYEAwh8t +G6BOHOs3yRNI2s9Y9EEfwoil2uIKrZhqiL3AwdIpu5uNIMuPnbaEpXvRX6jv/qtL +321i8vZLc31aM7zfxQ6B4ReQFJfYC80FJsWvcLwT9hB9mTJpLS4sIu5tzQc87O6w +RtjFMom+5ns5hfPB4Eccy0EtbQWVY4nCzUeO6QMCgYBSvqqRRPXwG7VU8lznlHqP +upuABzChYrnScY+Y0TixUlL54l79Wb6N6vzEOWceAWkzu8iewrU4QspNhr/PgoR3 +IeSxWlG0yy7Dc/ZnmTabx8O06I/iwrfkizzG5nOj6UEamRLJjPGNEB/jyZriQl7u +pnugg1K4mMliLbNSAnlhBQKBgQCmYepbv260Qrex1KGhSg9Ia3k5V74weYYFfJnz +UhChD+1NK+ourcsOtp3C6PlwMHBjq5aAjlU9QfUxq8NgjQaO8/xGXdfUjsFSfAtq +TA4vZkUFpuTAJgEYBHc4CXx7OzTxLzRPxQRgaMgC7KNFOMR34vu/CsJQq3R7uFwL +bsYC2QKBgQCtEmg1uDZVdByX9zyUMuRxz5Tq/vDcp+A5lJj2mha1+bUMaKX2+lxQ +vPxY55Vaw/ukWkJirRrpGv6IytBn0dLAFSlKZworZGBaxsm8OGTFJ5Oe9+kZTjI9 +hvjpClOA1otbmj2F2uZAbuIjxQGDNUkLoifN5yDYCC8JPujHuHmULw== +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIGeTCCBGGgAwIBAgIBAjANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJGUjEW +MBQGA1UECBMNSWxlLWRlLUZyYW5jZTEOMAwGA1UEBxMFUGFyaXMxEDAOBgNVBAoT +B296b24uaW8xFTATBgNVBAMTDE96b24gVGVzdCBDQTEeMBwGCSqGSIb3DQEJARYP +c3VwcG9ydEBvem9uLmlvMB4XDTE2MDExNzIzMDIzOFoXDTE4MDExNjIzMDIzOFow +gb4xCzAJBgNVBAYTAkZSMRYwFAYDVQQIEw1JbGUtZGUtRnJhbmNlMRowGAYDVQQH +ExFOZXVpbGx5LXN1ci1TZWluZTEYMBYGA1UEChMPVE9BRCBDb25zdWx0aW5nMRcw +FQYDVQQLEw5lUGFyYXBoZXIgVGVhbTEWMBQGA1UEAxMNd3d3LnRlc3QxLmNvbTEw +MC4GCSqGSIb3DQEJARYhYXJuYXVsdC5taWNoZWxAdG9hZC1jb25zdWx0aW5nLmZy +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnb0BDF7FsqzslakNg7u/ +n/JQkq6nheuKwvyTqECfpc9y7uSBe/vrEFqBaDSLQagJxuZdL5geFeVtRbdAoB97 +N1/LZa6vecjjgGSP0Aag/gS/ocnMRIyvlVWWT9MrD46OG3qZY1ORU1ltrVL0NKtt +JP8xME7j3bTwIDElx/hNI0n7L+ySkAe2xb/7CbZRfoOhjTVAcGv4aSLVc/Hi8k6V +kIzdOEtH6TcghXmuGcuqvLNH9BuosyngKTcQ8zg6J+e64aVvC+e7vi94uil9Qu+J +Hm0pkDzAZ2WluNsuXlrJToPirWyj6/YdN6xgSI1hbZkBmUPAebgYuxBt6huvfyQd +3wIDAQABo4IBvzCCAbswCwYDVR0PBAQDAgOoMBMGA1UdJQQMMAoGCCsGAQUFBwMB +MB0GA1UdDgQWBBTIihFNVNgOseQnsWEcAQxAbIKE4TCBsgYDVR0jBIGqMIGngBRv +G9At9gzk2MW5Z7JVey1LtPIZ8KGBg6SBgDB+MQswCQYDVQQGEwJGUjEWMBQGA1UE +CBMNSWxlLWRlLUZyYW5jZTEOMAwGA1UEBxMFUGFyaXMxEDAOBgNVBAoTB296b24u +aW8xFTATBgNVBAMTDE96b24gVGVzdCBDQTEeMBwGCSqGSIb3DQEJARYPc3VwcG9y +dEBvem9uLmlvggkA15FtIaGcrk8wDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg9j +b21tb25OYW1lOmNvcHkwCQYDVR0SBAIwADBIBgNVHR8EQTA/MD2gO6A5hjdodHRw +Oi8vb3BlbnNzbGNhLnRvYWQtY29uc3VsdGluZy5jb20vb3BlbnZwbi9MYXRlc3Qu +Y3JsMBEGCWCGSAGG+EIBAQQEAwIGQDAxBglghkgBhvhCAQ0EJBYiVE9BRC1Db25z +dWx0aW5nIHNlcnZlciBjZXJ0aWZpY2F0ZTANBgkqhkiG9w0BAQsFAAOCAgEAewDa +9BukGNJMex8gsXmmdaczTr8yh9Uvw4NJcZS38I+26o//2g+d6i7wxcQg8hIm62Hj +0TblGU3+RsJo4uzcWxxA5YUYlVszbHNBRpQengEE5pjwHvoXVMNES6Bt8xP04+Vj +0qVnA8gUaDMk9lN5anK7tF/mbHOIJwHJZYCa2t3y95dIOVEXFwOIzzbSbaprjkLN +w0BgR5paJz7NZWNqo4sZHUUz94uH2bPEd01SqHO0dJwEVxadgxuPnD05I9gqGpGX +Zf3Rn7EQylvUtX9mpPaulQPXc3emefewLUSSAdnZrVikZK2J/B4lSi9FpUwl4iQH +pZoE0QLQHtB1SBKacnOAddGSTLSdFvpzjErjjWSpMukF0vutmrP86GG3xtshWVhI +u+yLfDJVm/pXfaeDtWMXpxIT/U1i0avpk5MZtFMRC0MTaxEWBTnnJm+/yiaAXQYg +E1ZIP0mkZkiUojIawTR7JTjHGhIraP9UVPNceVy0DLfETHEou3vhwBn7PFOz7piJ +wjp3A47DStJD4fapaX6B1fqM+n34CMD9ZAiJFgQEIQfObAWC9hyr4m+pqkp1Qfuw +vsAP/ZoS1CBirJfm3i+Gshh+VeH+TAmO/NBBYCfzBdgkNz4tJCkOc7CUT/NQTR/L +N2OskR/Fkge149RJi7hHvE3gk/mtGtNmHJPuQ+s= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIJazCCBVOgAwIBAgIUWHoc5e2FUECgyCvyVf8wCtt8gTYwDQYJKoZIhvcNAQEL +BQAwRTELMAkGA1UEBhMCRlIxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDA4MDQxODU4MTZaFw0yMDA5 +MDMxODU4MTZaMEUxCzAJBgNVBAYTAkZSMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw +HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggQiMA0GCSqGSIb3DQEB +AQUAA4IEDwAwggQKAoIEAQDARiuHkhrnf38Md1nxGDSneJfwv/QksdNNMNTJBdjg +OVmaRCIAyz43oefTWDQ/TebbSwB+Lg9pud1zadGWhlZRhCgBPP8JDMhIKH4eXIRk +5IIa8WD08EwvSlqJL0r4gsMtVsxy7BZHAkka/2Ket9pyGt4kG5n75RFdc6BI80/8 +RwJt/MDxPrcVBAT7LnCluxQpyya9mZCabj7l+9a2yU2hgWS6QqfZJ133krkP/MMh +AEQkSoA4mmBwWk9yPqXmUqiOi7v6iLkIUEh5SgYVPRk9BtU/kDaUdSwuqRrpCZo4 +SsWZWFLxBmLHkSh+G+BWjCVYMQr2ye7e+VMT/20+5xAfq4fj9n5BsPcx3QcVuTof +RAc/Oygnt4MYnIcUb7zRFvCAvgpUHL7BnEn6nhyXjHJGqGDchsg8m9t3v/Y3ohq+ +qmrSzdeuylE1n3W5aWJlbFmyXegNP45MJ0xicesVrXEWF7YD/ir9mGJ8bQYr4blf +77PrbF02komC6AzVPKOJa0jR+eW1wErzYlkYgez6ylBWCiHJd1dhEHlK3h2rXdYa +Gnb45ILCLpEDjNEUrHifLLNXwqJpgZQsJU6BgMgk7ZgBfAKrCfTeg0rkCqCAPeVb +8eSLf7FBF7YBRJ5P6u8qXc4RtgEu607GaWV0gIMfyVBY52oV+OaNsEdFetrJnp3c +friG8vJ+7jdq6zjUCGgnfUIHoViJPh3JuFfhA3jT0gQDKW5PeI7dxhrNvlqdYfHI +fxX7Y1/J6cTQkqJ1cai2f0bwJIJiTAThNbG+zrtjJ7fZ3wJ4udyU/IKrwShqtmTb +1Ofj0tJDdwOH8i84vIySLUvR9aAb7ClFlnsx6rzwOxG90W7C0LA2M0EHm4FezJm/ +FfujnZwEWr1T9Wki6qE0MHCbdN/TTDws//EKkkE44FC+amL96w0IQl70vpE37j2A +zlDWvFFID95SIxfmpkwWDvXDKv6gr1GMLeysCl2fgpY05Xidw5cEo9/tEkuWn/dG +x/D9hnLBGeroA0251ES12jemqDjI2U0tfaeHakjwSsoWElf94Qmuh2iPZ+1zIxQs +7o6nAWN8X9hfsmrDTTHlww0TEfrjlbzG5Yh+0ZRxmejgiUyOCXck+eh/ZXMXvfWh +y3CorIIuWgkRjm80PYkdaRDJdZuyP6R7tXfTXNVzAiSQf0Qx9ru2KB2Fs/XZPamH +KjItAU5Q6msIVvaRMS0muQgV+b6hqSEBzqXqJfAlpVLHXr5FqK+U7EB9y02B6piB +tAmxqXP8OOCoQql6/vgIcrDFUOo6KtGBW36ef74XE3KCUVaIzVJZSIt6i/Vi0bZj +bAjsJUQ3qDlHdorv9TRVOhnC1GUz7SuYnpEOyiXmyx3LAgMBAAGjUzBRMB0GA1Ud +DgQWBBQ62csZcH/meQcENHhNbqz9LMzwjjAfBgNVHSMEGDAWgBQ62csZcH/meQcE +NHhNbqz9LMzwjjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IEAQBA +wLsGf3R1+/I2zQE+lsj7RasZtA/Cos92iEGDAPvFbx9e+roG8Gg8KBsEJu/HN0JH +lMMiQ8dDRHSBMvRBENL5/57oOOhmqc+1u5sazLuANhzAYPZG17Klib7YpEwWoXar +FDDiJYtCyLW0oNLpCswYopWK9GC0RJNucB0NFvOxehJ2sP2/fxGBQMB09L6mjKjd +4KsOzyd3dNf0VYS6jB+/1pcKSHKQUo9HRHB5FK04PsYHoh4AtmEHvmYQKcWWidgU +v26ftlH00ERzuW2juqBbz9mghlNRqXi0IyZ9b4tSj29dxW+WWFzo7j2zEPaD6z2W +DEHq7zvON+g+q6qLgWeszqMgJzjvWjMj00E/t06PoHPiz/cAnDKEqp+ZzxCIFrxj +/qneChpogDWyLbawhyyzbZvbirx5znOSbWjPZgydqaNEFViqbxwinBx4Xxabo6XN +TU020FuMWmgfbIcvtgjKgyKqc97l7JMNNm7LQV9+9W0U5zdIqQKLZ9MMrd2w3xh4 +MAB8NKnwzHReK0TWwUU9HSgFAGdEX6HnyZ3bQ13ijg+sNBRMEi0gBHaqZKDdyoft +B2u2uasSwioV48dbSIcHl+rTBKxiMh5XQ7ENnaGOJkjsIqTVzizqnPHU8eMBnSbb +dsXlamROYII44+j3Ku6OGt51w86eGk4VxI3tmaECcJKqTkwUFD8AcNDrkjtmLuxK +12yjnoM+u1cclfqQ5NOtRc6MJZ27jCobfBBhVdKVDp4X1WNyqGlbsU5adDAzknuI +GT7MJO7lGjkZX2n54BNPSfrSknYMOVYcZqL0Dbcrhx5IyEmg+iOlOu1HO1tdnZop +ej4vT+1V2w9Sa4Wo3UCo84jcm5v/4z7jCYh4BRQ60CFb7GLxZoqXIslcGSPool3n +jl8JWoaLXrJUPfZGXo1iAlayJ5EiMyZl4eB/TBUf6TMm8vLvsPiUT+CEsjLppOdS +eYppZAZ6H1JrJGs5kKBdOJHGn6Pkp5QsHIswOBd1HqHrBbYbZmDaDLRHduILWLrM +e0/IfDdeXB/bKfmZoEpT8xRiauw15p0AHLumiK7KISAehfgBqUnxx+YmgGoZ7EWX +KnMYAfCuC6oJ1DL0gp4Z9yMK1eu+GV1sLxPq9ZruEHW1R+H+4sGyiA5Gso2tgB6/ +XW//wxKclNp5LZR7hqfs/kGuh5asrJrnEbMwWn2+tr/LqfYtYh1D6nHfIXpT0o1d +rNy/HrsKnRDMWxjm03r4hCViuNVD3Zb9anAF/NSPDVu8ATM5JbJNrCYX4eipz6ZE +aQBkwIBkTPgtgP4r8v2G+uMYDw8nq7xh72FK107aeTTwc6MgU5jfeFNMr2XJisJd +lSem1ngKYQSEzjVsTE4c +-----END CERTIFICATE----- diff --git a/reg-tests/startup/default_rules.vtc b/reg-tests/startup/default_rules.vtc new file mode 100644 index 0000000..cd86f74 --- /dev/null +++ b/reg-tests/startup/default_rules.vtc @@ -0,0 +1,185 @@ +varnishtest "Misuses of defaults section defining TCP/HTTP rules" + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature ignore_unknown_macro + +# +# anonymous defaults section cannot define TCP/HTTP rules +# +haproxy h1 -conf-BAD {} { + defaults + http-request set-header X-Hdr 1 +} + +haproxy h2 -conf-BAD {} { + defaults + http-response set-header X-Hdr 1 +} + +haproxy h3 -conf-BAD {} { + defaults + http-after-request set-header X-Hdr 1 +} + +haproxy h4 -conf-BAD {} { + defaults + tcp-request connection accept +} + +haproxy h5 -conf-BAD {} { + defaults + tcp-request session accept +} + +haproxy h6 -conf-BAD {} { + defaults + tcp-request inspect-delay 5s + tcp-request content accept +} + +haproxy h7 -conf-BAD {} { + defaults + tcp-response inspect-delay 5s + tcp-response content accept +} + +# +# defaults section defining TCP/HTTP rules cannot be used to init another +# defaults section +# +haproxy h8 -conf-BAD {} { + defaults invalid + tcp-response inspect-delay 5s + tcp-response content accept + + defaults from invalid + mode tcp +} + +# +# defaults section defining TCP/HTTP rules cannot be used to init a listen +# section +# +haproxy h9 -conf-BAD {} { + defaults invalid + tcp-request inspect-delay 5s + tcp-request content accept + + listen li from invalid + mode tcp + bind "fd@${lih9}" + server www 127.0.0.1:80 +} + +# +# defaults section defining TCP/HTTP rules cannot be used to init frontend and +# backend sections at the same time +# +# +haproxy h10 -conf-BAD {} { + defaults invalid + tcp-request inspect-delay 5s + tcp-request content accept + + frontend fe from invalid + mode tcp + bind "fd@${feh10}" + default_backend be1 + + backend be from invalid + mode tcp + server www 127.0.0.1:80 +} + +# +# defaults section defining 'tcp-request connection' or 'tcp-request session' +# rules cannot be used to init backend sections +# +haproxy h11 -conf-BAD {} { + defaults invalid + tcp-request connection accept + + backend be from invalid + mode tcp + server www 127.0.0.1:80 +} + +haproxy h12 -conf-BAD {} { + defaults invalid + tcp-request session accept + + backend be from invalid + mode tcp + server www 127.0.0.1:80 +} + +# +# defaults section defining 'tcp-response content' rules cannot be used to init +# a frontend section +# +haproxy h13 -conf-BAD {} { + defaults invalid + tcp-response inspect-delay 5s + tcp-response content accept + + frontend fe from invalid + mode tcp + bind "fd@${feh10}" +} + +haproxy h14 -conf-OK { + defaults tcp + tcp-response inspect-delay 5s + tcp-response content accept + + backend be from tcp + mode tcp + server www 127.0.0.1:80 +} + +# +# Check arguments resolutions in rules. FE/BE arguments must be resolved, but +# SRV/TAB arguments without an explicit proxy name are not allowed. +# + +haproxy h15 -conf-BAD {} { + defaults invalid + mode http + http-request set-header x-test "%[srv_conn(www)]" + + backend be from invalid + server www 127.0.0.1:80 +} + +haproxy h16 -conf-BAD {} { + defaults invalid + mode http + http-request track-sc0 src + http-request deny deny_status 429 if { sc_http_req_rate(0) gt 20 } + + backend be + stick-table type ip size 100k expire 30s store http_req_rate(10s) + server www 127.0.0.1:80 +} + +haproxy h17 -conf-OK { + defaults common + mode http + + defaults def_front from common + http-request set-header x-test1 "%[fe_conn]" + + defaults def_back from common + http-request track-sc0 src table be + http-request deny deny_status 429 if { sc_http_req_rate(0,be) gt 20 } + http-request set-header x-test2 "%[be_conn]" + http-request set-header x-test3 "%[srv_conn(be/www)]" + + frontend fe from def_front + bind "fd@${feh15}" + default_backend be + + backend be from def_back + stick-table type ip size 100k expire 30s store http_req_rate(10s) + server www 127.0.0.1:80 +} diff --git a/reg-tests/stick-table/converteers_ref_cnt_never_dec.vtc b/reg-tests/stick-table/converteers_ref_cnt_never_dec.vtc new file mode 100644 index 0000000..e571810 --- /dev/null +++ b/reg-tests/stick-table/converteers_ref_cnt_never_dec.vtc @@ -0,0 +1,75 @@ +# commit 3e60b11 +# BUG/MEDIUM: stick-tables: Decrement ref_cnt in table_* converters +# +# When using table_* converters ref_cnt was incremented +# and never decremented causing entries to not expire. +# +# The root cause appears to be that stktable_lookup_key() +# was called within all sample_conv_table_* functions which was +# incrementing ref_cnt and not decrementing after completion. +# +# Added stktable_release() to the end of each sample_conv_table_* +# function and reworked the end logic to ensure that ref_cnt is +# always decremented after use. +# +# This should be backported to 1.8 + +#REGTEST_TYPE=bug +#REQUIRE_VERSION=2.4 + +varnishtest "stick-tables: Test expirations when used with table_*" + +# As some macros for haproxy are used in this file, this line is mandatory. +feature ignore_unknown_macro + +# Do nothing. +server s1 { +} -start + +haproxy h1 -conf { + # Configuration file of 'h1' haproxy instance. + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend http1 + bind "fd@${my_frontend_fd}" + stick-table size 1k expire 1ms type ip store conn_rate(10s),http_req_cnt,http_err_cnt,http_fail_cnt,http_req_rate(10s),http_err_rate(10s),http_fail_rate(10s),gpc0,gpc0_rate(10s),gpt0 + http-request track-sc0 req.hdr(X-Forwarded-For) + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_http_req_cnt(http1) -m int lt 0 } + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_trackers(http1) -m int lt 0 } + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),in_table(http1) -m int lt 0 } + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_bytes_in_rate(http1) -m int lt 0 } + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_bytes_out_rate(http1) -m int lt 0 } + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_conn_cnt(http1) -m int lt 0 } + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_conn_cur(http1) -m int lt 0 } + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_conn_rate(http1) -m int lt 0 } + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_gpt0(http1) -m int lt 0 } + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_gpc0(http1) -m int lt 0 } + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_gpc0_rate(http1) -m int lt 0 } + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_http_err_cnt(http1) -m int lt 0 } + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_http_err_rate(http1) -m int lt 0 } + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_http_fail_cnt(http1) -m int lt 0 } + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_http_fail_rate(http1) -m int lt 0 } + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_http_req_cnt(http1) -m int lt 0 } + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_http_req_rate(http1) -m int lt 0 } + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_kbytes_in(http1) -m int lt 0 } + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_kbytes_out(http1) -m int lt 0 } + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_server_id(http1) -m int lt 0 } + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_sess_cnt(http1) -m int lt 0 } + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_sess_rate(http1) -m int lt 0 } + http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_trackers(http1) -m int lt 0 } +} -start + +client c1 -connect ${h1_my_frontend_fd_sock} { + txreq -url "/" -hdr "X-Forwarded-For: 127.0.0.1" + rxresp + expect resp.status == 503 +} -run + +haproxy h1 -cli { + send "show table http1" + expect ~ "table: http1, type: ip, size:1024, used:(0|1\\n0x[0-9a-f]*: key=127\\.0\\.0\\.1 use=0 exp=[0-9]* gpt0=0 gpc0=0 gpc0_rate\\(10000\\)=0 conn_rate\\(10000\\)=1 http_req_cnt=1 http_req_rate\\(10000\\)=1 http_err_cnt=0 http_err_rate\\(10000\\)=0 http_fail_cnt=0 http_fail_rate\\(10000\\)=0)\\n$" +} -wait diff --git a/reg-tests/stick-table/src_conn_rate.vtc b/reg-tests/stick-table/src_conn_rate.vtc new file mode 100644 index 0000000..bdf8869 --- /dev/null +++ b/reg-tests/stick-table/src_conn_rate.vtc @@ -0,0 +1,43 @@ +varnishtest "stick table: src_conn_rate" +feature ignore_unknown_macro + +haproxy h0 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + listen li + bind "fd@${fe1}" + http-request track-sc0 src table conn_rate_table + http-request deny if { src_conn_rate(conn_rate_table) gt 3 } + http-request return status 200 + + backend conn_rate_table + stick-table type ip size 1m expire 1m store conn_rate(1m) +} -start + +client c0 -connect ${h0_fe1_addr}:${h0_fe1_port} { + txreq + rxresp + expect resp.status == 200 +} -run + +client c1 -connect ${h0_fe1_addr}:${h0_fe1_port} { + txreq + rxresp + expect resp.status == 200 +} -run + +client c2 -connect ${h0_fe1_addr}:${h0_fe1_port} { + txreq + rxresp + expect resp.status == 200 +} -run + +client c3 -connect ${h0_fe1_addr}:${h0_fe1_port} { + txreq + rxresp + expect resp.status == 403 +} -run diff --git a/reg-tests/stick-table/unknown_key.vtc b/reg-tests/stick-table/unknown_key.vtc new file mode 100644 index 0000000..f0307cb --- /dev/null +++ b/reg-tests/stick-table/unknown_key.vtc @@ -0,0 +1,32 @@ +# Shipped with the commit fixing the bug. + +#REGTEST_TYPE=bug + +varnishtest "Stick Table: Crash when accessing unknown key." +feature ignore_unknown_macro + +server s0 { + rxreq + txresp +} -start + +haproxy h0 -conf { + defaults + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend test + mode http + bind "fd@${fe1}" + stick-table type ip size 1m expire 1h store gpc0 + http-request deny if { src,table_trackers(test) eq 1 } + http-request deny if { src,in_table(test) } + http-request deny deny_status 200 +} -start + +client c0 -connect ${h0_fe1_sock} { + txreq -url "/" + rxresp + expect resp.status == 200 +} -run diff --git a/reg-tests/stickiness/lb-services.vtc b/reg-tests/stickiness/lb-services.vtc new file mode 100644 index 0000000..a4e016f --- /dev/null +++ b/reg-tests/stickiness/lb-services.vtc @@ -0,0 +1,291 @@ +vtest "A reg test for stickiness" +feature ignore_unknown_macro + + +# The aim of this test is to check that "stick on" rules +# do the job they are supposed to do. +# If we remove one of the "stick on" rule, this script fails. + +#REQUIRE_VERSION=2.0 + +server s_not_used_1 {} +server s_not_used_2 {} +server s_not_used_3 {} +server s_not_used_4 {} +server s_not_used_5 {} +server s_not_used_6 {} +server s_not_used_7 {} +server s_not_used_8 {} +server s_not_used_9 {} +server s_not_used_10 {} +server s_not_used_11 {} +server s_not_used_12 {} + +# h1/be1 servers +server s1 { + rxreq + txresp -hdr "Server: be1/s1" +} -repeat 2 -start + +server s2 { + rxreq + txresp -hdr "Server: be1/s2" +} -repeat 2 -start + +# h1/be2 servers +server s3 { + rxreq + txresp -hdr "Server: be2/s3" +} -repeat 2 -start + +server s4 { + rxreq + txresp -hdr "Server: be2/s4" +} -repeat 2 -start + +haproxy h1 -arg "-L A" -conf { + defaults + mode http + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + log stdout format raw local0 debug + + peers mypeers + bind "fd@${A}" + server A + server B ${h2_B_addr}:${h2_B_port} + table mytable type string size 10m + + backend be1 + balance roundrobin + stick on urlp(client) table mypeers/mytable + server srv1 ${s1_addr}:${s1_port} + server srv2 ${s2_addr}:${s2_port} + + backend be2 + balance roundrobin + stick on urlp(client) table mypeers/mytable + server s_not_used_1 ${s_not_used_1_addr}:${s_not_used_1_port} + server s_not_used_2 ${s_not_used_2_addr}:${s_not_used_2_port} + server s_not_used_3 ${s_not_used_3_addr}:${s_not_used_3_port} + server srv2 ${s4_addr}:${s4_port} + server s_not_used_4 ${s_not_used_4_addr}:${s_not_used_4_port} + server s_not_used_5 ${s_not_used_5_addr}:${s_not_used_5_port} + server s_not_used_6 ${s_not_used_6_addr}:${s_not_used_6_port} + server srv1 ${s3_addr}:${s3_port} + + frontend fe + acl acl_be1 path_beg /be1 + acl acl_be2 path_beg /be2 + use_backend be1 if acl_be1 + use_backend be2 if acl_be2 + bind "fd@${fe}" +} -start + +# h2/be1 servers +server s5 { + rxreq + txresp -hdr "Server: be1/s5" +} -repeat 2 -start + +server s6 { + rxreq + txresp -hdr "Server: be1/s6" +} -repeat 2 -start + +# h2/be2 servers +server s7 { + rxreq + txresp -hdr "Server: be2/s7" +} -repeat 2 -start + +server s8 { + rxreq + txresp -hdr "Server: be2/s8" +} -repeat 2 -start + + +haproxy h2 -arg "-L B" -conf { + defaults + mode http + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + + peers mypeers + bind "fd@${B}" + server A ${h1_A_addr}:${h1_A_port} + server B + table mytable type string size 10m + + backend be1 + balance roundrobin + stick on urlp(client) table mypeers/mytable + server s_not_used_7 ${s_not_used_7_addr}:${s_not_used_7_port} + server s_not_used_8 ${s_not_used_8_addr}:${s_not_used_8_port} + server s_not_used_9 ${s_not_used_9_addr}:${s_not_used_9_port} + server srv1 ${s5_addr}:${s5_port} + server s_not_used_10 ${s_not_used_10_addr}:${s_not_used_10_port} + server s_not_used_11 ${s_not_used_11_addr}:${s_not_used_11_port} + server s_not_used_12 ${s_not_used_12_addr}:${s_not_used_12_port} + server srv2 ${s6_addr}:${s6_port} + + backend be2 + balance roundrobin + stick on urlp(client) table mypeers/mytable + server s_not_used_1 ${s_not_used_1_addr}:${s_not_used_1_port} + server s_not_used_2 ${s_not_used_2_addr}:${s_not_used_2_port} + server s_not_used_3 ${s_not_used_3_addr}:${s_not_used_3_port} + server s_not_used_4 ${s_not_used_4_addr}:${s_not_used_4_port} + server s_not_used_5 ${s_not_used_5_addr}:${s_not_used_5_port} + server s_not_used_6 ${s_not_used_6_addr}:${s_not_used_6_port} + server srv1 ${s7_addr}:${s7_port} + server srv2 ${s8_addr}:${s8_port} + + frontend fe + acl acl_be1 path_beg /be1 + acl acl_be2 path_beg /be2 + use_backend be1 if acl_be1 + use_backend be2 if acl_be2 + bind "fd@${fe}" +} -start + +delay 0.2 + +client cx -connect ${h1_fe_sock} { + txreq -url "/be1?client=c1" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ be1/s1 +} -repeat 2 -run + +haproxy h1 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +haproxy h2 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +client cy -connect ${h1_fe_sock} { + txreq -url "/be2?client=c1" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ be2/s3 +} -repeat 2 -run + +haproxy h1 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +haproxy h2 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +client cx -connect ${h2_fe_sock} { + txreq -url "/be1?client=c1" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ be1/s5 +} -repeat 2 -run + +haproxy h1 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +haproxy h2 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +client cy -connect ${h2_fe_sock} { + txreq -url "/be2?client=c1" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ be2/s7 +} -repeat 2 -run + +haproxy h1 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +haproxy h2 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +client cX -connect ${h1_fe_sock} { + txreq -url "/be1?client=c2" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ be1/s2 +} -repeat 2 -run + +haproxy h1 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +haproxy h2 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +client cY -connect ${h1_fe_sock} { + txreq -url "/be2?client=c2" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ be2/s4 +} -repeat 2 -run + +haproxy h1 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +haproxy h2 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +client cX -connect ${h2_fe_sock} { + txreq -url "/be1?client=c2" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ be1/s6 +} -repeat 2 -run + +haproxy h1 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +haproxy h2 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +client cY -connect ${h2_fe_sock} { + txreq -url "/be2?client=c2" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ be2/s8 +} -repeat 2 -run + +haproxy h1 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +haproxy h2 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + diff --git a/reg-tests/stickiness/srvkey-addr.vtc b/reg-tests/stickiness/srvkey-addr.vtc new file mode 100644 index 0000000..99a4d8b --- /dev/null +++ b/reg-tests/stickiness/srvkey-addr.vtc @@ -0,0 +1,260 @@ +vtest "A reg test for stickiness with srvkey addr" +feature ignore_unknown_macro + + +# The aim of this test is to check that "stick on" rules +# do the job they are supposed to do. +# If we remove one of the "stick on" rule, this script fails. + +#REQUIRE_VERSION=2.4 + +server s_not_used_1 {} +server s_not_used_2 {} +server s_not_used_3 {} +server s_not_used_4 {} +server s_not_used_5 {} +server s_not_used_6 {} +server s_not_used_7 {} +server s_not_used_8 {} +server s_not_used_9 {} +server s_not_used_10 {} +server s_not_used_11 {} +server s_not_used_12 {} + +# h1/be1 servers +server s1 { + rxreq + txresp -hdr "Server: s1" +} -repeat 8 -start + +server s2 { + rxreq + txresp -hdr "Server: s2" +} -repeat 8 -start + +haproxy h1 -arg "-L A" -conf { + defaults + mode http + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + log stdout format raw local0 debug + + peers mypeers + bind "fd@${A}" + server A + server B ${h2_B_addr}:${h2_B_port} + table mytable type string size 10m srvkey addr + + backend be1 + balance roundrobin + stick on urlp(client) table mypeers/mytable + server srv1 ${s1_addr}:${s1_port} + server srv2 ${s2_addr}:${s2_port} + + backend be2 + balance roundrobin + stick on urlp(client) table mypeers/mytable + server s_not_used_1 ${s_not_used_1_addr}:${s_not_used_1_port} + server s_not_used_2 ${s_not_used_2_addr}:${s_not_used_2_port} + server s_not_used_3 ${s_not_used_3_addr}:${s_not_used_3_port} + server srv2_2 ${s2_addr}:${s2_port} + server s_not_used_4 ${s_not_used_4_addr}:${s_not_used_4_port} + server s_not_used_5 ${s_not_used_5_addr}:${s_not_used_5_port} + server s_not_used_6 ${s_not_used_6_addr}:${s_not_used_6_port} + server srv1_2 ${s1_addr}:${s1_port} + server s_no_addr_1 unresolvable1.addr.local init-addr none + + frontend fe + acl acl_be1 path_beg /be1 + acl acl_be2 path_beg /be2 + use_backend be1 if acl_be1 + use_backend be2 if acl_be2 + bind "fd@${fe}" +} -start + +haproxy h2 -arg "-L B" -conf { + defaults + mode http + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + + peers mypeers + bind "fd@${B}" + server A ${h1_A_addr}:${h1_A_port} + server B + table mytable type string size 10m srvkey addr + + backend be1 + balance roundrobin + stick on urlp(client) table mypeers/mytable + server s_not_used_7 ${s_not_used_7_addr}:${s_not_used_7_port} + server s_not_used_8 ${s_not_used_8_addr}:${s_not_used_8_port} + server s_not_used_9 ${s_not_used_9_addr}:${s_not_used_9_port} + server srv1_h2_1 ${s1_addr}:${s1_port} + server s_not_used_10 ${s_not_used_10_addr}:${s_not_used_10_port} + server s_not_used_11 ${s_not_used_11_addr}:${s_not_used_11_port} + server s_not_used_12 ${s_not_used_12_addr}:${s_not_used_12_port} + server srv2_h2_1 ${s2_addr}:${s2_port} + server s_no_addr_1 unresolvable1.addr.local init-addr none + + backend be2 + balance roundrobin + stick on urlp(client) table mypeers/mytable + server s_not_used_1 ${s_not_used_1_addr}:${s_not_used_1_port} + server s_not_used_2 ${s_not_used_2_addr}:${s_not_used_2_port} + server s_not_used_3 ${s_not_used_3_addr}:${s_not_used_3_port} + server s_not_used_4 ${s_not_used_4_addr}:${s_not_used_4_port} + server s_not_used_5 ${s_not_used_5_addr}:${s_not_used_5_port} + server s_not_used_6 ${s_not_used_6_addr}:${s_not_used_6_port} + server srv1_h2_2 ${s1_addr}:${s1_port} + server srv2_h2_2 ${s2_addr}:${s2_port} + server s_no_addr_2 unresolvable2.addr.local init-addr none + + frontend fe + acl acl_be1 path_beg /be1 + acl acl_be2 path_beg /be2 + use_backend be1 if acl_be1 + use_backend be2 if acl_be2 + bind "fd@${fe}" +} -start + +delay 0.2 + +client cx -connect ${h1_fe_sock} { + txreq -url "/be1?client=c1" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s1 +} -repeat 2 -run + +haproxy h1 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +haproxy h2 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +client cy -connect ${h1_fe_sock} { + txreq -url "/be2?client=c1" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s1 +} -repeat 2 -run + +haproxy h1 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +haproxy h2 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +client cx -connect ${h2_fe_sock} { + txreq -url "/be1?client=c1" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s1 +} -repeat 2 -run + +haproxy h1 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +haproxy h2 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +client cy -connect ${h2_fe_sock} { + txreq -url "/be2?client=c1" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s1 +} -repeat 2 -run + +haproxy h1 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +haproxy h2 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +client cX -connect ${h1_fe_sock} { + txreq -url "/be1?client=c2" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s2 +} -repeat 2 -run + +haproxy h1 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +haproxy h2 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +client cY -connect ${h1_fe_sock} { + txreq -url "/be2?client=c2" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s2 +} -repeat 2 -run + +haproxy h1 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +haproxy h2 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +client cX -connect ${h2_fe_sock} { + txreq -url "/be1?client=c2" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s2 +} -repeat 2 -run + +haproxy h1 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +haproxy h2 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +client cY -connect ${h2_fe_sock} { + txreq -url "/be2?client=c2" + rxresp + expect resp.status == 200 + expect resp.http.Server ~ s2 +} -repeat 2 -run + +haproxy h1 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + +haproxy h2 -cli { + send "show table mypeers/mytable" + expect ~ .* +} + diff --git a/reg-tests/stream/unique-id-from-proxy.vtc b/reg-tests/stream/unique-id-from-proxy.vtc new file mode 100644 index 0000000..eaac065 --- /dev/null +++ b/reg-tests/stream/unique-id-from-proxy.vtc @@ -0,0 +1,38 @@ +varnishtest "Check that we are able to read a unique-id from PROXYv2" + +#REQUIRE_VERSION=2.2 + +feature ignore_unknown_macro + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend echo + bind "fd@${fe1}" accept-proxy + http-after-response set-header echo %[fc_pp_unique_id,hex] + http-request return status 200 +} -start + +client c1 -connect ${h1_fe1_sock} { + # PROXY v2 signature + sendhex "0d 0a 0d 0a 00 0d 0a 51 55 49 54 0a" + # version + PROXY + sendhex "21" + # TCP4 + sendhex "11" + # length of the address (12) + length of the TLV (8) + sendhex "00 14" + # 127.0.0.1 42 127.0.0.1 1337 + sendhex "7F 00 00 01 7F 00 00 01 00 2A 05 39" + # PP2_TYPE_UNIQUE_ID + length of the value + "12345" + sendhex "05 00 05 31 32 33 34 35" + + txreq -url "/" + rxresp + expect resp.status == 200 + expect resp.http.echo == "3132333435" +} -run diff --git a/reg-tests/stream/unique-id.vtc b/reg-tests/stream/unique-id.vtc new file mode 100644 index 0000000..3cb5a70 --- /dev/null +++ b/reg-tests/stream/unique-id.vtc @@ -0,0 +1,49 @@ +varnishtest "unique-id test" + +#REQUIRE_VERSION=2.0 + +feature ignore_unknown_macro + +server s1 { + rxreq + txresp +} -repeat 2 -start + +haproxy h1 -conf { + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend stable + bind "fd@${fe1}" + unique-id-format TEST-%[uuid] + http-response set-header A %[unique-id] + http-response set-header B %[unique-id] + default_backend be + + frontend request_data + bind "fd@${fe2}" + unique-id-format TEST-%[req.hdr(in)] + http-response set-header out %[unique-id] + default_backend be + + backend be + server srv1 ${s1_addr}:${s1_port} +} -start + +client c1 -connect ${h1_fe1_sock} { + txreq -url "/" + rxresp + expect resp.status == 200 + expect resp.http.a == resp.http.b +} -run + +client c2 -connect ${h1_fe2_sock} { + txreq -url "/" \ + -hdr "in: 12345678" + rxresp + expect resp.status == 200 + expect resp.http.out == "TEST-12345678" +} -run diff --git a/reg-tests/tcp-rules/default_rules.vtc b/reg-tests/tcp-rules/default_rules.vtc new file mode 100644 index 0000000..8c05f43 --- /dev/null +++ b/reg-tests/tcp-rules/default_rules.vtc @@ -0,0 +1,61 @@ +varnishtest "Test declaration of TCP rules in default sections" + +feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev0)'" +feature ignore_unknown_macro + +server s1 { + rxreq + txresp + expect req.http.x-test1-frt == "def_front" + expect req.http.x-test1-bck == "def_back" +} -start + +haproxy h1 -conf { + defaults common + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + defaults def_front from common + tcp-request connection accept + tcp-request session accept + tcp-request inspect-delay 5s + tcp-request content set-var(txn.test1) "str(def_front)" + tcp-request content accept + + defaults def_back from common + tcp-request inspect-delay 5s + tcp-request content set-var(txn.test1) "str(def_back)" + tcp-request content accept + + tcp-response inspect-delay 5s + tcp-response content set-var(txn.test2) "str(def_back)" + tcp-response content accept + + frontend fe from def_front + bind "fd@${feh1}" + tcp-request connection reject + tcp-request session reject + tcp-request content reject + + http-request set-header x-test1-frt "%[var(txn.test1)]" + + default_backend be + + backend be from def_back + tcp-response content reject + + http-request set-header x-test1-bck "%[var(txn.test1)]" + http-response set-header x-test2 "%[var(txn.test2)]" + + server s1 ${s1_addr}:${s1_port} + +} -start + +client c1 -connect ${h1_feh1_sock} { + txreq -req GET -url / + rxresp + expect resp.status == 200 + expect resp.http.x-test2 == "def_back" +} -run diff --git a/reg-tests/webstats/webstats-scope-and-post-change.vtc b/reg-tests/webstats/webstats-scope-and-post-change.vtc new file mode 100644 index 0000000..e896c05 --- /dev/null +++ b/reg-tests/webstats/webstats-scope-and-post-change.vtc @@ -0,0 +1,84 @@ +varnishtest "Webgui stats page check filtering with scope and changing server state" + +feature ignore_unknown_macro + +server s1 { +} -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 + mode http + + frontend fe1 + bind "fd@${fe1}" + stats enable + stats refresh 5s + stats uri / + stats admin if TRUE + + backend b1 + server srv1 ${s1_addr}:${s1_port} + server srv2 ${s1_addr}:${s1_port} + server srv3 ${s1_addr}:${s1_port} + + backend b2 + server srv1 ${s1_addr}:${s1_port} + server srv2 ${s1_addr}:${s1_port} + +} -start + +client c1 -connect ${h1_fe1_sock} { + txreq -url "/;csv;" + rxresp + expect resp.status == 200 +} -run + +client c2 -connect ${h1_fe1_sock} { + txreq -url "/?;csv;scope=b1" + rxresp + expect resp.status == 200 +} -run + +haproxy h1 -cli { + send "show stat" + expect ~ .* +} + +client c3 -connect ${h1_fe1_sock} { + txreq -url "/" + rxresp + expect resp.status == 200 + + txreq -url "/?;csv;scope=b1" + rxresp + expect resp.status == 200 + expect resp.body ~ ".*\nb1,BACKEND.*" + expect resp.body !~ ".*\nb2,BACKEND.*" + + txreq -req "POST" -url "/?scope=b2" -body "s=srv1&s=srv2&s=srv3&action=maint&b=%233" + rxresp + expect resp.status == 303 + + txreq -req "POST" -url "/" -body "s=srv2&action=drain&b=%233" + rxresp + expect resp.status == 303 + + txreq -req "POST" -url "/" -body "s=srv1&action=maint&b=%234" + rxresp + expect resp.status == 303 + + txreq -url "/?;csv;scope=fe1" + rxresp + expect resp.status == 200 +} -run + +haproxy h1 -cli { + send "show stat" + expect ~ "\nb1,srv1.*MAINT.*\nb1,srv2.*DRAIN.*\nb1,srv3.*MAINT.*\nb1,BACKEND.*DOWN.*\nb2,srv1.*MAINT.*\nb2,srv2.*no check.*\nb2,BACKEND.*UP" +} -wait |