innoweb / silverstripe-fastly
为 Silverstripe CMS 集成 Fastly CDN
Requires
README
概览
将 Fastly CDN 集成到 Silverstripe 网站中。
要求
- Silverstripe CMS 5.x
- Guzzle 7
注意:此版本与 Silverstripe 5 兼容。对于 Silverstripe 4,请参阅 2 版本分支。
安装
使用 composer 安装模块
composer require innoweb/silverstripe-fastly
然后运行 dev/build。
配置
Silverstripe
您需要将以下配置添加到您的环境中
Fastly:
service_id: [your Fastly service ID]
api_token: [your personal API token]
此外,以下配置选项在 Fastly
类中可用
soft_purge
:[true|false]
标志以启用 Fastly 软清除,请参阅 https://docs.fastly.com/en/guides/soft-purges。默认为true
verify_ssl
:[true|false]
标志以确定 Guzzle 是否应验证 SSL 证书。对于开发环境很有用。默认为true
debug_log
: 如果您想调试对 Fastly API 执行的 Guzzle 调用,您可以配置日志文件的路径,其中记录所有 Guzzle 请求。默认为''
flush_on_dev_build
:[true|false]
标志以确定是否应从 Fastly 中清除所有内容(页面、图像、CSS、JS 等)。不使用soft_purge
功能。默认为true
sitetree_flush_strategy
:'[single|parents|all|smart|everything]'
允许您选择在页面更改并发布时使用的清除策略。默认为'smart'
single
: 仅清除当前页面 URLparents
: 清除当前页面以及所有父页面all
: 清除所有页面smart
: 根据页面哪些字段已更改,应用single
、parents
或all
everything
: 从 fastly 缓存中清除所有内容。包括页面、图像、CSS、JS 等。
always_include_in_sitetree_flush
: 应在页面更改时始终清除的页面类型类数组,例如网站地图。默认为[]
图像代理键
由于在 Silverstripe 4 和 5 中我们还没有获取所有图像变体的方法(请参阅 silverstripe/silverstripe-assets#109),我们需要用代理键标记所有图像和图像变体,以便清除它们。
由于 SS 4.4+ 中所有图像变体的文件名都包含原始文件名的变体哈希,例如 my-file__FitWzYwLDYwXQ.jpg
,因此我们可以提取不带哈希的文件名并将其添加为代理键头。然后,模块清除文件的原始 URL 以及代理键,以清除原始图像以及所有变体。(这可能会清除具有不同文件夹中相同名称的其他图像,但我认为我们可以接受这种情况。)
对于 Apache,将以下片段添加到您的 .htaccess
文件中以添加代理键
### FASTLY START ###
<ifModule mod_headers.c>
<FilesMatch "\.(?i:html|htm|xhtml|js|css|bmp|png|gif|jpg|jpeg|ico|pcx|tif|tiff|svg|au|mid|midi|mpa|mp3|ogg|m4a|ra|wma|wav|cda|avi|mpg|mpeg|asf|wmv|m4v|mov|mkv|mp4|ogv|webm|swf|flv|ram|rm|doc|docx|txt|rtf|xls|xlsx|pages|ppt|pptx|pps|csv|cab|arj|tar|zip|zipx|sit|sitx|gz|tgz|bz2|ace|arc|pkg|dmg|hqx|jar|xml|pdf|gpx|kml)$">
SetEnvIfNoCase Request_URI "([^\/]*)__[^\.]*(\.[A-Za-z]*)|([^\/]*)(\.[A-Za-z]*)$" FASTLY_FILE_NAME=$1$3$2$4
Header set Surrogate-Key %{FASTLY_FILE_NAME}e
Header set Vary Accept-Encoding
</FilesMatch>
</ifModule>
### FASTLY END ###
Fastly
条件
type: cache
title: 不是管理员、已登录或表单
!(req.url ~ "^/(Security|admin|dev)") && !(req.http.Cookie ~ "sslogin=") && !(beresp.http.Cache-Control ~ "no-cache") && !(req.url ~ "stage=Stage")
type: request
title: 管理员或已登录
req.url ~ "^/(Security|admin|dev)" || req.http.Cookie ~ "sslogin=" || req.url ~ "stage=Stage"
请求设置
condition: admin or logged in
name: pass if logged in
action: pass
X-Forwarded-For: Append
头部
condition: not admin, logged in or form
name: set stale while revalidate
type: Cache
action: set
destination: stale_while_revalidate
source: 86400s
VCL 片段
type: recv
title: 清理请求
# remove cookies for static content
if (req.http.Cookie && req.url ~ "^[^?]*\.(?:js|css|bmp|png|gif|jpg|jpeg|ico|pcx|tif|tiff|au|mid|midi|mpa|mp3|ogg|m4a|ra|wma|wav|cda|avi|mpg|mpeg|asf|wmv|m4v|mov|mkv|mp4|ogv|webm|swf|flv|ram|rm|doc|docx|txt|rtf|xls|xlsx|pages|ppt|pptx|pps|csv|cab|arj|tar|zip|zipx|sit|sitx|gz|tgz|bz2|ace|arc|pkg|dmg|hqx|jar|pdf|woff|woff2|eot|ttf|otf|svg)(\?.*)?$") {
unset req.http.cookie;
}
# remove common cookies
if (req.http.Cookie) {
# remove silverstripe cookies
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(cms-panel-collapsed-cms-menu)=[^;]*", "");
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(cms-menu-sticky)=[^;]*", "");
# Remove any Google Analytics based cookies
# (removes everything starting with an underscore, which also includes AddThis, DoubleClick and others)
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-zA-Z0-9\-]+)=[^;]*", "");
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(utm[a-z]+)=[^;]*", "");
# Remove the Avanser phone tracking cookies
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(AUA[0-9]+)=[^;]*", "");
# Remove the StatCounter cookies
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(sc_is_visitor_unique)=[^;]*", "");
# Remove a ";" prefix, if present.
set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
# remove empty cookie
if (req.http.Cookie == "") {
unset req.http.cookie;
}
}
# remove adwords gclid parameter
set req.url = regsuball(req.url,"\?gclid=[^&]+$",""); # strips when QS = "?gclid=AAA"
set req.url = regsuball(req.url,"\?gclid=[^&]+&","?"); # strips when QS = "?gclid=AAA&foo=bar"
set req.url = regsuball(req.url,"&gclid=[^&]+",""); # strips when QS = "?foo=bar&gclid=AAA" or QS = "?foo=bar&gclid=AAA&bar=baz"
# strip hash, server doesn't need it
if (req.url ~ "\#") {
set req.url = regsub(req.url, "\#.*$", "");
}
# Strip a trailing questionsmark if it exists
if (req.url ~ "\?$") {
set req.url = regsub(req.url, "\?$", "");
}
type: fetch
title: 从静态内容中删除 cookie 头部
if (bereq.url ~ ".*\.(?:css|js)(?=\?|&|$)") {
unset beresp.http.set-cookie;
}
if (bereq.url ~ ".*\.(?:bmp|png|gif|jpg|jpeg|ico|pcx|tif|tiff|au|mid|midi|mpa|mp3|ogg|m4a|ra|wma|wav|cda|avi|mpg|mpeg|asf|wmv|m4v|mov|mkv|mp4|ogv|webm|swf|flv|ram|rm)(?=\?|&|$)") {
unset beresp.http.set-cookie;
}
if (bereq.url ~ ".*\.(?:doc|docx|txt|rtf|xls|xlsx|pages|ppt|pptx|pps|csv|cab|arj|tar|zip|zipx|sit|sitx|gz|tgz|bz2|ace|arc|pkg|dmg|hqx|jar|pdf)(?=\?|&|$)") {
unset beresp.http.set-cookie;
}
if (bereq.url ~ ".*\.(?:woff|woff2|eot|ttf|otf|svg)(?=\?|&|$)") {
unset beresp.http.set-cookie;
}
type: deliver
title: 对于非表单页面,删除会话 cookie
if (
(resp.http.Content-Type ~ "^text/html") &&
(req.http.Cookie) &&
!(req.url ~ "^/(Security|admin|dev)") &&
!(req.url ~ "stage=") &&
!(req.method == "POST") &&
!(req.http.Cookie ~ "sslogin=") &&
!(resp.http.Chache-Control ~ "no-store")
) {
set resp.http.set-cookie = "PHPSESSID=deleted; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Path=/; HttpOnly";
}
地理围栏
根据用户的位置提供不同的内容,请将以下VCL代码片段添加到您的Fastly配置中:
# sub routine: recv(vcl_recv)
if (fastly.ff.visits_this_service == 0 && req.restarts == 0) {
set req.http.client-geo-country = client.geo.country_code;
set req.http.client-geo-continent = client.geo.continent_code;
set req.http.client-geo-city = client.geo.city
set req.http.client-geo-longitude = client.geo.longitude
set req.http.client-geo-latitude = client.geo.latitude
}
您可以选择上述任何一行或所有行添加到您的配置中,具体取决于您的需求。
对于大洲和国家代码,所有页面请求都会自动添加VARY头。您可以使用updateVaryHeader
方法在您自己的页面控制器中覆盖此行为。
有关更多信息,请参阅https://developer.fastly.com/reference/vcl/variables/geolocation/和https://developer.fastly.com/solutions/patterns/geofence/。
许可证
BSD 3-Clause许可证,请参阅许可证