Reputation: 91
In an .htaccess
inside the subdirectory alpha
(a few directories down from root: http://domain.com/subsite/alpha/.htaccess
) I want to catch all requests for files in:
http://domain.com/subsite/alpha/images/
and redirect them to:
http://domain.com/subsite/alpha/img/
My .htaccess
looks like this:
RewriteRule ^images/(.*)$ %{REQUEST_URI}/\.\./\.\./img/$1 [R=302,NC,L]
This only works if there are no further directories inside /images
. I could make it work from root like so
RewriteRule ^images/(.*)$ /subsite/alpha/img/$1 [R=302,NC,L]
but then I'd have to manually update this from alpha
to beta
, preprod
, etc.
Basically, I need a way to isolate everything between ^
and images/
. I tried some variations on this:
RewriteRule ^(.*)images/(.*)$ /$1/img/$2 [R=302,NC,L]
RewriteRule ^(.*)images/(.*)$ ^$1/img/$2 [R=302,NC,L]
But it doesn't work because the .htaccess
is in alpha
and doesn't know about what's between it and root. Thus in the above, $1
isn't /subsite/alpha
but whatever is between /alpha
and images/
.
Upvotes: 1
Views: 1993
Reputation: 784918
You can use RewriteBase
and use relative path:
RewriteEngine On
RewriteBase /subsite/alpha/
RewriteRule ^images/(.*)$ img/$1 [R=302,NC,L]
Or else if you want to avoid using RewriteBase
then use this rule to generate dynamic RewriteBase
:
RewriteEngine On
RewriteCond $0#%{REQUEST_URI} ^([^#]*)#(.*)\1$
RewriteRule ^.*$ - [E=BASE:%2]
RewriteRule ^(.*?/)?images/(.*)$ %{ENV:BASE}$1img/$2 [R=302,NC,L,NE]
How dynamic RewriteBase
works:
REQUEST_URI
variable (which is complete path) with the URI matched by RewriteRule
(which is relative to current path) and gets differential in %{ENV:BASE}
variable.$0
captured from RewriteRule
in your RewriteCond
because mod_rewrite
actually processes a ruleset backwards. It starts with the pattern in the RewriteRule
, and if it matches, goes on to check the one or more RewriteCond
.RewriteCond
, the LHS (test string) can use back-reference variables e.g. $1
, $2
OR %1
, %2
etc but RHS side i.e. condition string cannot use these $1
, $2
OR %1
, %2
variables.\1
, \2
etc.RewriteCond
first captured group is ([^#]*)
. It will be represented by internal back-reference `\1.RewriteBase
dynamically by comparing %{REQUEST_URI}
and $0
. An example of %{REQUEST_URI}
will be /directory/foobar.php
and example of $0
for same example URI will be foobar.php
. ^([^#]*)#(.*)\1$
is putting the difference in 2nd captured group %2
or \2
. Here t will populate %2
or \2
with the value /directory/
which is used later in setting up env variable %{ENV:BASE}
i.e. E=BASE:%2
.Upvotes: 4