Apache: ExpiresDefault doesn't work, whereas "Header" does. How comes? - apache

If I do this:
<IfModule mod_expires.c>
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf|mp3|mp4|css|js|php)$">
ExpiresActive On
ExpiresDefault "access plus 30 days"
</FilesMatch>
</IfModule>
It doesn't set properly the Expire header, whereas if I "force" it by hand like this:
<IfModule mod_expires.c>
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|swf|mp3|mp4|css|js|php)$">
ExpiresActive On
Header set Expires "Thu, 18 Jan 2012 20:00:00 GMT"
</FilesMatch>
</IfModule>
It works. This implies 2 things:
mod_expire is installed (IfModule mod_expires.c is true)
the Expire header is not modified after this rule is applied.
What am I missing?
By the way: if you have any solution to make it work I'm your man!

Ok I've got it from the official documentation here:
Note that if you use a modification date based setting, the Expires
header will not be added to content that does not come from a file on
disk. This is due to the fact that there is no modification time for
such content.
So it works only for static files, and not for all the other ones: they're not static.

This one got me stumped as well because AFAIK, it should work so I tried it on a test VM varying the N days and refreshing. Works fine for me. My Apache version is
Server version: Apache/2.2.14 (Ubuntu)
Server built: Nov 18 2010 21:17:19
Any the headers for a test file (using chrome developer tools) (with N=15) show:
Date:Mon, 09 Jan 2012 01:48:43 GMT
ETag:"7574-5-4b60e88a820a1"
Expires:Tue, 24 Jan 2012 01:48:43 GMT
My thought is that any ExpiresDefault can be overridden by a Header set Expires. Have you grepped the .htaccess hierarchy to make sure that your ExpiresDefault isn't being overridden at a lower level.
If you don't want htaccess files doing this you need to disable them in your http config.

Related

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?
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:
Set the max-age for 1 year (the longest recommended)
Send the expires tag of 1 year
Send an Etag, so after 1 year the browser will perform etag validation
Let intermediate caching devices/services know that they can cache the file for 1 year.
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

How can I stop Joomla (Apache) from caching the admin backend?

I've a big cache issue with my Joomla 1.5.26 (Apache/2.2.14 Ubuntu) administrator panel.
Everything is cached for about 15 minutes, and by everything I mean everything.
If I go to global configuration and change any value there, for example the Site Name from "MyTestSite" to "MyTestSite2", or the Feed length from 15 to 30 and save it a message is displayed that everything was saved and the cache was cleaned. If I go immediately to the global config again, I see that the old values (MyTestSite and 15) are still there. If I look into configuration.php I see that the file was correctly changed. Also, if I wait 15 minutes I can see the correct value. This is not related only to configuration, but even to article editing!
It's the same on 2 computers, and with Firefox, Chrome, and IE.
I've tried to fix it by placing a .htaccess in /admistrator/ to disable any caching, but to no avail.
I've tried this:
<ifModule mod_headers.c>
Header unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</ifModule>
or this:
ExpiresActive On
ExpiresDefault "access plus 1 minute"
What is going on here? (it was working fine for 2 years). How can I stop Joomla from caching the admin backend?

Overwrite cache-headers with mod_expires

I want to set cache-headers using the mod_expires module from apache. My configuration looks somewhat like this:
<LocationMatch ^/static >
ExpiresDefault "access plus 1 years"
</LocationMatch>
The problem is, that the files are generated by a third system I don't control. These system provides files with the following headers:
Date Mon, 24 Oct 2011 08:39:02 GMT
Cache-Control no-cache,no-store,must-revalidate
Pragma no-cache
Expires Thu, 01 Dec 1994 16:00:00 GMT
These headers makes it impossible to set the cache-headers with mod_expires. http://httpd.apache.org/docs/2.2/mod/mod_expires.html tells us why:
When the Expires header is already part of the response generated by the server, for example when generated by a CGI script or proxied from an origin server, this module does not change or add an Expires or Cache-Control header.
Is there any possible way to circumvent this rule and overwrite the headers with mod_expires?
Update:
One possible solution, to avoid this limitation is to use only mod_headers to set the cache-headers. Unfortunately, this isn't an alternative because the values have to be calculated.
Thanks it advance.
Unfortunately, it's a known limitation and we had to fall back to use only mod_headers.
Regilero's suggestion won't work because header directives will be processed very late in the response processing - after mod_expire directive. So you'd unset the headers after mod_expires did (or didn't) what it was supposed to do.
If it's apache 2.2 you could try putting early at the end of each header directive. That will tell it to do this in an early stage of response processing as opposed to at the end.
so try:
<LocationMatch ^/static >
Header unset Cache-Control early
Header unset Pragma early
Header unset Expires early
ExpiresDefault "access plus 1 years"
</LocationMatch>
Haven't tested tho, but give it a try...
Have you tried mixing it with mod_headers?
<LocationMatch ^/static >
Header unset Cache-Control
Header unset Pragma
Header unset Expires
ExpiresDefault "access plus 1 years"
</LocationMatch>
Not tested, but in case of...

RewriteRule & Header set Expires : how to

I'm using rewrite rules to create a /fr /en on my website and does folder don't exist, therefore if I try to use
<Directory /fr>
ExpiresDefault "access plus 1 day"
</Directory>
Apache complain because the folder does not exist, can't find a way to do it in the http.conf
If I use
Header set Expires "access plus 1 day"
in the .htaccess, can see the header showing
Expires: access plus 1 day
instead of the date + 1 day, if i remove it I can see
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Also if I use
ExpiresDefault "access plus 1 day"
It does not work...
Can you please tell how to get this right?
Also I believe that Safari (and only safari) keep on reloading the page every minutes because of that, is that correct or just another issue?
Thx for your help!
Directory instructions are working on real filesystem paths. So a Directory setting should looks like :
<Directory /var/www/foo/bar/fr >
(...)
</Directory>
Instead, if you prefer working with url path you must use Location directives:
<Location /fr >
(...)
</Location>
This should at least fix your inexistents directories problems (if I understand your first sentence, which is quite strange)

mod_expires sending Cache-Control headers for 3## status codes

Apache is sending Cache-Control headers for 3## status codes, like 302 redirects. This is causing Firefox (possibly starting with Firefox 5) to cache the 302 redirects--which results in an infinite redirect loop for some of my pages.
Here are the settings that I am using in my httpd.conf:
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault A600
</IfModule>
If I remove the ExpiresDefault setting, the problem goes away, so I am confident that this is the exact setting that is causing the problem. If I change ExpiresDefault A600 to ExpiresByType text/html A600 the problem is still there.
I'd like to have browsers cache my content by default, but this is a deal-breaker.
Are there any settings I can use to tell Apache to send a different Cache-Control header for 3## status codes?
If you add the Cache-Control headers in your application, which builds the redirect, apache will not overwrite it.
Cache-Control: max-age=0
Expires: Sat, 04 Feb 2012 07:02:38 GMT
if you use apaches mod_rewrite to do the redirect you could add the headers with the
mod_headers module.