Probably the ProxyPass /
directive you have in your config routes all requests to the Tomcat backend, bypassing all your mod_rewrite directives. You can try to remove the ProxyPass
directive and use RewriteRule
with the [P]
flag after your other rewrites:
For the expire headers the situation is worse — in another similar question a solution was not found.
Option +FollowSymLinks
would be needed for using mod_rewrite in .htaccess
files; in your case it is not required, because you can put everything in the Apache config. Moving rules from config to .htaccess
is pointless and can only make things slower. However, there is an important difference between .htaccess
and the Apache config — in .htaccess
patterns in RewriteRule
are matched against relative filesystem paths (which never start with /
), while in the VirtualHost
context these patterns are matched against the URL path after the hostname, which always starts with /
. Therefore at least one of your rules is incorrect:
RewriteRule ^content/(js|css)/([a-z]+)-([0-9]+)\.(js|css)$ /content/$1/$2.$4
should be
RewriteRule ^/content/(js|css)/([a-z]+)-([0-9]+)\.(js|css)$ /content/$1/$2.$4
(note the additional slash in the beginning).
Ok, so I tracked down my issue and in the spirit of Stack Exchange I wanted to share my answer.
I have to start out with an admittion, I did not mention the Apache version I was using, I am using Apache 2.4.
Turns out that after all I was getting bitten by a reported bug in Apache (2.2 -> 2.4), namely Bug 38642 - mod_rewrite adds path info postfix after a substitution occured.
The bug intails addition of the path incorrectly when a substition is made, therefor after each of my RewriteRules affecting the query string the path was indeed re-appended.
The bug is fixed in Apache 2.5 reportedly, and there is a work around, by using the DPI flag in the rewrite rules.
This makes my example as so :
# Activate Rewrite and set the base to the web path
RewriteEngine On
RewriteBase /
# Remove 'key1' from the Querystring, and remove any resulting double &'s
RewriteCond %{QUERY_STRING} (.*)(?:^|&)key1=(?:[^&]*)((?:&|$).*)
RewriteCond %1%2 (^|&)([^&].*|$)
RewriteRule ^(.*)/$ $1?%2 [DPI,E=querycleaned:1]
#Remove 'key2' from the resulting URI, and remove double & again
RewriteCond %{QUERY_STRING} (.*)(?:^|&)key2=(?:[^&]*)((?:&|$).*)
RewriteCond %1%2 (^|&)([^&].*|$)
RewriteRule ^(.*)/$ $1?%2 [DPI,E=querycleaned:1]
#Catch and handle requests beginning with 'oldfolder'
#$1 = non greedy match everything following oldfolder
RewriteRule ^oldfolder(.*)$ $1 [L,NC,R=301]
#Catch the folder1/folder2/folder3 path and rewrite
RewriteRule ^folder1/folder2/folder3(.*)$ newfolder$1 [L,NC,R=301]
#Catchall, if query string cleaned but not previously matched, then redirect to clean string
RewriteCond %{ENV:querycleaned} 1
RewriteRule ^(.*)$ $1 [L,R=301]
As you can see, DPI
flag is added to any rule that might make a change but is not flagged as L
ast.
You may also notice the E=querycleaned:1
flag. This is simply to set an Enviroment Variable in order to catch all, you see the origional example would clean the query string if one of the following Rewrite rules matchd (started with oldfolder or folder1/folder2/folder3) however I wanted the query string cleaned regardless, so basicall I'm setting a variable to indicate if the query was cleaned, if it is you'll notice the new catch all rule at the bottom, which redirects to the existing path, with the clean query.
There you go, solved and solved. In the interest of fairness however once I knew the solution I was able to find a couple of duplicate questions here, so I wasn't the first. I can't even find the question I first found in my history but a quick search on DPI
yeilds a few results.
Best Answer
This should already have "worked". It should have removed any query string, providing "collcc=" was found anywhere in the requested URL's query string.
This is assuming you aren't getting any "errors" and mod_rewrite is already enabled, with the appropriate directives. For example:
The other possibility is that your directives are located in the wrong place in your
.htaccess
file which is resulting in a conflict with existing directives. This redirect will need to go near the top of your.htaccess
file, before any existing rewrites.