Varnish cookie issue with mantis bug tracker - linux

I have installed Varnish on my Linux server and configured for my websites including a wordpress site (www.mywordpress.com) and it is working fine. Now I have installed mantis bug tracker under my website (www.mywordpress.com/mantis). But when I am trying to login to the MantisBT as the default user (administrator/root), it shows an error like "Your browser either does not know how to handle cookies, or refuses to handle them". How can I set up a Varnish exception or allow cookies (in default.vcl) for Mantis url's. My default.vcl file looks like:
###my default.vcl file:
backend default {
.host = "127.0.0.1";
.port = "8080";
}
backend master {
.host = "127.0.0.1";
.port = "8080";
}
acl purge {
"localhost";
}
sub vcl_recv {
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
return(lookup);
}
if (req.restarts == 0) {
if (req.http.x-forwarded-for) {
set req.http.X-Forwarded-For =
req.http.X-Forwarded-For + ", " + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
### do not cache these files:
if (req.url ~ "/svn" || req.http.Authorization || req.http.Authenticate)
{
return (pass);
}
##never cache the admin pages, or the server-status page
if (req.url ~ "wp-(admin|login)" || req.http.Content-Type ~ "multipart/form-data")
{
set req.backend = master;
return(pass);
}
if (req.url ~ "opportunity-attachments" || req.http.Content-Type ~ "multipart/form-data")
{
set req.backend = master;
return(pass);
}
if (req.url ~ "^phpmyadmin") {
set req.backend = master;
return(pipe);
}
if (req.url ~ "^/login") {
set req.backend = master;
return(pipe);
}
## always cache these images & static assets
if (req.request == "GET" && req.url ~ "\.(css|js|gif|jpg|jpeg|bmp|png|ico|img|tga|wmf)$") {
remove req.http.cookie;
return(lookup);
}
if (req.request == "GET" && req.url ~ "(xmlrpc.php|wlmanifest.xml)") {
remove req.http.cookie;
return(lookup);
}
#never cache POST requests
if (req.request == "POST")
{
return(pass);
}
#DO cache this ajax request
if(req.http.X-Requested-With == "XMLHttpRequest" && req.url ~ "recent_reviews")
{
return (lookup);
}
#dont cache ajax requests
if(req.http.X-Requested-With == "XMLHttpRequest" || req.url ~ "nocache" || req.url ~ "(control.php|wp-comments-post.php|wp-login.php|bb-login.php|bb-reset-password.php|register.php)")
{
return (pass);
}
if (req.http.Cookie && req.http.Cookie ~ "wordpress_") {
set req.http.Cookie = regsuball(req.http.Cookie, "wordpress_test_cookie=", "; wpjunk=");
}
### don't cache authenticated sessions
if (req.http.Cookie && req.http.Cookie ~ "(wordpress_|PHPSESSID)") {
return(pass);
}
### parse accept encoding rulesets to make it look nice
if (req.http.Accept-Encoding) {
if (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elsif (req.http.Accept-Encoding ~ "deflate") {
set req.http.Accept-Encoding = "deflate";
} else {
# unkown algorithm
remove req.http.Accept-Encoding;
}
}
if (req.http.Cookie)
{
set req.http.Cookie = ";" + req.http.Cookie;
set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
set req.http.Cookie = regsuball(req.http.Cookie, ";(vendor_region|PHPSESSID|themetype2)=", "; \1=");
set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
if (req.http.Cookie == "") {
remove req.http.Cookie;
}
}
if (req.url ~ "^/$") {
unset req.http.cookie;
}
return(lookup);
}
sub vcl_hit {
if (req.request == "PURGE") {
set obj.ttl = 0s;
error 200 "Purged.";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
error 404 "Not in cache.";
}
if (!(req.url ~ "wp-(login|admin)")) {
unset req.http.cookie;
}
if (req.url ~ "^/[^?]+.(jpeg|jpg|png|gif|ico|js|css|txt|gz|zip|lzma|bz2|tgz|tbz|html|htm)(\?.|)$") {
unset req.http.cookie;
set req.url = regsub(req.url, "\?.$", "");
}
if (req.url ~ "^/$") {
unset req.http.cookie;
}
}
sub vcl_fetch {
if (req.url ~ "^/$") {
unset beresp.http.set-cookie;
}
if (!(req.url ~ "wp-(login|admin)")) {
unset beresp.http.set-cookie;
}
}

First, change this, it is unsetting any cookie which not inside wp-login or wp-admin:
if (!(req.url ~ "wp-(login|admin)")) {
unset req.http.cookie;
}
to something like this:
if (!(req.url ~ "wp-(login|admin)") || !(req.url ~ "mantis")) {
unset req.http.cookie;
}
(Where '||' means OR, '~' means equals to about, and 'req.url' - the requested URL)
and in vcl_recv (no matter where, put it in the beggining), ignore caching /mantis URLs:
sub vcl_recv {
...
if (req.url ~ "/mantis")
{
return (pass);
}
...
}
and restart varnish (usually sudo service varnish restart on ubuntu). check again and it should be fine (If its not working, clean your browser's cookies and cache).
...And, why is mantis not inside the wp-admin directory? is it a wordpress plugin?

Related

Varnish Request Url was not the same with apache request

I am sending a request to Varnish but the request was changed so that the output is wrong
original request:
admin/catalog/category/grid/key/d53fe1b4a969a873d1e0b2174848cef5b10797c35dce4c51be04d470db648e8c/id/2/filter//page/2/?ajax=true&isAjax=true
request which was pushed to varnish (varnishlog)
admin/catalog/category/grid/key/b5fbeb78a5bd6bedcb698beac083361a9891a04484bb59541b69e9420fb691aa/id/2/filter/page/3/?ajax=true&isAjax=true
a slightly different between the 2 requests is the filter/ and filter// part.
When coming with an original request: the site takes filter as param and with value ""
But with Request pushed to varnish: it becomes filter as param and with value page, then param page was not found and made the code go wrongs.
Adding my vcl content:
vcl 4.0;
import std;
# The minimal Varnish version is 4.0
# For SSL offloading, pass the following header in your proxy server or load balancer: 'X-Forwarded-Proto: https'
backend default {
.host = "web";
.port = "80";
}
acl purge {
"web";
"localhost";
"127.0.0.1";
}
sub vcl_recv {
if (req.method == "PURGE") {
if (client.ip !~ purge) {
return (synth(405, "Method not allowed"));
}
if (!req.http.X-Magento-Tags-Pattern) {
return (purge);
}
if (!req.http.X-Magento-Tags-Pattern && !req.http.X-Pool) {
return (synth(400, "X-Magento-Tags-Pattern or X-Pool header required"));
}
if (req.http.host && req.http.host != "") {
ban("obj.http.X-Host ~ " + req.http.host + " && obj.http.X-Magento-Tags ~ " + req.http.X-Magento-Tags-Pattern);
} else {
ban("obj.http.X-Magento-Tags ~ " + req.http.X-Magento-Tags-Pattern);
}
# If all Tags should be purged clear
# ban everything to catch assets as well
if (req.http.X-Magento-Tags-Pattern == ".*") {
ban("req.url ~ .*");
}
return (synth(200, "Purged"));
}
if (req.method != "GET" &&
req.method != "HEAD" &&
req.method != "PUT" &&
req.method != "POST" &&
req.method != "TRACE" &&
req.method != "OPTIONS" &&
req.method != "DELETE") {
/* Non-RFC2616 or CONNECT which is weird. */
return (pipe);
}
# We only deal with GET and HEAD by default
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}
# Bypass shopping cart, checkout
if (req.url ~ "/checkout") {
return (pass);
}
# normalize url in case of leading HTTP scheme and domain
set req.url = regsub(req.url, "^http[s]?://", "");
# collect all cookies
std.collect(req.http.Cookie);
# Remove Google gclid parameters to minimize the cache objects
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"
# static files are always cacheable. remove SSL flag and cookie
if (req.url ~ "^/(pub/)?(media|static)/.*\.(ico|css|js|jpg|jpeg|png|gif|tiff|bmp|mp3|ogg|svg|swf|woff|woff2|eot|ttf|otf)$") {
unset req.http.Https;
unset req.http.X-Forwarded-Proto;
unset req.http.Cookie;
}
return (hash);
}
sub vcl_hash {
if (req.http.cookie ~ "X-Magento-Vary=") {
hash_data(regsub(req.http.cookie, "^.*?X-Magento-Vary=([^;]+);*.*$", "\1"));
}
# For multi site configurations to not cache each other's content
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
# To make sure http users don't see ssl warning
if (req.http.X-Forwarded-Proto) {
hash_data(req.http.X-Forwarded-Proto);
}
}
sub vcl_backend_response {
set beresp.http.X-Host = bereq.http.host;
if (beresp.http.content-type ~ "text") {
set beresp.do_esi = true;
}
if (bereq.url ~ "\.js$" || beresp.http.content-type ~ "text") {
set beresp.do_gzip = true;
}
# cache only successfully responses and 404s
if (beresp.status != 200 && beresp.status != 404) {
set beresp.ttl = 0s;
set beresp.uncacheable = true;
return (deliver);
} elsif (beresp.http.Cache-Control ~ "private") {
set beresp.uncacheable = true;
set beresp.ttl = 86400s;
return (deliver);
}
if (beresp.http.X-Magento-Debug) {
set beresp.http.X-Magento-Cache-Control = beresp.http.Cache-Control;
}
# validate if we need to cache it and prevent from setting cookie
# images, css and js are cacheable by default so we have to remove cookie also
if (beresp.ttl > 0s && (bereq.method == "GET" || bereq.method == "HEAD")) {
unset beresp.http.set-cookie;
if (bereq.url !~ "\.(ico|css|js|jpg|jpeg|png|gif|tiff|bmp|gz|tgz|bz2|tbz|mp3|ogg|svg|swf|woff|woff2|eot|ttf|otf)(\?|$)") {
set beresp.http.Pragma = "no-cache";
set beresp.http.Expires = "-1";
set beresp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0";
set beresp.grace = 1m;
}
}
# "Microcache" for search
if (bereq.url ~ "/catalogsearch") {
set beresp.ttl = 30m;
}
# If page is not cacheable then bypass varnish for 2 minutes as Hit-For-Pass
if (beresp.ttl <= 0s ||
beresp.http.Surrogate-control ~ "no-store" ||
(!beresp.http.Surrogate-Control && beresp.http.Vary == "*")) {
# Mark as Hit-For-Pass for the next 2 minutes
set beresp.ttl = 120s;
set beresp.uncacheable = true;
}
return (deliver);
}
sub vcl_deliver {
if (resp.http.X-Magento-Debug) {
if (resp.http.x-varnish ~ " ") {
set resp.http.X-Magento-Cache-Debug = "HIT";
} else {
set resp.http.X-Magento-Cache-Debug = "MISS";
}
} else {
unset resp.http.Age;
}
unset resp.http.X-Magento-Debug;
unset resp.http.X-Magento-Tags;
unset resp.http.X-Powered-By;
unset resp.http.Server;
unset resp.http.X-Varnish;
unset resp.http.Via;
unset resp.http.Link;
}

Varnish add more slash in URL

My varnish cache is accelerator mode and it cause adding more slash after URL.
I check with gtmetrix:
Avoid landing page redirects for the following chain of redirected URLs.
https://www.example2.com/
https://www.example2.com//
https://www.example2.com/
and with google pagespeed test:
Reduce server response time
In our test, your server responded in 1.6 seconds. There are many factors that can slow down your server response time.
Here is my config:
vcl 4.0;
backend default {
.host = "localhost";
.port = "8080";
}
acl purger {
"localhost";
"XXX.XXX.XXX.XXX";
}
sub vcl_recv {
if (client.ip != "127.0.0.1" && req.http.host ~ "XXX.com") {
set req.http.x-redir = "https://www.example.com/" + req.url;
return(synth(850, ""));
}
if (client.ip != "127.0.0.1" && req.http.host ~ "YYY.com") {
set req.http.x-redir = "https://www.example2.com/" + req.url;
return(synth(850, ""));
}
if (req.method == "PURGE") {
if (!client.ip ~ purger) {
return(synth(405, "This IP is not allowed to send PURGE requests."));
}
return (purge);
}
if (req.restarts == 0) {
if (req.http.X-Forwarded-For) {
set req.http.X-Forwarded-For = client.ip;
}
}
if (req.http.Authorization || req.method == "POST") {
return (pass);
}
if (req.url ~ "/feed") {
return (pass);
}
set req.http.cookie = regsuball(req.http.cookie, "wp-settings-\d+=[^;]+(; )?", "");
set req.http.cookie = regsuball(req.http.cookie, "wp-settings-time-\d+=[^;]+(; )?", "");
if (req.http.cookie == "") {
unset req.http.cookie;
}
}
sub vcl_synth {
if (resp.status == 850) {
set resp.http.Location = req.http.x-redir;
set resp.status = 302;
return (deliver);
}
}
sub vcl_purge {
set req.method = "GET";
set req.http.X-Purger = "Purged";
return (restart);
}
sub vcl_backend_response {
set beresp.ttl = 24h;
set beresp.grace = 1h;
}
sub vcl_deliver {
if (req.http.X-Purger) {
set resp.http.X-Purger = req.http.X-Purger;
}
}
Somebody know the reason why varnish do that ?
req.url always includes a / at the beginning.
so correct would be:
set req.http.x-redir = "https://www.example2.com" + req.url;
your question does not correspond to the example1/example2 as it includes XXX and YYY
if you can post a less redacted VCL - i may can help you a bit more
you may need a != "/" on req.url before redirecting. as this would result in a //

How to exclude PHPSSID from responses returned by Varnish

We are currently configure Varnish on our server. This is the mess...
We encounter some difficulties with Varnish. Indeed when we return the response for uncached page, varnish include systematically the PHPSSID of the current user in the response. When another user ask the page wich is cached, he inherites of the PHPSSSID of a foreign user...
vcl 4.0;
include "includes/devicedetect.vcl";
import std;
backend local {
.host = "127.0.0.1";
.port = "80";
.connect_timeout = 5s;
.first_byte_timeout = 300s;
.between_bytes_timeout = 300s;
}
acl purge {
# ACL we'll use later to allow purges
# web01
# web02
"localhost";
"127.0.0.1";
}
sub vcl_recv {
# Disable all
# return (pass);
# Allow purging
if (req.method == "PURGE") {
if (!std.ip(regsub(req.http.X-Forwarded-For, "[, ].*$", ""), client.ip) ~ purge) {
# Not from an allowed IP? Then die with an error.
return (synth(405, "This IP is not allowed to send PURGE requests."));
}
# If you got this stage (and didn't error out above), purge the cached result
return (purge);
}
# Allow ban (global purge)
if (req.method == "BAN") {
if (!std.ip(regsub(req.http.X-Forwarded-For, "[, ].*$", ""), client.ip) ~ purge) {
# Not from an allowed IP? Then die with an error.
return (synth(405, "This IP is not allowed to send BAN requests."));
}
# If you got this stage (and didn't error out above), purge the cached result
ban("obj.http.x-url ~ /");
return (synth(200, "Ban added"));
}
# Only cache GET or HEAD requests. This makes sure the POST requests are always passed.
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}
if (req.http.Authorization) {
return (pass);
}
if (req.http.host ~ "(api\.domain\.com|api2\.domain\.com)") {
return (pass);
}
# Do not cache logout/login/forgot password url
if (req.url ~ "/(logout|forgotten-password|login|register|facebookLogin)") {
return (pass);
}
# Do not cache when Set-Cookie contain user[id] OR identity OR PHPSESSID OR PHPSERVERID
if (req.http.Set-Cookie ~ "(user\[id\]|identity|SERVERID)") {
return (pass);
}
# Do not cache customer french page
if (req.url ~ "/fr/(client|personnaliser|panier)") {
return (pass);
}
# Do not cache customer english page
if (req.url ~ "/en/(customer|personalize|cart)") {
return (pass);
}
# Do not cache checkout
if (req.url ~ "/checkout") {
return (pass);
}
# Normalize the header, remove the port (in case you're testing this on various TCP ports)
set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");
# Remove the proxy header (see https://httpoxy.org/#mitigate-varnish)
unset req.http.proxy;
# Strip hash, server doesn't need it.
if (req.url ~ "\#") {
set req.url = regsub(req.url, "\#.*$", "");
}
# Strip a trailing ? if it exists
if (req.url ~ "\?$") {
set req.url = regsub(req.url, "\?$", "");
}
# Normalize the query arguments
# set req.url = std.querysort(req.url);
# Remove the backend cache parameter for pagination
if (req.url ~ "(\&|\?)_=[0-9]+$") {
set req.url = regsub(req.url, "(\&|\?)_=[0-9]+$", "");
}
# Cache static files
if (req.url ~ "^[^?]*\.(7z|avi|bmp|bz2|css|csv|doc|docx|eot|flac|flv|gif|gz|ico|jpeg|jpg|js|less|mka|mkv|mov|mp3|mp4|mpeg|mpg|odt|otf|ogg|ogm|opus|pdf|png|ppt|pptx|rar|rtf|svg|svgz|swf|tar|tbz|tgz|ttf|txt|txz|wav|webm|webp|woff|woff2|xls|xlsx|xml|xz|zip)(\?.*)?$") {
unset req.http.Cookie;
return (hash);
}
# Mobile Detection set req.http.X-UA-Device
call devicedetect;
# Normalize accept-encoding
if (req.http.Accept-Encoding) {
if (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elsif (req.http.Accept-Encoding ~ "deflate") {
set req.http.Accept-Encoding = "deflate";
} else {
unset req.http.Accept-Encoding;
}
}
# Send Surrogate-Capability headers to announce ESI support to backend
set req.http.Surrogate-Capability = "abc=ESI/1.0";
if (req.http.cookie ~ "id_devise=") {
set req.http.Devise = regsuball(req.http.cookie, "(.*?)(id_devise=[^;]*)(.*)$", "\2");
}
if (req.http.cookie ~ "id_mesure=") {
set req.http.Mesure = regsuball(req.http.cookie, "(.*?)(id_mesure=[^;]*)(.*)$", "\2");
}
# Cache the rest
return (hash);
}
sub vcl_backend_response {
if (bereq.http.X-UA-Device) {
if (!beresp.http.Vary) { # no Vary at all
set beresp.http.Vary = "X-UA-Device";
} elsif (beresp.http.Vary !~ "X-UA-Device") { # add to existing Vary
set beresp.http.Vary = beresp.http.Vary + ", X-UA-Device";
}
}
if (bereq.url ~ "/esi/" || bereq.url ~ "checkout" || bereq.url ~ "/fr/(client|personnaliser)" || bereq.url ~ "/en/(customer|personalize)") {
unset beresp.http.Surrogate-Control;
set beresp.ttl = 0s;
} else {
set beresp.do_esi = true;
set beresp.ttl = 10m;
}
set beresp.grace = 6h;
return (deliver);
}
sub vcl_backend_error {
if (beresp.status == 503) {
set beresp.http.Content-Type = "text/html; charset=utf-8";
synthetic(std.fileread("/home/domain/www/503.html"));
return(deliver);
}
if (beresp.status == 500) {
set beresp.http.Content-Type = "text/html; charset=utf-8";
synthetic(std.fileread("/home/domain/www/500.html"));
return(deliver);
}
}
sub vcl_hash {
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
if (req.http.Devise) {
hash_data(req.http.Devise);
}
if (req.http.Mesure) {
hash_data(req.http.Mesure);
}
if (req.http.X-Requested-With) {
hash_data(req.http.X-Requested-With);
}
hash_data(req.http.cookie);
return (lookup);
}
sub vcl_hit {
if (obj.ttl == 0s) {
return (fetch);
} else if (obj.ttl >= 0s) {
return (deliver);
}
if (!std.healthy(req.backend_hint)) {
# backend is sick - use full grace
if (obj.ttl + obj.grace > 0s) {
return (deliver);
}
}
return (fetch);
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
if ((req.http.X-UA-Device) && (resp.http.Vary)) {
set resp.http.Vary = regsub(resp.http.Vary, "X-UA-Device", "User-Agent");
}
set resp.http.X-Cache-Hits = obj.hits;
unset resp.http.X-Powered-By;
unset resp.http.Server;
unset resp.http.X-Drupal-Cache;
unset resp.http.X-Varnish;
unset resp.http.Via;
unset resp.http.Link;
unset resp.http.X-Generator;
return (deliver);
}
sub vcl_pipe {
set bereq.http.Connection = "Close";
return (pipe);
}
sub vcl_pass {
return (fetch);
}
sub vcl_purge {
# Only handle actual PURGE HTTP methods, everything else is discarded
if (req.method != "PURGE") {
# restart request
set req.http.X-Purge = "Yes";
return(restart);
}
}
sub vcl_synth {
if (resp.status == 720) {
# We use this special error status 720 to force redirects with 301 (permanent) redirects
# To use this, call the following from anywhere in vcl_recv: return (synth(720, "http://host/new.html"));
set resp.http.Location = resp.reason;
set resp.status = 301;
return (deliver);
} elseif (resp.status == 721) {
# And we use error status 721 to force redirects with a 302 (temporary) redirect
# To use this, call the following from anywhere in vcl_recv: return (synth(720, "http://host/new.html"));
set resp.http.Location = resp.reason;
set resp.status = 302;
return (deliver);
}
return (deliver);
}
1) By default Varnish does not cache any responses which set a cookie:
sub vcl_backend_response {
if (beresp.ttl <= 0s ||
beresp.http.Set-Cookie ||
beresp.http.Surrogate-control ~ "no-store" ||
(!beresp.http.Surrogate-Control &&
beresp.http.Cache-Control ~ "no-cache|no-store|private") ||
beresp.http.Vary == "*") {
/*
* Mark as "Hit-For-Pass" for the next 2 minutes
*/
set beresp.ttl = 120s;
set beresp.uncacheable = true;
}
return (deliver);
}
See https://github.com/varnish/Varnish-Cache/blob/4.1/bin/varnishd/builtin.vcl
In your "sub vcl_backend_response" you always "return (deliver);". This means that the Varnish builtin VCL is never executed. Just remove "return (deliver);" from your own "sub vcl_backend_response" and things should get better.
2) Set-Cookie is a respose header and not a request header so this does not make sense to me
# Do not cache when Set-Cookie contain user[id] OR identity OR PHPSESSID OR PHPSERVERID
if (req.http.Set-Cookie ~ "(user\[id\]|identity|SERVERID)") {
return (pass);
}
3) In general you should not always call "return" in your own versions of "vcl_*" as it will always prevent the builtin VCL (with sensible default behaviour) from being executed. For example you should not call "return (hash);" at the end of "vcl_receive". If you did not do this you would not need stuff like
if (req.method != "GET" && req.method != "HEAD") {
return (pass);
}
if (req.http.Authorization) {
return (pass);
}
in your "vcl_receive" because this would also be handled in the builtin version.
4) Also your "sub vcl_hash" looks very dodgy to me. I would never hash on cookies like you do:
hash_data(req.http.cookie);
By default Varnish does not cache any request which has a Cookie - also see the builtin.vcl
if (req.http.Authorization || req.http.Cookie) {
/* Not cacheable by default */
return (pass);
}
That is why normally you remove any Cookies in your own "vcl_receive" for requests you want Varnish to cache, like you do for static files.
So yes - it is a bit of a mess.

Varnish Cache: Rewrite ESI include url if session is active

I'm looking to rewrite an ESI include url in Varnish.
In my template, I have:
<esi:include src="/esi/user.html" />
which just includes static content i.e. "Welcome Guest".
If they login I add the session into my .vcl.
What I want to do is rewrite the include to:
<esi:include src="/esi/user.active.html" />
where I'll do the db query.
Currently, in my sub vcl_recv I have:
if (req.http.Cookie) {
if (req.url ~ "^/esi/(.*)\.html") {
set req.url = regsub("^/esi/(.*)\.html", "$0", ".active");
}
}
It causes a 503 error on the front-end. How would I update this to rewrite the URL and make it work?
Ok, got this working. Here is my .VCL file if anyone's interested
backend default {
.host = "127.0.0.1";
.port = "8080";
}
sub vcl_recv {
if (req.request != "GET" &&
req.request != "HEAD" &&
req.request != "PUT" &&
req.request != "POST" &&
req.request != "TRACE" &&
req.request != "OPTIONS" &&
req.request != "DELETE") {
/* Non-RFC2616 or CONNECT which is weird. */
return (pipe);
}
# Remove cookie for static files
if (req.url ~ "(?i)\.(png|gif|jpeg|jpg|ico|swf|css|js|woff|ttf|eot|svg)(\?[a-zA-Z0-9\=\.\-]+)?$") {
remove req.http.cookie;
}
# Quick hack for now to clear the cache on post
if (req.request == "POST") {
ban("req.http.host == "+ req.http.Host);
return(pass);
}
# If CraftSessionId isn't active, remove cookies altogether
if (req.http.Cookie) {
set req.http.Cookie = ";" + req.http.Cookie;
set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
set req.http.Cookie = regsuball(req.http.Cookie, ";(CraftSessionId)=", "; \1=");
set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
if (req.http.Cookie == "") {
remove req.http.Cookie;
}
}
# If user is logged in/has cookies enabled, rewrite esi files to include *.active.html
if (req.http.cookie ~ "CraftSessionId=") {
if (req.url ~ "^/esi") {
set req.url = regsub(req.url, "^/esi/(.*).html", "/esi/\1-active.html");
}
}
# Grace period for falldown
set req.grace = 1h;
}
sub vcl_fetch {
set beresp.ttl = 24h; # Make cache last 24 hours
# Allow cookies in admin and account areas
if (req.url !~ "(admin/login|account/login|account/register)") {
unset beresp.http.set-cookie;
}
set beresp.do_gzip = true;
set beresp.do_esi = true; # Allow ESI
# Grace period for falldown
set beresp.grace = 1h;
}

