Skip to content

Usage Examples

Here are some examples for how to set rewrite rules and response headers for particular situations.

Cache Everything for 2 Minutes

<IfModule LiteSpeed>
  RewriteEngine On
  RewriteRule cacheablefolder/(.*\.php)?$ - [E=cache-control:max-age=120]
</IfModule>

Note

These rules only cache *.php files in the cacheablefolder directory. It is good practice to be specific, and cache only the files that are supposed to be cached.

Cache Pages With a Certain Signature

These two examples demonstrate how LSCache rewrite rules fit into an application's existing rewrite rules.

Public Cache Example

The second part of the ruleset is from the web application. Essentially everything goes through index.php (the web app framework) to process.

Note

%{ORG_REQ_URI} is a LiteSpeed-specific variable. In this example, it keeps the value of %{REQUEST_URI} prior to the rewrite to index.php.

# this part is for public cache.
<IfModule LiteSpeed>
RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^HEAD|GET$
RewriteCond %{HTTP_COOKIE} !cookiename   ## cookiename needs to be replaced by real cookie name  
RewriteCond %{ORG_REQ_URI} !^/administrator
RewriteRule .* - [E=Cache-Control:max-age=300]
</IfModule>

#application orgiginal rewite rules
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/index\.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php [L]

The first part of the ruleset indicates that LSWS only caches requests if:

  • They are HEAD or GET type requests AND
  • They don't contain cookiename in the HTTP_COOKIE AND
  • %{ORG_REQ_URI} does not start with /administrator/

Also:

  • The TTL of the cache is set to 300 seconds (5 minutes).

Private Cache Example

# this part is for private cache, note that HTTP_COOKIE is for loginuser
<IfModule LiteSpeed>
RewriteCond %{REQUEST_METHOD} ^HEAD|GET$
RewriteCond %{HTTP_COOKIE} loginuser
RewriteCond %{ORG_REQ_URI} !^/index\.php$
# there is no need to exclude admin area. it can be privately cached.
# RewriteCond %{ORG_REQ_URI} !^/administrator/
RewriteRule .* - [E=Cache-Control:private]
</IfModule>

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{REQUEST_URI} (/|\.php|\.html|\.htm|\.feed|\.pdf|\.raw|/[^.]*)$  [NC]
RewriteRule (.*) index.php [L]

This ruleset indicates that LSWS only privately caches requests if:

  • They are HEAD or GET type requests AND
  • They do contain loginuser in the HTTP_COOKIE AND
  • %{ORG_REQ_URI} is not /index.php AND
  • %{ORG_REQ_URI} ends with .php or .html or .htm , etc.

Also:

  • The TTL is set to whatever is the default in the private cache policy

Cache Mobile View Separately

If your web app produces a mobile view that has different HTML than the desktop view, you will want to set up a cache vary based on user agent. In this example, we set the vary value to cache the mobile view separately. We also exclude some folders from cache, and cache everything else for two minutes (120 seconds).

<IfModule LiteSpeed>
RewriteEngine On
CacheDisable public /
RewriteCond %{HTTP_USER_AGENT} "iPhone|iPod|BlackBerry|Palm|Mobile|Opera Mini|Fennec|Windows Phone"
RewriteRule .* - [E=Cache-Control:vary=ismobile]
RewriteCond %{REQUEST_METHOD} ^HEAD|PURGE|GET$
RewriteCond %{ORG_REQ_URI} !/news
RewriteCond %{ORG_REQ_URI} !/admincp
RewriteRule .* - [E=Cache-Control:max-age=120]
</IfModule>

Set up Cache Varies for Desktop, Mobile, and Tablet

You can use the user agent to create three cache varies. We'll call them Phone, Tablet, and Desktop

For these purposes, we'll assume user agents that include Android or iPad are tablets , iPhone or Mobile are phones, and everything else is a desktop. This is a simple solution but it should cover most cases. The rules can be further extended to match more specific cases, if you need them.

PHP Code

Save the following as test.php on your server:

if (stripos($_SERVER['HTTP_USER_AGENT'],"iPhone")!==false || stripos($_SERVER['HTTP_USER_AGENT'],"Mobile")!==false ) 
{
    echo 'This is Phone view'; 
}
elseif (stripos($_SERVER['HTTP_USER_AGENT'],"iPad")!==false or stripos($_SERVER['HTTP_USER_AGENT'],"Android") !==false) 
{
    echo 'This is Tablet view'; 
}
else 
{
    echo 'this is Desktop view'; 
}

.htaccess code

Add these rules to .htaccess:

CacheLookup public on
RewriteRule .* - [E=cache-control:max-age=120]

RewriteCond %{HTTP_USER_AGENT} iPad|Android [NC]
RewriteRule .* - [E=Cache-Control:vary=istablet]

RewriteCond %{HTTP_USER_AGENT} iPhone|Mobile [NC]
RewriteRule .* - [E=Cache-Control:vary=isphone]
The first rule will cache every page for 120 seconds.

The second rule will check the user agent. If it contains the keyword iPad or Android it will set vary to istablet. If the user agent ALSO contains the keyword Mobile though, such as from an Android Mobile device, it will set vary to isphone instead of istablet. All other user agents are treated as desktop.

Testing

Use curl to visit the test.php and simulate different user agents for testing. From the output, you will see that the correct versions of the page for each user agent are retrieved from cache.

Testing Tablet view with "Android":

curl https://example.com/test.php -i -H "User-Agent: Android"
HTTP/1.1 200 OK
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
Etag: "62-1566258748;;;"
X-Litespeed-Cache: hit
Content-Length: 19
Date: Mon, 19 Aug 2019 23:52:28 GMT
Server: LiteSpeed
Alt-Svc: quic=":443"; ma=2592000; v="39,43,46", h3-22=":443"; ma=2592000

This is Tablet view

Testing Phone view with "Android Mobile":

curl https://example.com/test.php -i -H "User-Agent: Android Mobile"
HTTP/1.1 200 OK
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
Etag: "63-1566258751;;;"
X-Litespeed-Cache: hit
Content-Length: 19
Date: Mon, 19 Aug 2019 23:52:31 GMT
Server: LiteSpeed
Alt-Svc: quic=":443"; ma=2592000; v="39,43,46", h3-22=":443"; ma=2592000

This is Phone view

Testing Desktop view with "Windows":

curl https://example.com/test.php -i -H "User-Agent: Windows"
HTTP/1.1 200 OK
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
Etag: "64-1566258765;;;"
X-Litespeed-Cache: hit
Content-Length: 20
Date: Mon, 19 Aug 2019 23:52:45 GMT
Server: LiteSpeed
Alt-Svc: quic=":443"; ma=2592000; v="39,43,46", h3-22=":443"; ma=2592000

This is Desktop view

Login Vary Cookie conflicts can pop up when you have multiple web applications with LSCache plugins enabled on the same document root, with one app being served from a subdirectory of another (as in www.example.com/ and www.example.com/app2/). This can happen with distinct web applications, or multiple installations of the same app (e.g. two copies of WordPress).

Of particular concern is the _lscache_vary cookie, which is the default used by every LSCache plugin, and indicates the logged-in status of a user. As such, it is in control of what version of a page (logged in or not logged in) is served.

As far as the browser is concerned, both apps are the same website because one app is actually a subdirectory of the other. When the browser visits app2, it will use the cookies for www.example.com/. Even though app2 is an entirely separate application, to the browser it looks simply like a part of app1 because it lives at www.example.com/app2/.

Here's how this situation presents itself: A user logs into app1, and the _lscache_vary cookie is set to indicate that they are logged in. This same user then visits app2 as a non-logged-in user and hits the backend. LSCache caches the non-logged-in request, but the logged-in _lscache_vary cookie is still set. This causes future users logged-in to app2 to get a "cache hit" on this page and be served the non-logged-in version of the page.

To avoid this situation, each application under the same root needs a uniquely-named cookie. Add the following to .htaccess after RewriteBase and before all rules using the [L]:

RewriteRule .? - [E=Cache-Vary:_my_custom_vary]

_my_custom_vary is the new login cookie name that should be used by your plugin.


Last update: August 1, 2023