I am trying to do reverse proxy caching for a wordpress blog and I am hit with snags.
The initial configuration was a simple reverse caching like this
location / {
proxy_cache_key "$scheme://$host$request_uri";
proxy_cache staticfilecache;
proxy_pass http://wordpressapache;
add_header Cache-Control public;
proxy_cache_valid 200 302 10d;
I quickly realized that logged in users will be sent for a toss with and so I did
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Accept-Encoding "";
location / {
# If logged in, don't cache.
if ($http_cookie ~* "comment_author_|wordpress_(?!test_cookie)|wp-postpass_" ) {
set $do_not_cache 1;
}
proxy_cache_key "$scheme://$host$request_uri $do_not_cache";
proxy_cache staticfilecache;
proxy_pass http://wordpressapache;
add_header Cache-Control public;
proxy_cache_valid 200 302 10d;
}
But this didn’t work since Nginx 1.0+ does not cache responses that has Set-Cookie. To my surprise even all anonymous user hits result in Set-Cookie
. An example below.
Now I can’t do a
proxy_ignore_headers "Set-Cookie";
proxy_hide_header "Set-Cookie";
since this will also not pass cookies for logged in users. I did something like this
location ~* wp\-.*\.php|wp\-admin {
proxy_pass http://wordpressapache;
}
But then the logged in users will also come back to the blog page and their cookies will be rejected.
One other way is to do something like this through plugin and send X-Accel-Expires.
function add_xaccel_header() {
# Set the X-Accel-Expires header to never cache the page if it looks like the page needs to be tailored for a user.
$user_cookie_there = false;
foreach($_COOKIE as $key => $value){
if( preg_match('/wordpress_(?!test_cookie)|comment_author|wp-postpass/', $key) ){
$user_cookie_there = true;
}
}
if($user_cookie_there){
header("X-Accel-Expires: 0");
}
}
add_action('init','add_xaccel_header');
But then the hide cookie is creating issues. Removing hide cookie breaks the caching too.
What’s a good strategy to cache pages for anonymous users using Nginx that can be invalidated by logged-in users. Perhaps using proxy_cache_bypass
?