Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Excerpt from <VirtualHost *:80> section in httpd.conf (goal: set Cache-Control for all JavaScript files):

<LocationMatch "\.js">
    Header set Cache-Control "max-age=290304000, public"

.htaccess (part of Symfony PHP framework):

Options +FollowSymLinks +ExecCGI

<IfModule mod_rewrite.c>
  RewriteEngine On

  # we check if the .html version is here (caching)
  RewriteRule ^$ index.html [QSA]
  RewriteRule ^([^.]+)$ $1.html [QSA]
  RewriteCond %{REQUEST_FILENAME} !-f

  # no, so we redirect to our front web controller
  RewriteRule ^(.*)$ index.php [QSA,L]

Now, I checked the Cache-Control header with two different URLs pointing at the same resource:

  1. /index.php/pt_BR/home_page.js: Cache-Control set as specified above

  2. /pt_BR/home_page.js: Cache-Control with some other value

Now, why is the Cache-Control header not set for /pt_BR/home_page.js?

Note that there is no query string involved, and <LocationMatch "\.js"> matches before and after rewrite.

share|improve this question
Is there a file in <DocumentRoot>/pt_BR/home_page.js ? The RewriteCond depends on this. – Ladadadada May 22 '12 at 15:23
@Ladadadada: No, no file in that location. Note that I am using LocationMatch, not FilesMatch. – feklee May 22 '12 at 16:16
@feklee Is it supposed to be rewriting to just index.php without appending what was captured from the original string? The rewritten request URL doesn't contain .js anywhere if that last RewriteRule directive hits. – Shane Madden May 23 '12 at 5:36
@Shane Madden: You are right - it's very simple. The URLs (/index.php/pt_BR/home_page.js, /pt_BR/home_page.js) get rewritten to /index.php?pt_BR/home_page.js. And then: LocationMatch doesn't match anymore, because it doesn't match query strings. – feklee May 23 '12 at 6:03
The LocationMatch and the front controller rewrite apply in both cases, however, and you are getting different results for them. Since the file doesn't exist, symfony must be serving both cases. My guess (and this is just a guess) is that both requests get the Cache-Control header from your LocationMatch but symfony overrides one of them later on in the processing of the request. You would need to ask a symfony expert why that might be. The key here is that I think symfony is the difference, not Apache. – Ladadadada May 23 '12 at 8:52

Need to head out now, I hope I'll have more time to explain later how this plays together.

share|improve this answer
Further explanation would be great! I don't see how merging could be the cause of the described behavior. I also read the Technical Note but it only leaves me puzzled. – feklee May 22 '12 at 18:48

Your Answer


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.