-
-
Notifications
You must be signed in to change notification settings - Fork 638
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Filename-based cache busting issue for Apache 2.2+ #47
Comments
@warrenski Thank you for taking the time to open this issue!
@warrenski Can you provide more details? What exactly do you mean by Thanks!
This project only supports Apache Note: Looking at our test results, everything seems to work (see results for |
Closing until more details are provided that would help reproduce the issue. |
@alrra I'm on CentOS 5.6 running Apache 2.2.29 compiled from source with a basic set of modules active, including mod_rewrite which is statically compiled and the only module of relevance for this particular section of config. I have added your filename-based cache busting config inside of a VirtualHost container inside of httpd.conf and restarted Apache after running a configtest. It goes without saying that the RewriteRule does what is intended (i.e. it achieves dynamic versioning of resources to invalidate browser cache). As an example, if you have a physical file on disk named "foo.css" and you referenced it via a URL as "foo.12345.css", then the contents of the file is correctly returned by the server. However, in my case, if you additionally happened to have a file on disk named "foo.12345.css", then rather than the server returning its contents (due to the presence of the RewriteCond directive blocking the RewriteRule directive), the contents of "foo.css" was incorrectly being returned. Logically this meant that the RewriteCond directive was not able to find REQUEST_FILENAME on disk. The solution for me was to prepend DOCUMENT_ROOT in front of REQUEST_FILENAME. Apache's mod_rewrite documentation does discuss some things to be aware of when using REQUEST_FILENAME, but I haven't digested or tested beyond what I've written above. Reading the notes now quickly, it appears that because I'm inside of a VirtualHost, REQUEST_FILENAME is unavailable. As I say, it might just be my situation, but hopefully if anyone else has a similar issue they will find this workaround. See also: |
@warrenski Thanks for providing the details.
No, this seems like a legitimate case, and we should address it. Can you open a pull request that updates the existing code with the solution you have so that if this gets merged you get the credit for it? Thanks! @warrenski I'll dig a little bit more into this, hopefully tonight. |
@alrra No worries on getting credit - we're using SVN over here so don't think I can facilitate the pull request. Good luck and thanks for looking into it. |
Using 2.4.10 I was not able to reproduce a problem (I also performed the same test with 2.2.22). This is with only the following physical files:
and h5bp's A request that should NOT be rewrittenRequesting a file matching the pattern that does exist:
The result is the contents of With log level set to
A request that should be rewrittenCompared to a request matching the pattern that does not exist:
The result is the contents of With the following log entries:
Take homeNotice that the input to the
I don't really understand "such as when used in a virtualhost context, the same value as Either way though, I do not recommend taking any action here as, without understanding why the path was wrong for @warrenski, changing the rule will simply break it for many other users. |
@AD7six Thanks for the legwork Andy This certainly is quite an odd situation. Based on Andy's evidence, I'm happy to accept that this is not an issue for everyone. However, below I'll give you the output I see on my server: first with the untouched RewriteRule config per the repo source, then with my I've followed the same process as @AD7six did in his experiment, and have used the same physical files, namely:
These files respectively contain the following simple style rules: /* main.12345.css */
body {
background-color: red;
} and /* main.css */
body {
background-color: green;
} Here's the relevant portion of my Apache <VirtualHost *:80>
ServerName vs9.lh.warrenski.com
DocumentRoot "/home/httpd/htdocs"
RewriteLog "/var/log/httpd/rewrite_log"
RewriteLogLevel 8
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)\.(\d+)\.(bmp|css|cur|gif|ico|jpe?g|js|png|svgz?|webp)$ $1.$3 [L]
</IfModule>
</VirtualHost> Restart Apache to apply the config:
A request that should NOT be rewrittenRequesting a file matching the pattern that does exist:
The result is the contents of The
A request that should be rewrittenRequesting a file matching the pattern that does not exist:
The result is the contents of The
Alter Apache's RewriteCond directiveAfter the above tests I altered Apache's RewriteCond directive to include the <VirtualHost *:80>
ServerName vs9.lh.warrenski.com
DocumentRoot "/home/httpd/htdocs"
RewriteLog "/var/log/httpd/rewrite_log"
RewriteLogLevel 8
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteRule ^(.+)\.(\d+)\.(bmp|css|cur|gif|ico|jpe?g|js|png|svgz?|webp)$ $1.$3 [L]
</IfModule>
</VirtualHost> Restart Apache to apply the config:
Re-testing a request that should NOT be rewrittenRequesting a file matching the pattern that does exist:
The result is the contents of The
ConclusionI'm stumped as to why my server's behaving differently to yours @AD7six, and I can't think of any leads to explain the difference. I'd have to concur with your recommendation not to make a change to the repo, in case it breaks it for others. Hopefully this thread will come up via a Google search and help anybody else battling with a similar problem. |
@warrenski so what's happening is the config you're using falls into:
I was using a .htaccess file, and your use case is (the preferred) conf files - My first attempt to use a conf-based test showed no change but by experimenting a little I think I've figured it out. This works:It'll work when the rule is in a .htaccess file, or inside a directory block i.e. this config would work:
This does not work:
Because: reasons. In this case the rule is applied "in virtual host context" - hence it's the URI not an absolute file path. There are actually quite a few tickets for this behavior in apache's bug tracker, such as this one - all stemming from the confusion created by this variable not being an absolute path sometimes. So mystery solved. I don't know if there are other cases like this to account for - definitely something to keep in mind though. |
@AD7six I think you've answered it then, thanks again for digging around. It's been a pleasure working through this together. |
@AD7six Thanks for looking into this! 👍 |
No problem - I'm quite happy to help in my selfish quest to learn and understand =). |
In the Apache RewriteRule that manages filename-based cache busting, the RewriteCond directive no longer work as intended for Apache versions 2.2+
Luckily the fix is quite simple; all you need to do is add the
DOCUMENT_ROOT
variable before theREQUEST_FILENAME
variable.Apache < 2.2:
Apache > 2.2:
On Apache 2.2.29 I've confirmed that the cache-busting RewriteRule works as intended after making this change (i.e. Apache serves the resource whose filename happens to match the regexp pattern).
The text was updated successfully, but these errors were encountered: