Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

I've got an Apache vhost which performs a number of rewrite operations (using mod_rewrite) on the requested URLs. Some of these RewriteRule calls redirect the browser to other hosts (using 301 and 302 redirections).

I have set a default expiry of 1 second in that vhost file:

ExpiresActive On
ExpiresDefault "access plus 1 second"

and accordingly, all of the redirections include this header:

Cache-Control: max-age=1

Now what I'm trying to do is to output a different caching header in the case of one particular redirection. I want most of the redirections (the 302s) to continue have a 1 second expiry, but for one of them (a 301), I'd like to use a 1-day expiry instead.

Is this doable?

share|improve this question

5 Answers 5

up vote 1 down vote accepted

There is a way to do this, but not with mod_expires. Instead you must set an environment variable using mod_rewrite and then conditionally add the right caching headers with mod_headers as described in http://mark.koli.ch/2010/12/set-cache-control-and-expires-headers-on-a-redirect-with-mod-rewrite.html.

So my final solution looks like this:

RewriteRule ... [last,redirect=301,env=longexpiry:1]
RewriteRule ... [last,redirect=302,env=nocache:1]

Header always set Cache-Control "no-store, no-cache, must-revalidate" env=nocache
Header always set Cache-Control "max-age=86400" env=longexpiry

Make sure you don't have a default expiry set by mod_expires though or you will end up with duplicate headers.

share|improve this answer
    
Thanks, I was having the same problem (trying to use a redirect to watermark hotlinked images) and the redirect was being cached. That fixed it. –  Lendrick Mar 22 '12 at 17:17

For this you need to make another virtual host that has the different settings, and for the redirects you want under "this situation" use that vHost instead. This is not PHP code, it's Apache language. Sorry. There are no if-thens.

share|improve this answer

You could try using SetEnvIf directive from Apache mod_setenvif. Something like this (not tested):

SetEnvIf Request_URI \.gif EXPIRES1DAY
Header set Cache-Control max-age=86400 env=EXPIRES1DAY
share|improve this answer

One way of solving this problem without removing your default expiration set by mod_expires is to add a <Location> block for the URL that is being redirected. Let's say you're redirecting to a versioned folder and you will periodically change that version:

RewriteRule ^/approot/(.*)  /approot.1.2.3.4/$1 [R=307,L]

If you don't want that redirect to be cached (but you do want actual content to be cached), just add this block to your configuration:

<Location /approot>
    ExpiresActive Off
</Location>

Of course, "/approot" represents whatever URL you are redirecting.

Simple and easy. You don't have to fiddle with your already-working mod_expires configuration. You don't have to try to add or remove headers with mod_headers. You just tell mod_expires to not add its headers for the URL that you're redirecting.

I first tried the accepted answer above (by Francois Marier) but it didn't work because I didn't want to disable my ExpiresDefault setting and then have to replicate an expiration in many different areas of the configuration in its place.

share|improve this answer

Expanding on @Francois Marier's answer, I needed a rewrite rule that looks like this without the 30X redirect :

RewriteRule ^version/[0-9a-z\-]*/(.*)$ /foo/$1 [E=versioncache:1]

And since I wanted to use versioncache in a Header set rule, it needs to be:

Header always set Cache-Control "max-age=86400" env=REWRITE_versioncache

How long do you think it to me to figure out why the obvious ... env=versioncache didn't work? Thanks to this answer for the hint on apache prepending REWRITE_.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.