Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

different rule evaluation order for cookie defined cache groups -> wrong content served #800

Open
aheinzel opened this issue Jan 14, 2024 · 0 comments

Comments

@aheinzel
Copy link

Description

Rules for cookie defined cache groups are evaluated differently in PgCache_ContentGrabber.php and the .htaccess file. If two or more cookies belonging to different cache groups are present on a request the cache group assigned during caching and when serving from cache do not match. This causes the cached page to be missed by the apache rewrite rules requiring a partial load of the WordPress instance before the cached file can be delivered. In the worst case this can also result in the wrong content being delivered from cache.

Test case

Cookie defined cache groups

Two active cookie defined cache groups named cookie1a and cookie2b, relevant part from config
cat master.php | awk '{if(NR == 1){sub(/[^>]+>/, ""); print $0}else{print $0}}' | jq '.["pgcache.cookiegrou ps.groups"]'

{
  "mobile": {
    "enabled": false,
    "cache": true,
    "cookies": [
      "wptouch-pro-cache-state=mobile",
      "wptouch-pro-view=mobile"
    ]
  },
  "loggedin": {
    "enabled": false,
    "cache": false,
    "cookies": [
      "wordpress_logged_in_.*"
    ]
  },
  "subscribers": {
    "enabled": false,
    "cache": true,
    "cookies": [
      "role=member",
      "role=subscriber"
    ]
  },
  "cookie1a": {
    "enabled": true,
    "cache": true,
    "cookies": [
      "cookie1=a"
    ]
  },
  "cookie2b": {
    "enabled": true,
    "cache": true,
    "cookies": [
      "cookie2=b"
    ]
  }
}

Wordpress test content

A callback registered on the WordPress wp_footer hook adding a comment with the values of cookie1 and cookies2 to the page source (format: new{cookie1Value}::{cookie2Value}).

add_action('wp_footer', function(){
	echo "<!--\n" . date("H:i:s") . " cookies: " . $_COOKIE['cookie1'] . "::" . $_COOKIE['cookie2'] . "\n-->\n";
});

Error log stmt in index.php

A php error_log call in the index.php file writing the string in index.php to the system error log when index.php is invoked.

Requests

Sequence of requests to simulate the problem. Caches have been purged before. Shown are the requests together with the observed response.

$ date && curl -s http://w3.test.local/test2/ -b "cookie1=a;cookie2=b" | grep -A 1 -B 1 "cookies"
Sun 14 Jan 2024 04:51:03 PM CET
<!--
15:51:04 cookies: a::b
-->

#page has been cached but cached file is not found by apache rewrite rules, see index.php is accessed
$ tail -n 0 -f error.log | grep -F "index.php" &
...
$ curl -s http://w3.test.local/test2/ -b "cookie1=a;cookie2=b" | grep -A 1 -B 1 "cookies"
... AH01071: Got error 'PHP message: in index.phpPHP message: from cache'
<!--
15:51:04 cookies: a::b
-->
$ pkill -P $$

#new request with cookie2 only - will be cached for cache group cookie2b
$ curl -s http://w3.test.local/test2/ -b "cookie2=b" | grep -A 1 -B 1 "cookies"
<!--
15:53:50 cookies: ::b
-->

#again request with both cookie1 and cookie2 - request should be served from cache group cookie1a but is served content from cache group cookie2b
$ curl -s http://w3.test.local/test2/ -b "cookie1=a;cookie2=b" | grep -A 1 -B 1 "cookies"
<!--
15:53:50 cookies: ::b
-->

Expected behaviour

Cached content is directly served via apache without the need for php, Cached content from the requests cache group is served to the client.

Actual behaviour

Request is dispatched to PHP before the cached content is served. Cached content from the wrong cache group is served to the client.

Environment

  • Apache: 2.4.38 (Debian)
  • W3 Total Cache: 2.6.1
    • cache mode: disk enhanced
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant