The following rule should target my front page (WordPress) to serve a different page instead.
RewriteCond %{HTTP_HOST} ^example.com$
RewriteCond %{REQUEST_URI} ^($|\/$|\?|\/\?)
RewriteRule ^(.*) https://yy.example.com [P]
so https://example.com
should serve https://yy.example.com
behind the scenes.
I also do this with several other sub-sites, like this:
RewriteCond %{HTTP_HOST} ^example.com$
RewriteCond %{REQUEST_URI} ^/zzz($|\/$|\?|\/\?)
RewriteRule ^(.*) https://yy.example.com/zzz [P]
which successfully serves https://yy.example.com/zzz
for a request on https://example.com/zzz
. This needs to be done for specific URLs only, and not for the whole domain btw.
However, the first rule for the front page does not work.
If I use [L,R=301]
instead, it does redirect to https://yy.example.com
so the RewriteCond
work correctly. But for some reason, only on the front page, the RewriteRule
does not work with [P]
while it does work with [L,R]
.
What could be the reason? Is there anything specific that needs to be added for the front page? Is WordPress somehow messing with this? The rewrite rules are at the very top of the .htaccess
file, so no earlier rule is messing with this. Also note that [R]
works which also indicates that this rule is actually reached but not correctly executed when using [P]
directive.
UPDATE:
The following rule (by MrWhite) makes is possible to correctly redirect the front page:
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteRule ^index\.php$ https://yy.example.com/ [P]
BUT, since there is WordPress running, it also redirects any other WordPress page, because from what I see, WordPress rewrites any "non-existing" path (due to pretty links, like https://example.com/zzz) to index.php, which then handles which page to display, with this default WordPress directives.
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
So, we are getting close, thanks to MrWhite, but we're not quite there yet.
ANOTHER UPDATE:
Fixed the WordPress redirects by renaming the index file of WordPress to index-wp.php
and adapt the rule to:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index-wp.php [L]
So effectively I use MrWhite's updated rule to forward access on the front page (index.php), then I filter the few /zzz sub-pages with the rules above, and everything else is then forwarded to either the actual server paths or to WordPress (index-wp.php) with those last rules.
— SOLVED —
Best Answer
mod_dir may be issuing an internal subrequest for the directory index (ie.
index.php
) before mod_rewrite/mod_proxy catches the request, in which case your directive won't match. However, there are other issues with your directive...The substitution string is missing a trailing slash after the hostname. Something needs to append this in order to make a valid HTTP request. In the case of an external redirect, the browser effectively appends the trailing slash here.
The CondPattern
^($|\/$|\?|\/\?)
is overly complex and matching too much. It will only ever match the 2nd alternation segment (ie.\/$
) - if any. TheREQUEST_URI
variable always starts with a slash and does not contain the query string. There is also no need to backslash escape the slash here (there are no regex delimiters). However, thisRewriteCond
directive is not required - you can perform the necessary check in theRewriteRule
pattern - which will also be more efficient.Try the following instead:
The
RewriteRule
pattern^(index\.php)?$
matches either/
or/index.php
.