From b46aad6df449445a9fc4aa7b32bd40005438e3f7 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 13 Apr 2024 14:18:05 +0200 Subject: Adding upstream version 2.9.5. Signed-off-by: Daniel Baumann --- reg-tests/cache/basic.vtc | 53 ++++ reg-tests/cache/caching_rules.vtc | 320 +++++++++++++++++++++ reg-tests/cache/expires.vtc | 127 +++++++++ reg-tests/cache/if-modified-since.vtc | 144 ++++++++++ reg-tests/cache/if-none-match.vtc | 89 ++++++ reg-tests/cache/post_on_entry.vtc | 65 +++++ reg-tests/cache/sample_fetches.vtc | 137 +++++++++ reg-tests/cache/vary.vtc | 461 +++++++++++++++++++++++++++++++ reg-tests/cache/vary_accept_encoding.vtc | 333 ++++++++++++++++++++++ 9 files changed, 1729 insertions(+) create mode 100644 reg-tests/cache/basic.vtc create mode 100644 reg-tests/cache/caching_rules.vtc create mode 100644 reg-tests/cache/expires.vtc create mode 100644 reg-tests/cache/if-modified-since.vtc create mode 100644 reg-tests/cache/if-none-match.vtc create mode 100644 reg-tests/cache/post_on_entry.vtc create mode 100644 reg-tests/cache/sample_fetches.vtc create mode 100644 reg-tests/cache/vary.vtc create mode 100644 reg-tests/cache/vary_accept_encoding.vtc (limited to 'reg-tests/cache') diff --git a/reg-tests/cache/basic.vtc b/reg-tests/cache/basic.vtc new file mode 100644 index 0000000..377cbb3 --- /dev/null +++ b/reg-tests/cache/basic.vtc @@ -0,0 +1,53 @@ +varnishtest "Basic cache test" + +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..a488875 --- /dev/null +++ b/reg-tests/cache/caching_rules.vtc @@ -0,0 +1,320 @@ +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 + + + # max-age=0 + rxreq + expect req.url == "/maxage_zero" + txresp -hdr "Cache-Control: max-age=0" \ + -bodylen 150 + + rxreq + expect req.url == "/maxage_zero" + txresp -hdr "Cache-Control: max-age=0" \ + -bodylen 150 + + # Overridden null max-age + rxreq + expect req.url == "/overridden" + txresp -hdr "Cache-Control: max-age=1, s-maxage=5" \ + -bodylen 160 + + rxreq + expect req.url == "/overridden_null_maxage" + txresp -hdr "Cache-Control: max-age=0, s-maxage=5" \ + -bodylen 190 + + +} -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 + + # max-age=0 (control test for the overridden null max-age test below) + txreq -url "/maxage_zero" + rxresp + expect resp.status == 200 + expect resp.bodylen == 150 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/maxage_zero" + rxresp + expect resp.status == 200 + expect resp.bodylen == 150 + expect resp.http.X-Cache-Hit == 0 + + # Overridden max-age directive + txreq -url "/overridden" + rxresp + expect resp.status == 200 + expect resp.bodylen == 160 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/overridden" + rxresp + expect resp.status == 200 + expect resp.bodylen == 160 + expect resp.http.X-Cache-Hit == 1 + + txreq -url "/overridden_null_maxage" + rxresp + expect resp.status == 200 + expect resp.bodylen == 190 + expect resp.http.X-Cache-Hit == 0 + + # The previous response should have been cached even if it had + # a max-age=0 since it also had a positive s-maxage + txreq -url "/overridden_null_maxage" + rxresp + expect resp.status == 200 + expect resp.bodylen == 190 + 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..1fd9a93 --- /dev/null +++ b/reg-tests/cache/if-modified-since.vtc @@ -0,0 +1,144 @@ +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 + + 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" + rxresphdrs + expect resp.status == 304 + # "Date" version + txreq -url "/date" \ + -hdr "If-Modified-Since: Thu, 22 Oct 2020 16:51:12 GMT" + rxresphdrs + expect resp.status == 304 + # "Last-Modified" and "Date" version + txreq -url "/last_modified_and_date" \ + -hdr "If-Modified-Since: Thu, 15 Oct 2020 16:51:12 GMT" + rxresphdrs + expect resp.status == 304 + + + # Later date + # "Last-Modified" version + txreq -url "/last_modified" \ + -hdr "If-Modified-Since: Thu, 22 Oct 2020 23:00:00 GMT" + rxresphdrs + expect resp.status == 304 + # "Date" version + txreq -url "/date" \ + -hdr "If-Modified-Since: Thu, 22 Oct 2020 23:00:00 GMT" + rxresphdrs + expect resp.status == 304 + # "Last-Modified" and "Date" version + txreq -url "/last_modified_and_date" \ + -hdr "If-Modified-Since: Thu, 22 Oct 2020 23:00:00 GMT" + rxresphdrs + expect resp.status == 304 + +} -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..3dcaec5 --- /dev/null +++ b/reg-tests/cache/if-none-match.vtc @@ -0,0 +1,89 @@ +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 + + 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: *" + rxresphdrs + expect resp.status == 304 + txreq \ + -hdr "if-none-match: \"etag\"" + rxresphdrs + expect resp.status == 304 + txreq \ + -hdr "if-none-match: W/\"etag\"" + rxresphdrs + 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\"" + rxresphdrs + 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..c2b99c2 --- /dev/null +++ b/reg-tests/cache/sample_fetches.vtc @@ -0,0 +1,137 @@ + +varnishtest "Basic cache test" + +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..6c8cedf --- /dev/null +++ b/reg-tests/cache/vary.vtc @@ -0,0 +1,461 @@ +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 + + rxreq + expect req.url == "/origin-referer-accept-encoding" + txresp -hdr "Vary: origin,referer,accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -hdr "Content-Encoding: gzip" \ + -bodylen 58 + + rxreq + expect req.url == "/origin-referer-accept-encoding" + txresp -hdr "Vary: origin,referer,accept-encoding" \ + -hdr "Cache-Control: max-age=5" \ + -hdr "Content-Encoding: gzip" \ + -bodylen 59 + + # 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 + + + # Mixed Vary (Accept-Encoding + Referer + Origin) + txreq -url "/origin-referer-accept-encoding" \ + -hdr "Accept-Encoding: br, gzip" \ + -hdr "Referer: referer" \ + -hdr "Origin: origin" + rxresp + expect resp.status == 200 + expect resp.bodylen == 58 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/origin-referer-accept-encoding" \ + -hdr "Accept-Encoding: br, gzip" \ + -hdr "Referer: referer" \ + -hdr "Origin: origin" + rxresp + expect resp.status == 200 + expect resp.bodylen == 58 + expect resp.http.X-Cache-Hit == 1 + + txreq -url "/origin-referer-accept-encoding" \ + -hdr "Accept-Encoding: br, gzip" \ + -hdr "Referer: referer" \ + -hdr "Origin: other-origin" + rxresp + expect resp.status == 200 + expect resp.bodylen == 59 + expect resp.http.X-Cache-Hit == 0 + + txreq -url "/origin-referer-accept-encoding" \ + -hdr "Accept-Encoding: br, gzip" \ + -hdr "Referer: referer" \ + -hdr "Origin: other-origin" + rxresp + expect resp.status == 200 + expect resp.bodylen == 59 + 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 == "" + 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 == "" + 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 == "" + 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 == "" + 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 -- cgit v1.2.3