DOCS: Update README and system.xml with Varnish/Fastly configuration …#16
DOCS: Update README and system.xml with Varnish/Fastly configuration …#16rhoerr merged 2 commits intomage-os:mainfrom
Conversation
…details for Back/Forward Cache support
rhoerr
left a comment
There was a problem hiding this comment.
Thank you Oli. I'm going to tentatively approve this, but leave it open a bit for anyone else that has comments.
|
Possible alternate bfcache config section, subject to testing and approval:
Updated with @convenient 's latest snippets (8 Oct) |
@rhoerr From the comment from @JaJuMa here #2 (comment)
In the case of this module, it seems like the |
|
Okay, in that case the Fastly snippet could potentially be simplified to ?: # BFCache optimization: Allow bfcache for public pages
if (resp.http.Cache-Control ~ "public") {
set resp.http.Cache-Control = "no-cache, must-revalidate, max-age=0";
}(setting aside whether pages can/should be edge cacheable in general -- out of scope for these purposes for now, and bfcache ignores that either way). |
|
To my last comment: no, because that value would already have been overwritten by deliver.vcl (priority 50) to remove any This seems to work instead, and avoids the # If the page is tagged as cacheable, but has no-store header, remove it to allow bfcache.
if (resp.http.Pragma ~ "^cache"
&& resp.http.Cache-Control ~ "no-store"
&& req.http.X-Requested-With !~ "XMLHttpRequest") {
set resp.http.Cache-Control = "no-cache, must-revalidate, max-age=0";
}It goes by the From a practical standpoint, the difference between An alternative solution would be to add two separate snippets, one before the standard Thoughts? @convenient While looking into this, I found in passing: https://github.com/fastly/fastly-magento2/blob/master/Documentation/Guides/CUSTOM-VCL-SNIPPETS.md#automated-custom-vcl-snippets-deployment It would be theoretically possible for us to automatically make the snippet available to Fastly by writing it to |
|
Relying on the Pragma header is a nice idea that could work. The two-snippet approach though, maybe slightly hacky, but imho a smart workaround given Fastly’s limitations. Maybe something like this could be worth testing? Snippet 1: Pre Fastly default rule (priority 40) Snippet 2: Post Fastly default rule (priority 60) By this we can still have it work consistently work with Magento/Varnish default, based on the original Would be great if someone could give this a spin on a Fastly setup and confirm it behaves as expected. Another alternative/suggestion: Single Snippet - Post Fastly default rule (priority 60) This moves the "hack" from the VCL layer into the PHP module, where it's more self-contained and doesn't require users to manage two separate VCL snippets. |
|
I will try and test the dual fastly snippet approach today, I do have a new site launch this week so am pretty stacked but will try and squeeze it in |
|
@JaJuMa @rhoerr I need a bit more time to test fastly on staging. I was attempting to do similar to what was suggested with a multi snippet approach I was having Once I can pass this header through to the "deliver" section then it will be similar to my HIT functionality, and I believe that will work okay. I just need to verify the pingpong between these two VCL snippets and the distributed fastly system. |
|
If we have to deal with reliability across Fastly nodes with multiple snippets, and don't want to rely on Pragma, maybe @JaJuMa's suggestion of a Magento-driven header flag for Fastly is the way to go here. That would be reliable, consistent, and easy to configure. The only risk I see is the value reaching the user if the snippet is never configured, but that shouldn't be an issue for security or performance even if so. |
|
@rhoerr TBH I believe I can get the above dual snippet approaching working. I just need a little longer to poke at it. The debug cycle to upload a snippet and wait for it to become active seems to be around 3-4 mins, so its just a bit of a process. I nabbed a few minutes today at EOD, I should be able to do the same tomorrow |
|
@JaJuMa @rhoerr the dual snippet approach worked okay I believe, as a fastly magento2 module user I would be happy with this approach. Name: bfcache-preserve-public-private
Type: fetch
Priority: 1
----------------------
if (beresp.http.Cache-Control) {
if (beresp.http.Cache-Control ~ "public") {
set beresp.http.X-MageOS-Bfcache = "public";
} else {
set beresp.http.X-MageOS-Bfcache = "private";
}
}Name: bfcache-remove-ccns
Type: deliver
Priority: 100
----------------------
if (fastly.ff.visits_this_service == 0 && req.restarts == 0) {
if (resp.http.X-MageOS-Bfcache == "public") {
set resp.http.Cache-Control = "no-cache, must-revalidate, max-age=0";
}
}
unset resp.http.X-MageOS-Bfcache;Test scriptClick to view test script#!/usr/bin/env bash
set -euo pipefail
BASE_URL="${1:-https://mcstaging.example.com/}"
KEY="${2:-t}"
pick_headers() { grep -iE '^(x-cache|cache-control):'; }
line() { printf '%s\n' "------------------------------------------------------------------------------"; }
assert_cache_control() {
local headers="$1"
local expectation="${2:-do_not_expect_no_store}"
local has_no_store="false"
local expect_no_store="false"
if [[ "$expectation" == "expect_no_store" ]]; then
expect_no_store="true"
fi
if echo "$headers" | grep -qi "no-store"; then
has_no_store="true"
fi
if [[ "$expect_no_store" == "$has_no_store" ]]; then
echo "PASS"
else
echo "FAIL"
fi
}
force_hit() {
local path="${1:-/}"
local expectation="${2:-do_not_expect_no_store}"
local token url headers
token="$(date +%s)"
url="${BASE_URL%/}/${path#/}"
curl -sI "${url}?${KEY}=${token}" >/dev/null
sleep 1
headers="$(curl -sI "${url}?${KEY}=${token}")"
echo "HIT: ${url}?${KEY}=${token}"
printf '%s\n' "$headers" | pick_headers
assert_cache_control "$headers" "$expectation"
line
}
force_miss() {
local path="${1:-/}"
local expectation="${2:-do_not_expect_no_store}"
local token url headers
token="$(date +%s%N)"
url="${BASE_URL%/}/${path#/}"
headers="$(curl -sI "${url}?${KEY}=${token}")"
echo "MISS: ${url}?${KEY}=${token}"
printf '%s\n' "$headers" | pick_headers
assert_cache_control "$headers" "$expectation"
line
}
line
echo "no-store header should not be present"
line
echo "Test homepage cache HIT"
line
force_hit "/" do_not_expect_no_store
echo "Test homepage cache MISS"
line
force_miss "/" do_not_expect_no_store
echo "Test HIT CMS delivery-info"
line
force_hit "/delivery-info" do_not_expect_no_store
echo "Test MISS CMS delivery-info"
line
force_miss "/delivery-info" do_not_expect_no_store
line
echo "no-store header expected"
line
echo "Test 404"
line
force_hit "/this-is-a-404" expect_no_store
echo "Test cart"
line
force_hit "/checkout/cart" expect_no_store
echo "Test customer/account/login"
line
force_hit "/customer/account/login/" expect_no_store------------------------------------------------------------------------------
no-store header should not be present
------------------------------------------------------------------------------
Test homepage cache HIT
------------------------------------------------------------------------------
HIT: https://mcstaging.example.com/?t=1759912507
x-cache: MISS, MISS, HIT
cache-control: no-cache, must-revalidate, max-age=0
PASS
------------------------------------------------------------------------------
Test homepage cache MISS
------------------------------------------------------------------------------
MISS: https://mcstaging.example.com/?t=1759912508N
x-cache: MISS, MISS, MISS
cache-control: no-cache, must-revalidate, max-age=0
PASS
------------------------------------------------------------------------------
Test HIT CMS delivery-info
------------------------------------------------------------------------------
HIT: https://mcstaging.example.com/delivery-info?t=1759912509
x-cache: MISS, MISS, HIT
cache-control: no-cache, must-revalidate, max-age=0
PASS
------------------------------------------------------------------------------
Test MISS CMS delivery-info
------------------------------------------------------------------------------
MISS: https://mcstaging.example.com/delivery-info?t=1759912511N
x-cache: MISS, MISS, MISS
cache-control: no-cache, must-revalidate, max-age=0
PASS
------------------------------------------------------------------------------
------------------------------------------------------------------------------
no-store header expected
------------------------------------------------------------------------------
Test 404
------------------------------------------------------------------------------
HIT: https://mcstaging.example.com/this-is-a-404?t=1759912511
x-cache: MISS, MISS, MISS
cache-control: no-store, no-cache, must-revalidate, max-age=0
PASS
------------------------------------------------------------------------------
Test cart
------------------------------------------------------------------------------
HIT: https://mcstaging.example.com/checkout/cart?t=1759912513
cache-control: max-age=0, must-revalidate, no-cache, no-store
x-cache: MISS, MISS
PASS
------------------------------------------------------------------------------
Test customer/account/login
------------------------------------------------------------------------------
HIT: https://mcstaging.example.com/customer/account/login/?t=1759912515
cache-control: max-age=0, must-revalidate, no-cache, no-store
x-cache: MISS, MISS, MISS
PASS
------------------------------------------------------------------------------ |
|
Updated suggested doc reads well to me @rhoerr |
…details for Back/Forward Cache support