How To Set Up A Caching Reverse Proxy With Squid 2.6 On Debian Etch - Page 2
4 HTTP Headers
Caching doesn't work out-of-the-box - you must modify your web application so that caching can work (it is possible that your web application already supports caching - please consult the documentation of your application to find out). Squid will cache web pages only if the HTTP headers sent out by your web application tell it to do so.
Here are some examples of headers that tell Squid not to cache:
- Expires headers with a date in the past: "Expires: Sun, 19 Nov 1978 05:00:00 GMT"
- Certain Cache-Control headers: "Cache-Control: no-store, no-cache, must-revalidate" or "Cache-Control: must-revalidate, max-age=0, s-maxage=0"
- Set-Cookie headers: a page will not be cached if a cookie is set.
So if you want Squid to cache your pages, modify your application to not send out such headers.
If you want Squid to cache your pages, you can set an Expires header with a date in the future, but the recommended way is to use s-maxage:
"Cache-Control: must-revalidate, max-age=0, s-maxage=600"
This tells Squid to cache the page for 600 seconds (s-maxage), and at the same time it tells the user's browser not to cache the page (max-age) - double-caching can lead to some unexpected results!
Of course, this header is useless if you send out one of the non-caching headers (Expires in the past, Set-Cookie, etc.) from above at the same time!
Another very important header for caching is this one:
"Vary: Accept-Encoding"
This makes Squid keep two copies of each cached page, one compressed (gzip) and one uncompressed so that it can deliver the right version depending on the capabilities of the user-agent/browser. Some user-agents don't understand gzip compression, so they should get the uncompressed version.
So here's the summary: use the following two headers if you want Squid to cache:
"Cache-Control: must-revalidate, max-age=0, s-maxage=600"
"Vary: Accept-Encoding"
and make sure that no Expires with a date in the past, cookies, etc. are sent.
If your application is written in PHP, you can use PHP's header() function to send out HTTP headers, e.g. like this:
header("Cache-Control: must-revalidate, max-age=0, s-maxage=600");
header("Vary: Accept-Encoding");
This page is a must-read if you want to learn more about HTTP headers and caching: http://www.mnot.net/cache_docs/
5 Different Content For Different Users
Now let's assume you have logged-in users whose pages should not be cached, whereas the pages for anonymous user should be cached.
You can do that by setting a cookie (I name it LOGGED_IN in this example) whenever a user logs in and by unsetting it when he logs out. When you user logs in, you can set the cookie like this in PHP (valid for a week = 604800 seconds):
setcookie('LOGGED_IN', 'Y', $_SERVER['REQUEST_TIME'] + 604800, '/');
When the user logs out, you can unset the cookie by giving it a date in the past:
setcookie('LOGGED_IN', '', $_SERVER['REQUEST_TIME'] - 31536000, '/');
Now we must configure Squid so that it does not cache pages when the cookie LOGGED_IN has the value Y. Open /etc/squid/squid.conf...
vi /etc/squid/squid.conf
... and add the following lines to it:
[...] acl cookie_logged_in_set rep_header Set-Cookie LOGGED_IN=Y cache deny cookie_logged_in_set acl cookie_logged_in_out rep_header Cookie LOGGED_IN=Y cache deny cookie_logged_in_out acl cookie_logged_in req_header Cookie LOGGED_IN=Y cache deny cookie_logged_in |
Then restart Squid:
/etc/init.d/squid restart
6 Watching Your Headers
To find out what HTTP headers your application is sending out, you can install the LiveHTTPHeaders plugin for Firefox. With the help of that plugin you can also find out if a page is served from the cache (HIT) or not (MISS).
Here's an example of a HIT (Age shows the age of the cache copy in seconds):
HTTP/1.0 200 OK
Date: Wed, 17 Dec 2008 09:57:03 GMT
Server: Apache/2.2.3 (Debian) PHP/5.2.0-8+etch13
X-Powered-By: PHP/5.2.0-8+etch13
Cache-Control: must-revalidate, max-age=0, s-maxage=600
X-UA-Compatible: IE=7
Last-Modified: Wed, 17 Dec 2008 09:06:29 GMT
Etag: "e8b0de24351dd12ab17a196fca9571a4"
Content-Encoding: gzip
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8
Age: 74
X-Cache: HIT from www.example.com
X-Cache-Lookup: HIT from www.example.com:80
Via: 1.0 www.example.com:80 (squid/2.6.STABLE5)
Connection: close
And here's a MISS:
HTTP/1.0 200 OK
Date: Wed, 17 Dec 2008 09:56:47 GMT
Server: Apache/2.2.3 (Debian) PHP/5.2.0-8+etch13
X-Powered-By: PHP/5.2.0-8+etch13
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
X-UA-Compatible: IE=7
Set-Cookie: PHPSESSID=c516a650bdba0719d216d21d345cb26a; expires=Fri, 09 Jan 2009 13:30:07 GMT; path=/
Last-Modified: Wed, 17 Dec 2008 09:56:47 GMT
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 9419
Content-Type: text/html; charset=utf-8
X-Cache: MISS from www.example.com
X-Cache-Lookup: MISS from www.example.com:80
Via: 1.0 www.example.com:80 (squid/2.6.STABLE5)
Connection: close
7 Links
- Squid: http://www.squid-cache.org/
- Apache: http://httpd.apache.org/
- LiveHTTPHeaders Firefox plugin: http://livehttpheaders.mozdev.org/
- Caching tutorial: http://www.mnot.net/cache_docs/
- PHP: http://www.php.net/
- Debian: http://www.debian.org/