Modules that break caching, and how to fix them

Admin (v. 2.0)

Problem

Adds a DrupalAdminToolbar cookie that is needed server-side to prevent "slow load JS flicker"

Solution

Most users won't have access to the admin toolbar, so this is probably a moot point

More Info

See this exchange with module's maintainer, yhahn, on #open-atrium:

<yhahn>

EvanDonovan: it is checked server side for rather trivial stuff

<EvanDonovan>

yhahn: if it were not present would that be bad.

<yhahn>

well not trivial but I believe you could exclude it if it is an issue

<yhahn>

it basically sets the initial css classes for the toolbar/body

<EvanDonovan>

b/c if i strip it in Varnish VCL then it won't be there

<EvanDonovan>

ah ok

<EvanDonovan>

i was hoping that would only happen client-side

<yhahn>

it's there to prevent slow-load js flicker

<EvanDonovan>

i will not strip it if the server-side checks are done in the theming layer

<EvanDonovan>

yeah, that makes sense

<EvanDonovan>

i will keep it then

<EvanDonovan>

most of the time it will be moot point

<yhahn>

cools

<EvanDonovan>

b/c most users with access to admin toolbar will not be anonymous

Autologout

Problem

Adds a "autologout_hits" cookie to anonymous pages.

Solutions

Disable the module

(Question: is this cookie necessary server-side? If not, then it could be stripped out in vcl_recv, without disabling the module.)

CiviCRM

Problem

Adds an empty $_SESSION["CiviCRM"] to many types of pages, which creates a session cookie unnecessarily. Two hooks that this happens for are: hook_user() and hook_block().

Solution

In civicrm/drupal/civicrm.module:

Change the bottom of the civicrm_initialize() function to the following:

        // fix needed for Pressflow lazy session initialization -
        // if $_SESSION['CiviCRM'] is empty, unset it
        if(empty($_SESSION['CiviCRM'])) {
           unset($_SESSION['CiviCRM']); }
        return true;

This will ensure that the CiviCRM session variable is only set as needed, and keep other pages cacheable by an external system.

As yet untested solution (from dlobo in #civicrm):

In civicrm/CRM/Core/Session.php:

Remove the $this->create(); line from the session's constructor function. Following patch is pasted from IRC and may need modification to apply. If so, please update this listing. Also, update if this works, so it can become the recommended solution.

svn diff CRM/Core/Session.php
Index: CRM/Core/Session.php
===================================================================
--- CRM/Core/Session.php (revision 26441)
+++ CRM/Core/Session.php (working copy)
@@ -84,8 +84,6 @@
function __construct()
{
$this->_session =& $_SESSION;
- $this->create();
}

Collapsiblock

Problem

Sets a cookie that is only needed on client-side.

Solution

Varnish

Modify the line that strips out cookies in vcl_recv:

 // Remove has_js and Google Analytics __* cookies. Also remove collapsiblock cookies.
  set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(__[a-z]+|__utma_a2a|has_js|collapsiblock)=[^;]*", "");

Global Redirect

Problem

When Global Redirect is enabled, http://www.example.com/node?page=X will always receive a 301 Moved Permanently.

Solutions

Varnish

Add the following to vcl_recv

if (req.url ~ "node\?page=[0-9]+$") {
         set req.url = regsub(req.url, "node(\?page=[0-9]+$)", "\1");
         return (lookup);
     }

Masquerade

Problem

Masquerade will start a $_SESSION value on every pageload in hook_init, thus creating a session cookie and breaking caching.

Solutions

Patch/Fix for Module

http://drupal.org/node/908194

This patch was applied to version 6.x-1.7.

mobile_tools

Problem

Mobile_tools will add to the = $_SESSION value on every pageload, thus creating a session cookie and breaking caching.

Solutions

Do it in Varnish

I have not done this yet, but here are examples:

http://www.varnish-cache.org/trac/wiki/VCLExampleRedirectInVCL

http://www.varnish-cache.org/trac/wiki/VCLExampleHostnameRemapping

The mobile_tools PHP code has a much more complete regex of mobile user agents, that should probably be copied into any vcl solution.