Can someone tell me how to fix this Varnish error please?

Here's the error I get:
Message from VCC-compiler:
Unterminated string at
(input Line 39 Pos 19)
if (req.url ~ "^/[^?]+.(jpeg|jpg|png|gif|ico|js|css|txt|gz|
------------------#############################################
Running VCC-compiler failed, exit 1
VCL compilation failed
and here's the default.vcl
backend default {
.host = "localhost";
.port = "8080";
}
acl purge {
"localhost";
}
sub vcl_recv {
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
return(lookup);
}
if (req.url ~ "^/$") {
unset req.http.cookie;
}
}
sub vcl_hit {
if (req.request == "PURGE") {
set obj.ttl = 0s;
error 200 "Purged.";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
error 404 "Not in cache.";
}
if (!(req.url ~ "wp-(login|admin)")) {
unset req.http.cookie;
}
if (req.url ~ "^/[^?]+.(jpeg|jpg|png|gif|ico|js|css|txt|gz|
zip|lzma|bz2|tgz|tbz|html|htm)(\?.|)$") {
unset req.http.cookie;
set req.url = regsub(req.url, "\?.$", "");
}
if (req.url ~ "^/$") {
unset req.http.cookie;
}
}
sub vcl_fetch {
if (req.url ~ "^/$") {
unset beresp.http.set-cookie;
}
if (!(req.url ~ "wp-(login|admin)")) {
unset beresp.http.set-cookie;
}
}
Um, obviously you can't have a line break in the middle of the string. Move the tail end of the string up to the line it starts on, or have two different strings and concatenate them with +.
If you want a long string you can use {" Hello
World
I'm long"}

Resources