169 lines
7.1 KiB
Plaintext
169 lines
7.1 KiB
Plaintext
/*
|
|
This is the minimal Varnish 4.x VCL configuration required for passing the
|
|
Apache mod_pagespeed system tests. To install varnish and start the varnish
|
|
server at the right port, do the following:
|
|
1) sudo apt-get install varnish
|
|
2) sudo vim /etc/default/varnish and put in the following lines at the
|
|
bottom of the file:
|
|
DAEMON_OPTS="-a :8020 \
|
|
-T localhost:6082 \
|
|
-f /etc/varnish/default.vcl \
|
|
-S /etc/varnish/secret \
|
|
-s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G"
|
|
3) sudo cp /path/to/install/sample_conf.vcl /etc/varnish/default.vcl
|
|
4) sudo service varnish restart
|
|
*/
|
|
|
|
# Marker to tell the VCL compiler that this VCL has been adapted to the
|
|
# new 4.0 format.
|
|
vcl 4.0;
|
|
|
|
import std;
|
|
|
|
# Block 1: Define upstream server's host and port.
|
|
backend default {
|
|
# Location of PageSpeed server.
|
|
.host = "127.0.0.1";
|
|
.port = "8080";
|
|
}
|
|
|
|
# Block 2: Define a key based on the User-Agent which can be used for hashing.
|
|
# Also set the PS-CapabilityList header for PageSpeed server to respect.
|
|
sub generate_user_agent_based_key {
|
|
# Define placeholder PS-CapabilityList header values for large and small
|
|
# screens with no UA dependent optimizations. Note that these placeholder
|
|
# values should not contain any of ll, ii, dj, jw or ws, since these
|
|
# codes will end up representing optimizations to be supported for the
|
|
# request.
|
|
set req.http.default_ps_capability_list_for_large_screens = "LargeScreen.SkipUADependentOptimizations:";
|
|
set req.http.default_ps_capability_list_for_small_screens = "TinyScreen.SkipUADependentOptimizations:";
|
|
|
|
# As a fallback, the PS-CapabilityList header that is sent to the upstream
|
|
# PageSpeed server should be for a large screen device with no browser
|
|
# specific optimizations.
|
|
set req.http.PS-CapabilityList = req.http.default_ps_capability_list_for_large_screens;
|
|
|
|
# Cache-fragment 1: Desktop User-Agents that support lazyload_images (ll),
|
|
# inline_images (ii) and defer_javascript (dj).
|
|
# Note: Wget is added for testing purposes only.
|
|
if (req.http.User-Agent ~ "(?i)Chrome/|Firefox/|Trident/6\.|Safari|Wget") {
|
|
set req.http.PS-CapabilityList = "ll,ii,dj:";
|
|
}
|
|
# Cache-fragment 2: Desktop User-Agents that support lazyload_images (ll),
|
|
# inline_images (ii), defer_javascript (dj), webp (jw) and lossless_webp
|
|
# (ws).
|
|
if (req.http.Accept ~ "webp") {
|
|
set req.http.PS-CapabilityList = "ll,ii,dj,jw,ws:";
|
|
}
|
|
# Cache-fragment 3: This fragment contains (a) Desktop User-Agents that
|
|
# should not map to fragments 1 or 2 and (b) all tablet User-Agents. These
|
|
# will only get optimizations that work on all browsers and use image
|
|
# compression qualities applicable to large screens. Note that even tablets
|
|
# that are capable of supporting inline or webp images, for e.g. Android
|
|
# 4.1.2, will not get these advanced optimizations.
|
|
if (req.http.User-Agent ~ "(?i)Firefox/[1-2]\.|bot|Yahoo!|Ruby|RPT-HTTPClient|(Google \(\+https\:\/\/developers\.google\.com\/\+\/web\/snippet\/\))|Android|iPad|TouchPad|Silk-Accelerated|Kindle Fire") {
|
|
set req.http.PS-CapabilityList = req.http.default_ps_capability_list_for_large_screens;
|
|
}
|
|
# Cache-fragment 4: Mobiles and small screen tablets will use image
|
|
# compression qualities applicable to small screens, but all other
|
|
# optimizations will be those that work on all browsers.
|
|
if (req.http.User-Agent ~ "(?i)Mozilla.*Android.*Mobile*|iPhone|BlackBerry|Opera Mobi|Opera Mini|SymbianOS|UP.Browser|J-PHONE|Profile/MIDP|portalmmm|DoCoMo|Obigo|Galaxy Nexus|GT-I9300|GT-N7100|HTC One|Nexus [4|7|S]|Xoom|XT907") {
|
|
set req.http.PS-CapabilityList = req.http.default_ps_capability_list_for_small_screens;
|
|
}
|
|
# Remove placeholder header values.
|
|
unset req.http.default_ps_capability_list_for_large_screens;
|
|
unset req.http.default_ps_capability_list_for_large_screens;
|
|
}
|
|
|
|
sub vcl_hash {
|
|
# Block 3: Use the PS-CapabilityList value for computing the hash.
|
|
hash_data(req.http.PS-CapabilityList);
|
|
}
|
|
|
|
# Block 3a: Define ACL for purge requests
|
|
acl purge {
|
|
# Purge requests are only allowed from localhost.
|
|
"localhost";
|
|
"127.0.0.1";
|
|
}
|
|
|
|
sub vcl_hit {
|
|
# Send 5% of the HITs to the backend for instrumentation.
|
|
if (std.random(0, 100) <= 5) {
|
|
set req.http.PS-ShouldBeacon = req.http.ps_should_beacon_key_value;
|
|
return (pass);
|
|
}
|
|
}
|
|
|
|
sub vcl_miss {
|
|
# Send 25% of the MISSes to the backend for instrumentation.
|
|
if (std.random(0, 100) <= 25) {
|
|
set req.http.PS-ShouldBeacon = req.http.ps_should_beacon_key_value;
|
|
return (pass);
|
|
}
|
|
}
|
|
|
|
# Block 4: In vcl_recv, on receiving a request, call the method responsible for
|
|
# generating the User-Agent based key for hashing into the cache.
|
|
sub vcl_recv {
|
|
call generate_user_agent_based_key;
|
|
|
|
# We want to support beaconing filters, i.e., one or more of inline_images,
|
|
# lazyload_images, inline_preview_images or prioritize_critical_css are
|
|
# enabled. We define a placeholder constant called ps_should_beacon_key_value
|
|
# so that some percentages of hits and misses can be sent to the backend
|
|
# with this value used for the PS-ShouldBeacon header to force beaconing.
|
|
# This value should match the value of the DownstreamCacheRebeaconingKey
|
|
# pagespeed directive used by your backend server.
|
|
# WARNING: Do not use "random_rebeaconing_key" for your configuration, but
|
|
# instead change it to something specific to your site, to keep it secure.
|
|
set req.http.ps_should_beacon_key_value = "random_rebeaconing_key";
|
|
# Incoming PS-ShouldBeacon headers should not be allowed since this will allow
|
|
# external entities to force the server to instrument pages.
|
|
unset req.http.PS-ShouldBeacon;
|
|
|
|
# Block 3d: Verify the ACL for an incoming purge request and handle it.
|
|
if (req.method == "PURGE") {
|
|
if (!client.ip ~ purge) {
|
|
return (synth(405,"Not allowed."));
|
|
}
|
|
return (purge);
|
|
}
|
|
# Blocks which decide whether cache should be bypassed or not go here.
|
|
# Block 5a: Bypass the cache for .pagespeed. resource. PageSpeed has its own
|
|
# cache for these, and these could bloat up the caching layer.
|
|
if (req.url ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+") {
|
|
# Skip the cache for .pagespeed. resource. PageSpeed has its own
|
|
# cache for these, and these could bloat up the caching layer.
|
|
return (pass);
|
|
}
|
|
# Block 5b: Only cache responses to clients that support gzip. Most clients
|
|
# do, and the cache holds much more if it stores gzipped responses.
|
|
if (req.http.Accept-Encoding !~ "gzip") {
|
|
return (pass);
|
|
}
|
|
}
|
|
|
|
# Block 6: Mark HTML uncacheable by caches beyond our control.
|
|
sub vcl_backend_response {
|
|
if (beresp.http.Content-Type ~ "text/html") {
|
|
# Hide the upstream cache control headers.
|
|
unset beresp.http.ETag;
|
|
unset beresp.http.Last-Modified;
|
|
unset beresp.http.Cache-Control;
|
|
# Add no-cache Cache-Control header for html.
|
|
set beresp.http.Cache-Control = "no-cache, max-age=0";
|
|
}
|
|
return (deliver);
|
|
}
|
|
|
|
# Block 7: Add a header for identifying cache hits/misses.
|
|
sub vcl_deliver {
|
|
set resp.http.PS-CapabilityList = req.http.PS-CapabilityList;
|
|
if (obj.hits > 0) {
|
|
set resp.http.X-Cache = "HIT";
|
|
} else {
|
|
set resp.http.X-Cache = "MISS";
|
|
}
|
|
}
|