Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apache: set max-age or expires in .htaccess for directory

I have a handful of directories with content which will never change.

Is it possible to create .htaccess file which tells the browser that anything in this directory and sub- directories can be cached for a very long time?

I would like to copy the same .htaccess file in each directory if possible.

If this is possible would you recommend max-age over expires or both?

like image 248
Brian McGinity Avatar asked May 25 '13 14:05

Brian McGinity


2 Answers

So it does look possible.... the .htaccess file syntax is:

Header unset Last-Modified
FileETag none
ExpiresActive On
ExpiresDefault "access plus 1 years"

This will turn off Etags and turn on cache-control: max-age

Then put this .htaccess file in the directory and all files (including it's sub-directories will be cached for 1 year.

I decided to put all my cache-able content under a single root directory and edit the httpd.conf as

<Directory "C:\somedir\cache">
  Header unset Last-Modified
  FileETag none
  ExpiresActive On
  ExpiresDefault "access plus 1 years"
</Directory>

I am still in the process of testing this. I just hope this does not turn off Etags for the rest of the site. So far it looks like it's working as planned.


UPDATE (after 6 months):

Setting the ExpiresDefault and allowing e-tags is the best thing to do.

in httpd.conf:

<Directory "C:\somedir\cache">
   ExpiresActive On
   ExpiresDefault "access plus 1 year"
</Directory>

Make sure "somedir" is inside of the apache root (such as htdocs).

Allowing e-tags is a good because after 1 year, the browser will re-validate the file by passing the e-tag. The web server will send back a 304 - Not Modified and reset the max-age to 1 year. This is very efficient.

All in all, you can watch the apache log file and see that items in /cache dir are begin served once.

Note: I have found that setting Header append Cache-Control "public" is ok to do if you want.


Final Version:

Here's the final version: (just add this at the bottom of the httd.conf)

<Directory "C:\somedir\cache">
   ExpiresActive On
   ExpiresDefault "access plus 1 year"
   Header append Cache-Control "public"
</Directory>

Inspecting the header should reveal this:

Accept-Ranges:bytes
Cache-Control:max-age=31536000, public
Connection:Keep-Alive
Content-Language:en
Content-Length:746
Content-Type:text/css
Date:Thu, 29 May 2014 15:23:50 GMT
ETag:"240000000add63-2ea-4f4086d72ad01"
Expires:Fri, 29 May 2015 15:23:50 GMT
Keep-Alive:timeout=40, max=200
Last-Modified:Fri, 07 Mar 2014 18:28:59 GMT

This will:

  1. Set the max-age for 1 year (the longest recommended)
  2. Send the expires tag of 1 year
  3. Send an Etag, so after 1 year the browser will perform etag validation
  4. Let intermediate caching devices/services know that they can cache the file for 1 year.
like image 173
Brian McGinity Avatar answered Sep 17 '22 14:09

Brian McGinity


FYI, if you do what is mentioned above and your Apache won't restart then you may be getting this error:

The Apache service named  reported the following error:
>>> Invalid command 'ExpiresActive', perhaps misspelled or defined by a module not included in the server configuration.

You can find that error by clicking "Start", type in "Computer Management", launch it, in the tree open "Event Viewer -> Windows Logs -> Application". That's where I found the error above.

Easy fix, just uncomment this line in httpd.conf:

#LoadModule expires_module modules/mod_expires.so
like image 20
gfrobenius Avatar answered Sep 17 '22 14:09

gfrobenius