Combining more then 1 Apache rewriterule: virtualhost domain redirect and inputfile redirection

I got stuck on using Apache's RewriteCond and RewriteRule conditions. I usually don't use them a lot and mostly the documentation provides me enough information to produce a solution by my self. This time however I got stuck on how to combine more then 1 rewrite situation.

On Apache 2.4.17 I have a virtual host with serveral ServerAliases all pointing to the same ServerName and directory. Every configured ServerAlias should redirect to the ServerName domain. So when I visit sub1.domain.com, sub2.domain.com or sub3.domain.com it all should be HTTP 301 redirected to www.domain.com.

Also I want to redirect all URL to the same PHP inputfile. For example: www.domain.com/news/1 should be internally redirected to the index.php file at the documentroot of the virtalhost without changing the URL in the user's webbrowser.

Above situations do work on it's own, but when I try to combine the situations at the .htaccess file things go wrong.

Example of my domain redirecting:

AcceptPathInfo On
Options +MultiViews

Options +FollowSymLinks  
RewriteEngine On  

# Following solution inspired by https://makandracards.com/makandra/922-apache-redirect-all-requests-from-one-host-to-another
RewriteCond %{HTTP_HOST} !^www.domain.com$
RewriteRule ^(.*)$ "https://www.domain.com/$1" [NC,QSA,R=301]

This works very well.

And this is the code I normally use to redirect all URL internally to index.php at the documentroot to be able to generate dynamic content based on the URL:

AcceptPathInfo On
Options +MultiViews

Options +FollowSymLinks  
RewriteEngine On  

RewriteCond %{SCRIPT_FILENAME} !-d  
RewriteCond %{SCRIPT_FILENAME} !-f  

RewriteRule ^.*$ ./index.php

This works also very well. The request don't get forwarded at the users browsers to index.php but only internal.

When I try to combine both redirects:

AcceptPathInfo On
Options +MultiViews

Options +FollowSymLinks  
RewriteEngine On  

# Following solution inspired by https://makandracards.com/makandra/922-apache-redirect-all-requests-from-one-host-to-another
RewriteCond %{HTTP_HOST} !^www.domain.com$
RewriteRule ^(.*)$ "https://www.domain.com/$1" [NC,QSA,R=301]

RewriteCond %{SCRIPT_FILENAME} !-d  
RewriteCond %{SCRIPT_FILENAME} !-f  

RewriteRule ^.*$ ./index.php

Then things go wrong. All requests on the other domains (for example sub1.domain.com, sub2.domain.com/test, etc.) results in an Apache error:

Moved Permanently

The document has moved here.

Additionally, a 301 Moved Permanently error was encountered while trying to use an ErrorDocument to handle the request.

While www.domain.com/test correctly serves the content of index.php at the document root.

When I try to change the order of the conditions and rules:

AcceptPathInfo On
Options +MultiViews

Options +FollowSymLinks  
RewriteEngine On  

RewriteCond %{SCRIPT_FILENAME} !-d  
RewriteCond %{SCRIPT_FILENAME} !-f  

RewriteRule ^.*$ ./index.php

# Following solution inspired by https://makandracards.com/makandra/922-apache-redirect-all-requests-from-one-host-to-another
RewriteCond %{HTTP_HOST} !^www.domain.com$
RewriteRule ^(.*)$ "https://www.domain.com/$1" [NC,QSA,R=301]

Then sub1.domain.com got correctly redirected at the user's browser to www.domain.com, but when I append a URI to it like sub1.domain.com/test then it got redirected to www.domain.com/index.php instead of www.domain.com/test and only internally fetching the content of index.php at the documentroot.

Requesting www.domain.com/test directly in this case does work well: the content of index.php at the documentroot is being displayed instead of redirecting the user to index.php.

I believe it have to do something with some flags, but don't know in which way to apply them. Who can explain me on what things I have to pay attention to?

1
задан 22 October 2016 в 18:38
1 ответ

Думаю, я уже решил проблему, добавив флаг [L] . в обе строки RewriteRule .

Это мой файл htaccess прямо сейчас:

AcceptPathInfo On
Options +MultiViews

Options +FollowSymLinks  
RewriteEngine On 

# Following solution inspired by https://makandracards.com/makandra/922-apache-redirect-all-requests-from-one-host-to-another
RewriteCond %{HTTP_HOST} !^www.domain.com$
RewriteRule ^(.*)$ "https://www.domain.com/$1" [NC,QSA,R=301,L]

RewriteCond %{SCRIPT_FILENAME} !-d  
RewriteCond %{SCRIPT_FILENAME} !-f  

RewriteRule ^.*$ ./index.php [L]

Насколько я понимаю, теперь Apache сначала посмотрит на

RewriteCond %{HTTP_HOST} !^www.domain.com$

, а затем выполнит

RewriteRule ^(.*)$ "https://www.domain.com/$1" [NC,QSA,R=301,L]

С тех пор RewriteRule имеет установленный флаг [L] Apache не будет проверять наличие других правил.

Если полный URL не соответствует первому RewriteCond Apache пропустит эта комбинация RewriteCond / RewriteRule и часть с

RewriteCond %{SCRIPT_FILENAME} !-d  
RewriteCond %{SCRIPT_FILENAME} !-f  

RewriteRule ^.*$ ./index.php [L]

, которая выполняет только внутренние перенаправления. И теперь оно не объединяется с первым RewriteRule , потому что это RewriteRule пропускается из-за флага [L] .

Я прав? Может кто-нибудь подтвердить или опровергнуть это объяснение? Или может прояснить?

0
ответ дан 4 December 2019 в 05:40

Теги

Похожие вопросы