I have a WordPress site that uses WPTouch Pro for Mobile. I have a nginx server with varnish cache. The problem is I can’t get Varnish WPTouch Pro and WordPress to work nice together. There are a lot of solutions on the Web, but nothing has worked. The attached default.vcl is the closest I’ve been able to come. Varnish appears to be caching for both desktop an mobile sites and both display properly. But now WordPress doesn’t work properly. I can’t save posts, can’t show preview pages and difficulty logging in. Varnish appears to be caching the admin pages. I know there is a simple solution. Please help me find it. Here’s the vcl
# Set the default backend (Nginx server for me)
backend default {
.host = "127.0.0.1";
.port = "8080";
.connect_timeout = 600s;
.first_byte_timeout = 1200s;
.between_bytes_timeout = 600s;
.max_connections = 2800;
}
# Purge ACL
acl purge {
"localhost";
}
# This function is used when a request is send by a HTTP client (Browser)
# !!! Replace: blog.nicolargo.com by your own URL !!!
sub vcl_recv {
set req.grace = 10m;
call detect_device;
# Set X-Forwarded-For header for logging in nginx
remove req.http.X-Forwarded-For;
set req.http.X-Forwarded-For = client.ip;
# Allow purging from ACL
if (req.request == "PURGE") {
# If not allowed then a error 405 is returned
if (!client.ip ~ purge) {
error 405 "This IP is not allowed to send PURGE requests.";
}
# If allowed, do a cache_lookup -> vlc_hit() or vlc_miss()
return (lookup);
}
# Post requests will not be cached
if (req.request == "POST") {
return (pass);
}
# --- WordPress specific configuration
# Did not cache the RSS feed
if (req.url ~ "/feed") {
return (pass);
}
# Did not cache the admin and login pages
if (req.url ~ "/wp-(login|admin)") {
return (pass);
}
// server1 must handle file uploads
if (req.url ~ "media-upload.php" || req.url ~ "file.php" || req.url ~ "async-upload.php") {
return(pass);
}
// do not cache xmlrpc.php
if (req.url ~ "xmlrpc.php") {
return(pass);
}
// strip cookies from xmlrpc
if (req.request == "GET" && req.url ~ "xmlrpc.php"){
remove req.http.cookie;return(pass);
}
# Remove the "has_js" cookie
set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", "");
# Remove any Google Analytics based cookies
set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", "");
# Remove the Quant Capital cookies (added by some plugin, all __qca)
set req.http.Cookie = regsuball(req.http.Cookie, "__qc.=[^;]+(; )?", "");
# Remove the wp-settings-1 cookie
set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-1=[^;]+(; )?", "");
# Remove the wp-settings-time-1 cookie
set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-time-1=[^;]+(; )?", "");
# Remove the wp test cookie
set req.http.Cookie = regsuball(req.http.Cookie, "wordpress_test_cookie=[^;]+(; )?", "");
# Are there cookies left with only spaces or that are empty?
if (req.http.cookie ~ "^ *$") {
unset req.http.cookie;
}
if (req.http.Accept-Encoding) {
# Do no compress compressed files...
if (req.url ~ ".(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
remove req.http.Accept-Encoding;
} elsif (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elsif (req.http.Accept-Encoding ~ "deflate") {
set req.http.Accept-Encoding = "deflate";
} else {
remove req.http.Accept-Encoding;
}
}
# Cache the following files extensions
if (req.url ~ ".(css|js|png|gif|jp(e)?g)") {
unset req.http.cookie;
}
# Check the cookies for wordpress-specific items
if (req.http.Cookie ~ "wordpress_" || req.http.Cookie ~ "comment_") {
return (pass);
}
if (!req.http.cookie) {
unset req.http.cookie;
}
# --- End of WordPress specific configuration
# Did not cache HTTP authentication and HTTP Cookie
if (req.http.Authorization || req.http.Cookie) {
# Not cacheable by default
return (pass);
}
# Cache all others requests
return (lookup);
}
sub vcl_pipe {
return (pipe);
}
sub vcl_pass {
return (pass);
}
# The data on which the hashing will take place
sub vcl_hash {
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
# ensure separate cache for mobile clients (WPTouch workaround)
if (req.http.X-Device ~ "smart" || req.http.X-Device ~ "other") {
hash_data(req.http.X-Device);
}
# If the client supports compression, keep that in a different cache
if (req.http.Accept-Encoding) {
hash_data(req.http.Accept-Encoding);
}
return (hash);
}
sub detect_device {
# Define the desktop device and ipad
set req.http.X-Device = "desktop";
if (req.http.User-Agent ~ "iP(hone|od)" || req.http.User-Agent ~ "Android" ) {
# Define smartphones and tablets
set req.http.X-Device = "smart";
}
elseif (req.http.User-Agent ~ "SymbianOS" || req.http.User-Agent ~ "^BlackBerry" || req.http.User-Agent ~ "^SonyEricsson" || req.http.User-Agent ~ "^Nokia" || req.http.User-Agent ~ "^SAMSUNG" || req.http.User-Agent ~ "^LG") {
# Define every other mobile device
set req.http.X-Device = "other";
}
# Try a cache-lookup
return (lookup);
}
sub vcl_fetch {
#set obj.grace = 5m;
set beresp.grace = 2m;
}
sub vcl_hit {
if (req.request == "PURGE") {
purge;
error 200 "Purged.";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
purge;
error 200 "Purged.";
}
}
# Drop any cookies sent to WordPress.
sub vcl_recv {
if (!(req.url ~ "wp-(login|admin)")) {
unset req.http.cookie;
}
}
# Drop any cookies WordPress tries to send back to the client.
sub vcl_fetch {
if (!(req.url ~ "wp-(login|admin)")) {
unset beresp.http.set-cookie;
}
}
You need to pass content containing the wordpress logged in cookie.
In your sub vcl_recv
Full working vcl for WordPress to use hash_always_miss is here which you may find userful