Varnish Request Url was not the same with apache request - varnish

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;
}

Related

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 configuration (always MISS)

I had this working at one point, but now it is broke again (may be because of some code changes in php), but default.vcl hasn't changed.
varnish version is
varnishd (varnish-3.0.7 revision f544cd8)
Copyright (c) 2006 Verdens Gang AS
Copyright (c) 2006-2014 Varnish Software AS
here are some rules that i want varnish to follow
I need varnish to cache all pages and remove php session or any other cookies except when there is a special cookie "sh_loggedin" present
/social-signup should be pass because it creates above cookie when user logs in
/content should be pass because that is admin area
add HIT / MISS or counter related things to header so i know if varnish is working
ignore all cache control or age headers, and make sure varnish HITS everything except when "sh_loggedin" cookie present
js,css,images, etc should be always served by varnish regardless
allow google analytics tracking to work
Here is what it looks like
backend default {
.host = "127.0.0.1";
.port = "8080";
.connect_timeout = 600s;
.first_byte_timeout = 600s;
.between_bytes_timeout = 600s;
}
acl purge {
"localhost";
"127.0.0.1";
}
sub vcl_recv {
if(req.url ~ "/social-signup") {
return (pass);
}
if(req.url ~ "/scripts") {
return (pass);
}
if(req.url ~ "/content") {
return (pass);
}
if(req.url ~ "/api") {
return (pass);
}
// Remove has_js and Google Analytics __* cookies.
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-z]+|has_js)=[^;]*", "");
// Remove a ";" prefix, if present.
set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
if (!req.backend.healthy) {
unset req.http.Cookie;
}
if (req.request == "GET" && req.url ~ "^/varnishcheck$") {
error 200 "Varnish is Ready";
}
if(req.url ~ "/blog") {
return (pass);
}
if (req.request != "GET" &&
req.request != "HEAD" &&
req.request != "PUT" &&
req.request != "POST" &&
req.request != "TRACE" &&
req.request != "OPTIONS" &&
req.request != "PURGE" &&
req.request != "DELETE") {
# Non-RFC2616 or CONNECT which is weird.
return (pipe);
}
# We only deal with GET, PURGE and HEAD by default.
if (req.request != "GET" && req.request != "HEAD" && req.request != "PURGE") {
return (pass);
}
# --- PURGE ---
if (req.request == "PURGE") {
# Check if the ip coresponds with the acl purge
if (!client.ip ~ purge) {
# Return error code 405 (Forbidden) when not
error 405 "Not allowed.";
}
return (lookup);
}
# --- PASSTHROUGH ---
# Always cache things with these extensions.
if (req.url ~ "\.(js|css|jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf)$") {
unset req.http.cookie;
return (lookup);
}
if(req.url ~ "/scripts") {
return (pass);
}
if(req.url ~ "/api") {
return (pass);
}
# Skip the Varnish cache for install, update, and cron.
if (req.url ~ "install\.php|update\.php|cron\.php") {
return (pass);
}
# Pass server-status.
if (req.url ~ ".*/server-status$") {
return (pass);
}
# Support for Pressflow Cookie-Cache Bypass.
if (req.http.cookie ~ "NO_CACHE") {
return (pass);
}
# Force lookup if the request is a no-cache request from the client.
if (req.http.Cache-Control ~ "no-cache") {
return (pass);
}
# Don't check cache if Drupal SESSION is set.
if (req.http.cookie ~ "SESS") {
return (pass);
}
# We "hide" the non-session cookies.
if (req.http.cookie) {
set req.http.X-Varnish-Cookie = req.http.cookie;
unset req.http.cookie;
}
# --- MISC ---
# Normalize the Accept-Encoding header
# as per: http://varnish-cache.org/wiki/FAQ/Compression
if (req.http.Accept-Encoding) {
if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
# No point in compressing these.
unset req.http.Accept-Encoding;
}
else if (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
}
else if (req.http.Accept-Encoding ~ "deflate") {
# Next, try deflate if it is supported.
set req.http.Accept-Encoding = "deflate";
}
else {
# Unknown or deflate algorithm.
unset req.http.Accept-Encoding;
}
}
# Let's have a little grace.
set req.grace = 5m;
return (lookup);
}
sub vcl_hash {
if (req.http.cookie) {
hash_data(req.http.cookie);
}
}
# Strip any cookies before an image/js/css is inserted into cache.
sub vcl_fetch {
remove beresp.http.Cache-Control;
remove beresp.http.Age;
set beresp.http.Age = "10";
set beresp.http.Cache-Control = "public";
set beresp.grace = 5m;
# These status codes should always pass through and never cache.
if (beresp.status == 503 || beresp.status == 500) {
set beresp.http.X-Cacheable = "NO: obj.status";
set beresp.http.X-Cacheable-status = beresp.status;
return (hit_for_pass);
}
if (req.url ~ "\.(js|css|jpg|jpeg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf)(\?[a-z0-9]+)?$") {
unset beresp.http.set-cookie;
}
else if (beresp.http.Cache-Control) {
unset beresp.http.Expires;
}
if(req.url !~ "/content") {
unset beresp.http.Expires;
}
if (bereq.http.Cookie !~ "__sh_loggedin__") {
unset bereq.http.Cookie;
unset beresp.http.Set-Cookie;
}
if (beresp.status == 301) {
set beresp.ttl = 1h;
return(deliver);
}
# All tests passed, therefore item is cacheable
set beresp.http.X-Cacheable = "YES";
}
# Set a header to track a cache HIT/MISS.
sub vcl_deliver {
set resp.http.cache-control = "max-age = 3600";
set resp.http.Age = "10";
if (obj.hits > 0) {
set resp.http.X-Varnish-Cache = "HIT";
set resp.http.X-Varnish-Hits = obj.hits;
}
else {
set resp.http.X-Varnish-Cache = "MISS";
}
# Set a header to track the webhead.
set resp.http.X-Varnish-IP = server.ip;
}
sub vcl_hit {
if (req.request == "PURGE") {
purge;
error 200 "Purged.";
}
}
sub vcl_miss {
if (req.http.X-Varnish-Cookie) {
set bereq.http.cookie = req.http.X-Varnish-Cookie;
unset bereq.http.X-Varnish-Cookie;
}
if (req.request == "PURGE") {
purge;
error 200 "Purged.";
}
}
sub vcl_error {
set obj.http.Content-Type = "text/html; charset=utf-8";
if (obj.status == 401) {
# Prompt for password.
set obj.http.WWW-Authenticate = "Basic realm=Secured";
}
synthetic {"
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>"} + obj.status + " " + obj.response + {"</title>
</head>
<body>
<div id="page">
<h1>Page Could Not Be Loaded</h1>
<p>We're very sorry, but the page could not be loaded properly. This should be fixed very soon, and we apologize for any inconvenience.</p>
<hr />
<h4>Debug Info:</h4>
<pre>Status: "} + obj.status + {"
Response: "} + obj.response + {"
XID: "} + req.xid + {"</pre>
</div>
</body>
</html>
"};
return (deliver);
}
http://www.isvarnishworking.com/ says, my site is properly served by varnish, but i know it is not, because HIT counter does not show up and logs don't say so too.
here is the response I am getting
HTTP/1.1 200 OK
Accept-Ranges: bytes
Age: 10
cache-control: max-age = 3600
Content-Encoding: gzip
Content-Type: text/html; charset=UTF-8
Date: Thu, 18 Aug 2016 23:29:25 GMT
Server: Apache/2.4.23 (Amazon) OpenSSL/1.0.1k-fips PHP/5.6.24
Vary: Accept-Encoding,User-Agent
Via: 1.1 varnish
X-Cacheable: YES
X-Content-Type-Options: nosniff
X-Frame-Options: GOFORIT
X-Varnish: 1595154742
X-Varnish-Cache: MISS
X-Varnish-IP: 172.31.41.246
X-XSS-Protection: 1; mode=block
Connection: keep-alive
The age value in response header is greater than zero that implies you are getting cached response. Otherwise it would be zero.
As i think you have defined the Age header in the VCL configuration, that's why we are getting it in the response header.
Please correct me if i am wrong

Varnish cookie issue with mantis bug tracker

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?

Varnish frontend server, Litespeed backend server

I wonder if someone could advise what I'm doing wrong.
I have Varnish set up on a frontend server, and this is working. I can put the IP address for several public websites into this (including CNN) into the configuration, and they are cached by Varnish.
When I put one of my site IP address' into Varnish, I get a 404 error back from the Litespeed server - this shows it's connecting to the server, but obviously not picking up the correct site to show Varnish. I have several domains on the Litespeed server, each with it's own IP address. The same happens with the direct URL.
This is I guess a problem with the Litespeed configuration - but any assistance would be appreciated.
For reference, I'm using the VCL configuration file for PageCache, which is a Magento module for Varnish.
Justin
# default backend definition. Set this to point to your content server.
backend default {
.host = "xxx.xxx.xxx.xxx";
.port = "80";
}
# admin backend with longer timeout.
backend admin {
.host = "xxx.xxx.xxx.xxx";
.port = "80";
.first_byte_timeout = 18000s;
.between_bytes_timeout = 18000s;
}
# add your Magento server IP to allow purges from the backend
acl purge {
"localhost";
"127.0.0.1";
}
sub vcl_recv {
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;
}
}
if (req.request != "GET" &&
req.request != "HEAD" &&
req.request != "PUT" &&
req.request != "POST" &&
req.request != "TRACE" &&
req.request != "OPTIONS" &&
req.request != "DELETE" &&
req.request != "PURGE") {
/* Non-RFC2616 or CONNECT which is weird. */
return (pipe);
}
# purge request
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
ban("obj.http.X-Purge-Host ~ " + req.http.X-Purge-Host + " && obj.http.X-Purge-URL ~ " + req.http.X-Purge-Regex + " && obj.http.Content-Type ~ " + req.http.X-Purge-Content-Type);
error 200 "Purged.";
}
# switch to admin backend configuration
if (req.http.cookie ~ "adminhtml=") {
set req.backend = admin;
}
# we only deal with GET and HEAD by default
if (req.request != "GET" && req.request != "HEAD") {
return (pass);
}
# normalize url in case of leading HTTP scheme and domain
set req.url = regsub(req.url, "^http[s]?://[^/]+", "");
# static files are always cacheable. remove SSL flag and cookie
if (req.url ~ "^/(media|js|skin)/.*\.(png|jpg|jpeg|gif|css|js|swf|ico)$") {
unset req.http.Https;
unset req.http.Cookie;
}
# not cacheable by default
if (req.http.Authorization || req.http.Https) {
return (pass);
}
# do not cache any page from
# - index files
# - ...
if (req.url ~ "^/(index)") {
return (pass);
}
# as soon as we have a NO_CACHE cookie pass request
if (req.http.cookie ~ "NO_CACHE=") {
return (pass);
}
# normalize Aceept-Encoding header
# http://varnish.projects.linpro.no/wiki/FAQ/Compression
if (req.http.Accept-Encoding) {
if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg|swf|flv)$") {
# No point in compressing these
remove req.http.Accept-Encoding;
} elsif (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elsif (req.http.Accept-Encoding ~ "deflate" && req.http.user-agent !~ "MSIE") {
set req.http.Accept-Encoding = "deflate";
} else {
# unkown algorithm
remove req.http.Accept-Encoding;
}
}
# remove Google gclid parameters
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"
return (lookup);
}
sub vcl_hash {
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
if (!(req.url ~ "^/(media|js|skin)/.*\.(png|jpg|jpeg|gif|css|js|swf|ico)$")) {
call design_exception;
}
return (hash);
}
sub vcl_fetch {
if (beresp.status == 500) {
set beresp.saintmode = 10s;
return (restart);
}
set beresp.grace = 5m;
# add ban-lurker tags to object
set beresp.http.X-Purge-URL = req.url;
set beresp.http.X-Purge-Host = req.http.host;
if (beresp.status == 200 || beresp.status == 301 || beresp.status == 404) {
if (beresp.http.Content-Type ~ "text/html" || beresp.http.Content-Type ~ "text/xml") {
if ((beresp.http.Set-Cookie ~ "NO_CACHE=") || (beresp.ttl < 1s)) {
set beresp.ttl = 0s;
return (hit_for_pass);
}
# marker for vcl_deliver to reset Age:
set beresp.http.magicmarker = "1";
# Don't cache cookies
unset beresp.http.set-cookie;
} else {
# set default TTL value for static content
set beresp.ttl = 4h;
}
return (deliver);
}
return (hit_for_pass);
}
sub vcl_deliver {
# debug info
if (resp.http.X-Cache-Debug) {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
set resp.http.X-Cache-Hits = obj.hits;
} else {
set resp.http.X-Cache = "MISS";
}
set resp.http.X-Cache-Expires = resp.http.Expires;
} else {
# remove Varnish/proxy header
remove resp.http.X-Varnish;
remove resp.http.Via;
remove resp.http.Age;
remove resp.http.X-Purge-URL;
remove resp.http.X-Purge-Host;
}
if (resp.http.magicmarker) {
# Remove the magic marker
unset resp.http.magicmarker;
set resp.http.Cache-Control = "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
set resp.http.Pragma = "no-cache";
set resp.http.Expires = "Mon, 31 Mar 2008 10:00:00 GMT";
set resp.http.Age = "0";
}
}
sub design_exception {
}
And...
START=yes
NFILES=131072
MEMLOCK=82000
INSTANCE=$(uname -n)
## Alternative 2, Configuration with VCL
#
# Listen on port 6080, administration on localhost:6082, and forward to
# one content server selected by the vcl file, based on the request. Use a 1GB
# fixed-size cache file.
DAEMON_OPTS="-a :80 \
-T localhost:6082 \
-f /etc/varnish/default.vcl \
-S /etc/varnish/secret \
-s malloc,256m"
To what port is your Varnish server bound? And what port do you use for Litespeed?
It would be useful if you could post your config files here to give you further advices.
This is what I needed! Configure multiple sites with Varnish
I needed to put the virtual host names into the configuration file. Followed this guide and had it work in moments!

Resources